From 905bd903e147ea0b5f8213c8e744dc069b989b84 Mon Sep 17 00:00:00 2001 From: Joe Seibel <1824701+joeseibel@users.noreply.github.com> Date: Thu, 25 Jul 2019 14:43:38 -0400 Subject: [PATCH 1/2] Validate that there is only one call sequence per mode. --- .../aadl2/validation/Aadl2JavaValidator.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/core/org.osate.xtext.aadl2/src/org/osate/xtext/aadl2/validation/Aadl2JavaValidator.java b/core/org.osate.xtext.aadl2/src/org/osate/xtext/aadl2/validation/Aadl2JavaValidator.java index 0d513e7898c..5b53eceb3eb 100644 --- a/core/org.osate.xtext.aadl2/src/org/osate/xtext/aadl2/validation/Aadl2JavaValidator.java +++ b/core/org.osate.xtext.aadl2/src/org/osate/xtext/aadl2/validation/Aadl2JavaValidator.java @@ -713,6 +713,33 @@ public void caseModeTransitionTrigger(ModeTransitionTrigger trigger) { public void casePackageSection(PackageSection packageSection) { checkWithsAreUsed(packageSection); } + + @Check + public void checkOneSequencePerMode(SubprogramCallSequence sequence) { + BehavioredImplementation classifier = EcoreUtil2.getContainerOfType(sequence, BehavioredImplementation.class); + List otherSequences = classifier.getAllSubprogramCallSequences().stream() + .filter(other -> other != sequence).collect(Collectors.toList()); + if (!classifier.getAllModes().isEmpty()) { + final List modes; + if (sequence.getInModes().isEmpty()) { + modes = classifier.getAllModes(); + } else { + modes = sequence.getInModes(); + } + Stream withMultiple = modes.stream().filter(mode -> { + return otherSequences.stream() + .anyMatch(other -> other.getInModes().isEmpty() || other.getInModes().contains(mode)); + }); + String modeMessage = withMultiple.map(mode -> mode.getName()).collect(Collectors.joining(", ")); + if (!modeMessage.isEmpty()) { + error("Multiple sequences declared for modes: " + modeMessage, + Aadl2Package.eINSTANCE.getNamedElement_Name()); + } + } else if (!otherSequences.isEmpty()) { + error("Multiple sequences declared for non-modal implementation", + Aadl2Package.eINSTANCE.getNamedElement_Name()); + } + } @Override public void checkForAppendsInContainedPropertyAssociation(PropertyAssociation propertyAssoc) { From 2324eb121e3f9585af9036e1373dc2aaa8a3b18a Mon Sep 17 00:00:00 2001 From: Joe Seibel <1824701+joeseibel@users.noreply.github.com> Date: Thu, 25 Jul 2019 14:45:05 -0400 Subject: [PATCH 2/2] Test for one call sequence per mode validation. --- .../models/issue1564/.gitignore | 1 + .../models/issue1564/.project | 18 ++++ .../models/issue1564/issue1564.aadl | 90 +++++++++++++++++++ .../OtherAadl2JavaValidatorTest.xtend | 27 ++++-- .../core/tests/issues/Issue1564Test.xtend | 78 ++++++++++++++++ .../PropertiesScopeProviderTest.xtend | 4 +- 6 files changed, 209 insertions(+), 9 deletions(-) create mode 100644 core/org.osate.core.tests/models/issue1564/.gitignore create mode 100644 core/org.osate.core.tests/models/issue1564/.project create mode 100644 core/org.osate.core.tests/models/issue1564/issue1564.aadl create mode 100644 core/org.osate.core.tests/src/org/osate/core/tests/issues/Issue1564Test.xtend diff --git a/core/org.osate.core.tests/models/issue1564/.gitignore b/core/org.osate.core.tests/models/issue1564/.gitignore new file mode 100644 index 00000000000..11d04b41d15 --- /dev/null +++ b/core/org.osate.core.tests/models/issue1564/.gitignore @@ -0,0 +1 @@ +/.aadlbin-gen/ diff --git a/core/org.osate.core.tests/models/issue1564/.project b/core/org.osate.core.tests/models/issue1564/.project new file mode 100644 index 00000000000..ffe429df812 --- /dev/null +++ b/core/org.osate.core.tests/models/issue1564/.project @@ -0,0 +1,18 @@ + + + issue1564 + + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + + org.osate.core.aadlnature + org.eclipse.xtext.ui.shared.xtextNature + + diff --git a/core/org.osate.core.tests/models/issue1564/issue1564.aadl b/core/org.osate.core.tests/models/issue1564/issue1564.aadl new file mode 100644 index 00000000000..24aaaaff0cd --- /dev/null +++ b/core/org.osate.core.tests/models/issue1564/issue1564.aadl @@ -0,0 +1,90 @@ +package issue1564 +public + subprogram sp + end sp; + + thread not_modal + end not_modal; + + thread implementation not_modal.i1 + calls + --Pass + sequence1: { + call1: subprogram sp; + }; + end not_modal.i1; + + thread implementation not_modal.i2 + calls + --Fail + sequence2: { + call2: subprogram sp; + }; + --Fail + sequence3: { + call3: subprogram sp; + }; + end not_modal.i2; + + thread modal + modes + m1: initial mode; + m2: mode; + end modal; + + thread implementation modal.i3 + calls + --Pass + sequence4: { + call4: subprogram sp; + }; + end modal.i3; + + thread implementation modal.i4 + calls + --Pass + sequence5: { + call5: subprogram sp; + } in modes (m1); + --Pass + sequence6: { + call6: subprogram sp; + } in modes (m2); + end modal.i4; + + thread implementation modal.i5 + calls + --Fail + sequence7: { + call7: subprogram sp; + } in modes (m1); + --Fail + sequence8: { + call8: subprogram sp; + } in modes (m1); + end modal.i5; + + thread implementation modal.i6 + calls + --Fail + sequence9: { + call9: subprogram sp; + } in modes (m1); + --Fail + sequence10: { + call10: subprogram sp; + }; + end modal.i6; + + thread implementation modal.i7 + calls + --Fail + sequence11: { + call11: subprogram sp; + }; + --Fail + sequence12: { + call12: subprogram sp; + }; + end modal.i7; +end issue1564; \ No newline at end of file diff --git a/core/org.osate.core.tests/src/org/osate/core/tests/aadl2javavalidator/OtherAadl2JavaValidatorTest.xtend b/core/org.osate.core.tests/src/org/osate/core/tests/aadl2javavalidator/OtherAadl2JavaValidatorTest.xtend index ea1d40ebc42..597923c2819 100644 --- a/core/org.osate.core.tests/src/org/osate/core/tests/aadl2javavalidator/OtherAadl2JavaValidatorTest.xtend +++ b/core/org.osate.core.tests/src/org/osate/core/tests/aadl2javavalidator/OtherAadl2JavaValidatorTest.xtend @@ -1712,7 +1712,8 @@ class OtherAadl2JavaValidatorTest extends XtextTest { publicSection.ownedClassifiers.get(11) as SubprogramImplementation => [ "subprog1.spi1".assertEquals(name) ownedSubprogramCallSequences.head => [ - "callseq1".assertEquals(name); + "callseq1".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for non-modal implementation") ownedSubprogramCalls.head => [ "callspi2".assertEquals(name) assertError(testFileResult.issues, issueCollection, "Duplicate identifiers 'callspi2' in subprog1.spi1") @@ -1727,26 +1728,38 @@ class OtherAadl2JavaValidatorTest extends XtextTest { ] ] ownedSubprogramCallSequences.get(1) => [ - "callseq2".assertEquals(name); + "callseq2".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for non-modal implementation") ownedSubprogramCalls.head => [ "callspi3".assertEquals(name) assertError(testFileResult.issues, issueCollection, "Duplicate identifiers 'callspi3' in subprog1.spi1") ] ] ownedSubprogramCallSequences.get(2) => [ - "callseq3".assertEquals(name); - assertError(testFileResult.issues, issueCollection, "Duplicate identifiers 'callseq3' in subprog1.spi1") + "callseq3".assertEquals(name) + assertError(testFileResult.issues, issueCollection, + "Duplicate identifiers 'callseq3' in subprog1.spi1", + "Multiple sequences declared for non-modal implementation" + ) ] ownedSubprogramCallSequences.get(3) => [ - "callseq3".assertEquals(name); - assertError(testFileResult.issues, issueCollection, "Duplicate identifiers 'callseq3' in subprog1.spi1") + "callseq3".assertEquals(name) + assertError(testFileResult.issues, issueCollection, + "Duplicate identifiers 'callseq3' in subprog1.spi1", + "Multiple sequences declared for non-modal implementation" + ) + ] + ownedSubprogramCallSequences.get(4) => [ + "callseq4".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for non-modal implementation") ] ] publicSection.ownedClassifiers.get(12) as SubprogramImplementation => [ "subprog1.spi3".assertEquals(name) ownedSubprogramCallSequences.head => [ - "callseq5".assertEquals(name); + "callseq5".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for non-modal implementation") ownedSubprogramCalls.head => [ "callspi6".assertEquals(name) assertError(testFileResult.issues, issueCollection, "Identifier 'callspi6' has previously been defined in 'componentimpluniquenames::subprog1.spi1'") diff --git a/core/org.osate.core.tests/src/org/osate/core/tests/issues/Issue1564Test.xtend b/core/org.osate.core.tests/src/org/osate/core/tests/issues/Issue1564Test.xtend new file mode 100644 index 00000000000..1ccd90680ae --- /dev/null +++ b/core/org.osate.core.tests/src/org/osate/core/tests/issues/Issue1564Test.xtend @@ -0,0 +1,78 @@ +package org.osate.core.tests.issues + +import com.google.inject.Inject +import com.itemis.xtext.testing.FluentIssueCollection +import com.itemis.xtext.testing.XtextTest +import org.eclipse.xtext.testing.InjectWith +import org.eclipse.xtext.testing.XtextRunner +import org.junit.Test +import org.junit.runner.RunWith +import org.osate.aadl2.AadlPackage +import org.osate.aadl2.ThreadImplementation +import org.osate.testsupport.Aadl2InjectorProvider +import org.osate.testsupport.TestHelper + +import static extension org.junit.Assert.assertEquals +import static extension org.osate.testsupport.AssertHelper.assertError + +@RunWith(XtextRunner) +@InjectWith(Aadl2InjectorProvider) +class Issue1564Test extends XtextTest { + @Inject + TestHelper testHelper + + @Test + def void testIssue1564() { + val testFileResult = issues = testHelper.testFile("org.osate.core.tests/models/issue1564/issue1564.aadl") + val issueCollection = new FluentIssueCollection(testFileResult.resource, newArrayList, newArrayList) + testFileResult.resource.contents.head as AadlPackage => [ + "issue1564".assertEquals(name) + publicSection.ownedClassifiers.get(3) as ThreadImplementation => [ + "not_modal.i2".assertEquals(name) + ownedSubprogramCallSequences.get(0) => [ + "sequence2".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for non-modal implementation") + ] + ownedSubprogramCallSequences.get(1) => [ + "sequence3".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for non-modal implementation") + ] + ] + publicSection.ownedClassifiers.get(7) as ThreadImplementation => [ + "modal.i5".assertEquals(name) + ownedSubprogramCallSequences.get(0) => [ + "sequence7".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for modes: m1") + ] + ownedSubprogramCallSequences.get(1) => [ + "sequence8".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for modes: m1") + ] + ] + publicSection.ownedClassifiers.get(8) as ThreadImplementation => [ + "modal.i6".assertEquals(name) + ownedSubprogramCallSequences.get(0) => [ + "sequence9".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for modes: m1") + ] + ownedSubprogramCallSequences.get(1) => [ + "sequence10".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for modes: m1") + ] + ] + publicSection.ownedClassifiers.get(9) as ThreadImplementation => [ + "modal.i7".assertEquals(name) + ownedSubprogramCallSequences.get(0) => [ + "sequence11".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for modes: m1, m2") + ] + ownedSubprogramCallSequences.get(1) => [ + "sequence12".assertEquals(name) + assertError(testFileResult.issues, issueCollection, "Multiple sequences declared for modes: m1, m2") + ] + ] + ] + issueCollection.sizeIs(testFileResult.issues.size) + assertConstraints(issueCollection) + } +} \ No newline at end of file diff --git a/core/org.osate.core.tests/src/org/osate/core/tests/propertiesscopeprovider/PropertiesScopeProviderTest.xtend b/core/org.osate.core.tests/src/org/osate/core/tests/propertiesscopeprovider/PropertiesScopeProviderTest.xtend index fb9f7f40e46..0621d5335f0 100644 --- a/core/org.osate.core.tests/src/org/osate/core/tests/propertiesscopeprovider/PropertiesScopeProviderTest.xtend +++ b/core/org.osate.core.tests/src/org/osate/core/tests/propertiesscopeprovider/PropertiesScopeProviderTest.xtend @@ -2745,7 +2745,7 @@ class PropertiesScopeProviderTest extends XtextTest { calls sequence1: { call1: subprogram subp1; - }; + } in modes (m1); connections fconn1: feature asub1.af3 -> asub1.af3; flows @@ -2797,7 +2797,7 @@ class PropertiesScopeProviderTest extends XtextTest { calls sequence2: { call2: subprogram subp1.i1; - }; + } in modes (m3); connections fconn1: refined to feature; modes