aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-02-29 16:33:59 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-04-07 14:55:46 +0200
commit23b0925f419894cf3f4699fa49dd91fb2ee4f4a5 (patch)
tree0fc5513b8e47b36a4aa822ee6b162a56f861ba1e /subprojects
parentrefactor(language): assignment and cast expression (diff)
downloadrefinery-23b0925f419894cf3f4699fa49dd91fb2ee4f4a5.tar.gz
refinery-23b0925f419894cf3f4699fa49dd91fb2ee4f4a5.tar.zst
refinery-23b0925f419894cf3f4699fa49dd91fb2ee4f4a5.zip
feat(language): validate assignment expressions
Diffstat (limited to 'subprojects')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java32
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/validation/AssignmentValidationTest.java61
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 */
6package tools.refinery.language.tests.validation;
7
8
9import com.google.inject.Inject;
10import org.eclipse.xtext.testing.InjectWith;
11import org.eclipse.xtext.testing.extensions.InjectionExtension;
12import org.junit.jupiter.api.Test;
13import org.junit.jupiter.api.extension.ExtendWith;
14import org.junit.jupiter.params.ParameterizedTest;
15import org.junit.jupiter.params.provider.ValueSource;
16import tools.refinery.language.model.tests.utils.ProblemParseHelper;
17import tools.refinery.language.tests.ProblemInjectorProvider;
18import tools.refinery.language.validation.ProblemValidator;
19
20import static org.hamcrest.MatcherAssert.assertThat;
21import static org.hamcrest.Matchers.*;
22
23@ExtendWith(InjectionExtension.class)
24@InjectWith(ProblemInjectorProvider.class)
25class 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}