Browse Source

#718: Added an error message when using an assignment in guards

t00manysecretss 9 years ago
parent
commit
f88d816a12

+ 12 - 1
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextJavaValidator.java

@@ -146,7 +146,18 @@ public class STextJavaValidator extends AbstractSTextJavaValidator implements ST
 	public void checkExpression(Guard expression) {
 		typeInferrer.inferType(expression, this);
 	}
-
+	
+	@Check
+	public void checkNoAssignmentInGuard(Guard guard) {
+		TreeIterator<EObject> eAllContents = guard.eAllContents();
+		while(eAllContents.hasNext()) {
+			EObject e = eAllContents.next();
+			if(e instanceof AssignmentExpression) {
+				error(GUARD_CONTAINS_ASSIGNMENT, guard, null);
+			}
+		}
+	}
+	
 	@Check(CheckType.FAST)
 	public void transitionsWithNoTrigger(Transition trans) {
 

+ 2 - 1
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextValidationMessages.java

@@ -29,6 +29,7 @@ public interface STextValidationMessages {
 	public static final String LOCAL_DECLARATIONS = "Local declarations are not allowed in interface scope.";
 	public static final String TIME_EXPRESSION = "The evaluation result of a time expression must be of type integer.";
 	public static final String GUARD_EXPRESSION = "The evaluation result of a guard expression must be of type boolean.";
+	public static final String GUARD_CONTAINS_ASSIGNMENT = "A guard must not contain assignments.";
 	public static final String ASSIGNMENT_EXPRESSION = "No nested assignment of the same variable allowed (different behavior in various programming languages).";
 	public static final String TRANSITION_ENTRY_SPEC_NOT_COMPOSITE = "Target state isn't composite.";
 	public static final String TRANSITION_EXIT_SPEC_NOT_COMPOSITE = "Source state isn't composite.";
@@ -50,4 +51,4 @@ public interface STextValidationMessages {
 	public static final String REFERENCE_TO_VARIABLE = "Cannot reference a variable in a constant initialization.";
 	public static final String REFERENCE_CONSTANT_BEFORE_DEFINED = "Cannot reference a constant from different scope or before it is defined.";	
 	public static final String INTERNAL_DECLARATION_UNUSED = "Internal declaration is not used in statechart.";
-}
+}

+ 21 - 6
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/validation/STextJavaValidatorTest.java

@@ -12,8 +12,7 @@
 package org.yakindu.sct.model.stext.test.validation;
 
 import static org.eclipse.xtext.junit4.validation.AssertableDiagnostics.errorCode;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 import static org.yakindu.sct.test.models.AbstractTestModelsUtil.VALIDATION_TESTMODEL_DIR;
 
 import java.lang.reflect.Method;
@@ -187,14 +186,30 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		validationResult.assertErrorContains(STextJavaValidator.GUARD_EXPRESSION);
 
 		Scope context = createInternalScope("internal: var myInt : integer var myBool : boolean = true");
-		expression = super.parseExpression("[myInt = 5]", context, ReactionTrigger.class.getSimpleName());
-		validationResult = tester.validate(expression);
-		validationResult.assertErrorContains(STextJavaValidator.GUARD_EXPRESSION);
-
 		expression = super.parseExpression("[myInt <= 5 || !myBool ]", context, ReactionTrigger.class.getSimpleName());
 		validationResult = tester.validate(expression);
 		validationResult.assertOK();
+	}
+	
+	@Test 
+	public void checkNoAssignmentInGuard() {
+		Scope context = createInternalScope("internal: var myInt : integer var myBool : boolean = true");
+		EObject expression = super.parseExpression("[myBool = false]", context, ReactionTrigger.class.getSimpleName());
+		AssertableDiagnostics validationResult = tester.validate(expression);
+		validationResult.assertErrorContains(STextJavaValidator.GUARD_CONTAINS_ASSIGNMENT);
 
+		expression = super.parseExpression("[myInt = 5]", context, ReactionTrigger.class.getSimpleName());
+		validationResult = tester.validate(expression);
+		Iterator<Diagnostic> diag = validationResult.getAllDiagnostics().iterator();
+		while (diag.hasNext()) {
+			Diagnostic d = diag.next();
+			if (d.getMessage().equals(GUARD_EXPRESSION)) {
+				assertEquals(STextJavaValidator.GUARD_EXPRESSION, d.getMessage());
+			} else {
+				assertEquals(STextJavaValidator.GUARD_CONTAINS_ASSIGNMENT, d.getMessage());
+			}
+		}
+ 		
 	}
 
 	/**