Skip to content

Commit f601773

Browse files
7.8.22: CoCo for AcceptAction in Event-Transitions
1 parent 209cd00 commit f601773

4 files changed

Lines changed: 149 additions & 1 deletion

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ assertj_version = 3.21.0
2525
junit_version = 5.8.2
2626

2727
# Version of published artifacts
28-
version = 7.8.21
28+
version = 7.8.22

language/src/main/java/de/monticore/lang/sysmlv2/SysMLv2Tool.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import de.monticore.lang.sysmlv2._symboltable.SysMLv2Symbols2Json;
2525
import de.monticore.lang.sysmlv2._visitor.SysMLv2Traverser;
2626
import de.monticore.lang.sysmlv2.cocos.AssignActionTypeCheck3;
27+
import de.monticore.lang.sysmlv2.cocos.EventTransitionRequiresAccept;
2728
import de.monticore.lang.sysmlv2.cocos.FlowCheckCoCo;
2829
import de.monticore.lang.sysmlv2.cocos.NameCompatible4Isabelle;
2930
import de.monticore.lang.sysmlv2.cocos.OneCardinality;
@@ -167,6 +168,7 @@ public void runAdditionalCoCos(
167168
checker.addCoCo(new FlowCheckCoCo());
168169
checker.addCoCo(new PortDefinitionExistsCoCo());
169170
checker.addCoCo(new PartBehaviorCoCo());
171+
checker.addCoCo(new EventTransitionRequiresAccept());
170172

171173
checker.checkAll(ast);
172174
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package de.monticore.lang.sysmlv2.cocos;
2+
3+
import de.monticore.lang.componentconnector._symboltable.EventAutomatonSymbol;
4+
import de.monticore.lang.sysmlstates._ast.ASTSysMLTransition;
5+
import de.monticore.lang.sysmlstates._cocos.SysMLStatesASTSysMLTransitionCoCo;
6+
import de.se_rwth.commons.logging.Log;
7+
8+
/**
9+
* All transitions in an Event-Automaton need AcceptActions
10+
*/
11+
public class EventTransitionRequiresAccept implements
12+
SysMLStatesASTSysMLTransitionCoCo {
13+
14+
@Override
15+
public void check(ASTSysMLTransition node) {
16+
if (!isInEventAutomaton(node)) return;
17+
18+
if (!node.isPresentInlineAcceptActionUsage()) {
19+
Log.error("EventAutomaton transition must contain an AcceptAction.",
20+
node.get_SourcePositionStart(),
21+
node.get_SourcePositionEnd());
22+
}
23+
}
24+
25+
private boolean isInEventAutomaton(ASTSysMLTransition node) {
26+
var scope = node.getEnclosingScope();
27+
28+
while (scope != null) {
29+
if (scope.isPresentSpanningSymbol()) {
30+
var sym = scope.getSpanningSymbol();
31+
if (sym instanceof EventAutomatonSymbol) return true;
32+
}
33+
scope = scope.getEnclosingScope();
34+
}
35+
return false;
36+
}
37+
38+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package cocos;
2+
3+
import de.monticore.lang.sysmlv2.SysMLv2Mill;
4+
import de.monticore.lang.sysmlv2.SysMLv2Tool;
5+
import de.monticore.lang.sysmlv2._ast.ASTSysMLModel;
6+
import de.monticore.lang.sysmlv2._cocos.SysMLv2CoCoChecker;
7+
import de.monticore.lang.sysmlv2.cocos.EventTransitionRequiresAccept;
8+
import de.se_rwth.commons.logging.Log;
9+
import de.se_rwth.commons.logging.LogStub;
10+
import org.junit.jupiter.api.BeforeAll;
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.Test;
13+
14+
import java.util.stream.Collectors;
15+
16+
import static org.junit.jupiter.api.Assertions.assertFalse;
17+
import static org.junit.jupiter.api.Assertions.assertTrue;
18+
import static org.junit.jupiter.api.Assertions.fail;
19+
20+
public class EventTransitionRequiresAcceptTest {
21+
22+
@BeforeAll
23+
public static void init() {
24+
LogStub.init();
25+
}
26+
27+
@BeforeEach
28+
public void clear() {
29+
Log.clearFindings();
30+
}
31+
32+
@Test
33+
void eventAutomaton_withAccept_mustNotLogError() {
34+
parseAndCheck(valid);
35+
var errors = Log.getFindings().stream()
36+
.filter(s -> s.isError())
37+
.collect(Collectors.toList());
38+
assertTrue(errors.isEmpty(),
39+
"Expected no errors, but got:\n" + errors);
40+
}
41+
42+
@Test
43+
void eventAutomaton_withoutAccept_mustLogError() {
44+
parseAndCheck(invalid);
45+
assertFalse(Log.getFindings().isEmpty());
46+
}
47+
48+
void parseAndCheck(String model) {
49+
var tool = new SysMLv2Tool();
50+
tool.init();
51+
ASTSysMLModel ast = null;
52+
try {
53+
ast = SysMLv2Mill.parser().parse_String(model).get();
54+
}
55+
catch (Exception e) {
56+
fail("Model was not parsable");
57+
}
58+
59+
tool.createSymbolTable(ast);
60+
tool.completeSymbolTable(ast);
61+
tool.finalizeSymbolTable(ast);
62+
63+
var checker = new SysMLv2CoCoChecker();
64+
checker.addCoCo(new EventTransitionRequiresAccept());
65+
checker.checkAll(ast);
66+
}
67+
68+
String valid = "part def TestWithAccept {\n"
69+
+ " port input: Booleans;\n"
70+
+ " port output: ~Booleans;\n"
71+
+ "\n"
72+
+ " exhibit state behavior {\n"
73+
+ " entry;\n"
74+
+ " then S;\n"
75+
+ "\n"
76+
+ " state S;\n"
77+
+ "\n"
78+
+ " transition\n"
79+
+ " first S\n"
80+
+ " accept input.val\n"
81+
+ " if input.val == true\n"
82+
+ " do action {\n"
83+
+ " send false to output.val;\n"
84+
+ " }\n"
85+
+ " then S;\n"
86+
+ " }\n"
87+
+ "}";
88+
89+
String invalid = "part def TestWithoutAccept {\n"
90+
+ " port input: Booleans;\n"
91+
+ "\n"
92+
+ " exhibit state behavior {\n"
93+
+ " entry; then S;\n"
94+
+ "\n"
95+
+ " state S;\n"
96+
+ "\n"
97+
+ " transition ok\n"
98+
+ " first S\n"
99+
+ " accept input.val\n"
100+
+ " then S;\n"
101+
+ "\n"
102+
+ " transition bad\n"
103+
+ " first S\n"
104+
+ " then S;\n"
105+
+ " }\n"
106+
+ "}";
107+
108+
}

0 commit comments

Comments
 (0)