Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/org.osate.core.tests/models/issue1564/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.aadlbin-gen/
18 changes: 18 additions & 0 deletions core/org.osate.core.tests/models/issue1564/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>issue1564</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.osate.core.aadlnature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
</projectDescription>
90 changes: 90 additions & 0 deletions core/org.osate.core.tests/models/issue1564/issue1564.aadl
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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'")
Expand Down
Original file line number Diff line number Diff line change
@@ -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<AadlPackage> 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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2745,7 +2745,7 @@ class PropertiesScopeProviderTest extends XtextTest {
calls
sequence1: {
call1: subprogram subp1;
};
} in modes (m1);
connections
fconn1: feature asub1.af3 -> asub1.af3;
flows
Expand Down Expand Up @@ -2797,7 +2797,7 @@ class PropertiesScopeProviderTest extends XtextTest {
calls
sequence2: {
call2: subprogram subp1.i1;
};
} in modes (m3);
connections
fconn1: refined to feature;
modes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<SubprogramCallSequence> otherSequences = classifier.getAllSubprogramCallSequences().stream()
.filter(other -> other != sequence).collect(Collectors.toList());
if (!classifier.getAllModes().isEmpty()) {
final List<Mode> modes;
if (sequence.getInModes().isEmpty()) {
modes = classifier.getAllModes();
} else {
modes = sequence.getInModes();
}
Stream<Mode> 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) {
Expand Down