diff options
2 files changed, 93 insertions, 0 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java index 560f612a..7f45bc20 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java +++ b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java | |||
@@ -63,6 +63,8 @@ public class ProblemValidator extends AbstractProblemValidator { | |||
63 | 63 | ||
64 | public static final String UNSUPPORTED_ASSERTION_ISSUE = ISSUE_PREFIX + "UNSUPPORTED_ASSERTION"; | 64 | public static final String UNSUPPORTED_ASSERTION_ISSUE = ISSUE_PREFIX + "UNSUPPORTED_ASSERTION"; |
65 | 65 | ||
66 | public static final String INVALID_ASSIGNMENT_ISSUE = ISSUE_PREFIX + "INVALID_ASSIGNMENT"; | ||
67 | |||
66 | @Inject | 68 | @Inject |
67 | private ReferenceCounter referenceCounter; | 69 | private ReferenceCounter referenceCounter; |
68 | 70 | ||
@@ -493,4 +495,34 @@ public class ProblemValidator extends AbstractProblemValidator { | |||
493 | } | 495 | } |
494 | } | 496 | } |
495 | } | 497 | } |
498 | |||
499 | @Check | ||
500 | private void checkAssignmentExpr(AssignmentExpr assignmentExpr) { | ||
501 | var left = assignmentExpr.getLeft(); | ||
502 | if (left == null) { | ||
503 | // Syntactically invalid, so we already emit an error. | ||
504 | return; | ||
505 | } | ||
506 | if (!(left instanceof VariableOrNodeExpr variableOrNodeExpr)) { | ||
507 | var message = "Left side of an assignment must be variable."; | ||
508 | acceptError(message, assignmentExpr, ProblemPackage.Literals.BINARY_EXPR__LEFT, | ||
509 | 0, INVALID_ASSIGNMENT_ISSUE); | ||
510 | return; | ||
511 | } | ||
512 | var target = variableOrNodeExpr.getVariableOrNode(); | ||
513 | if (target == null) { | ||
514 | // Syntactically invalid, so we already emit an error. | ||
515 | return; | ||
516 | } | ||
517 | if (target instanceof Parameter) { | ||
518 | var message = "Parameters cannot be assigned."; | ||
519 | acceptError(message, variableOrNodeExpr, ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE, | ||
520 | 0, INVALID_ASSIGNMENT_ISSUE); | ||
521 | } | ||
522 | if (target instanceof Node) { | ||
523 | var message = "Nodes cannot be assigned."; | ||
524 | acceptError(message, variableOrNodeExpr, ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE, | ||
525 | 0, INVALID_ASSIGNMENT_ISSUE); | ||
526 | } | ||
527 | } | ||
496 | } | 528 | } |
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssignmentValidationTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssignmentValidationTest.java new file mode 100644 index 00000000..a9e0e311 --- /dev/null +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssignmentValidationTest.java | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.language.tests.validation; | ||
7 | |||
8 | |||
9 | import com.google.inject.Inject; | ||
10 | import org.eclipse.xtext.testing.InjectWith; | ||
11 | import org.eclipse.xtext.testing.extensions.InjectionExtension; | ||
12 | import org.junit.jupiter.api.Test; | ||
13 | import org.junit.jupiter.api.extension.ExtendWith; | ||
14 | import org.junit.jupiter.params.ParameterizedTest; | ||
15 | import org.junit.jupiter.params.provider.ValueSource; | ||
16 | import tools.refinery.language.model.tests.utils.ProblemParseHelper; | ||
17 | import tools.refinery.language.tests.ProblemInjectorProvider; | ||
18 | import tools.refinery.language.validation.ProblemValidator; | ||
19 | |||
20 | import static org.hamcrest.MatcherAssert.assertThat; | ||
21 | import static org.hamcrest.Matchers.*; | ||
22 | |||
23 | @ExtendWith(InjectionExtension.class) | ||
24 | @InjectWith(ProblemInjectorProvider.class) | ||
25 | class AssignmentValidationTest { | ||
26 | @Inject | ||
27 | private ProblemParseHelper parseHelper; | ||
28 | |||
29 | @ParameterizedTest | ||
30 | @ValueSource(strings = {""" | ||
31 | pred foo(node a) <-> 5 is 5. | ||
32 | """, """ | ||
33 | pred foo(node a) <-> b + 2 is 5. | ||
34 | """, """ | ||
35 | pred foo(node a) <-> a is 5. | ||
36 | """, """ | ||
37 | node(n). | ||
38 | pred foo(node a) <-> n is 5. | ||
39 | """, """ | ||
40 | enum E { A, B } | ||
41 | pred foo(node a) <-> B is 5. | ||
42 | """}) | ||
43 | void invalidAssignmentTest(String text) { | ||
44 | var problem = parseHelper.parse(text); | ||
45 | var issues = problem.validate(); | ||
46 | assertThat(issues, hasItem(hasProperty("issueCode", is( | ||
47 | ProblemValidator.INVALID_ASSIGNMENT_ISSUE | ||
48 | )))); | ||
49 | } | ||
50 | |||
51 | @Test | ||
52 | void validAssignmentTest() { | ||
53 | var problem = parseHelper.parse(""" | ||
54 | pred foo(node a) <-> b is 5. | ||
55 | """); | ||
56 | var issues = problem.validate(); | ||
57 | assertThat(issues, not(hasItem(hasProperty("issueCode", is( | ||
58 | ProblemValidator.INVALID_ASSIGNMENT_ISSUE | ||
59 | ))))); | ||
60 | } | ||
61 | } | ||