From 667954ce8388c5833608fe72e8852266fa700026 Mon Sep 17 00:00:00 2001 From: Lutz Wrage Date: Fri, 11 Sep 2026 10:42:17 -0400 Subject: [PATCH 1/2] Add regression test for issue #3211 The model reads two properties through the AS5506/3 Rev A D.7 property reference alternative that names no element. Thread_Properties::Priority has no default value, so that reference denotes nothing; the assertion requires one error on it, naming the property and the reference as written. Communication_Properties::Queue_Size has a default value, which is the value its reference denotes, so requiring exactly one issue also pins that the defaulted reference stays legal. The reference is read in an assignment rather than an array size, since the rule is about property references and not about array dimensions. The regression fails today with no issue reported at all. The corpus goldens record that same current behavior, with an empty validated diagnostics projection, so the fix shows as the diagnostic appearing. Co-Authored-By: Claude Opus 5 (1M context) --- ...te.ba.tests_models_issue3211_Issue3211.txt | 0 ...te.ba.tests_models_issue3211_Issue3211.txt | 0 ...te.ba.tests_models_issue3211_Issue3211.txt | 29 ++++++++ ...te.ba.tests_models_issue3211_Issue3211.txt | 34 +++++++++ ...te.ba.tests_models_issue3211_Issue3211.txt | 17 +++++ .../models/issue3211/.gitignore | 2 + .../models/issue3211/.project | 18 +++++ .../models/issue3211/Issue3211.aadl | 50 +++++++++++++ .../src/org/osate/ba/tests/Issue3211Test.java | 74 +++++++++++++++++++ 9 files changed, 224 insertions(+) create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3211_Issue3211.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3211_Issue3211.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3211_Issue3211.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3211_Issue3211.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3211_Issue3211.txt create mode 100644 ba/org.osate.ba.tests/models/issue3211/.gitignore create mode 100644 ba/org.osate.ba.tests/models/issue3211/.project create mode 100644 ba/org.osate.ba.tests/models/issue3211/Issue3211.aadl create mode 100644 ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3211Test.java diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3211_Issue3211.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3211_Issue3211.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3211_Issue3211.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3211_Issue3211.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3211_Issue3211.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3211_Issue3211.txt new file mode 100644 index 00000000000..88189a8b3e2 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3211_Issue3211.txt @@ -0,0 +1,29 @@ +annex[0] owner=Issue3211::reader.impl + (AssignmentAction, , 2306, 38) + (AssignmentAction, , 2498, 47) + (BehaviorActionBlock, , 2304, 42) + (BehaviorActionBlock, , 2496, 51) + (BehaviorAnnex, behavior_specification, 1969, 579) + (BehaviorCondition, , 2468, 19) + (BehaviorState, done, 2081, 4) + (BehaviorState, ready, 2053, 5) + (BehaviorState, start, 2026, 5) + (BehaviorStateGroup, , 2026, 22) + (BehaviorStateGroup, , 2053, 23) + (BehaviorStateGroup, , 2081, 19) + (BehaviorTransition, , 2286, 61) + (BehaviorTransition, , 2460, 88) + (BehaviorVariable, value, 1983, 5) + (BehaviorVariableGroup, , 1983, 28) + (DispatchCondition, , 2471, 16) + (DispatchConjunction, , 2480, 7) + (DispatchTriggerCondition, , 2480, 7) + (DispatchTriggerLogicalExpression, , 2480, 7) + (HashPropertyReference, , 2315, 29) + (HashPropertyReference, , 2507, 38) + (Reference, , 2306, 5) + (Reference, , 2480, 7) + (Reference, , 2498, 5) + (ReferenceSegment, trigger, 2480, 7) + (ReferenceSegment, value, 2306, 5) + (ReferenceSegment, value, 2498, 5) diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3211_Issue3211.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3211_Issue3211.txt new file mode 100644 index 00000000000..c98f56e264e --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3211_Issue3211.txt @@ -0,0 +1,34 @@ +annex[0] owner=Issue3211::reader.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + variables[0] : BehaviorVariable name=value + states[0] : BehaviorState name=start + states[1] : BehaviorState name=ready + states[2] : BehaviorState name=done + transitions[0] : BehaviorTransition + transitions[1] : BehaviorTransition + condition : DispatchCondition + dispatchTriggerCondition : DispatchTriggerLogicalExpression + dispatchConjunctions[0] : DispatchConjunction + dispatchTriggers[0] : EventPortHolder element=Issue3211::reader.trigger [EventPort] + actions[0] : BehaviorActionBlock + content : AssignmentAction + target : BehaviorVariableHolder element=value [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Thread_Properties::Priority [Property] + actions[1] : BehaviorActionBlock + content : AssignmentAction + target : BehaviorVariableHolder element=value [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=IntegerLiteral [IntegerLiteral] diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3211_Issue3211.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3211_Issue3211.txt new file mode 100644 index 00000000000..47b998b1774 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3211_Issue3211.txt @@ -0,0 +1,17 @@ +===== annex[0] owner=Issue3211::reader.impl ===== + +\t\t\tvariables +\t\t\t\tvalue : Base_Types::Integer; +\t\t\tstates +\t\t\t\tstart : initial state; +\t\t\t\tready : complete state; +\t\t\t\tdone : final state; +\t\t\ttransitions +\t\t\t\t-- Thread_Properties::Priority has no default value, and nothing before the '#' names a thread that has a +\t\t\t\t-- value for it, so the reference denotes no value. +\t\t\t\tstart -[]-> ready { value := # Thread_Properties::Priority }; +\t\t\t\t-- Communication_Properties::Queue_Size has a default value, which is the value this reference denotes. +\t\t\t\tready -[on dispatch trigger]-> done { value := # Communication_Properties::Queue_Size }; +\t\t +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/models/issue3211/.gitignore b/ba/org.osate.ba.tests/models/issue3211/.gitignore new file mode 100644 index 00000000000..afce51184c6 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3211/.gitignore @@ -0,0 +1,2 @@ +/.aadlbin-gen/ +/instances/ diff --git a/ba/org.osate.ba.tests/models/issue3211/.project b/ba/org.osate.ba.tests/models/issue3211/.project new file mode 100644 index 00000000000..23e536afd43 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3211/.project @@ -0,0 +1,18 @@ + + + issue3211 + + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + + org.osate.core.aadlnature + org.eclipse.xtext.ui.shared.xtextNature + + diff --git a/ba/org.osate.ba.tests/models/issue3211/Issue3211.aadl b/ba/org.osate.ba.tests/models/issue3211/Issue3211.aadl new file mode 100644 index 00000000000..f0c3e4670c0 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3211/Issue3211.aadl @@ -0,0 +1,50 @@ +-- Copyright (c) 2004-2026 Carnegie Mellon University and others. (see Contributors file). +-- All Rights Reserved. +-- +-- NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY +-- KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE +-- OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT +-- MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. +-- +-- This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 +-- which is available at https://www.eclipse.org/legal/epl-2.0/ +-- SPDX-License-Identifier: EPL-2.0 +-- +-- Created, in part, with funding and support from the United States Government. (see Acknowledgments file). +-- +-- This program includes and/or can make use of certain third party source code, object code, documentation and other +-- files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system +-- configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and +-- conditions contained in any such Third Party Software or separate license file distributed with such Third Party +-- Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici- +-- aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li- +-- censes only apply to the Third Party Software and not any other portion of this program or this program as a whole. + +package Issue3211 +public + with Base_Types; + + thread reader + features + trigger : in event port; + properties + Dispatch_Protocol => Sporadic; + end reader; + + thread implementation reader.impl + annex behavior_specification {** + variables + value : Base_Types::Integer; + states + start : initial state; + ready : complete state; + done : final state; + transitions + -- Thread_Properties::Priority has no default value, and nothing before the '#' names a thread that has a + -- value for it, so the reference denotes no value. + start -[]-> ready { value := # Thread_Properties::Priority }; + -- Communication_Properties::Queue_Size has a default value, which is the value this reference denotes. + ready -[on dispatch trigger]-> done { value := # Communication_Properties::Queue_Size }; + **}; + end reader.impl; +end Issue3211; diff --git a/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3211Test.java b/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3211Test.java new file mode 100644 index 00000000000..d371dc93ae7 --- /dev/null +++ b/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3211Test.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2004-2026 Carnegie Mellon University and others. (see Contributors file). + * All Rights Reserved. + * + * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE + * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT + * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. + * + * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * SPDX-License-Identifier: EPL-2.0 + * + * Created, in part, with funding and support from the United States Government. (see Acknowledgments file). + * + * This program includes and/or can make use of certain third party source code, object code, documentation and other + * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system + * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and + * conditions contained in any such Third Party Software or separate license file distributed with such Third Party + * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici- + * aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li- + * censes only apply to the Third Party Software and not any other portion of this program or this program as a whole. + */ +package org.osate.ba.tests; + +import static org.junit.Assert.assertEquals; + +import java.util.Comparator; + +import org.eclipse.xtext.diagnostics.Severity; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.testing.InjectWith; +import org.eclipse.xtext.testing.XtextRunner; +import org.eclipse.xtext.testing.validation.ValidationTestHelper; +import org.eclipse.xtext.validation.Issue; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.osate.aadl2.AadlPackage; +import org.osate.testsupport.TestHelper; + +import com.google.inject.Inject; + +/** + * The first AS5506/3 Rev A D.7 property_reference alternative names a property definition and nothing that holds a value + * for it, so the only value it can denote is the default value of the property. Verifies that a reference to a property + * with no default value is reported, and that a reference to a property that has one is not. + */ +@RunWith(XtextRunner.class) +@InjectWith(BehaviorAnnexInjectorProvider.class) +public class Issue3211Test { + private static final String MODELS = "org.osate.ba.tests/models/issue3211/"; + + @Inject + private TestHelper testHelper; + + @Inject + private ValidationTestHelper validationHelper; + + @Test + public void aPropertyWithNoDefaultValueIsReported() throws Exception { + var root = testHelper.parseFile(MODELS + "Issue3211.aadl"); + var source = NodeModelUtils.getNode(root).getRootNode().getText(); + // Xtext does not hand back the issues of one resource in the order the checkers report them. + var issues = validationHelper.validate(root).stream().sorted(Comparator.comparing(Issue::getOffset)).toList(); + + assertEquals(issues.toString(), 1, issues.size()); + var issue = issues.getFirst(); + assertEquals(Severity.ERROR, issue.getSeverity()); + assertEquals("# Thread_Properties::Priority", + source.substring(issue.getOffset(), issue.getOffset() + issue.getLength())); + assertEquals("Property reference '# Thread_Properties::Priority' has no value: property 'Priority' has no" + + " default value and the reference names no element that has a value for it", issue.getMessage()); + } +} From a23d79c847b1560f116027a809c8ce191b72e29f Mon Sep 17 00:00:00 2001 From: Lutz Wrage Date: Fri, 11 Sep 2026 10:44:38 -0400 Subject: [PATCH 2/2] Report a property reference that has no value The AS5506/3 Rev A D.7 property reference alternative that names no element can only denote the default value of the property it names. Translation puts that default in the first property name holder, and leaves the property definition there when the property has none, which denotes no value at all. No strict checker constrains that, so such a reference was accepted and the translated model carried a reference with nothing behind it. Report each one on the reference as written, naming the property. A reference that names a property type is untouched, since an enumeration literal is a value of its own. The check does not gate the strict checkers: the strict model does carry the reference, unlike the constructs the neighboring checks reject, so the checkers keep their model and whatever else they have to say about it. Two corpus models already wrote references of this shape and now report it: covering_syntax/aadlBaTest007.aadl in the section it marks as having no default value defined, and characterization/HolderCoverage.aadl for a record property with no default value. Neither model loses translation coverage; HolderCoverage still instantiates the same holder classes. Fixes #3211 Co-Authored-By: Claude Opus 5 (1M context) --- ...models_characterization_HolderCoverage.txt | 1 + ...s_models_covering_syntax_aadlBaTest007.txt | 10 ++++++ ...te.ba.tests_models_issue3211_Issue3211.txt | 1 + .../ba/validation/BehaviorAnnexValidator.java | 31 +++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_characterization_HolderCoverage.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_characterization_HolderCoverage.txt index e69de29bb2d..6498ec2a760 100644 --- a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_characterization_HolderCoverage.txt +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_characterization_HolderCoverage.txt @@ -0,0 +1 @@ +error | semantic | 29 | 14 | 53 | Property reference '#Issue2445_Holder_Properties::record_property.omitted' has no value: property 'record_property' has no default value and the reference names no element that has a value for it diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_covering_syntax_aadlBaTest007.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_covering_syntax_aadlBaTest007.txt index ad0f0cb2178..dafff222f35 100644 --- a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_covering_syntax_aadlBaTest007.txt +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_covering_syntax_aadlBaTest007.txt @@ -1,3 +1,13 @@ +error | semantic | 259 | 23 | 36 | Property reference '#AadlBaTestPropertySet::aSimpleValue' has no value: property 'aSimpleValue' has no default value and the reference names no element that has a value for it +error | semantic | 261 | 23 | 42 | Property reference '#AadlBaTestPropertySet::aRange.upper_bound' has no value: property 'aRange' has no default value and the reference names no element that has a value for it +error | semantic | 262 | 23 | 42 | Property reference '#AadlBaTestPropertySet::aRange.lower_bound' has no value: property 'aRange' has no default value and the reference names no element that has a value for it +error | semantic | 264 | 19 | 29 | Property reference '#AadlBaTestPropertySet::aEnum' has no value: property 'aEnum' has no default value and the reference names no element that has a value for it +error | semantic | 264 | 51 | 33 | Property reference '#AadlBaTestPropertySet::aEnum.two' has no value: property 'aEnum' has no default value and the reference names no element that has a value for it +error | semantic | 265 | 19 | 29 | Property reference '#AadlBaTestPropertySet::aEnum' has no value: property 'aEnum' has no default value and the reference names no element that has a value for it +error | semantic | 265 | 51 | 32 | Property reference '#AadlBaTestPropertySet::aEnum[1]' has no value: property 'aEnum' has no default value and the reference names no element that has a value for it +error | semantic | 267 | 23 | 41 | Property reference '#AadlBaTestPropertySet::aSimpleRecord.int' has no value: property 'aSimpleRecord' has no default value and the reference names no element that has a value for it +error | semantic | 268 | 19 | 42 | Property reference '#AadlBaTestPropertySet::aSimpleRecord.bool' has no value: property 'aSimpleRecord' has no default value and the reference names no element that has a value for it +error | semantic | 270 | 23 | 42 | Property reference '#AadlBaTestPropertySet::aComplexRecord.int' has no value: property 'aComplexRecord' has no default value and the reference names no element that has a value for it error | semantic | 367 | 23 | 35 | resolved behavior annex holder has no element error | semantic | 411 | 23 | 30 | resolved behavior annex holder has no element warning | semantic | 105 | 56 | 17 | AadlBaTest::Types in 'with' clause of public package section is not used. diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3211_Issue3211.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3211_Issue3211.txt index e69de29bb2d..21081d36a3c 100644 --- a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3211_Issue3211.txt +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3211_Issue3211.txt @@ -0,0 +1 @@ +error | semantic | 45 | 34 | 29 | Property reference '# Thread_Properties::Priority' has no value: property 'Priority' has no default value and the reference names no element that has a value for it diff --git a/ba/org.osate.xtext.aadl2.ba/src/org/osate/xtext/aadl2/ba/validation/BehaviorAnnexValidator.java b/ba/org.osate.xtext.aadl2.ba/src/org/osate/xtext/aadl2/ba/validation/BehaviorAnnexValidator.java index 09d9af76cc4..61501f44d22 100644 --- a/ba/org.osate.xtext.aadl2.ba/src/org/osate/xtext/aadl2/ba/validation/BehaviorAnnexValidator.java +++ b/ba/org.osate.xtext.aadl2.ba/src/org/osate/xtext/aadl2/ba/validation/BehaviorAnnexValidator.java @@ -49,10 +49,12 @@ import org.osate.aadl2.EventDataPort; import org.osate.aadl2.EventPort; import org.osate.aadl2.InternalFeature; +import org.osate.aadl2.Property; import org.osate.aadl2.modelsupport.errorreporting.AbstractAnalysisErrorReporter; import org.osate.aadl2.modelsupport.errorreporting.AnalysisErrorReporterManager; import org.osate.aadl2.parsesupport.ParseUtil; import org.osate.annexsupport.ParseResultHolder; +import org.osate.ba.aadlba.PropertySetPropertyReference; import org.osate.ba.analyzers.AadlBaRulesCheckersDriver; import org.osate.ba.analyzers.AadlBaTypeChecker; import org.osate.ba.analyzers.AdaLikeDataTypeChecker; @@ -89,6 +91,7 @@ public final class BehaviorAnnexValidator extends AbstractBehaviorAnnexValidator public static final String TIMEOUT_RESET_PORT_TIME = "org.osate.xtext.aadl2.ba.timeoutResetPortTime"; public static final String ITERATIVE_VARIABLE_TARGET = "org.osate.xtext.aadl2.ba.iterativeVariableTarget"; public static final String ARRAY_SIZE = "org.osate.xtext.aadl2.ba.arraySize"; + public static final String PROPERTY_REFERENCE_VALUE = "org.osate.xtext.aadl2.ba.propertyReferenceValue"; private static final URI VALIDATION_RESOURCE_URI = URI.createURI("validation:/behavior-annex.aadlba"); @Inject @@ -120,6 +123,9 @@ public void checkBehaviorAnnex(final BehaviorAnnex source) { representable &= checkInternalConditionPorts(source, translation); representable &= checkTimeoutResetPorts(source, translation); representable &= checkIteratorTargets(source, translation); + // The strict model does carry a property reference that denotes no value, so this one is not a gate: the strict + // checkers keep their model and whatever else they have to say about it. + checkPropertyReferenceValues(translation); if (!representable) { return; } @@ -172,6 +178,31 @@ private boolean checkArraySizes(final BehaviorAnnex source) { return accepted; } + /** + * The first AS5506/3 Rev A D.7 property_reference alternative writes a property value name after {@code #} with no + * element before it, so the reference names a property definition without naming anything that holds a value for it. + * The only value such a reference can denote is the default value of the property, and translation puts that default + * in the property name holder. A property with no default value leaves the definition itself there, which denotes no + * value at all, and no strict checker rejects it. Report the reference as written. A reference that names a property + * type keeps its own value, an enumeration literal, so it is not one of these. + */ + private void checkPropertyReferenceValues(final TranslationResult translation) { + for (var contents = translation.getStrictAnnex().eAllContents(); contents.hasNext();) { + // A property-set property reference is the translation of the alternative that names no element, and its + // first property name holds the default value when the property has one. + if (!(contents.next() instanceof PropertySetPropertyReference reference) + || reference.getProperties().isEmpty() + || !(reference.getProperties().getFirst().getProperty().getElement() instanceof Property property)) { + continue; + } + var written = sourceFor(reference, translation); + error("Property reference '" + NodeModelUtils.getTokenText(NodeModelUtils.findActualNodeFor(written)) + + "' has no value: property '" + property.getName() + "' has no default value and the reference" + + " names no element that has a value for it", written, null, + ValidationMessageAcceptor.INSIGNIFICANT_INDEX, PROPERTY_REFERENCE_VALUE); + } + } + /** * AS5506/3 Rev A names an internal port in the D.3 internal_condition production and in the D.6 target and * communication_action productions only. The grammar accepts a generic reference everywhere else, so an internal