Procházet zdrojové kódy

Merge branch 'master' of https://github.com/Yakindu/statecharts.git

andreas muelder před 7 roky
rodič
revize
db324ee2b0
15 změnil soubory, kde provedl 317 přidání a 334 odebrání
  1. 19 167
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/validation/ExpressionsJavaValidator.java
  2. 0 28
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/validation/GenericsPrettyPrinter.xtend
  3. 11 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/validation/TypeValidator.java
  4. 203 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/validation/TypesJavaValidator.java
  5. 11 17
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/EntryValidator.java
  6. 7 16
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/ExitValidator.java
  7. 28 52
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/RegionValidator.java
  8. 0 1
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/StatechartValidator.java
  9. 10 15
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/SynchronizationValidator.java
  10. 1 3
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/TransitionValidator.java
  11. 1 1
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/VertexValidator.java
  12. 15 4
      plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/JavaOperationMockup.java
  13. 2 9
      test-plugins/org.yakindu.sct.model.sgraph.test/src/org/yakindu/sct/model/sgraph/test/validation/ExitValidatorTest.java
  14. 2 14
      test-plugins/org.yakindu.sct.model.sgraph.test/src/org/yakindu/sct/model/sgraph/test/validation/RegionValidatorTest.java
  15. 7 7
      test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/validation/STextJavaValidatorTest.java

+ 19 - 167
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/validation/ExpressionsJavaValidator.java

@@ -21,6 +21,7 @@ import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtext.validation.Check;
 import org.eclipse.xtext.validation.CheckType;
+import org.eclipse.xtext.validation.ComposedChecks;
 import org.yakindu.base.expressions.expressions.Argument;
 import org.yakindu.base.expressions.expressions.ArgumentExpression;
 import org.yakindu.base.expressions.expressions.AssignmentExpression;
@@ -31,22 +32,15 @@ import org.yakindu.base.expressions.expressions.FeatureCall;
 import org.yakindu.base.expressions.expressions.PostFixUnaryExpression;
 import org.yakindu.base.types.AnnotatableElement;
 import org.yakindu.base.types.Annotation;
-import org.yakindu.base.types.ComplexType;
-import org.yakindu.base.types.GenericElement;
 import org.yakindu.base.types.Operation;
 import org.yakindu.base.types.Parameter;
 import org.yakindu.base.types.Property;
-import org.yakindu.base.types.Type;
-import org.yakindu.base.types.TypeParameter;
-import org.yakindu.base.types.TypeSpecifier;
-import org.yakindu.base.types.TypesPackage;
 import org.yakindu.base.types.inferrer.ITypeSystemInferrer;
-import org.yakindu.base.types.typesystem.ITypeSystem;
 import org.yakindu.base.types.validation.IValidationIssueAcceptor;
+import org.yakindu.base.types.validation.TypesJavaValidator;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
 import com.google.inject.Inject;
 
 /**
@@ -54,57 +48,12 @@ import com.google.inject.Inject;
  * @author andreas muelder - Initial contribution and API
  * 
  */
+@ComposedChecks(validators = { TypesJavaValidator.class })
 public class ExpressionsJavaValidator extends org.yakindu.base.expressions.validation.AbstractExpressionsJavaValidator
 		implements IValidationIssueAcceptor {
 
-	public static final String WARNING_IS_RAW_CODE = "WarningRaw";
-	public static final String WARNING_IS_RAW_MSG = "%s is a raw type. References to generic type %s should be parameterized.";
-
-	public static final String ERROR_NOT_GENERIC_CODE = "TypeNotGeneric";
-	public static final String ERROR_NOT_GENERIC_MSG = "The type %s is not generic; it cannot be parameterized with arguments %s.";
-
-	public static final String ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_CODE = "IncorrectNrOfArguments";
-	public static final String ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_MSG = "Incorrect number of arguments for type %s; it cannot be parameterized with arguments %s.";
-
-	public static final String ERROR_BOUND_MISSMATCH_CODE = "TypeParameterBoundMissmatch";
-	public static final String ERROR_BOUND_MISSMATCH_MSG = "Bound mismatch: The type %s is not a valid substitute for the bounded parameter %s of the type %s.";
-
-	public static final String ERROR_DUPLICATE_TYPE_PARAMETER_CODE = "DuplicateTypeParameter";
-	public static final String ERROR_DUPLICATE_TYPE_PARAMETER_MSG = "Duplicate type parameter %s.";
-
-	public static final String ERROR_CYCLE_DETECTED_CODE = "TypeExtendsItself";
-	public static final String ERROR_CYCLE_DETECTED_MSG = "Cycle detected: the type %s cannot extend itself.";
-
-	public static final String ERROR_DUPLICATE_PARAMETER_ASSIGNMENT_CODE = "ErrorDuplicateParameterAssignment";
-	public static final String ERROR_DUPLICATE_PARAMETER_ASSIGNMENT_MSG = "Duplicate assignment to parameter '%s'.";
-
-	public static final String ERROR_ASSIGNMENT_TO_CONST_CODE = "AssignmentToConst";
-	public static final String ERROR_ASSIGNMENT_TO_CONST_MSG = "Assignment to constant not allowed.";
-
-	public static final String ERROR_LEFT_HAND_ASSIGNMENT_CODE = "LeftHandAssignment";
-	public static final String ERROR_LEFT_HAND_ASSIGNMENT_MSG = "The left-hand side of an assignment must be a variable.";
-
-	public static final String ERROR_WRONG_NUMBER_OF_ARGUMENTS_CODE = "WrongNrOfArgs";
-	public static final String ERROR_WRONG_NUMBER_OF_ARGUMENTS_MSG = "Wrong number of arguments, expected %s .";
-
-	public static final String ERROR_VAR_ARGS_LAST_CODE = "VarArgsMustBeLast";
-	public static final String ERROR_VAR_ARGS_LAST_MSG = "The variable argument type must be the last argument.";
-
-	public static final String ERROR_WRONG_ANNOTATION_TARGET_CODE = "WrongAnnotationTarget";
-	public static final String ERROR_WRONG_ANNOTATION_TARGET_MSG = "Annotation '%s' can not be applied on %s .";
-
-	public static final String ERROR_OPTIONAL_MUST_BE_LAST_CODE = "OptionalParametersLast";
-	public static final String ERROR_OPTIONAL_MUST_BE_LAST_MSG = "Required parameters must not be defined after optional parameters.";
-
-	public static final String POSTFIX_ONLY_ON_VARIABLES_CODE = "PostfixOnlyOnVariables";
-	public static final String POSTFIX_ONLY_ON_VARIABLES_MSG = "Invalid argument to operator '++/--'";
-
-	@Inject
-	private GenericsPrettyPrinter printer;
 	@Inject
 	private ITypeSystemInferrer typeInferrer;
-	@Inject
-	private ITypeSystem typeSystem;
 
 	@Check
 	public void checkExpression(Expression expression) {
@@ -127,6 +76,9 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 		}
 	}
 
+	public static final String POSTFIX_ONLY_ON_VARIABLES_CODE = "PostfixOnlyOnVariables";
+	public static final String POSTFIX_ONLY_ON_VARIABLES_MSG = "Invalid argument to operator '++/--'";
+
 	@Check
 	public void checkPostFixOperatorOnlyOnVariables(PostFixUnaryExpression expression) {
 		if (!(expression.getOperand() instanceof ElementReferenceExpression)
@@ -135,94 +87,8 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 		}
 	}
 
-	@Check
-	public void checkIsRaw(TypeSpecifier typedElement) {
-		Type type = typedElement.getType();
-		if (!(type instanceof GenericElement))
-			return;
-		EList<TypeParameter> typeParameter = ((GenericElement) type).getTypeParameters();
-		if (typedElement.getTypeArguments().size() == 0 && typeParameter.size() > 0) {
-			String s1 = typedElement.getType().getName();
-			String s2 = s1 + printer.concatTypeParameter(typeParameter);
-			warning(String.format(WARNING_IS_RAW_MSG, s1, s2), typedElement, TypesPackage.Literals.TYPE_SPECIFIER__TYPE,
-					WARNING_IS_RAW_CODE);
-		}
-	}
-
-	@Check
-	public void checkTypedElementNotGeneric(TypeSpecifier typedElement) {
-		if (typedElement.getTypeArguments().size() > 0 && ((!(typedElement.getType() instanceof GenericElement))
-				|| ((GenericElement) typedElement.getType()).getTypeParameters().size() == 0)) {
-			String s1 = typedElement.getType().getName();
-			String s2 = printer.concatTypeArguments(typedElement.getTypeArguments());
-			error(String.format(ERROR_NOT_GENERIC_MSG, s1, s2), typedElement,
-					TypesPackage.Literals.TYPE_SPECIFIER__TYPE, ERROR_NOT_GENERIC_CODE);
-		}
-	}
-
-	@Check
-	public void checkNofArguments(TypeSpecifier typedElement) {
-		if (!(typedElement.getType() instanceof GenericElement)) {
-			return;
-		}
-		GenericElement type = (GenericElement) typedElement.getType();
-		EList<TypeParameter> typeParameter = type.getTypeParameters();
-		if (typedElement.getTypeArguments().size() > 0
-				&& (typedElement.getTypeArguments().size() != typeParameter.size()) && typeParameter.size() > 0) {
-			String s1 = type.getName() + printer.concatTypeParameter(typeParameter);
-			String s2 = printer.concatTypeArguments(typedElement.getTypeArguments());
-			error(String.format(ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_MSG, s1, s2), typedElement,
-					TypesPackage.Literals.TYPE_SPECIFIER__TYPE, ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_CODE);
-		}
-	}
-
-	@Check
-	public void checkDuplicateTypeParameter(GenericElement type) {
-		Set<String> names = Sets.newHashSet();
-		EList<TypeParameter> typeParameter = type.getTypeParameters();
-		for (TypeParameter param : typeParameter) {
-			String name = param.getName();
-			if (names.contains(name)) {
-				error(String.format(ERROR_DUPLICATE_TYPE_PARAMETER_MSG, name), type,
-						TypesPackage.Literals.GENERIC_ELEMENT__TYPE_PARAMETERS, ERROR_DUPLICATE_TYPE_PARAMETER_CODE);
-			}
-			names.add(name);
-		}
-	}
-
-	@Check
-	public void checkTypeParameterBounds(TypeSpecifier typedElement) {
-		if (!(typedElement.getType() instanceof GenericElement)) {
-			return;
-		}
-		GenericElement type = (GenericElement) typedElement.getType();
-		EList<TypeParameter> typeParameter = type.getTypeParameters();
-		if (typedElement.getTypeArguments().size() == 0
-				|| (typedElement.getTypeArguments().size() != typeParameter.size()))
-			return;
-		for (int i = 0; i < typeParameter.size(); i++) {
-			TypeParameter parameter = typeParameter.get(i);
-			if (parameter.getBound() != null) {
-				Type argument = typedElement.getTypeArguments().get(i).getType();
-				if (!typeSystem.isSuperType(argument, parameter.getBound())) {
-					error(String.format(ERROR_BOUND_MISSMATCH_MSG, argument.getName(), (parameter.getBound()).getName(),
-							type.getName()), typedElement, TypesPackage.Literals.TYPE_SPECIFIER__TYPE_ARGUMENTS, i,
-							ERROR_BOUND_MISSMATCH_CODE);
-				}
-			}
-		}
-	}
-
-	@Check
-	public void checkTypeNotExtendsItself(ComplexType type) {
-		EList<Type> superTypes = type.getSuperTypes();
-		for (Type superType : superTypes) {
-			if (superType.equals(type)) {
-				error(String.format(ERROR_CYCLE_DETECTED_MSG, type.getName()), type,
-						TypesPackage.Literals.TYPE__SUPER_TYPES, ERROR_CYCLE_DETECTED_CODE);
-			}
-		}
-	}
+	public static final String ERROR_DUPLICATE_PARAMETER_ASSIGNMENT_CODE = "ErrorDuplicateParameterAssignment";
+	public static final String ERROR_DUPLICATE_PARAMETER_ASSIGNMENT_MSG = "Duplicate assignment to parameter '%s'.";
 
 	@Check
 	public void checkDuplicateParameterAssignment(ArgumentExpression exp) {
@@ -240,6 +106,9 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 		}
 	}
 
+	public static final String ERROR_ASSIGNMENT_TO_CONST_CODE = "AssignmentToConst";
+	public static final String ERROR_ASSIGNMENT_TO_CONST_MSG = "Assignment to constant not allowed.";
+
 	@Check(CheckType.FAST)
 	public void checkAssignmentToFinalVariable(AssignmentExpression exp) {
 		Expression varRef = exp.getVarRef();
@@ -256,6 +125,9 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 		}
 	}
 
+	public static final String ERROR_LEFT_HAND_ASSIGNMENT_CODE = "LeftHandAssignment";
+	public static final String ERROR_LEFT_HAND_ASSIGNMENT_MSG = "The left-hand side of an assignment must be a variable.";
+
 	@Check(CheckType.FAST)
 	public void checkLeftHandAssignment(final AssignmentExpression expression) {
 		Expression varRef = expression.getVarRef();
@@ -294,6 +166,9 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 		}
 	}
 
+	public static final String ERROR_WRONG_NUMBER_OF_ARGUMENTS_CODE = "WrongNrOfArgs";
+	public static final String ERROR_WRONG_NUMBER_OF_ARGUMENTS_MSG = "Wrong number of arguments, expected %s .";
+
 	protected void assertOperationArguments(Operation operation, List<Expression> args) {
 		EList<Parameter> parameters = operation.getParameters();
 		List<Parameter> optionalParameters = filterOptionalParameters(parameters);
@@ -305,10 +180,6 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 		}
 	}
 
-	/**
-	 * @param parameters
-	 * @return
-	 */
 	protected List<Parameter> filterOptionalParameters(EList<Parameter> parameters) {
 		List<Parameter> optionalParameters = new ArrayList<>();
 		for (Parameter p : parameters) {
@@ -319,13 +190,8 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 		return optionalParameters;
 	}
 
-	@Check(CheckType.FAST)
-	public void checkVarArgParameterIsLast(Operation operation) {
-		if (operation.isVariadic() && operation.getVarArgIndex() != operation.getParameters().size() - 1) {
-			error(ERROR_VAR_ARGS_LAST_MSG, operation.getParameters().get(operation.getVarArgIndex()), null,
-					ERROR_VAR_ARGS_LAST_CODE);
-		}
-	}
+	public static final String ERROR_WRONG_ANNOTATION_TARGET_CODE = "WrongAnnotationTarget";
+	public static final String ERROR_WRONG_ANNOTATION_TARGET_MSG = "Annotation '%s' can not be applied on %s .";
 
 	@Check(CheckType.FAST)
 	public void checkAnnotationTarget(final AnnotatableElement element) {
@@ -347,18 +213,4 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 			}
 		}
 	}
-
-	@Check(CheckType.FAST)
-	public void checkOptionalArgumentsAreLast(Operation op) {
-		boolean foundOptional = false;
-		for (Parameter p : op.getParameters()) {
-			if (foundOptional && !p.isOptional()) {
-				error(ERROR_OPTIONAL_MUST_BE_LAST_MSG, p, null, ERROR_OPTIONAL_MUST_BE_LAST_CODE);
-			}
-			if (p.isOptional()) {
-				foundOptional = true;
-			}
-		}
-	}
-
 }

+ 0 - 28
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/validation/GenericsPrettyPrinter.xtend

@@ -1,28 +0,0 @@
-/** 
- * Copyright (c) 2015 committers of YAKINDU and others. 
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Eclipse Public License v1.0 
- * which accompanies this distribution, and is available at 
- * http://www.eclipse.org/legal/epl-v10.html 
- * Contributors:
- * committers of YAKINDU - initial API and implementation
- *
-*/
-package org.yakindu.base.expressions.validation
-
-import java.util.List
-import org.yakindu.base.types.Type
-import org.yakindu.base.types.TypeParameter
-import org.yakindu.base.types.TypeSpecifier
-
-class GenericsPrettyPrinter {
-
-	def concatTypeParameter(List<TypeParameter> parameter) {
-		return '''<«FOR param : parameter SEPARATOR ', '»«param.name»«IF param.bound !== null» extends «(param.bound as Type).name»«ENDIF»«ENDFOR»>'''.toString
-	}
-
-	def concatTypeArguments(List<TypeSpecifier> parameter) {
-		// TODO: type arguments can have multiple hierarches Type1<Type2<T>>
-		return '''<«FOR param : parameter SEPARATOR ', '»«param.type.name»«ENDFOR»>'''.toString
-	}
-}

+ 11 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/validation/TypeValidator.java

@@ -20,6 +20,7 @@ import static org.yakindu.base.types.inferrer.ITypeSystemInferrer.NOT_TYPE_CODE;
 import java.util.List;
 
 import org.yakindu.base.types.ComplexType;
+import org.yakindu.base.types.Type;
 import org.yakindu.base.types.inferrer.ITypeSystemInferrer.InferenceResult;
 import org.yakindu.base.types.typesystem.ITypeSystem;
 import org.yakindu.base.types.validation.IValidationIssueAcceptor.ValidationIssue;
@@ -63,6 +64,7 @@ public class TypeValidator {
 				|| isNullOnComplexType(result2, result1)) {
 			return;
 		}
+
 		if (!registry.haveCommonType(result1.getType(), result2.getType())) {
 			msg = msg != null ? msg : String.format(ASSERT_COMPATIBLE, result1, result2);
 			acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_COMPATIBLE_CODE));
@@ -77,6 +79,11 @@ public class TypeValidator {
 		if (varResult == null || valueResult == null || isNullOnComplexType(varResult, valueResult)) {
 			return;
 		}
+
+		if (isAnyType(varResult.getType())) {
+			return;
+		}
+
 		if (!registry.isSuperType(valueResult.getType(), varResult.getType())) {
 			msg = msg != null ? msg : String.format(ASSERT_COMPATIBLE, varResult, valueResult);
 			acceptor.accept(new ValidationIssue(Severity.ERROR, msg, NOT_COMPATIBLE_CODE));
@@ -113,4 +120,8 @@ public class TypeValidator {
 		return result1.getType() instanceof ComplexType
 				&& registry.isSame(result2.getType(), registry.getType(ITypeSystem.NULL));
 	}
+
+	protected boolean isAnyType(Type type) {
+		return registry.isSame(type, registry.getType(ITypeSystem.ANY));
+	}
 }

+ 203 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/validation/TypesJavaValidator.java

@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2014 - 2018 itemis AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * 	itemis AG - initial API and implementation
+ *  
+ */
+package org.yakindu.base.types.validation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.StringJoiner;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.xtext.validation.Check;
+import org.eclipse.xtext.validation.CheckType;
+import org.yakindu.base.types.ComplexType;
+import org.yakindu.base.types.GenericElement;
+import org.yakindu.base.types.Operation;
+import org.yakindu.base.types.Parameter;
+import org.yakindu.base.types.Type;
+import org.yakindu.base.types.TypeParameter;
+import org.yakindu.base.types.TypeSpecifier;
+import org.yakindu.base.types.TypesPackage;
+import org.yakindu.base.types.typesystem.ITypeSystem;
+
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+
+/**
+ * Validation rules for types.ecore
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public class TypesJavaValidator extends org.eclipse.xtext.validation.AbstractDeclarativeValidator {
+
+	@Inject
+	private ITypeSystem typeSystem;
+
+	public static final String WARNING_IS_RAW_CODE = "WarningRaw";
+	public static final String WARNING_IS_RAW_MSG = "%s is a raw type. References to generic type %s should be parameterized.";
+
+	@Check
+	public void checkIsRaw(TypeSpecifier typedElement) {
+		Type type = typedElement.getType();
+		if (!(type instanceof GenericElement))
+			return;
+		EList<TypeParameter> typeParameter = ((GenericElement) type).getTypeParameters();
+		if (typedElement.getTypeArguments().size() == 0 && typeParameter.size() > 0) {
+			String s1 = typedElement.getType().getName();
+			String s2 = s1 + prettyPrintTypes(typeParameter);
+			warning(String.format(WARNING_IS_RAW_MSG, s1, s2), typedElement, TypesPackage.Literals.TYPE_SPECIFIER__TYPE,
+					WARNING_IS_RAW_CODE);
+		}
+	}
+
+	public static final String ERROR_NOT_GENERIC_CODE = "TypeNotGeneric";
+	public static final String ERROR_NOT_GENERIC_MSG = "The type %s is not generic; it cannot be parameterized with arguments %s.";
+
+	@Check
+	public void checkTypedElementNotGeneric(TypeSpecifier typedElement) {
+		if (typedElement.getTypeArguments().size() > 0 && ((!(typedElement.getType() instanceof GenericElement))
+				|| ((GenericElement) typedElement.getType()).getTypeParameters().size() == 0)) {
+			String s1 = typedElement.getType().getName();
+			String s2 = prettyPrintArguments(typedElement.getTypeArguments());
+			error(String.format(ERROR_NOT_GENERIC_MSG, s1, s2), typedElement,
+					TypesPackage.Literals.TYPE_SPECIFIER__TYPE, ERROR_NOT_GENERIC_CODE);
+		}
+	}
+
+	public static final String ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_CODE = "IncorrectNrOfArguments";
+	public static final String ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_MSG = "Incorrect number of arguments for type %s; it cannot be parameterized with arguments %s.";
+
+	@Check
+	public void checkNofArguments(TypeSpecifier typedElement) {
+		if (!(typedElement.getType() instanceof GenericElement)) {
+			return;
+		}
+		GenericElement type = (GenericElement) typedElement.getType();
+		EList<TypeParameter> typeParameter = type.getTypeParameters();
+		if (typedElement.getTypeArguments().size() > 0
+				&& (typedElement.getTypeArguments().size() != typeParameter.size()) && typeParameter.size() > 0) {
+			String s1 = type.getName() + prettyPrintTypes(typeParameter);
+			String s2 = prettyPrintArguments(typedElement.getTypeArguments());
+			error(String.format(ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_MSG, s1, s2), typedElement,
+					TypesPackage.Literals.TYPE_SPECIFIER__TYPE, ERROR_ARGUMENTED_SPECIFIER_INCORRECT_ARGUMENT_NR_CODE);
+		}
+	}
+
+	public static final String ERROR_BOUND_MISSMATCH_CODE = "TypeParameterBoundMissmatch";
+	public static final String ERROR_BOUND_MISSMATCH_MSG = "Bound mismatch: The type %s is not a valid substitute for the bounded parameter %s of the type %s.";
+
+	@Check
+	public void checkTypeParameterBounds(TypeSpecifier typedElement) {
+		if (!(typedElement.getType() instanceof GenericElement)) {
+			return;
+		}
+		GenericElement type = (GenericElement) typedElement.getType();
+		EList<TypeParameter> typeParameter = type.getTypeParameters();
+		if (typedElement.getTypeArguments().size() == 0
+				|| (typedElement.getTypeArguments().size() != typeParameter.size()))
+			return;
+		for (int i = 0; i < typeParameter.size(); i++) {
+			TypeParameter parameter = typeParameter.get(i);
+			if (parameter.getBound() != null) {
+				Type argument = typedElement.getTypeArguments().get(i).getType();
+				if (!typeSystem.isSuperType(argument, parameter.getBound())) {
+					error(String.format(ERROR_BOUND_MISSMATCH_MSG, argument.getName(), (parameter.getBound()).getName(),
+							type.getName()), typedElement, TypesPackage.Literals.TYPE_SPECIFIER__TYPE_ARGUMENTS, i,
+							ERROR_BOUND_MISSMATCH_CODE);
+				}
+			}
+		}
+	}
+
+	public static final String ERROR_CYCLE_DETECTED_CODE = "TypeExtendsItself";
+	public static final String ERROR_CYCLE_DETECTED_MSG = "Cycle detected: the type %s cannot extend itself.";
+
+	@Check
+	public void checkTypeNotExtendsItself(ComplexType type) {
+		EList<Type> superTypes = type.getSuperTypes();
+		for (Type superType : superTypes) {
+			if (superType.equals(type)) {
+				error(String.format(ERROR_CYCLE_DETECTED_MSG, type.getName()), type,
+						TypesPackage.Literals.TYPE__SUPER_TYPES, ERROR_CYCLE_DETECTED_CODE);
+			}
+		}
+	}
+
+	public static final String ERROR_DUPLICATE_TYPE_PARAMETER_CODE = "DuplicateTypeParameter";
+	public static final String ERROR_DUPLICATE_TYPE_PARAMETER_MSG = "Duplicate type parameter %s.";
+
+	@Check
+	public void checkDuplicateTypeParameter(GenericElement type) {
+		Set<String> names = Sets.newHashSet();
+		EList<TypeParameter> typeParameter = type.getTypeParameters();
+		for (TypeParameter param : typeParameter) {
+			String name = param.getName();
+			if (names.contains(name)) {
+				error(String.format(ERROR_DUPLICATE_TYPE_PARAMETER_MSG, name), type,
+						TypesPackage.Literals.GENERIC_ELEMENT__TYPE_PARAMETERS, ERROR_DUPLICATE_TYPE_PARAMETER_CODE);
+			}
+			names.add(name);
+		}
+	}
+
+	public static final String ERROR_VAR_ARGS_LAST_CODE = "VarArgsMustBeLast";
+	public static final String ERROR_VAR_ARGS_LAST_MSG = "The variable argument type must be the last argument.";
+
+	@Check(CheckType.FAST)
+	public void checkVarArgParameterIsLast(Operation operation) {
+		if (operation.isVariadic() && operation.getVarArgIndex() != operation.getParameters().size() - 1) {
+			error(ERROR_VAR_ARGS_LAST_MSG, operation.getParameters().get(operation.getVarArgIndex()), null,
+					ERROR_VAR_ARGS_LAST_CODE);
+		}
+	}
+
+	public static final String ERROR_OPTIONAL_MUST_BE_LAST_CODE = "OptionalParametersLast";
+	public static final String ERROR_OPTIONAL_MUST_BE_LAST_MSG = "Required parameters must not be defined after optional parameters.";
+
+	@Check(CheckType.FAST)
+	public void checkOptionalArgumentsAreLast(Operation op) {
+		boolean foundOptional = false;
+		for (Parameter p : op.getParameters()) {
+			if (foundOptional && !p.isOptional()) {
+				error(ERROR_OPTIONAL_MUST_BE_LAST_MSG, p, null, ERROR_OPTIONAL_MUST_BE_LAST_CODE);
+			}
+			if (p.isOptional()) {
+				foundOptional = true;
+			}
+		}
+	}
+
+	protected String prettyPrintTypes(List<TypeParameter> typeParameters) {
+		StringJoiner joiner = new StringJoiner(", ");
+		for (TypeParameter typeParameter : typeParameters) {
+			joiner.add(typeParameter.getName());
+		}
+		return "<" + joiner.toString() + ">";
+	}
+
+	protected String prettyPrintArguments(List<TypeSpecifier> specifiers) {
+		StringJoiner joiner = new StringJoiner(", ");
+		for (TypeSpecifier specifier : specifiers) {
+			joiner.add(specifier.getType().getName());
+		}
+		return "<" + joiner.toString() + ">";
+	}
+
+	@Override
+	protected List<EPackage> getEPackages() {
+		List<EPackage> result = new ArrayList<EPackage>();
+		result.add(EPackage.Registry.INSTANCE.getEPackage("http://www.yakindu.org/base/types/2.0.0"));
+		return result;
+	}
+}

+ 11 - 17
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/EntryValidator.java

@@ -23,12 +23,8 @@ import org.yakindu.sct.model.sgraph.Transition;
  */
 public class EntryValidator extends AbstractSGraphValidator {
 
-
-
-	
-	
-	private static final String ENTRY_TRANSITIONS_NO_IN_IF_INITIAL_MSG  = "Initial entry should have no incoming transition.";
-	public static final String  ENTRY_TRANSITIONS_NO_IN_IF_INITIAL_CODE = "entry.transitions.NoInIfInitial";
+	private static final String ENTRY_TRANSITIONS_NO_IN_IF_INITIAL_MSG = "Initial entry should have no incoming transition.";
+	public static final String ENTRY_TRANSITIONS_NO_IN_IF_INITIAL_CODE = "entry.transitions.NoInIfInitial";
 
 	@Check(CheckType.FAST)
 	public void checkEntryTransitionsNoInIfInitial(Entry entry) {
@@ -37,20 +33,19 @@ public class EntryValidator extends AbstractSGraphValidator {
 		}
 	}
 
-
-	private static final String ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_MSG  = "Initial entry must have an outgoing transition.";
-	public static final String  ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_CODE = "entry.transitions.RequireOutIfInitial";
+	private static final String ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_MSG = "Initial entry must have an outgoing transition.";
+	public static final String ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_CODE = "entry.transitions.RequireOutIfInitial";
 
 	@Check(CheckType.FAST)
 	public void checkEntryTransitionsRequireOneOutIfInitial(Entry entry) {
-		if (entry.getKind().equals(EntryKind.INITIAL) && entry.getOutgoingTransitions().size() == 0 ) {
-			error(ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_MSG, entry, null, -1, ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_CODE);
+		if (entry.getKind().equals(EntryKind.INITIAL) && entry.getOutgoingTransitions().size() == 0) {
+			error(ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_MSG, entry, null, -1,
+					ENTRY_TRANSITIONS_REQUIRE_OUT_IF_INITIAL_CODE);
 		}
 	}
 
-		
-	private static final String ENTRY_TRANSITIONS_NO_MULTIPLE_OUT_MSG  = "Entries must not have more than one outgoing transition.";
-	public static final String  ENTRY_TRANSITIONS_NO_MULTIPLE_OUT_CODE = "entry.transitions.NoMultipleOut";
+	private static final String ENTRY_TRANSITIONS_NO_MULTIPLE_OUT_MSG = "Entries must not have more than one outgoing transition.";
+	public static final String ENTRY_TRANSITIONS_NO_MULTIPLE_OUT_CODE = "entry.transitions.NoMultipleOut";
 
 	@Check(CheckType.FAST)
 	public void checkEntryTransitionsNoMultipleOut(Entry entry) {
@@ -59,7 +54,6 @@ public class EntryValidator extends AbstractSGraphValidator {
 		}
 	}
 
-	
 	private static final String ENTRY_TRANSITIONS_NO_TRIGGER_ON_OUT_MSG = "The outgoing transitions of an entry must not have a trigger or guard.";
 	public static final String ENTRY_TRANSITIONS_NO_TRIGGER_ON_OUT_CODE = "entry.transitions.NoTriggerOnOut";
 
@@ -67,10 +61,10 @@ public class EntryValidator extends AbstractSGraphValidator {
 	public void checkEntryTransitionsNoTriggerOnOut(Entry entry) {
 		for (Transition transition : entry.getOutgoingTransitions()) {
 			if (transition.getTrigger() != null) {
-				error(ENTRY_TRANSITIONS_NO_TRIGGER_ON_OUT_MSG, entry, null, -1, ENTRY_TRANSITIONS_NO_TRIGGER_ON_OUT_CODE);
+				error(ENTRY_TRANSITIONS_NO_TRIGGER_ON_OUT_MSG, entry, null, -1,
+						ENTRY_TRANSITIONS_NO_TRIGGER_ON_OUT_CODE);
 			}
 		}
 	}
 
-
 }

+ 7 - 16
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/ExitValidator.java

@@ -20,26 +20,19 @@ import org.yakindu.sct.model.sgraph.Exit;
  *
  */
 public class ExitValidator extends AbstractSGraphValidator {
-	
-	
-	private static final String EXIT_TRANSITIONS_MUST_HAVE_N_IN_MSG  = "Exit node should have at least one incoming transition.";
-	public static final String  EXIT_TRANSITIONS_MUST_HAVE_N_IN_CODE = "exit.transitions.MustHaveNIn";
-	
-	/**
-	 * TODO: severity error?
-	 * @param exit
-	 */
+
+	private static final String EXIT_TRANSITIONS_MUST_HAVE_N_IN_MSG = "Exit node should have at least one incoming transition.";
+	public static final String EXIT_TRANSITIONS_MUST_HAVE_N_IN_CODE = "exit.transitions.MustHaveNIn";
+
 	@Check(CheckType.FAST)
 	public void checkExitTransitionsMustHaveNIn(Exit exit) {
 		if (exit.getIncomingTransitions().size() == 0) {
-			warning(EXIT_TRANSITIONS_MUST_HAVE_N_IN_MSG, exit, null, -1, EXIT_TRANSITIONS_MUST_HAVE_N_IN_CODE);
+			error(EXIT_TRANSITIONS_MUST_HAVE_N_IN_MSG, exit, null, -1, EXIT_TRANSITIONS_MUST_HAVE_N_IN_CODE);
 		}
 	}
 
-	
-	
-	private static final String EXIT_TRANSITIONS_NO_OUT_MSG  = "Exit node must not have outgoing transitions.";
-	public static final String  EXIT_TRANSITIONS_NO_OUT_CODE = "exit.transitions.NoOut";
+	private static final String EXIT_TRANSITIONS_NO_OUT_MSG = "Exit node must not have outgoing transitions.";
+	public static final String EXIT_TRANSITIONS_NO_OUT_CODE = "exit.transitions.NoOut";
 
 	@Check(CheckType.FAST)
 	public void checkExtitTransitionsNoOut(Exit exit) {
@@ -48,6 +41,4 @@ public class ExitValidator extends AbstractSGraphValidator {
 		}
 	}
 
-	
-
 }

+ 28 - 52
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/RegionValidator.java

@@ -24,34 +24,25 @@ import org.yakindu.sct.model.sgraph.EntryKind;
 import org.yakindu.sct.model.sgraph.Exit;
 import org.yakindu.sct.model.sgraph.Region;
 import org.yakindu.sct.model.sgraph.Statechart;
-import org.yakindu.sct.model.sgraph.Transition;
 import org.yakindu.sct.model.sgraph.Vertex;
 
 /**
  * 
  * All validation contraints for the meta model elements {@link Region}
  * 
- * 
- *
  */
 public class RegionValidator extends AbstractSGraphValidator {
 
+	private static final String REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_MSG = "The region can't be entered using the shallow history. Add a default entry node.";
+	public static final String REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_CODE = "region.RequiresDefaultEntryIfEnteredByShallowHistory";
 
-	private static final String REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_MSG  = "The region can't be entered using the shallow history. Add a default entry node.";
-	public static final String  REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_CODE = "region.RequiresDefaultEntryIfEnteredByShallowHistory";
-
-	private static final String REGION_CANT_BE_ENTERED_USING_SHALLOW_HISTORY_NON_CONNECTED_DEFAULT_ENTRY_MSG = "The region can't be entered using the shallow history. Add a transition from default entry to a state.";
-	public static final String REGION_CANT_BE_ENTERED_USING_SHALLOW_HISTORY_NON_CONNECTED_DEFAULT_ENTRY_CODE = "region.CantBeEnteredUsingShallowHistoryNonConnectedDefaultEntry";
-
-	/**
-	 * TODO: remove second message as this is not required. Every default entry must have a target transition.
-	 * TODO: check on region instead of entry. 
-	 * 
-	 * @param e
-	 */
 	@Check(CheckType.FAST)
-	public void checkRegionRequiresDefaultEntryIfEnteredByShallowHistory(Entry e) {
-		if (e.getKind() == EntryKind.SHALLOW_HISTORY) {
+	public void checkRegionRequiresDefaultEntryIfEnteredByShallowHistory(Region region) {
+		List<Entry> shallowHistories = region.getVertices().stream()
+				.filter(v -> v instanceof Entry && ((Entry) v).getKind() == EntryKind.SHALLOW_HISTORY)
+				.map(entry -> (Entry) entry).collect(Collectors.toList());
+
+		for (Entry e : shallowHistories) {
 			List<Region> regions = new ArrayList<>();
 			for (Vertex v : e.getParentRegion().getVertices()) {
 				if (v instanceof CompositeElement) {
@@ -72,24 +63,14 @@ public class RegionValidator extends AbstractSGraphValidator {
 				if (defaultEntry == null) {
 					error(REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_MSG, r, null, -1,
 							REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_CODE);
-				} else if (defaultEntry.getOutgoingTransitions().size() != 1) {
-					error(REGION_CANT_BE_ENTERED_USING_SHALLOW_HISTORY_NON_CONNECTED_DEFAULT_ENTRY_MSG, r, null, -1,
-							REGION_CANT_BE_ENTERED_USING_SHALLOW_HISTORY_NON_CONNECTED_DEFAULT_ENTRY_CODE);
 				}
 			}
-
 		}
-
 	}
 
-	
 	private final static String REGION_NO_MULTIPLE_DEFAULT_ENTRIES_MSG = "There are multiple default entry nodes (one without a name and one named 'default') in this region.";
 	public final static String REGION_MUST_NOT_HAVE_MULTIPLE_DEFAULT_ENTRIES_CODE = "region.MustNotHaveMultipleDefaultEntries";
 
-	/**
-	 * TODO: check on region instead of entry.
-	 * @param entry
-	 */
 	@Check
 	public void checkRegionMustNotHaveMultipleDefaultEntries(Entry entry) {
 		Region region = (Region) entry.eContainer();
@@ -99,41 +80,36 @@ public class RegionValidator extends AbstractSGraphValidator {
 		boolean defaultNamedEntryExists = initialEntires.stream()
 				.filter(v -> v.getName().trim().equalsIgnoreCase("default")).count() > 0;
 		if (unamedEntryExists && defaultNamedEntryExists) {
-			error(REGION_NO_MULTIPLE_DEFAULT_ENTRIES_MSG, region, null, -1, REGION_MUST_NOT_HAVE_MULTIPLE_DEFAULT_ENTRIES_CODE);
+			error(REGION_NO_MULTIPLE_DEFAULT_ENTRIES_MSG, region, null, -1,
+					REGION_MUST_NOT_HAVE_MULTIPLE_DEFAULT_ENTRIES_CODE);
 		}
 	}
 
-	
-	
-	private static final String REGION_NO_EXIT_ON_TOP_LEVEL_MSG  = "Exit node in top level region not supported - use final states instead.";
-	public static final String  REGION_NO_EXIT_ON_TOP_LEVEL_CODE = "region.NoExitOnTopLevel";
+	private static final String REGION_NO_EXIT_ON_TOP_LEVEL_MSG = "Exit node in top level region not supported - use final states instead.";
+	public static final String REGION_NO_EXIT_ON_TOP_LEVEL_CODE = "region.NoExitOnTopLevel";
 
-	/**
-	 * TODO: check region instead of exit. 
-	 * @param exit
-	 */
 	@Check(CheckType.FAST)
-	public void checkRegionNoExitOnTopLevel(Exit exit) {
-		if (exit.getParentRegion().getComposite() instanceof Statechart) {
-			error(REGION_NO_EXIT_ON_TOP_LEVEL_MSG, exit, null, -1, REGION_NO_EXIT_ON_TOP_LEVEL_CODE);
+	public void checkRegionNoExitOnTopLevel(Region region) {
+		if (region.getComposite() instanceof Statechart) {
+			region.getVertices().stream().filter(v -> v instanceof Exit).forEach(
+					exit -> error(REGION_NO_EXIT_ON_TOP_LEVEL_MSG, exit, null, -1, REGION_NO_EXIT_ON_TOP_LEVEL_CODE));
+
 		}
 	}
 
-	
-	
-	private static final String REGION_ENTRY_TARGET_MUST_BE_CHILD_MSG  = "Entry target must be child of the region.";
-	public static final String  REGION_ENTRY_TARGET_MUST_BE_CHILD_CODE = "region.EntryTargetMustBeChild";
+	private static final String REGION_ENTRY_TARGET_MUST_BE_CHILD_MSG = "Entry target must be child of the region.";
+	public static final String REGION_ENTRY_TARGET_MUST_BE_CHILD_CODE = "region.EntryTargetMustBeChild";
 
-	/**
-	 * TODO: check region instead of transition.
-	 * @param t
-	 */
 	@Check(CheckType.FAST)
-	public void checkRegionEntryTargetMustBeChild(Transition t) {
-		if (t.getSource() instanceof Entry && !isChildOrSibling(t.getSource(), t.getTarget())) {
-			error(REGION_ENTRY_TARGET_MUST_BE_CHILD_MSG, t, null, -1,
-					REGION_ENTRY_TARGET_MUST_BE_CHILD_CODE);
-		}
+	public void checkRegionEntryTargetMustBeChild(Region region) {
+		region.getVertices().stream().filter(v -> v instanceof Entry)
+				.forEach(entry -> entry.getOutgoingTransitions().stream().forEach(t -> {
+					if (!isChildOrSibling(t.getSource(), t.getTarget())) {
+						error(REGION_ENTRY_TARGET_MUST_BE_CHILD_MSG, t, null, -1,
+								REGION_ENTRY_TARGET_MUST_BE_CHILD_CODE);
+					}
+				}));
+
 	}
 
 	protected boolean isChildOrSibling(Vertex source, Vertex target) {

+ 0 - 1
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/StatechartValidator.java

@@ -33,7 +33,6 @@ public class StatechartValidator extends AbstractSGraphValidator {
 		}
 	}
 
-	
 	protected boolean isValidJavaIdentifier(String s) {
 		if (s == null || s.length() == 0) {
 			return false;

+ 10 - 15
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/SynchronizationValidator.java

@@ -35,33 +35,30 @@ import org.yakindu.sct.model.sgraph.Vertex;
  */
 public class SynchronizationValidator extends AbstractSGraphValidator {
 
-
 	private static final String SYNCHRONIZATION_TRANSITIONS_REQUIRE_N_OUT_MSG = "A synchronization must have at least one outgoing transition.";
 	public static final String SYNCHRONIZATION_TRANSITIONS_REQUIRE_N_OUT_CODE = "synchronization.transitions.RequireNOut";
 
 	@Check(CheckType.FAST)
 	public void checkSynchronizationTransitionsRequireNOut(Synchronization sync) {
 		if (sync.getOutgoingTransitions().size() == 0) {
-			error(SYNCHRONIZATION_TRANSITIONS_REQUIRE_N_OUT_MSG, sync, null, -1, SYNCHRONIZATION_TRANSITIONS_REQUIRE_N_OUT_CODE);
+			error(SYNCHRONIZATION_TRANSITIONS_REQUIRE_N_OUT_MSG, sync, null, -1,
+					SYNCHRONIZATION_TRANSITIONS_REQUIRE_N_OUT_CODE);
 		}
 	}
 
-
-	
 	private static final String SYNCHRONIZATION_TRANSITIONS_REQUIRE_MULTIPLE_IN_OR_MULTIPLE_OUT_MSG = "A synchronization must have either multiple incoming or multiple outgoing transitions.";
 	public static final String SYNCHRONIZATION_TRANSITIONS_REQUIRE_MULTIPLE_IN_OR_MULTIPLE_OUT_CODE = "synchronization.transitions.RequireMultipleInOrMultipleOut";
-	
+
 	@Check(CheckType.FAST)
 	public void checkSynchronizationTransitionsRequireMultipleInOrMultipleOut(Synchronization sync) {
 		int in = sync.getIncomingTransitions().size();
 		int out = sync.getOutgoingTransitions().size();
 		if (in < 2 && out < 2) {
-			error(SYNCHRONIZATION_TRANSITIONS_REQUIRE_MULTIPLE_IN_OR_MULTIPLE_OUT_MSG, sync, null, -1, SYNCHRONIZATION_TRANSITIONS_REQUIRE_MULTIPLE_IN_OR_MULTIPLE_OUT_CODE);
+			error(SYNCHRONIZATION_TRANSITIONS_REQUIRE_MULTIPLE_IN_OR_MULTIPLE_OUT_MSG, sync, null, -1,
+					SYNCHRONIZATION_TRANSITIONS_REQUIRE_MULTIPLE_IN_OR_MULTIPLE_OUT_CODE);
 		}
 	}
 
-
-	
 	private static final String SYNCHRONIZATION_REQUIRES_ORTHOGONAL_SOURCE_STATES_MSG = "The source states of a synchronization must be orthogonal.";
 	public static final String SYNCHRONIZATION_REQUIRES_ORTHOGONAL_SOURCE_STATES_CODE = "synchronization.RequiresOrthogonalSourceStates";
 
@@ -69,12 +66,11 @@ public class SynchronizationValidator extends AbstractSGraphValidator {
 	public void checkSynchronizationRequiresOrthogonalSourceStates(Synchronization sync) {
 		List<Vertex> sourceVertices = sources(sync.getIncomingTransitions());
 		if (!areOrthogonal(sourceVertices)) {
-			error(SYNCHRONIZATION_REQUIRES_ORTHOGONAL_SOURCE_STATES_MSG, sync, null, -1, SYNCHRONIZATION_REQUIRES_ORTHOGONAL_SOURCE_STATES_CODE);
+			error(SYNCHRONIZATION_REQUIRES_ORTHOGONAL_SOURCE_STATES_MSG, sync, null, -1,
+					SYNCHRONIZATION_REQUIRES_ORTHOGONAL_SOURCE_STATES_CODE);
 		}
 	}
 
-	
-	
 	private static final String SYNCHRONIZATION_REQUIRES_ORTHOGONAL_TARGET_STATES_MSG = "The target states of a synchronization must be orthogonal.";
 	public static final String SYNCHRONIZATION_REQUIRES_ORTHOGONAL_TARGET_STATES_CODE = "synchronization.RequiresOrthogonalTargetStates";
 
@@ -82,18 +78,17 @@ public class SynchronizationValidator extends AbstractSGraphValidator {
 	public void checkSynchronizationRequiresOrthogonalTargetStates(Synchronization sync) {
 		List<Vertex> sourceVertices = targets(sync.getOutgoingTransitions());
 		if (!areOrthogonal(sourceVertices)) {
-			error(SYNCHRONIZATION_REQUIRES_ORTHOGONAL_TARGET_STATES_MSG, sync, null, -1, SYNCHRONIZATION_REQUIRES_ORTHOGONAL_TARGET_STATES_CODE);
+			error(SYNCHRONIZATION_REQUIRES_ORTHOGONAL_TARGET_STATES_MSG, sync, null, -1,
+					SYNCHRONIZATION_REQUIRES_ORTHOGONAL_TARGET_STATES_CODE);
 		}
 	}
 
-
-	
 	private static final String SYNCHRONIZATION_REQUIRES_SOURCE_STATES_ORTHOGONAL_TO_TARGET_STATES_MSG = "A synchronization's source states must be orthogonal to it's target states. (Common ancestor must be a region.)";
 	public static final String SYNCHRONIZATION_REQUIRES_SOURCE_STATES_ORTHOGONAL_TO_TARGET_STATES_CODE = "synchronization.RequiresSourceStatesOrthogonalToTargetStates";
 
 	@Check
 	public void checkSynchronizationRequiresSourceStatesOrthogonalToTargetStates(Synchronization sync) {
-		
+
 		List<Transition> incoming = sync.getIncomingTransitions();
 		List<List<EObject>> inAncestorsList = new ArrayList<>();
 		for (Transition trans : incoming) {

+ 1 - 3
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/TransitionValidator.java

@@ -27,7 +27,7 @@ import org.yakindu.sct.model.sgraph.Vertex;
 public class TransitionValidator extends AbstractSGraphValidator {
 
 	private static final String RANSITION_SOURCE_NOT_ORTHOGONAL_TO_TARGET_MSG = "Source and target of a transition must not be located in orthogonal regions!";
-	public static final String  TRANSITION_SOURCE_NOT_ORTHOGONAL_TO_TARGET_CODE = "transition.SourceNotOrthogonalToTarget";
+	public static final String TRANSITION_SOURCE_NOT_ORTHOGONAL_TO_TARGET_CODE = "transition.SourceNotOrthogonalToTarget";
 
 	@Check
 	public void checkTransitionSourceNotOrthogonalToTarget(Transition transition) {
@@ -42,6 +42,4 @@ public class TransitionValidator extends AbstractSGraphValidator {
 		}
 	}
 
-
-	
 }

+ 1 - 1
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/VertexValidator.java

@@ -47,7 +47,7 @@ public class VertexValidator extends AbstractSGraphValidator {
 			}
 			stateScopeSet.add(vertex);
 			final List<Object> externalPredecessors = new ArrayList<>();
-			
+
 			DFS dfs = new DFS() {
 
 				@Override

+ 15 - 4
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/JavaOperationMockup.java

@@ -12,6 +12,7 @@ package org.yakindu.sct.simulation.core.sexec.interpreter;
 
 import java.lang.reflect.Method;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.emf.common.util.WrappedException;
@@ -20,6 +21,7 @@ import org.yakindu.base.expressions.interpreter.IExecutionSlotResolver;
 import org.yakindu.base.expressions.interpreter.IOperationMockup;
 import org.yakindu.base.types.Operation;
 import org.yakindu.sct.commons.WorkspaceClassLoaderFactory;
+import org.yakindu.sct.model.stext.stext.InterfaceScope;
 
 import com.google.common.collect.Lists;
 import com.google.inject.Inject;
@@ -44,8 +46,8 @@ public class JavaOperationMockup implements IOperationMockup {
 	public void initOperationCallbacks(IProject project, String[] classes) {
 		callbacks = Lists.newArrayList();
 
-		ClassLoader classLoader = new WorkspaceClassLoaderFactory().createClassLoader(project, getClass()
-				.getClassLoader());
+		ClassLoader classLoader = new WorkspaceClassLoaderFactory().createClassLoader(project,
+				getClass().getClassLoader());
 		try {
 			if (classes.length > 0)
 				for (String string : classes) {
@@ -79,8 +81,17 @@ public class JavaOperationMockup implements IOperationMockup {
 	}
 
 	public Object execute(Operation definition, Object[] parameter) {
-		PolymorphicDispatcher<Object> dispatcher = new PolymorphicDispatcher<Object>(definition.getName(), definition
-				.getParameters().size(), definition.getParameters().size(), callbacks);
+		List<Object> targets = callbacks;
+		if (definition.eContainer() instanceof InterfaceScope) {
+			String className = ((InterfaceScope) definition.eContainer()).getName();
+			if (className != null) {
+				targets = callbacks.stream().filter(c -> className.equals(c.getClass().getSimpleName()))
+						.collect(Collectors.toList());
+			}
+		}
+		PolymorphicDispatcher<Object> dispatcher = new PolymorphicDispatcher<Object>(definition.getName(),
+				definition.getParameters().size(), definition.getParameters().size(),
+				targets.size() > 0 ? targets : callbacks);
 		try {
 			return dispatcher.invoke(parameter);
 		} catch (Exception ex) {

+ 2 - 9
test-plugins/org.yakindu.sct.model.sgraph.test/src/org/yakindu/sct/model/sgraph/test/validation/ExitValidatorTest.java

@@ -33,11 +33,6 @@ public class ExitValidatorTest extends AbstractSGraphValidatorTest {
 	@Inject
 	protected SGraphJavaValidatorTester<ExitValidator> tester;
 
-
-
-
-
-
 	/**
 	 * An exit node should have at leat one incoming transition.
 	 */
@@ -48,8 +43,7 @@ public class ExitValidatorTest extends AbstractSGraphValidatorTest {
 		state.getRegions().add(subRegion);
 		Exit exit = factory.createExit();
 		subRegion.getVertices().add(exit);
-
-		tester.validate(exit).assertWarning(EXIT_TRANSITIONS_MUST_HAVE_N_IN_CODE);
+		tester.validate(exit).assertError(EXIT_TRANSITIONS_MUST_HAVE_N_IN_CODE);
 	}
 
 	/**
@@ -70,7 +64,6 @@ public class ExitValidatorTest extends AbstractSGraphValidatorTest {
 		tester.validate(exit).assertError(EXIT_TRANSITIONS_NO_OUT_CODE);
 	}
 
-
 	/**
 	 * Tests a scenario where no issues for an exit nodes exists.
 	 */
@@ -89,5 +82,5 @@ public class ExitValidatorTest extends AbstractSGraphValidatorTest {
 
 		tester.validate(exit).assertOK();
 	}
-	
+
 }

+ 2 - 14
test-plugins/org.yakindu.sct.model.sgraph.test/src/org/yakindu/sct/model/sgraph/test/validation/RegionValidatorTest.java

@@ -34,9 +34,6 @@ public class RegionValidatorTest extends AbstractSGraphValidatorTest {
 	@Inject
 	protected SGraphJavaValidatorTester<RegionValidator> tester;
 
-
-
-
 	@Test
 	public void checkOnlyOneDefaultEntryPermitted() {
 		State state = createState();
@@ -55,12 +52,7 @@ public class RegionValidatorTest extends AbstractSGraphValidatorTest {
 	public void regionCantBeEnteredUsingShallowHistory() {
 		Statechart statechart = loadStatechart("RegionCantBeEnteredUsingShallowHistory.sct");
 		AssertableDiagnostics result = tester.validate(statechart);
-		result.assertDiagnosticsCount(2);
-
-		result.assertAny(
-				AssertableDiagnostics.errorCode(REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_CODE));
-		result.assertAny(AssertableDiagnostics
-				.errorCode(REGION_CANT_BE_ENTERED_USING_SHALLOW_HISTORY_NON_CONNECTED_DEFAULT_ENTRY_CODE));
+		result.assertError(REGION_REQUIRES_DEFAULT_ENTRY_IF_ENTERED_BY_SHALLOW_HISTORY_CODE);
 	}
 
 	@Test
@@ -69,7 +61,6 @@ public class RegionValidatorTest extends AbstractSGraphValidatorTest {
 		tester.validate(statechart).assertOK();
 	}
 
-	
 	/**
 	 * An exit node must not be used in top level regions.
 	 */
@@ -80,18 +71,15 @@ public class RegionValidatorTest extends AbstractSGraphValidatorTest {
 		Exit exit = factory.createExit();
 		createTransition(state, exit);
 		region.getVertices().add(exit);
-		tester.validate(exit).assertError(REGION_NO_EXIT_ON_TOP_LEVEL_CODE);
+		tester.validate(region).assertError(REGION_NO_EXIT_ON_TOP_LEVEL_CODE);
 	}
 
-	
 	@Test
 	public void initialEntryWithTransitionToContainer() {
 		Statechart statechart = loadStatechart("EntryTransitionToParentState.sct");
 		tester.validate(statechart).assertError(REGION_ENTRY_TARGET_MUST_BE_CHILD_CODE);
 	}
 
-
-	
 	@Override
 	protected Statechart loadStatechart(String path) {
 		return super.loadStatechart("region/" + path);

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

@@ -17,9 +17,9 @@ import static org.eclipse.xtext.junit4.validation.AssertableDiagnostics.warningM
 import static org.junit.Assert.assertEquals;
 import static org.yakindu.base.expressions.validation.ExpressionsJavaValidator.ERROR_ASSIGNMENT_TO_CONST_MSG;
 import static org.yakindu.base.expressions.validation.ExpressionsJavaValidator.ERROR_LEFT_HAND_ASSIGNMENT_MSG;
-import static org.yakindu.base.expressions.validation.ExpressionsJavaValidator.ERROR_OPTIONAL_MUST_BE_LAST_CODE;
-import static org.yakindu.base.expressions.validation.ExpressionsJavaValidator.ERROR_VAR_ARGS_LAST_CODE;
 import static org.yakindu.base.expressions.validation.ExpressionsJavaValidator.ERROR_WRONG_NUMBER_OF_ARGUMENTS_CODE;
+import static org.yakindu.base.types.validation.TypesJavaValidator.ERROR_OPTIONAL_MUST_BE_LAST_CODE;
+import static org.yakindu.base.types.validation.TypesJavaValidator.ERROR_VAR_ARGS_LAST_CODE;
 import static org.yakindu.sct.test.models.AbstractTestModelsUtil.VALIDATION_TESTMODEL_DIR;
 
 import java.util.HashMap;
@@ -864,7 +864,7 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		Scope context = (Scope) parseExpression("import: \"does.not.exist\"", ImportScope.class.getSimpleName());
 		AssertableDiagnostics validationResult = tester.validate(context);
 		validationResult
-		.assertErrorContains(String.format(STextValidationMessages.IMPORT_NOT_RESOLVED_MSG, "does.not.exist"));
+				.assertErrorContains(String.format(STextValidationMessages.IMPORT_NOT_RESOLVED_MSG, "does.not.exist"));
 	}
 
 	@Test
@@ -1028,7 +1028,7 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		result.assertAll(warningMsg("Duplicate"), warningMsg("Duplicate"), errorMsg("Duplicate"),
 				errorMsg("Duplicate"));
 	}
-	
+
 	@Test
 	public void checkUnknownEntry() {
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnknownEntryPoint.sct");
@@ -1042,12 +1042,12 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		assertIssueCount(diagnostics, 1);
 		assertWarning(diagnostics, ENTRY_NOT_EXIST + "'doesNotExist'");
 	}
-	
+
 	@Test
 	public void checkNeverUsedExit() {
 		statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnusedExitPoint2.sct");
 		Iterator<EObject> iter = statechart.eAllContents();
-		while (iter.hasNext()) { 
+		while (iter.hasNext()) {
 			EObject element = iter.next();
 			if (element instanceof Exit) {
 				validator.validate(element, diagnostics, new HashMap<>());
@@ -1056,5 +1056,5 @@ public class STextJavaValidatorTest extends AbstractSTextValidationTest implemen
 		assertIssueCount(diagnostics, 1);
 		assertWarning(diagnostics, EXIT_NEVER_USED + "'unusedExitPoint'");
 	}
-	
+
 }