From 693dbe4a37497574598c2747564d6bf390258aa7 Mon Sep 17 00:00:00 2001 From: Lutz Wrage Date: Tue, 15 Sep 2026 13:07:14 -0400 Subject: [PATCH 1/2] Add regression test for issue #3186 AS5506/3 Rev. A D.3 restricts external conditions by component category and by in modes context: a thread and a subprogram must not use one, the transitions out of one complete state of a device must use either only external conditions or only dispatch conditions, and a subclause with an in modes statement must not use one. D.3 also applies an ancestor's subclauses to a descendant unless the descendant declares its own, which replace them completely. Issue3186Test models each restriction through ordinary embedded AADL validation and asserts the exact diagnostic, with a positive control beside each one: a process leaving an execution state on an event, a device leaving a mode-representing complete state on external conditions alone, and an in modes subclause using an execute condition. It also asserts that the triggers of an external condition out of a mode-representing complete state are compared with the corresponding mode transition, which is how a component of a category other than thread and subprogram describes a mode transition. The subprogram fixture triggers on an outgoing event port because core AADL admits no other event port on a subprogram, so no subprogram can name the incoming port the D.3 event_trigger production asks for. The rule constrains the form of the condition rather than its triggers. Inheritance.aadl and ModalSubclauses.aadl cover the access path: inheritance from an ancestor implementation, replacement by a descendant, fallback to the type of an implementation that declares none, every modal subclause of a classifier, and selection by mode including a subclause without an in modes statement. BehaviorAnnexGrammarTest matched a subclause by its annex text followed by a semicolon, so it silently skipped every subclause with an in modes statement, and where another subclause followed one it paired their delimiters across the two. Its pattern now accepts the statement, which brings ModalSubclauses.aadl and the existing InModes.aadl under that test. The corpus goldens record the new fixtures in both registration states. The one existing golden that changes is issue2147, whose thread group leaves a mode-representing complete state on an external condition while declaring no mode transition: the D.3.(C4) comparison now reads external condition triggers as well, so that model reports the finding its dispatch equivalent already produced. Co-Authored-By: Claude Opus 5 (1M context) --- ...te.ba.tests_models_issue2147_issue2147.txt | 1 + ...ts_models_issue3186_DeviceConditionMix.txt | 2 + ...dels_issue3186_DeviceExternalCondition.txt | 0 ...ssue3186_DeviceExternalTriggerMismatch.txt | 1 + ...dels_issue3186_InModesExecuteCondition.txt | 0 ...els_issue3186_InModesExternalCondition.txt | 1 + ....ba.tests_models_issue3186_Inheritance.txt | 0 ...te.ba.tests_models_issue3186_Issue3186.txt | 0 ...tests_models_issue3186_ModalSubclauses.txt | 0 ..._issue3186_SubprogramExternalCondition.txt | 1 + ...dels_issue3186_ThreadExternalCondition.txt | 1 + ...ts_models_issue3186_DeviceConditionMix.txt | 0 ...dels_issue3186_DeviceExternalCondition.txt | 0 ...ssue3186_DeviceExternalTriggerMismatch.txt | 0 ...dels_issue3186_InModesExecuteCondition.txt | 0 ...els_issue3186_InModesExternalCondition.txt | 0 ....ba.tests_models_issue3186_Inheritance.txt | 0 ...te.ba.tests_models_issue3186_Issue3186.txt | 0 ...tests_models_issue3186_ModalSubclauses.txt | 0 ..._issue3186_SubprogramExternalCondition.txt | 0 ...dels_issue3186_ThreadExternalCondition.txt | 0 ...ts_models_issue3186_DeviceConditionMix.txt | 21 ++ ...dels_issue3186_DeviceExternalCondition.txt | 13 ++ ...ssue3186_DeviceExternalTriggerMismatch.txt | 13 ++ ...dels_issue3186_InModesExecuteCondition.txt | 7 + ...els_issue3186_InModesExternalCondition.txt | 13 ++ ....ba.tests_models_issue3186_Inheritance.txt | 21 ++ ...te.ba.tests_models_issue3186_Issue3186.txt | 13 ++ ...tests_models_issue3186_ModalSubclauses.txt | 12 + ..._issue3186_SubprogramExternalCondition.txt | 13 ++ ...dels_issue3186_ThreadExternalCondition.txt | 16 ++ ...ts_models_issue3186_DeviceConditionMix.txt | 13 ++ ...dels_issue3186_DeviceExternalCondition.txt | 8 + ...ssue3186_DeviceExternalTriggerMismatch.txt | 8 + ...dels_issue3186_InModesExecuteCondition.txt | 5 + ...els_issue3186_InModesExternalCondition.txt | 8 + ....ba.tests_models_issue3186_Inheritance.txt | 14 ++ ...te.ba.tests_models_issue3186_Issue3186.txt | 8 + ...tests_models_issue3186_ModalSubclauses.txt | 9 + ..._issue3186_SubprogramExternalCondition.txt | 8 + ...dels_issue3186_ThreadExternalCondition.txt | 10 + ...ts_models_issue3186_DeviceConditionMix.txt | 10 + ...dels_issue3186_DeviceExternalCondition.txt | 9 + ...ssue3186_DeviceExternalTriggerMismatch.txt | 9 + ...dels_issue3186_InModesExecuteCondition.txt | 9 + ...els_issue3186_InModesExternalCondition.txt | 9 + ....ba.tests_models_issue3186_Inheritance.txt | 21 ++ ...te.ba.tests_models_issue3186_Issue3186.txt | 9 + ...tests_models_issue3186_ModalSubclauses.txt | 18 ++ ..._issue3186_SubprogramExternalCondition.txt | 9 + ...dels_issue3186_ThreadExternalCondition.txt | 10 + .../models/issue3186/.gitignore | 2 + .../models/issue3186/.project | 8 + .../models/issue3186/DeviceConditionMix.aadl | 45 ++++ .../issue3186/DeviceExternalCondition.aadl | 44 ++++ .../DeviceExternalTriggerMismatch.aadl | 45 ++++ .../issue3186/InModesExecuteCondition.aadl | 40 ++++ .../issue3186/InModesExternalCondition.aadl | 42 ++++ .../models/issue3186/Inheritance.aadl | 57 +++++ .../models/issue3186/Issue3186.aadl | 40 ++++ .../models/issue3186/ModalSubclauses.aadl | 52 +++++ .../SubprogramExternalCondition.aadl | 40 ++++ .../issue3186/ThreadExternalCondition.aadl | 41 ++++ .../src/org/osate/ba/tests/Issue3186Test.java | 221 ++++++++++++++++++ .../ba/tests/BehaviorAnnexGrammarTest.java | 5 +- 65 files changed, 1034 insertions(+), 1 deletion(-) create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_Inheritance.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_Issue3186.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_Inheritance.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_Issue3186.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Inheritance.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Issue3186.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Inheritance.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Issue3186.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Inheritance.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Issue3186.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt create mode 100644 ba/org.osate.ba.tests/models/issue3186/.gitignore create mode 100644 ba/org.osate.ba.tests/models/issue3186/.project create mode 100644 ba/org.osate.ba.tests/models/issue3186/DeviceConditionMix.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/DeviceExternalCondition.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/DeviceExternalTriggerMismatch.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/InModesExecuteCondition.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/InModesExternalCondition.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/Inheritance.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/Issue3186.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/ModalSubclauses.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/SubprogramExternalCondition.aadl create mode 100644 ba/org.osate.ba.tests/models/issue3186/ThreadExternalCondition.aadl create mode 100644 ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3186Test.java diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue2147_issue2147.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue2147_issue2147.txt index e69de29bb2d..bb4bb6b8f17 100644 --- a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue2147_issue2147.txt +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue2147_issue2147.txt @@ -0,0 +1 @@ +error | semantic | 35 | 11 | 8 | The behavior transition tries to refine a transition mode while issue2147::threadA.impl component hasn't got any transition mode: Behavior Annex D.3.(C4) consistency rule failed. diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt new file mode 100644 index 00000000000..f0e50602b5c --- /dev/null +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt @@ -0,0 +1,2 @@ +error | semantic | 41 | 9 | 14 | The transitions out of complete state 'idle' of a device must use either only external conditions or only dispatch conditions: Behavior Annex D.3 consistency rule failed. +error | semantic | 42 | 9 | 5 | The transitions out of complete state 'idle' of a device must use either only external conditions or only dispatch conditions: Behavior Annex D.3 consistency rule failed. diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt new file mode 100644 index 00000000000..b50af0b18b4 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt @@ -0,0 +1 @@ +error | semantic | 42 | 9 | 8 | The behavior transition tries to refine a transition mode but it is not consisting with any transition mode of DeviceExternalTriggerMismatch::sensor.impl component: Behavior Annex D.3.(C4) consistency rule failed. diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt new file mode 100644 index 00000000000..700eb7380cc --- /dev/null +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt @@ -0,0 +1 @@ +error | semantic | 39 | 12 | 5 | A Behavior Annex subclause with an in modes statement cannot use an external condition: Behavior Annex D.3 consistency rule failed. diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_Inheritance.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_Inheritance.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_Issue3186.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_Issue3186.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt new file mode 100644 index 00000000000..e7a554bf9b9 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt @@ -0,0 +1 @@ +error | semantic | 37 | 10 | 5 | subprogram components cannot use an external condition: an execute or internal condition must be used instead: Behavior Annex D.3 consistency rule failed. diff --git a/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt new file mode 100644 index 00000000000..62c95dcd8b0 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/diagnostics-validated/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt @@ -0,0 +1 @@ +error | semantic | 38 | 12 | 5 | thread components cannot use an external condition: an execute, dispatch, or internal condition must be used instead: Behavior Annex D.3 consistency rule failed. diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_Inheritance.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_Inheritance.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_Issue3186.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_Issue3186.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt b/ba/org.osate.ba.tests/expected/diagnostics/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt new file mode 100644 index 00000000000..acc071483f2 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt @@ -0,0 +1,21 @@ +annex[0] owner=DeviceConditionMix::sensor.impl + (BehaviorAnnex, behavior_specification, 1966, 135) + (BehaviorCondition, , 2051, 14) + (BehaviorCondition, , 2085, 5) + (BehaviorState, active, 2006, 6) + (BehaviorState, idle, 1974, 4) + (BehaviorStateGroup, , 1974, 30) + (BehaviorStateGroup, , 2006, 24) + (BehaviorTransition, , 2044, 32) + (BehaviorTransition, , 2078, 23) + (DispatchCondition, , 2054, 11) + (DispatchConjunction, , 2063, 2) + (DispatchTriggerCondition, , 2063, 2) + (DispatchTriggerLogicalExpression, , 2063, 2) + (ModeSwitchCondition, , 2088, 2) + (ModeSwitchConjunction, , 2088, 2) + (ModeSwitchTrigger, , 2088, 2) + (Reference, , 2063, 2) + (Reference, , 2088, 2) + (ReferenceSegment, go, 2063, 2) + (ReferenceSegment, go, 2088, 2) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt new file mode 100644 index 00000000000..d1f4c0242ae --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt @@ -0,0 +1,13 @@ +annex[0] owner=DeviceExternalCondition::sensor.impl + (BehaviorAnnex, behavior_specification, 1971, 101) + (BehaviorCondition, , 2056, 5) + (BehaviorState, active, 2011, 6) + (BehaviorState, idle, 1979, 4) + (BehaviorStateGroup, , 1979, 30) + (BehaviorStateGroup, , 2011, 24) + (BehaviorTransition, , 2049, 23) + (ModeSwitchCondition, , 2059, 2) + (ModeSwitchConjunction, , 2059, 2) + (ModeSwitchTrigger, , 2059, 2) + (Reference, , 2059, 2) + (ReferenceSegment, go, 2059, 2) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt new file mode 100644 index 00000000000..5686bdc0e32 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt @@ -0,0 +1,13 @@ +annex[0] owner=DeviceExternalTriggerMismatch::sensor.impl + (BehaviorAnnex, behavior_specification, 2001, 104) + (BehaviorCondition, , 2086, 8) + (BehaviorState, active, 2041, 6) + (BehaviorState, idle, 2009, 4) + (BehaviorStateGroup, , 2009, 30) + (BehaviorStateGroup, , 2041, 24) + (BehaviorTransition, , 2079, 26) + (ModeSwitchCondition, , 2089, 5) + (ModeSwitchConjunction, , 2089, 5) + (ModeSwitchTrigger, , 2089, 5) + (Reference, , 2089, 5) + (ReferenceSegment, wrong, 2089, 5) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt new file mode 100644 index 00000000000..1aae906ae30 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt @@ -0,0 +1,7 @@ +annex[0] owner=InModesExecuteCondition::controller.impl + (BehaviorAnnex, behavior_specification, 1919, 86) + (BehaviorState, running, 1953, 7) + (BehaviorState, waiting, 1927, 7) + (BehaviorStateGroup, , 1927, 24) + (BehaviorStateGroup, , 1953, 16) + (BehaviorTransition, , 1983, 22) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt new file mode 100644 index 00000000000..b870059c8b0 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt @@ -0,0 +1,13 @@ +annex[0] owner=InModesExternalCondition::controller.impl + (BehaviorAnnex, behavior_specification, 1950, 91) + (BehaviorCondition, , 2024, 5) + (BehaviorState, running, 1984, 7) + (BehaviorState, waiting, 1958, 7) + (BehaviorStateGroup, , 1958, 24) + (BehaviorStateGroup, , 1984, 16) + (BehaviorTransition, , 2014, 27) + (ModeSwitchCondition, , 2027, 2) + (ModeSwitchConjunction, , 2027, 2) + (ModeSwitchTrigger, , 2027, 2) + (Reference, , 2027, 2) + (ReferenceSegment, go, 2027, 2) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Inheritance.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Inheritance.txt new file mode 100644 index 00000000000..ad70ade26f0 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Inheritance.txt @@ -0,0 +1,21 @@ +annex[0] owner=Inheritance::base + (BehaviorAnnex, behavior_specification, 1846, 33) + (BehaviorState, fromtype, 1854, 8) + (BehaviorStateGroup, , 1854, 25) +annex[1] owner=Inheritance::base.impl + (BehaviorAnnex, behavior_specification, 1963, 91) + (BehaviorCondition, , 2037, 5) + (BehaviorState, running, 1997, 7) + (BehaviorState, waiting, 1971, 7) + (BehaviorStateGroup, , 1971, 24) + (BehaviorStateGroup, , 1997, 16) + (BehaviorTransition, , 2027, 27) + (ModeSwitchCondition, , 2040, 2) + (ModeSwitchConjunction, , 2040, 2) + (ModeSwitchTrigger, , 2040, 2) + (Reference, , 2040, 2) + (ReferenceSegment, go, 2040, 2) +annex[2] owner=Inheritance::base.replaced + (BehaviorAnnex, behavior_specification, 2243, 29) + (BehaviorState, only, 2251, 4) + (BehaviorStateGroup, , 2251, 21) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Issue3186.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Issue3186.txt new file mode 100644 index 00000000000..31096e5d25d --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_Issue3186.txt @@ -0,0 +1,13 @@ +annex[0] owner=Issue3186::controller.impl + (BehaviorAnnex, behavior_specification, 1905, 91) + (BehaviorCondition, , 1979, 5) + (BehaviorState, running, 1939, 7) + (BehaviorState, waiting, 1913, 7) + (BehaviorStateGroup, , 1913, 24) + (BehaviorStateGroup, , 1939, 16) + (BehaviorTransition, , 1969, 27) + (ModeSwitchCondition, , 1982, 2) + (ModeSwitchConjunction, , 1982, 2) + (ModeSwitchTrigger, , 1982, 2) + (Reference, , 1982, 2) + (ReferenceSegment, go, 1982, 2) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt new file mode 100644 index 00000000000..c85440968cb --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt @@ -0,0 +1,12 @@ +annex[0] owner=ModalSubclauses::modal.impl + (BehaviorAnnex, behavior_specification, 1914, 35) + (BehaviorState, whennormal, 1922, 10) + (BehaviorStateGroup, , 1922, 27) +annex[1] owner=ModalSubclauses::modal.impl + (BehaviorAnnex, behavior_specification, 2006, 35) + (BehaviorState, whenbackup, 2014, 10) + (BehaviorStateGroup, , 2014, 27) +annex[2] owner=ModalSubclauses::modal.always + (BehaviorAnnex, behavior_specification, 2198, 32) + (BehaviorState, anymode, 2206, 7) + (BehaviorStateGroup, , 2206, 24) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt new file mode 100644 index 00000000000..525718448d8 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt @@ -0,0 +1,13 @@ +annex[0] owner=SubprogramExternalCondition::calc.impl + (BehaviorAnnex, behavior_specification, 1912, 87) + (BehaviorCondition, , 1985, 5) + (BehaviorState, done, 1944, 4) + (BehaviorState, start, 1920, 5) + (BehaviorStateGroup, , 1920, 22) + (BehaviorStateGroup, , 1944, 19) + (BehaviorTransition, , 1977, 22) + (ModeSwitchCondition, , 1988, 2) + (ModeSwitchConjunction, , 1988, 2) + (ModeSwitchTrigger, , 1988, 2) + (Reference, , 1988, 2) + (ReferenceSegment, go, 1988, 2) diff --git a/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt new file mode 100644 index 00000000000..f0780ae7659 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/positions/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt @@ -0,0 +1,16 @@ +annex[0] owner=ThreadExternalCondition::worker.impl + (BehaviorAnnex, behavior_specification, 1905, 135) + (BehaviorCondition, , 1988, 11) + (BehaviorCondition, , 2023, 5) + (BehaviorState, running, 1948, 7) + (BehaviorState, waiting, 1913, 7) + (BehaviorStateGroup, , 1913, 33) + (BehaviorStateGroup, , 1948, 16) + (BehaviorTransition, , 1978, 33) + (BehaviorTransition, , 2013, 27) + (DispatchCondition, , 1991, 8) + (ModeSwitchCondition, , 2026, 2) + (ModeSwitchConjunction, , 2026, 2) + (ModeSwitchTrigger, , 2026, 2) + (Reference, , 2026, 2) + (ReferenceSegment, go, 2026, 2) diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt new file mode 100644 index 00000000000..9d3433ac09d --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt @@ -0,0 +1,13 @@ +annex[0] owner=DeviceConditionMix::sensor.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=idle + states[1] : BehaviorState name=active + transitions[0] : BehaviorTransition + condition : DispatchCondition + dispatchTriggerCondition : DispatchTriggerLogicalExpression + dispatchConjunctions[0] : DispatchConjunction + dispatchTriggers[0] : EventPortHolder element=DeviceConditionMix::sensor.go [EventPort] + transitions[1] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=DeviceConditionMix::sensor.go [EventPort] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt new file mode 100644 index 00000000000..db16df081d9 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt @@ -0,0 +1,8 @@ +annex[0] owner=DeviceExternalCondition::sensor.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=idle + states[1] : BehaviorState name=active + transitions[0] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=DeviceExternalCondition::sensor.go [EventPort] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt new file mode 100644 index 00000000000..7d9ab88768b --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt @@ -0,0 +1,8 @@ +annex[0] owner=DeviceExternalTriggerMismatch::sensor.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=idle + states[1] : BehaviorState name=active + transitions[0] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=DeviceExternalTriggerMismatch::sensor.wrong [EventPort] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt new file mode 100644 index 00000000000..ac188d9f721 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt @@ -0,0 +1,5 @@ +annex[0] owner=InModesExecuteCondition::controller.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=waiting + states[1] : BehaviorState name=running + transitions[0] : BehaviorTransition diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt new file mode 100644 index 00000000000..65802ca5dc9 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt @@ -0,0 +1,8 @@ +annex[0] owner=InModesExternalCondition::controller.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=waiting + states[1] : BehaviorState name=running + transitions[0] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=InModesExternalCondition::controller.go [EventPort] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Inheritance.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Inheritance.txt new file mode 100644 index 00000000000..cf175a8529f --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Inheritance.txt @@ -0,0 +1,14 @@ +annex[0] owner=Inheritance::base + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=fromtype +annex[1] owner=Inheritance::base.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=waiting + states[1] : BehaviorState name=running + transitions[0] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=Inheritance::base.go [EventPort] +annex[2] owner=Inheritance::base.replaced + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=only diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Issue3186.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Issue3186.txt new file mode 100644 index 00000000000..23b3dd32fb6 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_Issue3186.txt @@ -0,0 +1,8 @@ +annex[0] owner=Issue3186::controller.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=waiting + states[1] : BehaviorState name=running + transitions[0] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=Issue3186::controller.go [EventPort] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt new file mode 100644 index 00000000000..7f012bb4d5e --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt @@ -0,0 +1,9 @@ +annex[0] owner=ModalSubclauses::modal.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=whennormal +annex[1] owner=ModalSubclauses::modal.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=whenbackup +annex[2] owner=ModalSubclauses::modal.always + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=anymode diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt new file mode 100644 index 00000000000..2998eab92b1 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt @@ -0,0 +1,8 @@ +annex[0] owner=SubprogramExternalCondition::calc.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=start + states[1] : BehaviorState name=done + transitions[0] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=SubprogramExternalCondition::calc.go [EventPort] diff --git a/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt new file mode 100644 index 00000000000..f118ba0384c --- /dev/null +++ b/ba/org.osate.ba.tests/expected/resolved-model/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt @@ -0,0 +1,10 @@ +annex[0] owner=ThreadExternalCondition::worker.impl + parsedAnnexSubclause : BehaviorAnnex name=behavior_specification + states[0] : BehaviorState name=waiting + states[1] : BehaviorState name=running + transitions[0] : BehaviorTransition + condition : DispatchCondition + transitions[1] : BehaviorTransition + condition : ModeSwitchTriggerLogicalExpression + modeSwitchConjunctions[0] : ModeSwitchConjunction + modeSwitchTriggers[0] : EventPortHolder element=ThreadExternalCondition::worker.go [EventPort] diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt new file mode 100644 index 00000000000..e5c8f108090 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceConditionMix.txt @@ -0,0 +1,10 @@ +===== annex[0] owner=DeviceConditionMix::sensor.impl ===== + +states +\tidle : initial complete state; +\tactive : complete state; +transitions +\tidle -[on dispatch go]-> active; +\tidle -[on go]-> active; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt new file mode 100644 index 00000000000..c6b959551b1 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalCondition.txt @@ -0,0 +1,9 @@ +===== annex[0] owner=DeviceExternalCondition::sensor.impl ===== + +states +\tidle : initial complete state; +\tactive : complete state; +transitions +\tidle -[on go]-> active; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt new file mode 100644 index 00000000000..20c8bc2f5dd --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_DeviceExternalTriggerMismatch.txt @@ -0,0 +1,9 @@ +===== annex[0] owner=DeviceExternalTriggerMismatch::sensor.impl ===== + +states +\tidle : initial complete state; +\tactive : complete state; +transitions +\tidle -[on wrong]-> active; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt new file mode 100644 index 00000000000..a54963c811a --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExecuteCondition.txt @@ -0,0 +1,9 @@ +===== annex[0] owner=InModesExecuteCondition::controller.impl ===== + +states +\twaiting : initial state; +\trunning : state; +transitions +\twaiting -[]-> running; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt new file mode 100644 index 00000000000..2b2eb1b4839 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_InModesExternalCondition.txt @@ -0,0 +1,9 @@ +===== annex[0] owner=InModesExternalCondition::controller.impl ===== + +states +\twaiting : initial state; +\trunning : state; +transitions +\twaiting -[on go]-> running; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Inheritance.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Inheritance.txt new file mode 100644 index 00000000000..67b8e532750 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Inheritance.txt @@ -0,0 +1,21 @@ +===== annex[0] owner=Inheritance::base ===== + +states +\tfromtype : initial state; +----- Xtext reparse ----- +reparsed +===== annex[1] owner=Inheritance::base.impl ===== + +states +\twaiting : initial state; +\trunning : state; +transitions +\twaiting -[on go]-> running; +----- Xtext reparse ----- +reparsed +===== annex[2] owner=Inheritance::base.replaced ===== + +states +\tonly : initial state; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Issue3186.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Issue3186.txt new file mode 100644 index 00000000000..cfc2dfeef2b --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_Issue3186.txt @@ -0,0 +1,9 @@ +===== annex[0] owner=Issue3186::controller.impl ===== + +states +\twaiting : initial state; +\trunning : state; +transitions +\twaiting -[on go]-> running; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt new file mode 100644 index 00000000000..8eedc2a22d2 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ModalSubclauses.txt @@ -0,0 +1,18 @@ +===== annex[0] owner=ModalSubclauses::modal.impl ===== + +states +\twhennormal : initial state; +----- Xtext reparse ----- +reparsed +===== annex[1] owner=ModalSubclauses::modal.impl ===== + +states +\twhenbackup : initial state; +----- Xtext reparse ----- +reparsed +===== annex[2] owner=ModalSubclauses::modal.always ===== + +states +\tanymode : initial state; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt new file mode 100644 index 00000000000..7563fae3999 --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_SubprogramExternalCondition.txt @@ -0,0 +1,9 @@ +===== annex[0] owner=SubprogramExternalCondition::calc.impl ===== + +states +\tstart : initial state; +\tdone : final state; +transitions +\tstart -[on go]-> done; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt new file mode 100644 index 00000000000..e0457ee727b --- /dev/null +++ b/ba/org.osate.ba.tests/expected/unparse/org.osate.ba.tests_models_issue3186_ThreadExternalCondition.txt @@ -0,0 +1,10 @@ +===== annex[0] owner=ThreadExternalCondition::worker.impl ===== + +states +\twaiting : initial complete state; +\trunning : state; +transitions +\twaiting -[on dispatch]-> running; +\trunning -[on go]-> waiting; +----- Xtext reparse ----- +reparsed diff --git a/ba/org.osate.ba.tests/models/issue3186/.gitignore b/ba/org.osate.ba.tests/models/issue3186/.gitignore new file mode 100644 index 00000000000..afce51184c6 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/.gitignore @@ -0,0 +1,2 @@ +/.aadlbin-gen/ +/instances/ diff --git a/ba/org.osate.ba.tests/models/issue3186/.project b/ba/org.osate.ba.tests/models/issue3186/.project new file mode 100644 index 00000000000..174561b5476 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/.project @@ -0,0 +1,8 @@ + + + issue3186 + + + org.eclipse.xtext.ui.shared.xtextBuilder + org.osate.core.aadlnatureorg.eclipse.xtext.ui.shared.xtextNature + diff --git a/ba/org.osate.ba.tests/models/issue3186/DeviceConditionMix.aadl b/ba/org.osate.ba.tests/models/issue3186/DeviceConditionMix.aadl new file mode 100644 index 00000000000..6592d552b1f --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/DeviceConditionMix.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. + +package DeviceConditionMix +public + +device sensor +features + go : in event port; +end sensor; + +device implementation sensor.impl +modes + idle : initial mode; + active : mode; + idle -[go]-> active; +annex behavior_specification {** +states + idle : initial complete state; + active : complete state; +transitions + idle -[on dispatch go]-> active; + idle -[on go]-> active; +**}; +end sensor.impl; +end DeviceConditionMix; diff --git a/ba/org.osate.ba.tests/models/issue3186/DeviceExternalCondition.aadl b/ba/org.osate.ba.tests/models/issue3186/DeviceExternalCondition.aadl new file mode 100644 index 00000000000..1ce4bf0d650 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/DeviceExternalCondition.aadl @@ -0,0 +1,44 @@ +-- 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 DeviceExternalCondition +public + +device sensor +features + go : in event port; +end sensor; + +device implementation sensor.impl +modes + idle : initial mode; + active : mode; + idle -[go]-> active; +annex behavior_specification {** +states + idle : initial complete state; + active : complete state; +transitions + idle -[on go]-> active; +**}; +end sensor.impl; +end DeviceExternalCondition; diff --git a/ba/org.osate.ba.tests/models/issue3186/DeviceExternalTriggerMismatch.aadl b/ba/org.osate.ba.tests/models/issue3186/DeviceExternalTriggerMismatch.aadl new file mode 100644 index 00000000000..b668f6352ef --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/DeviceExternalTriggerMismatch.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. + +package DeviceExternalTriggerMismatch +public + +device sensor +features + go : in event port; + wrong : in event port; +end sensor; + +device implementation sensor.impl +modes + idle : initial mode; + active : mode; + idle -[go]-> active; +annex behavior_specification {** +states + idle : initial complete state; + active : complete state; +transitions + idle -[on wrong]-> active; +**}; +end sensor.impl; +end DeviceExternalTriggerMismatch; diff --git a/ba/org.osate.ba.tests/models/issue3186/InModesExecuteCondition.aadl b/ba/org.osate.ba.tests/models/issue3186/InModesExecuteCondition.aadl new file mode 100644 index 00000000000..5e88579921e --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/InModesExecuteCondition.aadl @@ -0,0 +1,40 @@ +-- 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 InModesExecuteCondition +public + +process controller +end controller; + +process implementation controller.impl +modes + normal : initial mode; +annex behavior_specification {** +states + waiting : initial state; + running : state; +transitions + waiting -[]-> running; +**} in modes (normal); +end controller.impl; +end InModesExecuteCondition; diff --git a/ba/org.osate.ba.tests/models/issue3186/InModesExternalCondition.aadl b/ba/org.osate.ba.tests/models/issue3186/InModesExternalCondition.aadl new file mode 100644 index 00000000000..2f7e5209919 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/InModesExternalCondition.aadl @@ -0,0 +1,42 @@ +-- 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 InModesExternalCondition +public + +process controller +features + go : in event port; +end controller; + +process implementation controller.impl +modes + normal : initial mode; +annex behavior_specification {** +states + waiting : initial state; + running : state; +transitions + waiting -[on go]-> running; +**} in modes (normal); +end controller.impl; +end InModesExternalCondition; diff --git a/ba/org.osate.ba.tests/models/issue3186/Inheritance.aadl b/ba/org.osate.ba.tests/models/issue3186/Inheritance.aadl new file mode 100644 index 00000000000..8fff9847e9d --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/Inheritance.aadl @@ -0,0 +1,57 @@ +-- 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 Inheritance +public + +abstract base +features + go : in event port; +annex behavior_specification {** +states + fromtype : initial state; +**}; +end base; + +abstract implementation base.impl +annex behavior_specification {** +states + waiting : initial state; + running : state; +transitions + waiting -[on go]-> running; +**}; +end base.impl; + +abstract implementation base.inherited extends base.impl +end base.inherited; + +abstract implementation base.replaced extends base.impl +annex behavior_specification {** +states + only : initial state; +**}; +end base.replaced; + +abstract implementation base.fromtype +end base.fromtype; +end Inheritance; diff --git a/ba/org.osate.ba.tests/models/issue3186/Issue3186.aadl b/ba/org.osate.ba.tests/models/issue3186/Issue3186.aadl new file mode 100644 index 00000000000..6b3bd2b24d9 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/Issue3186.aadl @@ -0,0 +1,40 @@ +-- 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 Issue3186 +public + +process controller +features + go : in event port; +end controller; + +process implementation controller.impl +annex behavior_specification {** +states + waiting : initial state; + running : state; +transitions + waiting -[on go]-> running; +**}; +end controller.impl; +end Issue3186; diff --git a/ba/org.osate.ba.tests/models/issue3186/ModalSubclauses.aadl b/ba/org.osate.ba.tests/models/issue3186/ModalSubclauses.aadl new file mode 100644 index 00000000000..ed25fb20d2f --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/ModalSubclauses.aadl @@ -0,0 +1,52 @@ +-- 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 ModalSubclauses +public + +abstract modal +end modal; + +abstract implementation modal.impl +modes + normal : initial mode; + backup : mode; +annex behavior_specification {** +states + whennormal : initial state; +**} in modes (normal); +annex behavior_specification {** +states + whenbackup : initial state; +**} in modes (backup); +end modal.impl; + +abstract implementation modal.always +modes + normal : initial mode; + backup : mode; +annex behavior_specification {** +states + anymode : initial state; +**}; +end modal.always; +end ModalSubclauses; diff --git a/ba/org.osate.ba.tests/models/issue3186/SubprogramExternalCondition.aadl b/ba/org.osate.ba.tests/models/issue3186/SubprogramExternalCondition.aadl new file mode 100644 index 00000000000..9d09bcffb6c --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/SubprogramExternalCondition.aadl @@ -0,0 +1,40 @@ +-- 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 SubprogramExternalCondition +public + +subprogram calc +features + go : out event port; +end calc; + +subprogram implementation calc.impl +annex behavior_specification {** +states + start : initial state; + done : final state; +transitions + start -[on go]-> done; +**}; +end calc.impl; +end SubprogramExternalCondition; diff --git a/ba/org.osate.ba.tests/models/issue3186/ThreadExternalCondition.aadl b/ba/org.osate.ba.tests/models/issue3186/ThreadExternalCondition.aadl new file mode 100644 index 00000000000..bfa4b868276 --- /dev/null +++ b/ba/org.osate.ba.tests/models/issue3186/ThreadExternalCondition.aadl @@ -0,0 +1,41 @@ +-- 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 ThreadExternalCondition +public + +thread worker +features + go : in event port; +end worker; + +thread implementation worker.impl +annex behavior_specification {** +states + waiting : initial complete state; + running : state; +transitions + waiting -[on dispatch]-> running; + running -[on go]-> waiting; +**}; +end worker.impl; +end ThreadExternalCondition; diff --git a/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3186Test.java b/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3186Test.java new file mode 100644 index 00000000000..6f64aa1e203 --- /dev/null +++ b/ba/org.osate.ba.tests/src/org/osate/ba/tests/Issue3186Test.java @@ -0,0 +1,221 @@ +/** + * 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 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.ComponentClassifier; +import org.osate.aadl2.DefaultAnnexSubclause; +import org.osate.aadl2.Mode; +import org.osate.testsupport.TestHelper; +import org.osate.xtext.aadl2.ba.util.BehaviorAnnexUtil; + +import com.google.inject.Inject; +import com.itemis.xtext.testing.XtextTest; + +/** + * Exercises the AS5506/3 Rev. A D.3 restrictions on external conditions by component category and {@code in modes} + * context, and the inheritance and replacement of Behavior Annex subclauses through the public access path. + */ +@RunWith(XtextRunner.class) +@InjectWith(BehaviorAnnexInjectorProvider.class) +public class Issue3186Test extends XtextTest { + private static final String PATH = "org.osate.ba.tests/models/issue3186/"; + private static final String CHECKER = "org.osate.xtext.aadl2.ba.checker"; + private static final String EXTERNAL_CONDITION_IN_MODES = "org.osate.xtext.aadl2.ba.externalConditionInModes"; + + @Inject + private TestHelper testHelper; + + @Inject + private ValidationTestHelper validationHelper; + + /** A component of a category other than thread and subprogram may leave an execution state on an event. */ + @Test + public void externalConditionIsAcceptedOutOfAnExecutionState() throws Exception { + validationHelper.assertNoIssues(testHelper.parseFile(PATH + "Issue3186.aadl")); + } + + @Test + public void threadCannotUseAnExternalCondition() throws Exception { + assertDiagnostics("ThreadExternalCondition", List.of(new Expected("on go", CHECKER, + "thread components cannot use an external condition: an execute, dispatch, or internal condition must" + + " be used instead: Behavior Annex D.3 consistency rule failed."))); + } + + /** + * The fixture's trigger is an outgoing event port because core AADL admits no other event port on a subprogram, + * so no subprogram can name the incoming port the D.3 event_trigger production asks for. The rule constrains the + * form of the condition rather than its triggers, which is what makes it worth reporting anyway. + */ + @Test + public void subprogramCannotUseAnExternalCondition() throws Exception { + assertDiagnostics("SubprogramExternalCondition", List.of(new Expected("on go", CHECKER, + "subprogram components cannot use an external condition: an execute or internal condition must be used" + + " instead: Behavior Annex D.3 consistency rule failed."))); + } + + /** Only external conditions leave the complete state, so the device rule has nothing to reject. */ + @Test + public void deviceMayLeaveACompleteStateOnExternalConditionsAlone() throws Exception { + validationHelper.assertNoIssues(testHelper.parseFile(PATH + "DeviceExternalCondition.aadl")); + } + + /** Each condition of the state is equally part of the mixture, so each one is reported. */ + @Test + public void deviceCannotMixExternalAndDispatchConditionsOutOfOneCompleteState() throws Exception { + var mixture = "The transitions out of complete state 'idle' of a device must use either only external" + + " conditions or only dispatch conditions: Behavior Annex D.3 consistency rule failed."; + assertDiagnostics("DeviceConditionMix", + List.of(new Expected("on dispatch go", CHECKER, mixture), new Expected("on go", CHECKER, mixture))); + } + + /** + * An external condition describes the mode transition of a mode-representing complete state, so its triggers are + * checked against that mode transition the way a dispatch condition's triggers are. + */ + @Test + public void externalConditionTriggersMustMatchTheModeTransition() throws Exception { + assertDiagnostics("DeviceExternalTriggerMismatch", List.of(new Expected("on wrong", CHECKER, + "The behavior transition tries to refine a transition mode but it is not consisting with any transition" + + " mode of DeviceExternalTriggerMismatch::sensor.impl component: Behavior Annex D.3.(C4)" + + " consistency rule failed."))); + } + + @Test + public void inModesSubclauseCannotUseAnExternalCondition() throws Exception { + assertDiagnostics("InModesExternalCondition", List.of(new Expected("on go", EXTERNAL_CONDITION_IN_MODES, + "A Behavior Annex subclause with an in modes statement cannot use an external condition: Behavior" + + " Annex D.3 consistency rule failed."))); + } + + @Test + public void inModesSubclauseMayUseAnExecuteCondition() throws Exception { + validationHelper.assertNoIssues(testHelper.parseFile(PATH + "InModesExecuteCondition.aadl")); + } + + @Test + public void classifierSubclauseAppliesToItself() throws Exception { + assertStates(subclauses("base.impl"), List.of(List.of("waiting", "running"))); + } + + @Test + public void ancestorSubclauseAppliesToADescendantThatDeclaresNone() throws Exception { + assertStates(subclauses("base.inherited"), List.of(List.of("waiting", "running"))); + } + + @Test + public void descendantSubclauseReplacesTheAncestorOne() throws Exception { + assertStates(subclauses("base.replaced"), List.of(List.of("only"))); + } + + @Test + public void typeSubclauseAppliesToAnImplementationThatDeclaresNone() throws Exception { + assertStates(subclauses("base.fromtype"), List.of(List.of("fromtype"))); + } + + /** D.3 lets a component with modes declare a separate subclause for each mode. */ + @Test + public void everyModalSubclauseOfTheClassifierApplies() throws Exception { + assertStates(BehaviorAnnexUtil.getBehaviorAnnexSubclauses(modalClassifier("modal.impl")), + List.of(List.of("whennormal"), List.of("whenbackup"))); + } + + @Test + public void modalSubclausesAreSelectedByMode() throws Exception { + var owner = modalClassifier("modal.impl"); + assertStates(BehaviorAnnexUtil.getBehaviorAnnexSubclauses(owner, mode(owner, "normal")), + List.of(List.of("whennormal"))); + assertStates(BehaviorAnnexUtil.getBehaviorAnnexSubclauses(owner, mode(owner, "backup")), + List.of(List.of("whenbackup"))); + } + + /** A subclause without an in modes statement is in effect in every mode. */ + @Test + public void subclauseWithoutInModesIsSelectedInEveryMode() throws Exception { + var owner = modalClassifier("modal.always"); + assertStates(BehaviorAnnexUtil.getBehaviorAnnexSubclauses(owner, mode(owner, "normal")), + List.of(List.of("anymode"))); + assertStates(BehaviorAnnexUtil.getBehaviorAnnexSubclauses(owner, mode(owner, "backup")), + List.of(List.of("anymode"))); + } + + private List subclauses(String classifierName) throws Exception { + return BehaviorAnnexUtil.getBehaviorAnnexSubclauses(classifier("Inheritance", classifierName)); + } + + private ComponentClassifier modalClassifier(String classifierName) throws Exception { + return classifier("ModalSubclauses", classifierName); + } + + private ComponentClassifier classifier(String model, String classifierName) throws Exception { + return (ComponentClassifier) testHelper.parseFile(PATH + model + ".aadl").getOwnedPublicSection() + .getOwnedClassifiers().stream() + .filter(candidate -> classifierName.equalsIgnoreCase(candidate.getName())) + .findFirst() + .orElseThrow(); + } + + private static void assertStates(List subclauses, List> expected) { + assertEquals(expected, subclauses.stream() + .map(subclause -> BehaviorAnnexUtil.getStrictModel(subclause).getStates().stream() + .map(org.osate.ba.aadlba.BehaviorState::getName) + .toList()) + .toList()); + } + + private static Mode mode(ComponentClassifier owner, String name) { + return owner.getAllModes().stream() + .filter(mode -> name.equalsIgnoreCase(mode.getName())) + .findFirst() + .orElseThrow(); + } + + private void assertDiagnostics(String model, List expected) throws Exception { + var root = testHelper.parseFile(PATH + model + ".aadl"); + var source = NodeModelUtils.getNode(root).getRootNode().getText(); + var issues = validationHelper.validate(root).stream().sorted(Comparator.comparing(Issue::getOffset)).toList(); + assertEquals(issues.toString(), expected.size(), issues.size()); + assertEquals(expected, issues.stream().map(issue -> { + assertEquals(Severity.ERROR, issue.getSeverity()); + var target = source.substring(issue.getOffset(), issue.getOffset() + issue.getLength()); + return new Expected(target, issue.getCode(), issue.getMessage()); + }).toList()); + } + + private record Expected(String target, String code, String message) { + } +} diff --git a/ba/org.osate.xtext.aadl2.ba.tests/src/org/osate/xtext/aadl2/ba/tests/BehaviorAnnexGrammarTest.java b/ba/org.osate.xtext.aadl2.ba.tests/src/org/osate/xtext/aadl2/ba/tests/BehaviorAnnexGrammarTest.java index 9fafd353cc3..e47e2eecb3f 100644 --- a/ba/org.osate.xtext.aadl2.ba.tests/src/org/osate/xtext/aadl2/ba/tests/BehaviorAnnexGrammarTest.java +++ b/ba/org.osate.xtext.aadl2.ba.tests/src/org/osate/xtext/aadl2/ba/tests/BehaviorAnnexGrammarTest.java @@ -57,8 +57,11 @@ @RunWith(XtextRunner.class) @InjectWith(BehaviorAnnexInjectorProvider.class) public class BehaviorAnnexGrammarTest { + // A subclause may carry an in modes statement between its annex text and the semicolon. Accepting it here keeps + // such a subclause covered instead of leaving its opening delimiter to pair with a later subclause's closing one. private static final Pattern BEHAVIOR_ANNEX = Pattern.compile( - "(?is)\\bannex\\s+behavior_specification\\s*\\{\\*\\*(.*?)\\*\\*\\}\\s*;"); + "(?is)\\bannex\\s+behavior_specification\\s*\\{\\*\\*(.*?)\\*\\*\\}" + + "\\s*(?:in\\s+modes\\s*\\([^)]*\\)\\s*)?;"); @Inject private ParseHelper parseHelper; From b002f5fe51636915149c9b36657abf2f788aab27 Mon Sep 17 00:00:00 2001 From: Lutz Wrage Date: Tue, 15 Sep 2026 13:07:39 -0400 Subject: [PATCH 2/2] Enforce Behavior Annex condition restrictions across component categories and modes AadlBaConsistencyRulesChecker gains the two D.3 condition rules the rules driver can decide from the strict model. The first rejects an external condition in a thread or a subprogram, naming the conditions that category uses instead; the driver checks it once per declaration so a multi-source transition reports once. The second rejects a mixture of external and dispatch conditions out of one complete state of a device, reporting each condition of that state and naming it, the way every conflicting otherwise transition of a state is reported; the driver checks it once for the subclause because the rule compares the conditions of several transitions. Both rules are cited by section. The numbered rule list these classes follow comes from the 0.94 draft, which orders the D.3 rules differently, so no number carries over. D.3.(C4) now reads the triggers of an external condition as well as those of a dispatch condition. AS5506/3 Rev. A D.3 lets a component of any category other than thread and subprogram describe a mode transition with an external condition, and C4 exists to compare such a transition with the corresponding mode transition triggers; it previously returned false without a diagnostic for every condition that was not a dispatch condition. The comparison reads triggers without their logical operators, as it already did for dispatch conditions. BehaviorAnnexValidator rejects an external condition in a subclause with an in modes statement. Core AADL keeps that statement on the enclosing DefaultAnnexSubclause and the strict model does not carry it, so this rule is checked on the declarative model, where the complete-state mode-refinement rule already is. DeclarativeToStrictTranslator exposes hasInModes for it and defines canRefineModes as its negation, which changes no behavior. D.3 states no per-category restriction on internal conditions beyond the execution-state rule already enforced, so none is added. BehaviorAnnexUtil.getBehaviorAnnexSubclauses puts the D.3 inheritance and replacement rule on the public access path: the nearest classifier in the extends order that declares a subclause supplies all of them, and an implementation falls back to its type. A mode-selecting overload uses the in modes statement core AADL retains, matching mode names case insensitively because an applicable subclause can be declared by an ancestor. Mode applicability is not duplicated into the strict model: every consumer of getStrictModel already holds the subclause that carries it. The subcomponent override rule is not enforced. It selects which subclause a consumer interprets for an instance rather than constraining a declaration, so it belongs to the consumer that walks the instance hierarchy; conformance.md records that. Fixes #3186 Co-Authored-By: Claude Opus 5 (1M context) --- ba/doc/conformance.md | 12 +- .../AadlBaConsistencyRulesChecker.java | 177 +++++++++++++++--- .../analyzers/AadlBaRulesCheckersDriver.java | 12 ++ .../DeclarativeToStrictTranslator.java | 15 +- .../aadl2/ba/util/BehaviorAnnexUtil.java | 77 ++++++++ .../ba/validation/BehaviorAnnexValidator.java | 22 +++ 6 files changed, 277 insertions(+), 38 deletions(-) diff --git a/ba/doc/conformance.md b/ba/doc/conformance.md index be778fc0164..e644f7587b3 100644 --- a/ba/doc/conformance.md +++ b/ba/doc/conformance.md @@ -19,7 +19,7 @@ The user directed that the report findings be treated as valid and filed without | G05 ✅ | [#3169](https://github.com/osate/osate2/issues/3169) | V02 ✅ | [#3183](https://github.com/osate/osate2/issues/3183) | | G06 ✅ | [#3170](https://github.com/osate/osate2/issues/3170) | V03 ✅ | [#3184](https://github.com/osate/osate2/issues/3184) | | G07 ✅ | [#3171](https://github.com/osate/osate2/issues/3171) | V04 | [#3185](https://github.com/osate/osate2/issues/3185) | -| G08 ✅ | [#3172](https://github.com/osate/osate2/issues/3172) | V05 | [#3186](https://github.com/osate/osate2/issues/3186) | +| G08 ✅ | [#3172](https://github.com/osate/osate2/issues/3172) | V05 ✅ | [#3186](https://github.com/osate/osate2/issues/3186) | | G09 | [#3173](https://github.com/osate/osate2/issues/3173) | V06 | [#3187](https://github.com/osate/osate2/issues/3187) | | 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) | @@ -28,9 +28,9 @@ The user directed that the report findings be treated as valid and filed without | 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) | | | -Closed since the review: G01 ([#3165](https://github.com/osate/osate2/issues/3165), internal conditions), G02 ([#3166](https://github.com/osate/osate2/issues/3166), external-condition expressions), G03 ([#3167](https://github.com/osate/osate2/issues/3167), frozen-port parentheses), G04 ([#3168](https://github.com/osate/osate2/issues/3168), timeout reset ports), G05 ([#3169](https://github.com/osate/osate2/issues/3169), short-circuit logical operators), G07 ([#3171](https://github.com/osate/osate2/issues/3171), the port `updated` value), G08 ([#3172](https://github.com/osate/osate2/issues/3172), `self` property references), G10 ([#3174](https://github.com/osate/osate2/issues/3174), internal port actions), G11 ([#3175](https://github.com/osate/osate2/issues/3175), numeric literals), G12 ([#3176](https://github.com/osate/osate2/issues/3176), array extents) together with its follow-ups [#3208](https://github.com/osate/osate2/issues/3208) and [#3210](https://github.com/osate/osate2/issues/3210), G13 ([#3177](https://github.com/osate/osate2/issues/3177), expression precedence and grouping), G16 ([#3180](https://github.com/osate/osate2/issues/3180), loop-variable assignment targets), V01 ([#3182](https://github.com/osate/osate2/issues/3182), declaration naming rules), V02 ([#3183](https://github.com/osate/osate2/issues/3183), otherwise-transition rules), and V03 ([#3184](https://github.com/osate/osate2/issues/3184), action timeout legality rules). +Closed since the review: G01 ([#3165](https://github.com/osate/osate2/issues/3165), internal conditions), G02 ([#3166](https://github.com/osate/osate2/issues/3166), external-condition expressions), G03 ([#3167](https://github.com/osate/osate2/issues/3167), frozen-port parentheses), G04 ([#3168](https://github.com/osate/osate2/issues/3168), timeout reset ports), G05 ([#3169](https://github.com/osate/osate2/issues/3169), short-circuit logical operators), G07 ([#3171](https://github.com/osate/osate2/issues/3171), the port `updated` value), G08 ([#3172](https://github.com/osate/osate2/issues/3172), `self` property references), G10 ([#3174](https://github.com/osate/osate2/issues/3174), internal port actions), G11 ([#3175](https://github.com/osate/osate2/issues/3175), numeric literals), G12 ([#3176](https://github.com/osate/osate2/issues/3176), array extents) together with its follow-ups [#3208](https://github.com/osate/osate2/issues/3208) and [#3210](https://github.com/osate/osate2/issues/3210), G13 ([#3177](https://github.com/osate/osate2/issues/3177), expression precedence and grouping), G16 ([#3180](https://github.com/osate/osate2/issues/3180), loop-variable assignment targets), V01 ([#3182](https://github.com/osate/osate2/issues/3182), declaration naming rules), V02 ([#3183](https://github.com/osate/osate2/issues/3183), otherwise-transition rules), V03 ([#3184](https://github.com/osate/osate2/issues/3184), action timeout legality rules), and V05 ([#3186](https://github.com/osate/osate2/issues/3186), condition restrictions by component category and `in modes` context, and subclause inheritance on the public access path). -That work opened four defects the review itself did not name: [#3195](https://github.com/osate/osate2/issues/3195), a bare `on dispatch` losing its condition unless exactly one space separated the keywords; [#3205](https://github.com/osate/osate2/issues/3205), the dequeue form of the G16 rule, which the assignment check did not reach; and [#3208](https://github.com/osate/osate2/issues/3208) and [#3210](https://github.com/osate/osate2/issues/3210), both from G12 and both described in that row. Each row's assessment below still describes the state at the review date unless it says otherwise. +That work opened five defects the review itself did not name: [#3195](https://github.com/osate/osate2/issues/3195), a bare `on dispatch` losing its condition unless exactly one space separated the keywords; [#3205](https://github.com/osate/osate2/issues/3205), the dequeue form of the G16 rule, which the assignment check did not reach; [#3208](https://github.com/osate/osate2/issues/3208) and [#3210](https://github.com/osate/osate2/issues/3210), both from G12 and both described in that row; and [#3232](https://github.com/osate/osate2/issues/3232), found while implementing V05, where an external-condition trigger that is not an incoming event or event data port is dropped in translation or kept despite its direction, in either case without a diagnostic. Each row's assessment below still describes the state at the review date unless it says otherwise. ## Reference and review method @@ -192,7 +192,7 @@ These are bounded findings from the inspected grammar/translator/checker path. E | V02 | D.3 otherwise rules: no assigned priority and at most one otherwise transition per source state. | Implemented for [#3183](https://github.com/osate/osate2/issues/3183): report every conflicting otherwise transition as an error identifying its source state, including overlapping multi-source declarations. Explicit priorities produce a warning once per declaration, reflecting the standard's “should not” wording. `Issue3183Test` covers duplicates, source overlap, explicit zero and positive priorities, and valid otherwise transitions. | | V03 | D.3 and D.6 action timeouts: a matching simple timeout transition from the same source; restrictions on combining an action timeout with timeout conditions. | Implemented for [#3184](https://github.com/osate/osate2/issues/3184): every top-level or nested action timeout is checked against each source of its transition for a same-source simple timeout catch. Action timeouts on execution-timeout, dispatch-relative-timeout, and completion-relative-timeout transitions are rejected. Diagnostics mark the behavior time and name a missing source state; `Issue3184Test` covers positive, missing, wrong-source, nested, expanded multi-source, and all three prohibited timeout-condition forms. | | V04 | D.3 nonblocking execution-state behavior. | The only consistency-checker method is the mode-related C4 check; no guard-exhaustiveness analysis is present there. The driver also comments out the call to the older `D_3_18_Checker`; that method's existence does not establish coverage. Distinguish general symbolic proof from simple detectable dead ends and clearly document any analysis limit. | -| V05 | D.3 component-category/mode restrictions on external/internal conditions; behavior inheritance and replacement. | Conditions can be parsed generically, while type checking dispatches only execute conditions and the rules driver primarily dispatch conditions. Same-named complete states are now bound for no-`in modes` refinements (G14), but the builder does not copy an in-modes context into the strict annex. Core AADL may retain mode applicability on the enclosing annex. Verify the complete consumer path before declaring inheritance or mode-specific selection unsupported. Cover thread/subprogram external-condition rejection and device condition mixing. | +| V05 | D.3 component-category/mode restrictions on external/internal conditions; behavior inheritance and replacement. | Conditions can be parsed generically, while type checking dispatches only execute conditions and the rules driver primarily dispatch conditions. Same-named complete states are now bound for no-`in modes` refinements (G14), but the builder does not copy an in-modes context into the strict annex. Core AADL may retain mode applicability on the enclosing annex. Verify the complete consumer path before declaring inheritance or mode-specific selection unsupported. Cover thread/subprogram external-condition rejection and device condition mixing. **Addressed by [#3186](https://github.com/osate/osate2/issues/3186):** the consistency checker rejects an external condition in a thread or a subprogram and rejects a mixture of external and dispatch conditions out of one complete state of a device; the validator rejects an external condition in a subclause with an `in modes` statement, which is where in-modes rules already live because core AADL keeps that statement on the enclosing subclause rather than in the strict annex. D.3 states no per-category restriction on internal conditions beyond the execution-state rule closed with [#3165](https://github.com/osate/osate2/issues/3165). C4 now reads the triggers of an external condition as well, so the mode-transition comparison covers the way a component of any other category than thread and subprogram describes a mode transition; that made `issue2147` report the missing-mode-transition finding its dispatch equivalent already produced. Mode applicability is not duplicated into the strict annex: core AADL keeps it on the `DefaultAnnexSubclause` that every consumer of `BehaviorAnnexUtil.getStrictModel` already holds. `BehaviorAnnexUtil.getBehaviorAnnexSubclauses` implements the ancestor/descendant rule on that access path, with a mode-selecting overload. `Issue3186Test` covers each rejection, a positive control for each, and the inheritance, replacement, type-fallback, and mode-selection cases. The subcomponent override rule is not enforced: it selects which subclause a consumer interprets for an instance rather than constraining a declaration, so it belongs to the consumer that walks the instance hierarchy. | | V06 | D.4 protocol/trigger compatibility, legal trigger/frozen-port categories, and consistency with core dispatch/freeze properties. | The checker has dedicated timeout branches and a stop check, but no complete implementation of the document's protocol/trigger table was found. Dispatch references use generic `Reference` syntax. A rule implementing one timeout form is not evidence for all rows of the table. Test the matrix and invalid trigger direction/category through embedded source. | | 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. | @@ -208,7 +208,7 @@ Some checker comments identify their source as **AADL Behavior Annex draft 0.94* 2. **Characterization still compares actual goldens.** `BehaviorAnnexCharacterizationTest.characterizeCurrentImplementation` uses `GoldenFile.assertMatches` for diagnostics, model shape, positions, and unparse results. This remains useful regression evidence. However, a golden preserving a known failure or malformed strict model is not a standard-conformance oracle. -3. **The complete-corpus tests exclude the known gap fixtures.** `BehaviorAnnexGrammarTest.parseAcceptedBehaviorAnnexCorpus` and `BehaviorAnnexTranslationTest.translatedModelsMatchResolvedModelGoldens` skip the conformance directory and fixtures with syntax-error goldens. A successful accepted-corpus test therefore cannot resolve G01–G10. The serializer round-trip test also skips models with issues. The two diagnostics golden suites do cover the conformance directory, so after step 1 each gap fixture has an exact recorded outcome in both registration states, but that records the gap; it does not close it. +3. **The complete-corpus tests exclude the known gap fixtures.** `BehaviorAnnexGrammarTest.parseAcceptedBehaviorAnnexCorpus` and `BehaviorAnnexTranslationTest.translatedModelsMatchResolvedModelGoldens` skip the conformance directory and fixtures with syntax-error goldens. A successful accepted-corpus test therefore cannot resolve G01–G10. The serializer round-trip test also skips models with issues. The two diagnostics golden suites do cover the conformance directory, so after step 1 each gap fixture has an exact recorded outcome in both registration states, but that records the gap; it does not close it. `parseAcceptedBehaviorAnnexCorpus` also matched a subclause by its annex text and a following semicolon, so it silently skipped every subclause with an `in modes` statement and, where another subclause followed one, paired their delimiters across the two; #3186 widened that pattern to accept the statement. 4. **Model goldens omit the attributes most relevant to G11–G13.** `BehaviorAnnexCharacterizationTest.appendModel`, line 260, records EClass, names, holder targets, and containment structure, but not general scalar attributes such as literal values, array sizes, or operator enum values. The translator test uses this representation and adds selected checks for property associations and freeze actions. It does not establish numeric or operator-value preservation. @@ -230,6 +230,6 @@ These are proposed follow-up changes, not changes made by this review. | 2 | Preserve strict-model meaning: numeric literals, array extents, logical grouping, `self`, internal events, and mode bindings (G08, G10–G14). **Done:** G08 and G10–G14 are implemented. | External AADL input produces correct literal values, extents, references, operation kinds, and mode links; no test-only model mutation is needed. Assert attributes and semantic structure directly. | | 3 | Implement the missing standard syntax and remove unwanted overacceptance (G01–G07, G09, G13). **Under way:** G01–G07 and G13 are closed; G09 remains. G06 uses a deliberate warned-extension policy rather than strict grammar rejection. | Each standard form parses and translates; nonstandard forms have deliberate rejection/extension policy. Enable corrected standard acceptance tests and add AST/strict-model expression tests. | | 4 | Correct the explicit validation mismatches and add the remaining static legality checks (G15–G18, V01–V03, V06–V07, V10–V11). G18 belongs first in this step: with type conformance disabled, several of the others cannot be demonstrated. **Under way:** G16 and V01–V03 are addressed; G15, G17, G18, V06, V07, V10, and V11 remain, and the G16 dequeue form (#3205) is open. | Each negative model has an exact rule diagnostic and a nearby positive control. For G18, every diagnostic that appears in the existing corpus is triaged and its golden updated deliberately. Reproduce independently before opening an issue; use one independently reviewable defect per issue/fix. | -| 5 | Establish behavioral/dataflow coverage and consumer boundaries (V04–V05, V08–V09, D.5 and D.8 runtime semantics). | State which obligations the front end can prove, which are warnings/approximations, and which belong to a simulator, analyzer, or generator. Validate queue behavior, timeouts, lock lifetimes, initialization, and call synchronization in the responsible consumer. | +| 5 | Establish behavioral/dataflow coverage and consumer boundaries (V04–V05, V08–V09, D.5 and D.8 runtime semantics). **Under way:** V05 is addressed, except for the subcomponent override rule, which that row assigns to the consumer that walks the instance hierarchy. | State which obligations the front end can prove, which are warnings/approximations, and which belong to a simulator, analyzer, or generator. Validate queue behavior, timeouts, lock lifetimes, initialization, and call synchronization in the responsible consumer. | There is no basis here for a numerical conformance percentage: the suite is not a clause-complete standard test suite, some assertions are ineffective, and operational semantics were outside the executed scope. A defensible future claim should distinguish syntax acceptance, valid strict-model construction, legality/consistency enforcement, and downstream execution semantics. diff --git a/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaConsistencyRulesChecker.java b/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaConsistencyRulesChecker.java index 89c27ea09dc..8f8648f80aa 100644 --- a/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaConsistencyRulesChecker.java +++ b/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaConsistencyRulesChecker.java @@ -22,9 +22,12 @@ package org.osate.ba.analyzers; import java.util.ArrayList; +import java.util.IdentityHashMap; import java.util.List; +import java.util.Map; import org.eclipse.emf.common.util.EList; +import org.osate.aadl2.ComponentCategory; import org.osate.aadl2.ComponentClassifier; import org.osate.aadl2.Mode; import org.osate.aadl2.ModeTransition; @@ -33,12 +36,17 @@ import org.osate.aadl2.modelsupport.errorreporting.AnalysisErrorReporterManager; import org.osate.ba.aadlba.ActualPortHolder; import org.osate.ba.aadlba.BehaviorAnnex; +import org.osate.ba.aadlba.BehaviorCondition; import org.osate.ba.aadlba.BehaviorElement; import org.osate.ba.aadlba.BehaviorState; import org.osate.ba.aadlba.BehaviorTransition; import org.osate.ba.aadlba.DispatchCondition; import org.osate.ba.aadlba.DispatchTrigger; import org.osate.ba.aadlba.DispatchTriggerLogicalExpression; +import org.osate.ba.aadlba.ModeSwitchConjunction; +import org.osate.ba.aadlba.ModeSwitchTrigger; +import org.osate.ba.aadlba.ModeSwitchTriggerCondition; +import org.osate.ba.aadlba.ModeSwitchTriggerLogicalExpression; import org.osate.ba.utils.AadlBaUtils; import org.osate.ba.utils.AadlBaVisitors; import org.osate.utils.internal.Aadl2Utils; @@ -87,27 +95,40 @@ public boolean D_3_C4_Check(BehaviorTransition btOwner, BehaviorState srcState) // At this point, one of the current behavior transtion's src states // represent a mode. - DispatchTriggerLogicalExpression dtle; var mode = declaredState.getBindedMode(); - // As D.3.(C4), behavior state that represents a mode is a complete - // state and as D.3.(L6) and D.3(L7) legality rules: only dispatch - // trigger logical expression is analyzed. - if (!(btOwner.getCondition() instanceof DispatchCondition dispatchCondition)) { - // D.3.(L6) and D.3(L7) error case. Do not report error but - // exit with false result. - return false; - } + // The element the triggers were read from, which carries any mismatch diagnostic. + final BehaviorElement triggerOwner; + // Fetches trigger names in the given behavior transition. + final var lCondTriggs = new ArrayList(); - if (dispatchCondition.getDispatchTriggerCondition() instanceof DispatchTriggerLogicalExpression expression) { - dtle = expression; + // As D.3.(C4), a behavior state that represents a mode is a complete state, so D.3.(L6) and D.3.(L7) leave a + // dispatch condition as the only condition a thread can use here. AS5506/3 Rev A D.3 also lets a component of + // any other category than thread and subprogram describe a mode transition with an external condition, whose + // event triggers are read the same way. + if (btOwner.getCondition() instanceof DispatchCondition dispatchCondition) { + if (!(dispatchCondition + .getDispatchTriggerCondition() instanceof DispatchTriggerLogicalExpression expression)) { + // At least, there is one mode transition trigger in a mode + // transition. So this transition is not consistency. + // The state declaration is legal; the transition's dispatch condition is what is inconsistent. + reportConsistencyError(dispatchCondition, + "The behavior transition tries " + "to refine a transition mode but it hasn't got any dispatch " + + "trigger logical expression: Behavior Annex D.3.(C4) " + "consistency rule failed"); + return false; + } + triggerOwner = expression; + for (var trigg : AadlBaVisitors.getDispatchTriggers(expression)) { + lCondTriggs.add(((ActualPortHolder) trigg).getPort().getName()); + } + } else if (btOwner.getCondition() instanceof ModeSwitchTriggerLogicalExpression expression) { + triggerOwner = expression; + for (var trigg : getExternalConditionTriggers(expression)) { + lCondTriggs.add(trigg.getPort().getName()); + } } else { - // At least, there is one mode transition trigger in a mode - // transition. So this transition is not consistency. - // The state declaration is legal; the transition's dispatch condition is what is inconsistent. - reportConsistencyError(dispatchCondition, - "The behavior transition tries " + "to refine a transition mode but it hasn't got any dispatch " - + "trigger logical expression: Behavior Annex D.3.(C4) " + "consistency rule failed"); + // D.3.(L6) and D.3(L7) error case. Do not report error but + // exit with false result. return false; } @@ -117,7 +138,7 @@ public boolean D_3_C4_Check(BehaviorTransition btOwner, BehaviorState srcState) // Can't be out a state/mode if the parent container doesn't declare // any transition mode. if (lModeTrans.isEmpty()) { - reportConsistencyError(dispatchCondition, + reportConsistencyError(btOwner.getCondition(), "The behavior transition tries to " + "refine a transition mode while " + _baParentContainer.getQualifiedName() + " component hasn't got any transition mode: " + "Behavior Annex D.3.(C4) consistency rule failed"); @@ -128,14 +149,6 @@ public boolean D_3_C4_Check(BehaviorTransition btOwner, BehaviorState srcState) var lModeTriggs = new ArrayList(); - // Fetches dispatch trigger names in the given behavior transition. - var ldispTriggs = new ArrayList(); - - for (var trigg : AadlBaVisitors.getDispatchTriggers(dtle)) { - var portHolder = (ActualPortHolder) trigg; - ldispTriggs.add(portHolder.getPort().getName()); - } - // Checks if the behavior transition is consisting with one of // the mode transitions where the considered mode is contained. // Otherwise reports an error. @@ -149,7 +162,7 @@ public boolean D_3_C4_Check(BehaviorTransition btOwner, BehaviorState srcState) // Checks consistency between the two triggers lists without // considering their order. - if (Aadl2Utils.compareStringList(ldispTriggs, lModeTriggs)) { + if (Aadl2Utils.compareStringList(lCondTriggs, lModeTriggs)) { return true; } else { lModeTriggs.clear(); @@ -162,15 +175,121 @@ public boolean D_3_C4_Check(BehaviorTransition btOwner, BehaviorState srcState) // Error case : the given behavior transition which is out of a mode // is not consisting with any transition mode which involves the considered // mode. - // The mismatch is between the dispatch triggers and the mode transition triggers, so mark the trigger + // The mismatch is between the condition's triggers and the mode transition triggers, so mark the trigger // expression rather than the legal source state declaration. - reportConsistencyError(dtle, + reportConsistencyError(triggerOwner, "The behavior transition tries to " + "refine a transition mode but it is not consisting with any " + "transition mode of " + _baParentContainer.getQualifiedName() + " component: Behavior Annex D.3.(C4) consistency rule failed"); return false; } + /** + * Document: AS5506/3 Rev A + * Type : Consistency rule + * Section : D.3 Behavior Specification + * Object : Threads and subprograms must not use external conditions; they describe their transitions with + * execute, dispatch, and internal conditions instead. The rule is cited by section rather than by number because + * the numbered rule list this class follows comes from the 0.94 draft, which orders the D.3 rules differently. + * Keys : external condition thread subprogram component category + */ + public boolean D_3_External_Condition_Category_Check(BehaviorTransition bt) { + if (!(bt.getCondition() instanceof ModeSwitchTriggerCondition)) { + return true; + } + var category = _baParentContainer.getCategory(); + final String admitted; + if (category == ComponentCategory.THREAD) { + admitted = "an execute, dispatch, or internal condition"; + } else if (category == ComponentCategory.SUBPROGRAM) { + admitted = "an execute or internal condition"; + } else { + return true; + } + // The source state declaration is legal; the external condition is what the rule forbids here. + reportConsistencyError(bt.getCondition(), category.getName() + " components cannot use an external condition: " + + admitted + " must be used instead: Behavior Annex D.3 consistency rule failed"); + return false; + } + + /** + * Document: AS5506/3 Rev A + * Type : Consistency rule + * Section : D.3 Behavior Specification + * Object : For devices, the transitions out of a given complete state use either only external conditions or only + * dispatch conditions. Each condition of the state is equally part of the mixture, so each one is reported, the + * way every conflicting otherwise transition of a state is. Cited by section for the reason given on + * {@link #D_3_External_Condition_Category_Check(BehaviorTransition)}. + * Keys : external condition dispatch condition device complete state + */ + public boolean D_3_Device_Condition_Check(BehaviorAnnex ba) { + if (_baParentContainer.getCategory() != ComponentCategory.DEVICE) { + return true; + } + Map> external = new IdentityHashMap<>(); + Map> dispatch = new IdentityHashMap<>(); + for (var transition : ba.getTransitions()) { + var condition = transition.getCondition(); + final Map> kind; + if (condition instanceof ModeSwitchTriggerCondition) { + kind = external; + } else if (condition instanceof DispatchCondition) { + kind = dispatch; + } else { + continue; + } + for (var source : BehaviorTransitionContext.getSourceStates(transition)) { + if (source.isComplete()) { + kind.computeIfAbsent(source, key -> new ArrayList<>()).add(condition); + } + } + } + + var result = true; + for (var state : ba.getStates()) { + var externalConditions = external.get(state); + var dispatchConditions = dispatch.get(state); + if (externalConditions == null || dispatchConditions == null) { + continue; + } + result = false; + var conflicting = new ArrayList<>(externalConditions); + conflicting.addAll(dispatchConditions); + for (var condition : conflicting) { + // Include the source name so distinct conflicts on a multi-source declaration remain visible. + reportConsistencyError(condition, "The transitions out of complete state '" + state.getName() + + "' of a device must use either only external conditions or only dispatch conditions: " + + "Behavior Annex D.3 consistency rule failed"); + } + } + return result; + } + + /** + * Returns the event triggers of an external condition, including those of its parenthesized groups. Like the + * dispatch trigger comparison this feeds, it reads the triggers without their logical operators, so the comparison + * with the mode transition triggers is about which events take part, not how they are combined. + */ + private static List getExternalConditionTriggers( + ModeSwitchTriggerLogicalExpression expression) { + var result = new ArrayList(); + collectExternalConditionTriggers(expression, result); + return result; + } + + private static void collectExternalConditionTriggers(ModeSwitchTriggerLogicalExpression expression, + List result) { + for (ModeSwitchConjunction conjunction : expression.getModeSwitchConjunctions()) { + for (ModeSwitchTrigger trigger : conjunction.getModeSwitchTriggers()) { + if (trigger instanceof ModeSwitchTriggerLogicalExpression group) { + collectExternalConditionTriggers(group, result); + } else if (trigger instanceof ActualPortHolder port) { + result.add(port); + } + } + } + } + // TODO Provide column number. private void reportConsistencyError(BehaviorElement obj, String msg) { _errManager.error(obj, msg + "."); diff --git a/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaRulesCheckersDriver.java b/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaRulesCheckersDriver.java index 5602a436834..e9dff377719 100644 --- a/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaRulesCheckersDriver.java +++ b/ba/org.osate.ba/src/org/osate/ba/analyzers/AadlBaRulesCheckersDriver.java @@ -50,6 +50,7 @@ import org.osate.ba.aadlba.ElseStatement; import org.osate.ba.aadlba.IfStatement; import org.osate.ba.aadlba.LoopStatement; +import org.osate.ba.aadlba.ModeSwitchTriggerCondition; import org.osate.ba.aadlba.Otherwise; import org.osate.ba.aadlba.TimedAction; import org.osate.ba.aadlba.util.AadlBaSwitch; @@ -169,6 +170,10 @@ public Boolean caseAnnexSubclause(AnnexSubclause object) { // here instead of from the per-transition traversal below. result &= _legality.D_6_L11_Check(_ba); + // The device condition rule compares the conditions of every transition out of one complete state, + // so it is checked once for the subclause rather than from the per-transition traversal below. + result &= _consistency.D_3_Device_Condition_Check(_ba); + // A multi-source transition has copies of its condition and a shared action block. Check each once // per annex traversal, while retaining the state checks for every expanded transition. Set checked = Collections.newSetFromMap(new IdentityHashMap<>()); @@ -236,6 +241,13 @@ private boolean checkBehaviorTransition(BehaviorTransition tmp, SetD.3 also lets a component with modes declare a separate subclause for each mode, so every subclause of the + * classifier that supplies them is returned; {@link #getBehaviorAnnexSubclauses(ComponentClassifier, Mode)} + * selects among them by mode. + * + * @param classifier component classifier to find the applicable subclauses of + * @return the applicable subclauses in declaration order, empty when neither the classifier nor anything it + * inherits from declares one + */ + public static List getBehaviorAnnexSubclauses(final ComponentClassifier classifier) { + Objects.requireNonNull(classifier, "classifier"); + final List searchOrder = new ArrayList<>(classifier.getSelfPlusAllExtended()); + if (classifier instanceof ComponentImplementation implementation && implementation.getType() != null) { + searchOrder.addAll(implementation.getType().getSelfPlusAllExtended()); + } + for (final var candidate : searchOrder) { + final var declared = declaredBehaviorAnnexSubclauses(candidate); + if (!declared.isEmpty()) { + return declared; + } + } + return List.of(); + } + + /** + * Returns the applicable Behavior Annex subclauses of a classifier that are in effect in a mode. D.3 lets a + * component with modes declare a separate subclause for each mode, and core AADL expresses which modes a subclause + * applies in with its {@code in modes} statement, so a subclause without one is in effect in every mode. Modes are + * matched by name, case insensitively, because an applicable subclause can be declared by an ancestor and name + * that ancestor's mode. + * + * @param classifier component classifier to find the applicable subclauses of + * @param mode mode to select the subclauses in effect in + * @return the applicable subclauses in effect in the mode, in declaration order + */ + public static List getBehaviorAnnexSubclauses(final ComponentClassifier classifier, + final Mode mode) { + Objects.requireNonNull(mode, "mode"); + final List result = new ArrayList<>(); + for (final var subclause : getBehaviorAnnexSubclauses(classifier)) { + if (subclause.getInModes().isEmpty() || subclause.getInModes().stream() + .anyMatch(applicable -> applicable.getName() != null + && applicable.getName().equalsIgnoreCase(mode.getName()))) { + result.add(subclause); + } + } + return Collections.unmodifiableList(result); + } + + /** + * Returns the Behavior Annex subclauses a classifier declares itself. Selection is by annex name so that finding + * the applicable subclauses of a classifier does not parse the subclauses of other annexes. + */ + private static List declaredBehaviorAnnexSubclauses(final Classifier classifier) { + final List result = new ArrayList<>(); + for (final var subclause : classifier.getOwnedAnnexSubclauses()) { + if (subclause instanceof DefaultAnnexSubclause defaultAnnex + && BehaviorAnnexStandaloneSetup.ANNEX_NAME.equalsIgnoreCase(defaultAnnex.getName())) { + result.add(defaultAnnex); + } + } + return Collections.unmodifiableList(result); + } + public static org.osate.ba.aadlba.BehaviorAnnex getStrictModel(final DefaultAnnexSubclause defaultAnnex) { Objects.requireNonNull(defaultAnnex, "defaultAnnex"); if (!(defaultAnnex.getParsedAnnexSubclause() instanceof BehaviorAnnex source)) { 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 bc0a7e35517..a47fe022d17 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 @@ -102,6 +102,7 @@ public final class BehaviorAnnexValidator extends AbstractBehaviorAnnexValidator 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 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"; public static final String PORT_STATUS_DIRECTION = "org.osate.xtext.aadl2.ba.portStatusDirection"; private static final URI VALIDATION_RESOURCE_URI = URI.createURI("validation:/behavior-annex.aadlba"); @@ -139,6 +140,7 @@ public void checkBehaviorAnnex(final BehaviorAnnex source) { representable &= checkIteratorTargets(source, translation); representable &= checkIteratedValues(source, translation); checkPortStatusValues(source, translation); + checkExternalConditionsInModes(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); @@ -547,6 +549,26 @@ private boolean checkCompleteModeStates(final BehaviorAnnex source, final Compon return valid; } + /** + * D.3 does not allow an external condition in a subclause that carries an {@code in modes} statement: such a + * subclause applies in the modes it lists rather than describing mode transitions of its owner. Core AADL keeps the + * statement on the enclosing subclause and the strict model does not carry it, so this rule is checked here, like + * the complete-state mode-refinement rule, rather than by the strict-model checkers. + */ + private void checkExternalConditionsInModes(final BehaviorAnnex source) { + if (!DeclarativeToStrictTranslator.hasInModes(source)) { + return; + } + for (var transition : source.getTransitions()) { + var condition = transition.getCondition(); + if (condition != null && condition.getModeSwitch() != null) { + error("A Behavior Annex subclause with an in modes statement cannot use an external condition:" + + " Behavior Annex D.3 consistency rule failed.", condition, null, + ValidationMessageAcceptor.INSIGNIFICANT_INDEX, EXTERNAL_CONDITION_IN_MODES); + } + } + } + private record Declaration(String name, EObject source, EStructuralFeature feature, boolean complete) { }