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 e69de29bb2..6498ec2a76 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 ad0f0cb217..dafff222f3 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 new file mode 100644 index 0000000000..21081d36a3 --- /dev/null +++ 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.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 0000000000..e69de29bb2 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 0000000000..88189a8b3e --- /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 0000000000..c98f56e264 --- /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 0000000000..47b998b177 --- /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 0000000000..afce51184c --- /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 0000000000..23e536afd4 --- /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 0000000000..f0c3e4670c --- /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 0000000000..d371dc93ae --- /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()); + } +} 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 09d9af76cc..61501f44d2 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