diff --git a/ba/doc/conformance.md b/ba/doc/conformance.md index 3c571aa3c8..f5b821ad36 100644 --- a/ba/doc/conformance.md +++ b/ba/doc/conformance.md @@ -24,7 +24,7 @@ The user directed that the report findings be treated as valid and filed without | G10 ✅ | [#3174](https://github.com/osate/osate2/issues/3174) | V07 | [#3188](https://github.com/osate/osate2/issues/3188) | | G11 ✅ | [#3175](https://github.com/osate/osate2/issues/3175) | V08 | [#3189](https://github.com/osate/osate2/issues/3189) | | G12 ✅ | [#3176](https://github.com/osate/osate2/issues/3176) | V09 | [#3190](https://github.com/osate/osate2/issues/3190) | -| G13 ✅ | [#3177](https://github.com/osate/osate2/issues/3177) | V10 | [#3191](https://github.com/osate/osate2/issues/3191) | +| G13 ✅ | [#3177](https://github.com/osate/osate2/issues/3177) | V10 ✅ | [#3191](https://github.com/osate/osate2/issues/3191) | | G14 ✅ | [#3178](https://github.com/osate/osate2/issues/3178) | V11 | [#3192](https://github.com/osate/osate2/issues/3192) | | G18 | [#3199](https://github.com/osate/osate2/issues/3199) | | | @@ -201,7 +201,7 @@ These are bounded findings from the inspected grammar/translator/checker path. E | V07 | D.5 C1/C2: BA freeze/send operations agree with `Input_Time`/`Output_Time`, or are absent where required. | No BA check referring to these properties was found in the active BA checker/translator/validator code. Core property validation alone does not establish agreement with BA actions. Use models that are individually legal on each side but inconsistent together. | | V08 | D.6: a complete state cannot be reached while shared data remains locked. | Lock/unlock syntax and holders exist; `Issue2372Test` checks resolved lock references. No path-sensitive lock-balance check was found. Cover a balanced path, an unreleased resource, alternative branches, loops, and wildcard lock/unlock. Parsing a lock operation does not establish this rule. | | V09 | D.7: right-hand-side variables/data must be initialized; declaration initialization overrides the Data Modeling `Initial_Value` property. | Declaration initializer types and declarative definite initialization are checked by #3190. Explicit declaration initializers and unprefixed `Data_Model::Initial_Value` associations seed the analysis, with declaration initialization taking precedence. Instance-dependent initialization from prefixed property values is tracked by #3230 and blocked by #3229. | -| V10 | D.7 property references are restricted to unitless properties or properties with time units. | Property reference machinery exists, but no explicit end-to-end check of this BA-specific restriction was identified. Add positive unitless/time cases and a property with another units type. Do not infer compliance merely because a property name resolves. | +| V10 | D.7 property references are restricted to unitless properties or properties with time units. | **Addressed by [#3191](https://github.com/osate/osate2/issues/3191):** the validator checks the declared units type of referenced properties, constants, and selected record fields, accepting unitless values and `AADL_Project::Time_Units`. Other units types are reported at the property reference. `Issue3191Test` covers integer and real values, defaults, symbolic element prefixes, record fields, and a custom units type whose literal is named `ms`. Translation retains default values and their written units, and prefixed references retain their owners and property definitions. Effective instance-value selection remains part of #3229. | | V11 | D.8 LSER/ASER prohibits synchronous called-subprogram type and out/in-out parameters. | The [property set](../../ba/org.osate.ba.contrib/resources/properties/behavior_properties.aadl) matches the standard. Searches of BA and the core AADL validator found no checks consuming `Subprogram_Call_Protocol`; [ba_example_007.aadl](../../ba/org.osate.ba/examples/standard_examples/ba_example_007.aadl) describes the rules in comments but is not negative legality coverage. Add both prohibited combinations for both protocols. | Some checker comments identify their source as **AADL Behavior Annex draft 0.94**. This matters: names such as `D_3_L1_And_L2_Check` and diagnostics labelled `D.3.(L3)` cannot be assumed to correspond one-for-one to the supplied Rev. A rule ordering. `D_3_L4_Check` is explicitly suspended and returns true with its body commented out. The Rev. A text makes explicit initialization/finalization modeling optional, so suspension of an older check is not automatically a Rev. A defect. Update the traceability by rule meaning before reviving old checks. diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt new file mode 100644 index 0000000000..b8f6d67de1 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt @@ -0,0 +1,9 @@ +error | semantic | 47 | 10 | 30 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 48 | 10 | 31 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 49 | 14 | 30 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 50 | 15 | 30 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 51 | 14 | 42 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 52 | 10 | 35 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 53 | 10 | 27 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 54 | 10 | 39 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units +error | semantic | 55 | 14 | 49 | Behavior Annex property references must be unitless or use AADL_Project::Time_Units diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3191_Issue3191.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3191_Issue3191.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3191_Issue3191.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3191_Issue3191.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt new file mode 100644 index 0000000000..faeb2e058c --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt @@ -0,0 +1,67 @@ +annex[0] owner=DisallowedUnits::reader.impl + (AssignmentAction, , 2252, 35) + (AssignmentAction, , 2293, 36) + (AssignmentAction, , 2335, 39) + (AssignmentAction, , 2380, 40) + (AssignmentAction, , 2426, 51) + (AssignmentAction, , 2483, 40) + (AssignmentAction, , 2529, 32) + (AssignmentAction, , 2567, 44) + (AssignmentAction, , 2617, 58) + (BehaviorActionBlock, , 2246, 434) + (BehaviorActionSequence, , 2252, 423) + (BehaviorAnnex, behavior_specification, 2026, 655) + (BehaviorState, done, 2183, 4) + (BehaviorState, start, 2157, 5) + (BehaviorStateGroup, , 2157, 22) + (BehaviorStateGroup, , 2183, 28) + (BehaviorTransition, , 2229, 452) + (BehaviorVariable, b, 2093, 1) + (BehaviorVariable, i, 2039, 1) + (BehaviorVariable, r, 2067, 1) + (BehaviorVariable, s, 2121, 1) + (BehaviorVariableGroup, , 2039, 24) + (BehaviorVariableGroup, , 2067, 22) + (BehaviorVariableGroup, , 2093, 24) + (BehaviorVariableGroup, , 2121, 23) + (HashPropertyReference, , 2257, 30) + (HashPropertyReference, , 2298, 31) + (HashPropertyReference, , 2488, 35) + (HashPropertyReference, , 2534, 27) + (HashPropertyReference, , 2572, 39) + (NamedPropertyField, size, 2606, 5) + (NamedPropertyField, size, 2670, 5) + (PropertyReferenceTail, , 2344, 30) + (PropertyReferenceTail, , 2390, 30) + (PropertyReferenceTail, , 2435, 42) + (PropertyReferenceTail, , 2626, 49) + (Reference, , 2252, 1) + (Reference, , 2293, 1) + (Reference, , 2335, 1) + (Reference, , 2340, 4) + (Reference, , 2380, 1) + (Reference, , 2385, 5) + (Reference, , 2426, 1) + (Reference, , 2431, 4) + (Reference, , 2483, 1) + (Reference, , 2529, 1) + (Reference, , 2567, 1) + (Reference, , 2617, 1) + (Reference, , 2622, 4) + (ReferenceExpression, , 2340, 34) + (ReferenceExpression, , 2385, 35) + (ReferenceExpression, , 2431, 46) + (ReferenceExpression, , 2622, 53) + (ReferenceSegment, i, 2252, 1) + (ReferenceSegment, i, 2335, 1) + (ReferenceSegment, i, 2380, 1) + (ReferenceSegment, i, 2426, 1) + (ReferenceSegment, i, 2483, 1) + (ReferenceSegment, i, 2529, 1) + (ReferenceSegment, i, 2567, 1) + (ReferenceSegment, i, 2617, 1) + (ReferenceSegment, input, 2385, 5) + (ReferenceSegment, r, 2293, 1) + (ReferenceSegment, self, 2340, 4) + (ReferenceSegment, self, 2431, 4) + (ReferenceSegment, self, 2622, 4) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_Issue3191.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_Issue3191.txt new file mode 100644 index 0000000000..a0b7977782 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_Issue3191.txt @@ -0,0 +1,72 @@ +annex[0] owner=Issue3191::reader.impl + (AssignmentAction, , 2246, 39) + (AssignmentAction, , 2291, 31) + (AssignmentAction, , 2328, 32) + (AssignmentAction, , 2366, 35) + (AssignmentAction, , 2407, 36) + (AssignmentAction, , 2449, 40) + (AssignmentAction, , 2495, 39) + (AssignmentAction, , 2540, 40) + (AssignmentAction, , 2586, 37) + (AssignmentAction, , 2629, 45) + (AssignmentAction, , 2680, 44) + (BehaviorActionBlock, , 2240, 489) + (BehaviorActionSequence, , 2246, 478) + (BehaviorAnnex, behavior_specification, 2020, 710) + (BehaviorState, done, 2177, 4) + (BehaviorState, start, 2151, 5) + (BehaviorStateGroup, , 2151, 22) + (BehaviorStateGroup, , 2177, 28) + (BehaviorTransition, , 2223, 507) + (BehaviorVariable, b, 2087, 1) + (BehaviorVariable, i, 2033, 1) + (BehaviorVariable, r, 2061, 1) + (BehaviorVariable, s, 2115, 1) + (BehaviorVariableGroup, , 2033, 24) + (BehaviorVariableGroup, , 2061, 22) + (BehaviorVariableGroup, , 2087, 24) + (BehaviorVariableGroup, , 2115, 23) + (HashPropertyReference, , 2251, 34) + (HashPropertyReference, , 2296, 26) + (HashPropertyReference, , 2333, 27) + (HashPropertyReference, , 2371, 30) + (HashPropertyReference, , 2412, 31) + (HashPropertyReference, , 2454, 35) + (HashPropertyReference, , 2634, 40) + (HashPropertyReference, , 2685, 39) + (NamedPropertyField, delay, 2668, 6) + (NamedPropertyField, flag, 2719, 5) + (PropertyReferenceTail, , 2504, 30) + (PropertyReferenceTail, , 2550, 30) + (PropertyReferenceTail, , 2595, 28) + (Reference, , 2246, 1) + (Reference, , 2291, 1) + (Reference, , 2328, 1) + (Reference, , 2366, 1) + (Reference, , 2407, 1) + (Reference, , 2449, 1) + (Reference, , 2495, 1) + (Reference, , 2500, 4) + (Reference, , 2540, 1) + (Reference, , 2545, 5) + (Reference, , 2586, 1) + (Reference, , 2591, 4) + (Reference, , 2629, 1) + (Reference, , 2680, 1) + (ReferenceExpression, , 2500, 34) + (ReferenceExpression, , 2545, 35) + (ReferenceExpression, , 2591, 32) + (ReferenceSegment, b, 2291, 1) + (ReferenceSegment, b, 2680, 1) + (ReferenceSegment, i, 2246, 1) + (ReferenceSegment, i, 2366, 1) + (ReferenceSegment, i, 2449, 1) + (ReferenceSegment, i, 2495, 1) + (ReferenceSegment, i, 2540, 1) + (ReferenceSegment, i, 2586, 1) + (ReferenceSegment, i, 2629, 1) + (ReferenceSegment, input, 2545, 5) + (ReferenceSegment, r, 2407, 1) + (ReferenceSegment, s, 2328, 1) + (ReferenceSegment, self, 2500, 4) + (ReferenceSegment, self, 2591, 4) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt new file mode 100644 index 0000000000..40c05dc915 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt @@ -0,0 +1,104 @@ +annex[0] owner=DisallowedUnits::reader.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + variables[0] : BehaviorVariable name=i + variables[1] : BehaviorVariable name=r + variables[2] : BehaviorVariable name=b + variables[3] : BehaviorVariable name=s + states[0] : BehaviorState name=start + states[1] : BehaviorState name=done + transitions[0] : BehaviorTransition + actions[0] : BehaviorActionBlock + content : BehaviorActionSequence + actions[0] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=IntegerLiteral [IntegerLiteral] + actions[1] : AssignmentAction + target : BehaviorVariableHolder element=r [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=RealLiteral [RealLiteral] + actions[2] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : ClassifierPropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Issue3191Properties::Size_Int [Property] + actions[3] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : ClassifierFeaturePropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Issue3191Properties::Size_Int [Property] + component : DataPortHolder element=DisallowedUnits::reader.input [DataPort] + actions[4] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : ClassifierPropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Issue3191Properties::Size_Without_Default [Property] + actions[5] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : BehaviorPropertyConstant + actions[6] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=IntegerLiteral [IntegerLiteral] + actions[7] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=RecordValue [RecordValue] + properties[1] : PropertyNameHolder + property : PropertyExpressionHolder element=IntegerLiteral [IntegerLiteral] + actions[8] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : ClassifierPropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Issue3191Properties::Record_Without_Default [Property] + properties[1] : PropertyNameHolder + property : BasicPropertyHolder element=Issue3191Properties::Record_Type.size [BasicProperty] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_Issue3191.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_Issue3191.txt new file mode 100644 index 0000000000..3295306a71 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_Issue3191.txt @@ -0,0 +1,124 @@ +annex[0] owner=Issue3191::reader.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + variables[0] : BehaviorVariable name=i + variables[1] : BehaviorVariable name=r + variables[2] : BehaviorVariable name=b + variables[3] : BehaviorVariable name=s + states[0] : BehaviorState name=start + states[1] : BehaviorState name=done + transitions[0] : BehaviorTransition + actions[0] : BehaviorActionBlock + content : BehaviorActionSequence + actions[0] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=IntegerLiteral [IntegerLiteral] + actions[1] : AssignmentAction + target : BehaviorVariableHolder element=b [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=BooleanLiteral [BooleanLiteral] + actions[2] : AssignmentAction + target : BehaviorVariableHolder element=s [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=StringLiteral [StringLiteral] + actions[3] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=IntegerLiteral [IntegerLiteral] + actions[4] : AssignmentAction + target : BehaviorVariableHolder element=r [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=RealLiteral [RealLiteral] + actions[5] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : BehaviorPropertyConstant + actions[6] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : ClassifierPropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Issue3191Properties::Time_Int [Property] + actions[7] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : ClassifierFeaturePropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Issue3191Properties::Time_Int [Property] + component : DataPortHolder element=Issue3191::reader.input [DataPort] + actions[8] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : ClassifierPropertyReference + properties[0] : PropertyNameHolder + property : BasicPropertyHolder element=Timing_Properties::Deadline [Property] + actions[9] : AssignmentAction + target : BehaviorVariableHolder element=i [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=RecordValue [RecordValue] + properties[1] : PropertyNameHolder + property : PropertyExpressionHolder element=IntegerLiteral [IntegerLiteral] + actions[10] : AssignmentAction + target : BehaviorVariableHolder element=b [BehaviorVariable] + valueExpression : ValueExpression + relations[0] : Relation + firstExpression : SimpleExpression + terms[0] : Term + factors[0] : Factor + firstValue : PropertySetPropertyReference + properties[0] : PropertyNameHolder + property : PropertyExpressionHolder element=RecordValue [RecordValue] + properties[1] : PropertyNameHolder + property : PropertyExpressionHolder element=BooleanLiteral [BooleanLiteral] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt new file mode 100644 index 0000000000..0b6db8baac --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_DisallowedUnits.txt @@ -0,0 +1,25 @@ +===== annex[0] owner=DisallowedUnits::reader.impl ===== + +\t\tvariables +\t\t\ti : Base_Types::Integer; +\t\t\tr : Base_Types::Float; +\t\t\tb : Base_Types::Boolean; +\t\t\ts : Base_Types::String; +\t\tstates +\t\t\tstart : initial state; +\t\t\tdone : complete final state; +\t\ttransitions +\t\t\tstart -[]-> done { +\t\t\t\ti := #Issue3191Properties::Size_Int; +\t\t\t\tr := #Issue3191Properties::Size_Real; +\t\t\t\ti := self#Issue3191Properties::Size_Int; +\t\t\t\ti := input#Issue3191Properties::Size_Int; +\t\t\t\ti := self#Issue3191Properties::Size_Without_Default; +\t\t\t\ti := #Issue3191Properties::Size_Constant; +\t\t\t\ti := #Issue3191Properties::Other; +\t\t\t\ti := #Issue3191Properties::Record_Value.size; +\t\t\t\ti := self#Issue3191Properties::Record_Without_Default.size +\t\t\t}; +\t +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_Issue3191.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_Issue3191.txt new file mode 100644 index 0000000000..ebf112cf2f --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_Issue3191.txt @@ -0,0 +1,27 @@ +===== annex[0] owner=Issue3191::reader.impl ===== + +\t\tvariables +\t\t\ti : Base_Types::Integer; +\t\t\tr : Base_Types::Float; +\t\t\tb : Base_Types::Boolean; +\t\t\ts : Base_Types::String; +\t\tstates +\t\t\tstart : initial state; +\t\t\tdone : complete final state; +\t\ttransitions +\t\t\tstart -[]-> done { +\t\t\t\ti := #Issue3191Properties::Unitless_Int; +\t\t\t\tb := #Issue3191Properties::Flag; +\t\t\t\ts := #Issue3191Properties::Label; +\t\t\t\ti := #Issue3191Properties::Time_Int; +\t\t\t\tr := #Issue3191Properties::Time_Real; +\t\t\t\ti := #Issue3191Properties::Time_Constant; +\t\t\t\ti := self#Issue3191Properties::Time_Int; +\t\t\t\ti := input#Issue3191Properties::Time_Int; +\t\t\t\ti := self#Timing_Properties::Deadline; +\t\t\t\ti := #Issue3191Properties::Record_Value.delay; +\t\t\t\tb := #Issue3191Properties::Record_Value.flag +\t\t\t}; +\t +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3191_Issue3191Properties.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ba/org.osate.ba.tests/models/issue3191/.gitignore b/ba/org.osate.ba.tests/models/issue3191/.gitignore new file mode 100644 index 0000000000..afce51184c --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3191/.gitignore @@ -0,0 +1,2 @@ +/.aadlbin-gen/ +/instances/ diff --git a/ba/org.osate.ba.tests/models/issue3191/.project b/ba/org.osate.ba.tests/models/issue3191/.project new file mode 100644 index 0000000000..fb6e96b2ed --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3191/.project @@ -0,0 +1,18 @@ + + + issue3191 + + + + + + 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/issue3191/DisallowedUnits.aadl b/ba/org.osate.ba.tests/models/issue3191/DisallowedUnits.aadl new file mode 100644 index 0000000000..0494f89389 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3191/DisallowedUnits.aadl @@ -0,0 +1,59 @@ +-- 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 DisallowedUnits +public + with Base_Types; + with Issue3191Properties; + + thread reader + features + input : in data port Base_Types::Integer; + properties + Issue3191Properties::Unitless_Int => 7; + end reader; + + thread implementation reader.impl + annex behavior_specification {** + variables + i : Base_Types::Integer; + r : Base_Types::Float; + b : Base_Types::Boolean; + s : Base_Types::String; + states + start : initial state; + done : complete final state; + transitions + start -[]-> done { + i := #Issue3191Properties::Size_Int; + r := #Issue3191Properties::Size_Real; + i := self#Issue3191Properties::Size_Int; + i := input#Issue3191Properties::Size_Int; + i := self#Issue3191Properties::Size_Without_Default; + i := #Issue3191Properties::Size_Constant; + i := #Issue3191Properties::Other; + i := #Issue3191Properties::Record_Value.size; + i := self#Issue3191Properties::Record_Without_Default.size + }; + **}; + end reader.impl; +end DisallowedUnits; diff --git a/ba/org.osate.ba.tests/models/issue3191/Issue3191.aadl b/ba/org.osate.ba.tests/models/issue3191/Issue3191.aadl new file mode 100644 index 0000000000..6257a7dd1e --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3191/Issue3191.aadl @@ -0,0 +1,61 @@ +-- 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 Issue3191 +public + with Base_Types; + with Issue3191Properties; + + thread reader + features + input : in data port Base_Types::Integer; + properties + Issue3191Properties::Unitless_Int => 7; + end reader; + + thread implementation reader.impl + annex behavior_specification {** + variables + i : Base_Types::Integer; + r : Base_Types::Float; + b : Base_Types::Boolean; + s : Base_Types::String; + states + start : initial state; + done : complete final state; + transitions + start -[]-> done { + i := #Issue3191Properties::Unitless_Int; + b := #Issue3191Properties::Flag; + s := #Issue3191Properties::Label; + i := #Issue3191Properties::Time_Int; + r := #Issue3191Properties::Time_Real; + i := #Issue3191Properties::Time_Constant; + i := self#Issue3191Properties::Time_Int; + i := input#Issue3191Properties::Time_Int; + i := self#Timing_Properties::Deadline; + i := #Issue3191Properties::Record_Value.delay; + b := #Issue3191Properties::Record_Value.flag + }; + **}; + end reader.impl; +end Issue3191; diff --git a/ba/org.osate.ba.tests/models/issue3191/Issue3191Properties.aadl b/ba/org.osate.ba.tests/models/issue3191/Issue3191Properties.aadl new file mode 100644 index 0000000000..77370d52df --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3191/Issue3191Properties.aadl @@ -0,0 +1,45 @@ +-- 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. + +property set Issue3191Properties is + Unitless_Int : aadlinteger => 7 applies to (all); + Flag : aadlboolean => true applies to (all); + Label : aadlstring => "unitless" applies to (all); + Duration : type aadlinteger units AADL_Project::Time_Units; + Time_Int : Issue3191Properties::Duration => 3 ms applies to (all); + Time_Real : aadlreal units AADL_Project::Time_Units => 1.5 sec applies to (all); + Time_Constant : constant Issue3191Properties::Duration => 2 us; + Size_Int : aadlinteger units AADL_Project::Size_Units => 8 Bytes applies to (all); + Size_Real : aadlreal units AADL_Project::Size_Units => 1.5 KByte applies to (all); + Size_Without_Default : aadlinteger units AADL_Project::Size_Units applies to (all); + Size_Constant : constant aadlinteger units AADL_Project::Size_Units => 4 Bytes; + -- A matching unit literal name does not make this the standard time units type. + Other_Units : type units (ms); + Other : aadlinteger units Issue3191Properties::Other_Units => 5 ms applies to (all); + Record_Type : type record ( + delay : Issue3191Properties::Duration; + size : aadlinteger units AADL_Project::Size_Units; + flag : aadlboolean; + ); + Record_Value : Issue3191Properties::Record_Type => [delay => 6 us; size => 16 Bytes; flag => true;] applies to (all); + Record_Without_Default : Issue3191Properties::Record_Type applies to (all); +end Issue3191Properties; diff --git a/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3191Test.java b/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3191Test.java new file mode 100644 index 0000000000..33a8091b58 --- /dev/null +++ b/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3191Test.java @@ -0,0 +1,133 @@ +/** + * 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 static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +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.aadl2.IntegerLiteral; +import org.osate.aadl2.Property; +import org.osate.aadl2.RealLiteral; +import org.osate.annexsupport.AnnexUtil; +import org.osate.ba.aadlba.ClassifierFeaturePropertyReference; +import org.osate.ba.aadlba.ClassifierPropertyReference; +import org.osate.ba.aadlba.PropertyReference; +import org.osate.testsupport.TestHelper; +import org.osate.xtext.aadl2.ba.util.BehaviorAnnexUtil; + +import com.google.inject.Inject; +import com.itemis.xtext.testing.XtextTest; + +/** Checks D.7 unit categories without selecting instance-dependent property values. */ +@RunWith(XtextRunner.class) +@InjectWith(BehaviorAnnexInjectorProvider.class) +public class Issue3191Test extends XtextTest { + private static final String MODELS = "org.osate.ba.tests/models/issue3191/"; + + @Inject + private TestHelper testHelper; + + @Inject + private ValidationTestHelper validationHelper; + + @Test + public void unitlessAndTimePropertiesAreAcceptedAndKeepTheirUnits() throws Exception { + var root = parse("Issue3191"); + validationHelper.assertNoIssues(root); + var references = references(root); + var integer = (IntegerLiteral) references.get(3).getProperties().getFirst().getProperty().getElement(); + assertEquals(3, integer.getValue()); + assertEquals("ms", integer.getUnit().getName()); + var real = (RealLiteral) references.get(4).getProperties().getFirst().getProperty().getElement(); + assertEquals(1.5, real.getValue(), 0.0); + assertEquals("sec", real.getUnit().getName()); + } + + @Test + public void prefixedTimeReferencesRetainTheirOwnersAndPropertyDefinitions() throws Exception { + var root = parse("Issue3191"); + validationHelper.assertNoIssues(root); + var references = references(root); + var self = (ClassifierPropertyReference) references.get(5); + assertEquals("Issue3191::reader.impl", self.getClassifier().getQualifiedName()); + var property = (Property) self.getProperties().getFirst().getProperty().getElement(); + assertEquals("Issue3191Properties::Time_Int", property.getQualifiedName()); + var feature = (ClassifierFeaturePropertyReference) references.get(6); + assertEquals("input", feature.getComponent().getElement().getName()); + assertSame(property, feature.getProperties().getFirst().getProperty().getElement()); + assertTrue(references.get(7).getProperties().getFirst().getProperty().getElement() instanceof Property); + } + + @Test + public void otherUnitCategoriesAreReportedAtEachReference() throws Exception { + var root = parse("DisallowedUnits"); + var source = NodeModelUtils.getNode(root).getRootNode().getText(); + var issues = validationHelper.validate(root).stream().sorted(Comparator.comparing(Issue::getOffset)).toList(); + assertEquals(issues.toString(), 9, issues.size()); + assertEquals(List.of("#Issue3191Properties::Size_Int", "#Issue3191Properties::Size_Real", + "#Issue3191Properties::Size_Int", "#Issue3191Properties::Size_Int", + "#Issue3191Properties::Size_Without_Default", "#Issue3191Properties::Size_Constant", + "#Issue3191Properties::Other", "#Issue3191Properties::Record_Value.size", + "#Issue3191Properties::Record_Without_Default.size"), issues.stream().map(issue -> { + assertEquals(Severity.ERROR, issue.getSeverity()); + assertEquals("org.osate.xtext.aadl2.ba.propertyReferenceUnits", issue.getCode()); + assertEquals("Behavior Annex property references must be unitless or use AADL_Project::Time_Units", + issue.getMessage()); + return source.substring(issue.getOffset(), issue.getOffset() + issue.getLength()); + }).toList()); + } + + private AadlPackage parse(String name) { + var root = testHelper.parseFile(MODELS + name + ".aadl", MODELS + "Issue3191Properties.aadl"); + root.eResource().getResourceSet().getResources().stream() + .filter(resource -> resource.getURI().lastSegment().equals("Issue3191Properties.aadl")) + .forEach(resource -> validationHelper.assertNoIssues(resource.getContents().getFirst())); + return root; + } + + private static List references(AadlPackage root) { + var strict = BehaviorAnnexUtil.getStrictModel(AnnexUtil.getAllDefaultAnnexSubclauses(root).getFirst()); + var result = new ArrayList(); + strict.eAllContents().forEachRemaining(object -> { + if (object instanceof PropertyReference reference) { + result.add(reference); + } + }); + return result; + } +} diff --git a/ba/org.osate.ba.tests/src/org/osate/ba/tests/characterization/BehaviorAnnexCorpus.java b/ba/org.osate.ba.tests/src/org/osate/ba/tests/characterization/BehaviorAnnexCorpus.java index 873afaea99..7d658452dd 100644 --- a/ba/org.osate.ba.tests/src/org/osate/ba/tests/characterization/BehaviorAnnexCorpus.java +++ b/ba/org.osate.ba.tests/src/org/osate/ba/tests/characterization/BehaviorAnnexCorpus.java @@ -91,6 +91,10 @@ static List discover() throws IOException { references = characterizationPaths.stream() .filter(reference -> !reference.equals(path)) .toList(); + } else if (path.startsWith("org.osate.ba.tests/models/issue3191/")) { + references = List.of("org.osate.ba.tests/models/issue3191/Issue3191Properties.aadl").stream() + .filter(reference -> !reference.equals(path)) + .toList(); } else { references = List.of(); } 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 473b2679e5..7f3370ec39 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 @@ -52,14 +52,20 @@ import org.osate.aadl2.EventPort; import org.osate.aadl2.FeatureGroup; import org.osate.aadl2.InternalFeature; +import org.osate.aadl2.NumberType; import org.osate.aadl2.Port; import org.osate.aadl2.Property; +import org.osate.aadl2.PropertyType; +import org.osate.aadl2.RangeType; import org.osate.aadl2.Subcomponent; import org.osate.aadl2.modelsupport.errorreporting.AbstractAnalysisErrorReporter; import org.osate.aadl2.modelsupport.errorreporting.AnalysisErrorReporterManager; +import org.osate.aadl2.modelsupport.util.AadlUtil; import org.osate.aadl2.parsesupport.ParseUtil; import org.osate.annexsupport.ParseResultHolder; +import org.osate.ba.aadlba.BehaviorPropertyConstant; import org.osate.ba.aadlba.ForOrForAllStatement; +import org.osate.ba.aadlba.PropertyReference; import org.osate.ba.aadlba.PropertySetPropertyReference; import org.osate.ba.analyzers.AadlBaInitializationChecker; import org.osate.ba.analyzers.AadlBaRulesCheckersDriver; @@ -107,6 +113,7 @@ public final class BehaviorAnnexValidator extends AbstractBehaviorAnnexValidator public static final String ITERATOR_CLASSIFIER = "org.osate.xtext.aadl2.ba.iteratorClassifier"; 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"; + public static final String PROPERTY_REFERENCE_UNITS = "org.osate.xtext.aadl2.ba.propertyReferenceUnits"; public static final String MODE_REFINEMENT = "org.osate.xtext.aadl2.ba.modeRefinement"; public static final String EXTERNAL_CONDITION_IN_MODES = "org.osate.xtext.aadl2.ba.externalConditionInModes"; public static final String UNARY_PLUS = "org.osate.xtext.aadl2.ba.unaryPlus"; @@ -151,6 +158,7 @@ public void checkBehaviorAnnex(final BehaviorAnnex source) { // 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); + checkPropertyReferenceUnits(translation); if (!representable) { return; } @@ -284,6 +292,42 @@ private void checkPropertyReferenceValues(final TranslationResult translation) { } } + /** + * D.7 permits only unitless or time-valued property references. Inspect the declared type of the selected property + * or record field, including when its holder carries a default expression. Prefixed references stay symbolic: + * neither an effective instance value nor its written unit is needed to check the declared units type. + */ + private void checkPropertyReferenceUnits(final TranslationResult translation) { + var reported = new HashSet(); + for (var contents = translation.getStrictAnnex().eAllContents(); contents.hasNext();) { + var value = contents.next(); + final PropertyType declaredType; + if (value instanceof PropertyReference reference && !reference.getProperties().isEmpty()) { + declaredType = AadlBaUtils.getPropertyType(reference.getProperties().getLast().getProperty()); + } else if (value instanceof BehaviorPropertyConstant constant && constant.getProperty() != null) { + declaredType = constant.getProperty().getPropertyType(); + } else { + continue; + } + var type = AadlUtil.getBasePropertyType(declaredType); + if (type instanceof RangeType range) { + type = range.getNumberType(); + } + if (!(type instanceof NumberType number)) { + continue; + } + var units = number.getUnitsType(); + if (units != null && !"AADL_Project::Time_Units".equalsIgnoreCase(units.getQualifiedName())) { + var source = sourceFor(value, translation); + // Translation can copy a condition for multiple source states; report the written reference once. + if (reported.add(source)) { + error("Behavior Annex property references must be unitless or use AADL_Project::Time_Units", source, + null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, PROPERTY_REFERENCE_UNITS); + } + } + } + } + /** * 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