Explorar o código

Added Validation rule:
"The left-hand side of an assignment must be a variable"

Andreas Mülder %!s(int64=11) %!d(string=hai) anos
pai
achega
34b2addb03

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

@@ -49,6 +49,7 @@ import org.yakindu.sct.model.sgraph.Scope;
 import org.yakindu.sct.model.sgraph.ScopedElement;
 import org.yakindu.sct.model.sgraph.Transition;
 import org.yakindu.sct.model.sgraph.Trigger;
+import org.yakindu.sct.model.sgraph.Variable;
 import org.yakindu.sct.model.sgraph.resource.AbstractSCTResource;
 import org.yakindu.sct.model.sgraph.validation.SCTResourceValidator;
 import org.yakindu.sct.model.sgraph.validation.SGraphJavaValidator;
@@ -116,6 +117,7 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public static final String EXIT_UNUSED = "The named exit is not used by outgoing transitions.";
 	public static final String EXIT_DEFAULT_UNUSED = "The parent composite state has no 'default' exit transition.";
 	public static final String TRANSITION_EXIT_SPEC_ON_MULTIPLE_SIBLINGS = "ExitPointSpec can't be used on transition siblings.";
+	public static final String LEFT_HAND_ASSIGNMENT = "The left-hand side of an assignment must be a variable";
 
 	@Inject
 	private ISTextTypeInferrer typeInferrer;
@@ -135,22 +137,14 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 				&& entry.getIncomingTransitions().isEmpty()) {
 			org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) entry.getParentRegion()
 					.getComposite();
-
 			if (!STextValidationModelUtils.isDefault(entry)) {
-
 				boolean hasIncomingTransition = false;
 				Iterator<Transition> transitionIt = state.getIncomingTransitions().iterator();
-
 				while (transitionIt.hasNext() && !hasIncomingTransition) {
-
 					Iterator<ReactionProperty> propertyIt = transitionIt.next().getProperties().iterator();
-
 					while (propertyIt.hasNext() && !hasIncomingTransition) {
-
 						ReactionProperty property = propertyIt.next();
-
 						if (property instanceof EntryPointSpec) {
-
 							hasIncomingTransition = entry.getName().equals(((EntryPointSpec) property).getEntrypoint());
 						}
 					}
@@ -162,6 +156,25 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		}
 	}
 
+	@Check(CheckType.FAST)
+	public void checkLeftHandAssignment(final AssignmentExpression expression) {
+		Expression varRef = expression.getVarRef();
+		if (varRef instanceof FeatureCall) {
+			EObject referencedObject = ((FeatureCall) varRef).getFeature();
+			if (!(referencedObject instanceof Variable)) {
+				error(LEFT_HAND_ASSIGNMENT, StextPackage.Literals.ASSIGNMENT_EXPRESSION__VAR_REF);
+			}
+		} else if (varRef instanceof ElementReferenceExpression) {
+			EObject referencedObject = ((ElementReferenceExpression) varRef).getReference();
+			if (!(referencedObject instanceof Variable)) {
+				error(LEFT_HAND_ASSIGNMENT, StextPackage.Literals.ASSIGNMENT_EXPRESSION__VAR_REF);
+			}
+
+		} else {
+			error(LEFT_HAND_ASSIGNMENT, StextPackage.Literals.ASSIGNMENT_EXPRESSION__VAR_REF);
+		}
+	}
+
 	@Check(CheckType.FAST)
 	public void checkUnusedExit(final Exit exit) {
 		if (exit.getParentRegion().getComposite() instanceof org.yakindu.sct.model.sgraph.State
@@ -170,14 +183,10 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 					.getComposite();
 
 			if (!STextValidationModelUtils.isDefault(exit)) {
-
 				boolean hasOutgoingTransition = false;
 				Iterator<Transition> transitionIt = state.getOutgoingTransitions().iterator();
-
 				while (transitionIt.hasNext() && !hasOutgoingTransition) {
-
 					Transition transition = transitionIt.next();
-
 					hasOutgoingTransition = STextValidationModelUtils.isDefaultExitTransition(transition) ? true
 							: STextValidationModelUtils.isNamedExitTransition(transition, exit.getName());
 				}

+ 44 - 2
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/STextJavaValidatorTest.java

@@ -75,8 +75,7 @@ import com.google.inject.Inject;
 import com.google.inject.Injector;
 
 /**
- * @author andreas muelder - Initial contribution and APIimport
- *         org.yakindu.sct.model.sgraph.test.util.SGraphTestModelUtil;
+ * @author andreas muelder - Initial contribution and API
  * 
  */
 @RunWith(XtextRunner.class)
@@ -140,6 +139,49 @@ public class STextJavaValidatorTest extends AbstractSTextTest {
 		// covered by inferrer tests
 	}
 
+	@Test
+	public void checkLeftHandAssignment() {
+		
+		Scope scope = (Scope) parseExpression(
+				"interface if : operation myOperation() : boolean event Event1 : boolean var myVar : boolean", null,
+				InterfaceScope.class.getSimpleName());
+
+		EObject model = super.parseExpression("3 = 3", Expression.class.getSimpleName(), scope);
+		AssertableDiagnostics validationResult = tester.validate(model);
+		validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
+
+		// Check for referenced elements in interface
+		model = super.parseExpression("if.myOperation() = true", Expression.class.getSimpleName(), scope);
+		validationResult = tester.validate(model);
+		validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
+
+		model = super.parseExpression("if.Event1 = true", Expression.class.getSimpleName(), scope);
+		validationResult = tester.validate(model);
+		validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
+
+		model = super.parseExpression("if.myVar = true", Expression.class.getSimpleName(), scope);
+		validationResult = tester.validate(model);
+		validationResult.assertOK();
+
+		// check for internal referenced elements
+		scope = (Scope) parseExpression(
+				"internal : operation myOperation() : integer event Event1 : integer var myVar : integer", null,
+				InternalScope.class.getSimpleName());
+
+		model = super.parseExpression("myOperation() = 5", Expression.class.getSimpleName(), scope);
+		validationResult = tester.validate(model);
+		validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
+
+		model = super.parseExpression("Event1 = 3", Expression.class.getSimpleName(), scope);
+		validationResult = tester.validate(model);
+		validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
+
+		model = super.parseExpression("myVar = 5", Expression.class.getSimpleName(), scope);
+		validationResult = tester.validate(model);
+		validationResult.assertOK();
+
+	}
+
 	/**
 	 * @see STextJavaValidator#checkOperationArguments_FeatureCall(org.yakindu.sct.model.stext.stext.FeatureCall)
 	 */