瀏覽代碼

First draft of new type system implementation

Andreas Mülder 10 年之前
父節點
當前提交
ebd8f34011
共有 28 個文件被更改,包括 972 次插入1607 次删除
  1. 7 3
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/ExpressionsRuntimeModule.java
  2. 0 321
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/DefaultExpressionsTypeInferrer.xtend
  3. 200 0
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/ExpressionsTypeInferrer.java
  4. 34 0
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/ExpressionsTypeInferrerMessages.java
  5. 0 33
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/IExpressionsTypeInferrer.java
  6. 140 0
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/interpreter/ExpressionsTypeInterpreter.java
  7. 27 38
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/validation/ExpressionsJavaValidator.java
  8. 1 1
      plugins/org.yakindu.base.types.scope/src/org/yakindu/base/types/scope/TypeSystemAwareScope.java
  9. 0 2
      plugins/org.yakindu.base.types/.settings/org.eclipse.core.resources.prefs
  10. 5 1
      plugins/org.yakindu.base.types/META-INF/MANIFEST.MF
  11. 1 1
      plugins/org.yakindu.base.types/plugin.xml
  12. 0 100
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/AbstractTypeSystem.java
  13. 0 615
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/DefaultTypeSystem.java
  14. 1 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/DefaultTypeSystemRegistry.java
  15. 0 203
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/ITypeSystem.java
  16. 2 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/ITypeSystemRegistry.java
  17. 0 83
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/InferenceIssue.java
  18. 0 73
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/InferenceResult.java
  19. 0 103
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/InferredType.java
  20. 0 30
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/TypeSystemUtils.xtend
  21. 125 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/inferrer/AbstractTypeSystemInferrer.java
  22. 97 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/inferrer/ITypeSystemInferrer.java
  23. 63 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/interpreter/AbstractTypeSystemInterpreter.java
  24. 37 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/interpreter/DefaultTypeSystemInterpreter.java
  25. 28 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/interpreter/ITypeSystemInterpreter.java
  26. 107 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/AbstractTypeSystem.java
  27. 53 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/DefaultTypeSystem.java
  28. 44 0
      plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/ITypeSystem.java

+ 7 - 3
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/ExpressionsRuntimeModule.java

@@ -3,9 +3,13 @@
  */
 package org.yakindu.base.expressions;
 
-/**
- * Use this class to register components to be used at runtime / without the Equinox extension registry.
- */
+import org.yakindu.base.expressions.inferrer.ExpressionsTypeInferrer;
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer;
+
 public class ExpressionsRuntimeModule extends org.yakindu.base.expressions.AbstractExpressionsRuntimeModule {
 
+	public Class<? extends ITypeSystemInferrer> bindITypeSystemInferrer() {
+		return ExpressionsTypeInferrer.class;
+	}
+
 }

+ 0 - 321
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/DefaultExpressionsTypeInferrer.xtend

@@ -1,321 +0,0 @@
-/**
- * Copyright (c) 2011 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.expressions.inferrer
-
-import com.google.common.collect.Iterables
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.core.runtime.IStatus
-import org.eclipse.emf.ecore.EObject
-import org.yakindu.base.expressions.expressions.AdditiveOperator
-import org.yakindu.base.expressions.expressions.AssignmentOperator
-import org.yakindu.base.expressions.expressions.BitwiseAndExpression
-import org.yakindu.base.expressions.expressions.BitwiseOrExpression
-import org.yakindu.base.expressions.expressions.BitwiseXorExpression
-import org.yakindu.base.expressions.expressions.BoolLiteral
-import org.yakindu.base.expressions.expressions.ConditionalExpression
-import org.yakindu.base.expressions.expressions.Expression
-import org.yakindu.base.expressions.expressions.HexLiteral
-import org.yakindu.base.expressions.expressions.IntLiteral
-import org.yakindu.base.expressions.expressions.Literal
-import org.yakindu.base.expressions.expressions.LogicalAndExpression
-import org.yakindu.base.expressions.expressions.LogicalNotExpression
-import org.yakindu.base.expressions.expressions.LogicalOrExpression
-import org.yakindu.base.expressions.expressions.LogicalRelationExpression
-import org.yakindu.base.expressions.expressions.MultiplicativeOperator
-import org.yakindu.base.expressions.expressions.NullLiteral
-import org.yakindu.base.expressions.expressions.NumericalAddSubtractExpression
-import org.yakindu.base.expressions.expressions.NumericalMultiplyDivideExpression
-import org.yakindu.base.expressions.expressions.NumericalUnaryExpression
-import org.yakindu.base.expressions.expressions.ParenthesizedExpression
-import org.yakindu.base.expressions.expressions.PrimitiveValueExpression
-import org.yakindu.base.expressions.expressions.RealLiteral
-import org.yakindu.base.expressions.expressions.RelationalOperator
-import org.yakindu.base.expressions.expressions.ShiftExpression
-import org.yakindu.base.expressions.expressions.ShiftOperator
-import org.yakindu.base.expressions.expressions.StringLiteral
-import org.yakindu.base.expressions.expressions.TypeCastExpression
-import org.yakindu.base.expressions.expressions.UnaryOperator
-import org.yakindu.base.types.Enumerator
-import org.yakindu.base.types.ITypeSystem
-import org.yakindu.base.types.ITypeSystem.ITypeSystemOperator
-import org.yakindu.base.types.InferenceIssue
-import org.yakindu.base.types.InferenceResult
-import org.yakindu.base.types.InferredType
-import org.yakindu.base.types.TypedElement
-import org.yakindu.base.types.Type
-
-/**
- * 
- * The TypeInferrer checks an expression AST for type conformance
- * 
- * @author andreas muelder - Initial contribution and API
- * @author Alexander Nyßen - Complete revision of API
- *  
- */
-@Singleton
-class DefaultExpressionsTypeInferrer implements IExpressionsTypeInferrer {
-
-	@Inject protected extension ITypeSystem ts
-
-	override inferType(Expression e) {
-		if (e == null) {
-			throw new IllegalArgumentException("Expression may not be null")
-		} else {
-			return doInferType(e)
-		}
-	}
-
-	def dispatch InferenceResult doInferType(TypedElement typedElement) {
-		if (typedElement.type == null)
-			return new InferenceResult(null,
-				new InferenceIssue("Could not infer type of typedelement: " + typedElement, IStatus::ERROR))
-		else
-			return new InferenceResult(new InferredType(typedElement.type))
-	}
-
-	def dispatch InferenceResult doInferType(Enumerator enumerator) {
-		return new InferenceResult(new InferredType(enumerator.owningEnumeration));
-	}
-
-	def InferenceResult inferResult(InferenceResult operand, ITypeSystemOperator unaryOperator) {
-		if (operand.getType() != null) {
-			return ts.inferType(operand.type, unaryOperator);
-
-		//			result.issues.addAll(operand.issues);
-		}
-		return new InferenceResult(null, operand.issues)
-	}
-
-	def InferenceResult inferResult(InferenceResult firstOperand, InferenceResult secondOperand,
-		ITypeSystemOperator binaryOperator) {
-		if (firstOperand.getType() != null && secondOperand.getType() != null) {
-			val result = ts.inferType(firstOperand.type, secondOperand.type, binaryOperator);
-			result?.issues.addAll(firstOperand.issues);
-			result?.issues.addAll(secondOperand.issues);
-			return result;
-		}
-		return new InferenceResult(null, Iterables::concat(firstOperand.issues, secondOperand.issues).toList);
-	}
-
-	def InferenceResult inferResult(InferenceResult firstOperand, InferenceResult secondOperand,
-		InferenceResult thirdOperand, ITypeSystemOperator ternaryOperator) {
-		if (firstOperand.getType() != null && secondOperand.getType() != null && thirdOperand.getType() != null) {
-			val result = ts.inferType(firstOperand.type, secondOperand.type, thirdOperand.type, ternaryOperator);
-			result.issues.addAll(firstOperand.issues);
-			result.issues.addAll(secondOperand.issues);
-			result.issues.addAll(thirdOperand.issues);
-			return result;
-		}
-		return new InferenceResult(null, Iterables::concat(firstOperand.issues, secondOperand.issues).toList);
-	}
-
-	def dispatch InferenceResult doInferType(LogicalAndExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			ITypeSystem.BinaryOperators::LOGICAL_AND)
-	}
-
-	def dispatch InferenceResult doInferType(LogicalOrExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			ITypeSystem.BinaryOperators::LOGICAL_OR)
-	}
-
-	def dispatch InferenceResult doInferType(LogicalNotExpression expression) {
-		return inferResult(expression.operand.doInferType, ITypeSystem.UnaryOperators::LOGICAL_NOT)
-	}
-
-	def dispatch InferenceResult doInferType(BitwiseAndExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			ITypeSystem.BinaryOperators::BITWISE_AND)
-	}
-
-	def dispatch InferenceResult doInferType(BitwiseOrExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			ITypeSystem.BinaryOperators::BITWISE_OR)
-	}
-
-	def dispatch InferenceResult doInferType(BitwiseXorExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			ITypeSystem.BinaryOperators::BITWISE_XOR)
-	}
-
-	def dispatch InferenceResult doInferType(LogicalRelationExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			getTypeSystemOperator(expression.operator))
-	}
-
-	def dispatch InferenceResult doInferType(NumericalAddSubtractExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			getTypeSystemOperator(expression.operator))
-	}
-
-	def dispatch InferenceResult doInferType(NumericalMultiplyDivideExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			getTypeSystemOperator(expression.operator))
-	}
-
-	def dispatch InferenceResult doInferType(NumericalUnaryExpression expression) {
-		return inferResult(expression.operand.doInferType, getTypeSystemOperator(expression.operator))
-	}
-
-	def dispatch InferenceResult doInferType(PrimitiveValueExpression expression) {
-		return expression.value.doInferType
-	}
-
-	def dispatch InferenceResult doInferType(TypeCastExpression expression) {
-		return inferResult(expression.operand.doInferType, new InferenceResult(expression.type as Type),
-			ITypeSystem.BinaryOperators::CAST)
-	}
-
-	def dispatch InferenceResult doInferType(ShiftExpression expression) {
-		return inferResult(expression.leftOperand.doInferType, expression.rightOperand.doInferType,
-			getTypeSystemOperator(expression.operator))
-	}
-
-	def dispatch InferenceResult doInferType(ConditionalExpression expression) {
-		return inferResult(expression.condition.doInferType, expression.trueCase.doInferType,
-			expression.falseCase.doInferType, ITypeSystem.TernaryOperators::CONDITIONAL);
-	}
-
-	def dispatch InferenceResult doInferType(StringLiteral literal) {
-		return inferTypeForLiteral(literal.value);
-	}
-
-	def dispatch InferenceResult doInferType(BoolLiteral literal) {
-		return inferTypeForLiteral(literal.value);
-	}
-
-	def dispatch InferenceResult doInferType(RealLiteral literal) {
-		return inferTypeForLiteral(literal.value);
-	}
-
-	def dispatch InferenceResult doInferType(HexLiteral literal) {
-		return inferTypeForLiteral(literal.value);
-	}
-
-	def dispatch InferenceResult doInferType(IntLiteral literal) {
-		return inferTypeForLiteral(literal.value);
-	}
-
-	def dispatch InferenceResult doInferType(NullLiteral literal) {
-		return inferTypeForLiteral(null);
-	}
-
-	def dispatch InferenceResult doInferType(Literal l) {
-		throw new IllegalArgumentException("Unsupported literal kind " + l)
-	}
-
-	def dispatch InferenceResult doInferType(EObject e) {
-		return inferTypeForLiteral(e);
-	}
-
-	def dispatch InferenceResult doInferType(ParenthesizedExpression expression) {
-		return doInferType(expression.expression)
-	}
-
-	def protected dispatch ITypeSystemOperator getTypeSystemOperator(UnaryOperator operator) {
-		switch (operator) {
-			case UnaryOperator::COMPLEMENT:
-				ITypeSystem.UnaryOperators::COMPLEMENT
-			case UnaryOperator::NEGATIVE:
-				ITypeSystem.UnaryOperators::NEGATIVE
-			case UnaryOperator::POSITIVE:
-				ITypeSystem.UnaryOperators::POSITIVE
-			default:
-				throw new IllegalArgumentException("Unsupported operator" + operator)
-		}
-	}
-
-	def protected dispatch ITypeSystemOperator getTypeSystemOperator(AssignmentOperator operator) {
-		switch (operator) {
-			case AssignmentOperator::ADD_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_ADD
-			case AssignmentOperator::AND_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_BITWISE_AND
-			case AssignmentOperator::ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN
-			case AssignmentOperator::DIV_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_DIV
-			case AssignmentOperator::LEFT_SHIFT_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_LEFT_SHIFT
-			case AssignmentOperator::MOD_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_MOD
-			case AssignmentOperator::MULT_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_MULTIPLY
-			case AssignmentOperator::OR_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_BITWISE_OR
-			case AssignmentOperator::RIGHT_SHIFT_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_RIGHT_SHIFT
-			case AssignmentOperator::SUB_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_SUBTRACT
-			case AssignmentOperator::XOR_ASSIGN:
-				ITypeSystem.BinaryOperators::ASSIGN_BITWISE_XOR
-			default:
-				throw new IllegalArgumentException("Unsupported operator" + operator)
-		}
-	}
-
-	def dispatch ITypeSystemOperator getTypeSystemOperator(ShiftOperator operator) {
-		switch (operator) {
-			case ShiftOperator::LEFT:
-				ITypeSystem.BinaryOperators::LEFT_SHIFT
-			case ShiftOperator::RIGHT:
-				ITypeSystem.BinaryOperators::RIGHT_SHIFT
-			default:
-				throw new IllegalArgumentException("Unsupported operator" + operator)
-		}
-	}
-
-	def protected dispatch ITypeSystemOperator getTypeSystemOperator(AdditiveOperator operator) {
-		switch (operator) {
-			case AdditiveOperator::PLUS:
-				ITypeSystem.BinaryOperators::ADD
-			case AdditiveOperator::MINUS:
-				ITypeSystem.BinaryOperators::SUBTRACT
-			default:
-				throw new IllegalArgumentException("Unsupported operator" + operator)
-		}
-	}
-
-	def protected dispatch ITypeSystemOperator getTypeSystemOperator(MultiplicativeOperator operator) {
-		switch (operator) {
-			case MultiplicativeOperator::DIV:
-				ITypeSystem.BinaryOperators::DIV
-			case MultiplicativeOperator::MOD:
-				ITypeSystem.BinaryOperators::MOD
-			case MultiplicativeOperator::MUL:
-				ITypeSystem.BinaryOperators::MULTIPLY
-			default:
-				throw new IllegalArgumentException("Unsupported operator" + operator)
-		}
-	}
-
-	def protected dispatch ITypeSystemOperator getTypeSystemOperator(RelationalOperator operator) {
-		switch (operator) {
-			case RelationalOperator::EQUALS:
-				ITypeSystem.BinaryOperators::EQUAL
-			case RelationalOperator::NOT_EQUALS:
-				ITypeSystem.BinaryOperators::NOT_EQUAL
-			case RelationalOperator::GREATER:
-				ITypeSystem.BinaryOperators::GREATER
-			case RelationalOperator::GREATER_EQUAL:
-				ITypeSystem.BinaryOperators::GREATER_EQUAL
-			case RelationalOperator::SMALLER:
-				ITypeSystem.BinaryOperators::SMALLER
-			case RelationalOperator::SMALLER_EQUAL:
-				ITypeSystem.BinaryOperators::SMALLER_EQUAL
-			default:
-				throw new IllegalArgumentException("Unsupported operator" + operator)
-		}
-	}
-
-}

+ 200 - 0
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/ExpressionsTypeInferrer.java

@@ -0,0 +1,200 @@
+/**
+ * Copyright (c) 2014 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.inferrer;
+
+import static org.yakindu.base.types.typesystem.DefaultTypeSystem.BOOLEAN;
+import static org.yakindu.base.types.typesystem.DefaultTypeSystem.INTEGER;
+import static org.yakindu.base.types.typesystem.DefaultTypeSystem.NULL;
+import static org.yakindu.base.types.typesystem.DefaultTypeSystem.REAL;
+import static org.yakindu.base.types.typesystem.DefaultTypeSystem.STRING;
+
+import org.yakindu.base.expressions.expressions.AssignmentExpression;
+import org.yakindu.base.expressions.expressions.BitwiseAndExpression;
+import org.yakindu.base.expressions.expressions.BitwiseOrExpression;
+import org.yakindu.base.expressions.expressions.BitwiseXorExpression;
+import org.yakindu.base.expressions.expressions.BoolLiteral;
+import org.yakindu.base.expressions.expressions.ConditionalExpression;
+import org.yakindu.base.expressions.expressions.ElementReferenceExpression;
+import org.yakindu.base.expressions.expressions.FeatureCall;
+import org.yakindu.base.expressions.expressions.HexLiteral;
+import org.yakindu.base.expressions.expressions.IntLiteral;
+import org.yakindu.base.expressions.expressions.LogicalAndExpression;
+import org.yakindu.base.expressions.expressions.LogicalNotExpression;
+import org.yakindu.base.expressions.expressions.LogicalOrExpression;
+import org.yakindu.base.expressions.expressions.LogicalRelationExpression;
+import org.yakindu.base.expressions.expressions.NullLiteral;
+import org.yakindu.base.expressions.expressions.NumericalAddSubtractExpression;
+import org.yakindu.base.expressions.expressions.NumericalMultiplyDivideExpression;
+import org.yakindu.base.expressions.expressions.NumericalUnaryExpression;
+import org.yakindu.base.expressions.expressions.ParenthesizedExpression;
+import org.yakindu.base.expressions.expressions.PrimitiveValueExpression;
+import org.yakindu.base.expressions.expressions.RealLiteral;
+import org.yakindu.base.expressions.expressions.ShiftExpression;
+import org.yakindu.base.expressions.expressions.StringLiteral;
+import org.yakindu.base.expressions.expressions.TypeCastExpression;
+import org.yakindu.base.types.Type;
+import org.yakindu.base.types.inferrer.AbstractTypeSystemInferrer;
+
+/**
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implements ExpressionsTypeInferrerMessages {
+
+	public Type infer(AssignmentExpression e) {
+		Type type1 = inferType(e.getVarRef());
+		Type type2 = inferType(e.getExpression());
+		assertIsSuperType(type2, type1, String.format(ASSIGNMENT_OPERATOR, e.getOperator(), type1, type2));
+		return inferType(e.getVarRef());
+	}
+
+	public Type infer(ConditionalExpression e) {
+		Type type1 = inferType(e.getTrueCase());
+		Type type2 = inferType(e.getFalseCase());
+		assertCompatibleType(type1, type2, String.format(COMMON_TYPE, type1, type2));
+		assertType(inferType(e.getCondition()), CONDITIONAL_BOOLEAN, getType(BOOLEAN));
+		return getCommonType(type1, type2);
+	}
+
+	public Type infer(LogicalOrExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertType(type1, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
+		assertType(type2, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
+		return getType(BOOLEAN);
+	}
+
+	public Type infer(LogicalAndExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertType(type1, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
+		assertType(type2, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
+		return getType(BOOLEAN);
+	}
+
+	public Type infer(LogicalNotExpression e) {
+		Type type = inferType(e.getOperand());
+		assertType(type, String.format(LOGICAL_OPERATOR, "!", type), getType(BOOLEAN));
+		return getType(BOOLEAN);
+	}
+
+	public Type infer(BitwiseXorExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertType(type1, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
+		assertType(type2, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
+		return getType(INTEGER);
+	}
+
+	public Type infer(BitwiseOrExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertType(type1, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
+		assertType(type2, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
+		return getType(INTEGER);
+	}
+
+	public Type infer(BitwiseAndExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertType(type1, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
+		assertType(type2, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
+		return getType(INTEGER);
+	}
+
+	public Type infer(ShiftExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertType(type1, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
+		assertType(type2, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
+		return getType(INTEGER);
+	}
+
+	public Type infer(LogicalRelationExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertCompatibleType(type1, type2, String.format(COMPARSION_OPERATOR, e.getOperator(), type1, type2));
+		return getType(BOOLEAN);
+
+	}
+
+	public Type infer(NumericalAddSubtractExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertCompatibleType(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
+		assertType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
+				getType(REAL));
+		return getCommonType(e.getLeftOperand(), e.getRightOperand());
+	}
+
+	public Type infer(NumericalMultiplyDivideExpression e) {
+		Type type1 = inferType(e.getLeftOperand());
+		Type type2 = inferType(e.getRightOperand());
+		assertCompatibleType(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
+		assertType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
+				getType(REAL));
+		return getCommonType(type1, type2);
+	}
+
+	public Type infer(NumericalUnaryExpression e) {
+		Type type1 = inferType(e.getOperand());
+		assertType(type1, String.format(BITWISE_OPERATOR, '~', type1), getType(INTEGER));
+		return type1;
+	}
+
+	public Type infer(TypeCastExpression e) {
+		Type type1 = inferType(e.getOperand());
+		Type type2 = inferType(e.getType());
+		assertCompatibleType(type1, type2, String.format(CAST_OPERATORS, type1, type2));
+		return e.getType();
+	}
+
+	public Type infer(FeatureCall e) {
+		return inferType(e.getFeature());
+	}
+
+	public Type infer(ElementReferenceExpression e) {
+		return inferType(e.getReference());
+	}
+
+	public Type infer(ParenthesizedExpression e) {
+		return inferType(e.getExpression());
+	}
+
+	public Type infer(PrimitiveValueExpression e) {
+		return inferType(e.getValue());
+	}
+
+	public Type infer(BoolLiteral literal) {
+		return getType(BOOLEAN);
+	}
+
+	public Type infer(IntLiteral literal) {
+		return getType(INTEGER);
+	}
+
+	public Type infer(HexLiteral literal) {
+		return getType(INTEGER);
+	}
+
+	public Type infer(RealLiteral literal) {
+		return getType(REAL);
+	}
+
+	public Type infer(StringLiteral literal) {
+		return getType(STRING);
+	}
+
+	public Type infer(NullLiteral literal) {
+		return getType(NULL);
+	}
+
+}

+ 34 - 0
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/ExpressionsTypeInferrerMessages.java

@@ -0,0 +1,34 @@
+package org.yakindu.base.expressions.inferrer;
+
+public interface ExpressionsTypeInferrerMessages {
+
+	public static final String LOGICAL_OPERATOR = "Logical operator '%s' may only be applied on boolean types, not on %s.";
+	public static final String LOGICAL_OPERATORS = "Logical operator '%s' may only be applied on boolean types, not on %s and %s.";
+	public static final String COMPARSION_OPERATOR = "Comparison operator '%s' may only be applied on compatible types, not on %s and %s.";
+	public static final String BITWISE_OPERATOR = "Bitwise operator '%s' may only be applied on integer types, not on %s.";
+	public static final String BITWISE_OPERATORS = "Bitwise operator '%s' may only be applied on integer types, not on %s and %s.";
+	public static final String ASSIGNMENT_OPERATOR = "Assignment operator '%s' may only be applied on compatible types, not on %s and %s.";
+	public static final String ARITHMETIC_OPERATOR = "Arithmetic operator '%s' may only be applied on numeric types, not on %s.";
+	public static final String ARITHMETIC_OPERATORS = "Arithmetic operator '%s' may only be applied on numeric types, not on %s and %s.";
+	public static final String COMMON_TYPE = "Could not determine a common type for %s and %s.";
+	public static final String CONDITIONAL_BOOLEAN = "conditional expression must be of type boolean.";
+	public static final String CAST_OPERATORS = "Cannot cast from %s to %s.";
+	
+//	public static final String COULD_NOT_INFER_A_TYPE_FOR_THE_OPERATION_NO_TYPE = "Could not infer a type for the operation %s, because no type was inferred for its operand.";
+//	public static final String COULD_NOT_INFER_A_TYPE_FOR_THE_OPERATION_NOT_INFERRED = "Could not infer a type for the operation %s, because types were not inferred for all of its operands.";
+//
+//	public static final String OPERATOR_MAY_ONLY_BE_APPLIED_ON_A_PRIMITIVE_TYPE = "Operator %s may only be applied on a primitive type.";
+//
+//	public static final String BITWISE_OPERATOR_MAY_ONLY_BE_APPLIED_ON_INTEGER_TYPES = "Bitwise operator '%s' may only be applied on integer types, not on %s.";
+//
+//	public static final String ARITHMETIC_OPERATORS_MAY_ONLY_BE_APPLIED_ON_NUMERIC_TYPES_2 = "Arithmetic operator '%s' may only be applied on numeric types, not on %s and %s.";
+//
+//	public static final String LOGICAL_OPERATORS_MAY_ONLY_BE_APPLIED_ON_BOOLEAN_TYPES = "Logical operator '%s' may only be applied on boolean types, not on %s.";
+//
+//	public static final String COMPARSION_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES = "Comparison operator '%s' may only be applied on compatible types, not on %s and %s.";
+//
+//	public static final String ASSIGNMENT_AND_EQUALITY_OPERATIONS_MAY_ONLY_BE_APPLIED_ON_TYPES_OF_THE_SAME_KIND = "Assignment and equality operations may only be applied on types of the same kind, not on %s and %s.";
+//
+//
+//	
+}

+ 0 - 33
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/IExpressionsTypeInferrer.java

@@ -1,33 +0,0 @@
-/**
- * Copyright (c) 2014 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.expressions.inferrer;
-
-import org.yakindu.base.expressions.expressions.Expression;
-import org.yakindu.base.types.InferenceResult;
-
-import com.google.inject.ImplementedBy;
-
-/**
- * 
- * @author andreas muelder - Initial contribution and API
- * 
- */
-@ImplementedBy(DefaultExpressionsTypeInferrer.class)
-public interface IExpressionsTypeInferrer {
-
-	/**
-	 * Infers the type for a given {@link Expression}
-	 * 
-	 */
-	InferenceResult inferType(Expression e);
-
-}

+ 140 - 0
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/interpreter/ExpressionsTypeInterpreter.java

@@ -0,0 +1,140 @@
+package org.yakindu.base.expressions.interpreter;
+
+import org.eclipse.emf.ecore.EObject;
+import org.yakindu.base.expressions.expressions.AssignmentExpression;
+import org.yakindu.base.expressions.expressions.BitwiseAndExpression;
+import org.yakindu.base.expressions.expressions.BitwiseOrExpression;
+import org.yakindu.base.expressions.expressions.BitwiseXorExpression;
+import org.yakindu.base.expressions.expressions.BoolLiteral;
+import org.yakindu.base.expressions.expressions.ConditionalExpression;
+import org.yakindu.base.expressions.expressions.ElementReferenceExpression;
+import org.yakindu.base.expressions.expressions.FeatureCall;
+import org.yakindu.base.expressions.expressions.HexLiteral;
+import org.yakindu.base.expressions.expressions.IntLiteral;
+import org.yakindu.base.expressions.expressions.LogicalAndExpression;
+import org.yakindu.base.expressions.expressions.LogicalNotExpression;
+import org.yakindu.base.expressions.expressions.LogicalOrExpression;
+import org.yakindu.base.expressions.expressions.LogicalRelationExpression;
+import org.yakindu.base.expressions.expressions.NullLiteral;
+import org.yakindu.base.expressions.expressions.NumericalAddSubtractExpression;
+import org.yakindu.base.expressions.expressions.NumericalMultiplyDivideExpression;
+import org.yakindu.base.expressions.expressions.NumericalUnaryExpression;
+import org.yakindu.base.expressions.expressions.ParenthesizedExpression;
+import org.yakindu.base.expressions.expressions.PrimitiveValueExpression;
+import org.yakindu.base.expressions.expressions.RealLiteral;
+import org.yakindu.base.expressions.expressions.ShiftExpression;
+import org.yakindu.base.expressions.expressions.StringLiteral;
+import org.yakindu.base.expressions.expressions.TypeCastExpression;
+import org.yakindu.base.types.Type;
+import org.yakindu.base.types.interpreter.AbstractTypeSystemInterpreter;
+
+public class ExpressionsTypeInterpreter extends AbstractTypeSystemInterpreter {
+
+	public Object interpret(AssignmentExpression e) {
+		return null;
+	}
+
+	public Object interpret(ConditionalExpression e) {
+		return null;
+	}
+
+	public Object interpret(LogicalOrExpression e) {
+		return null;
+	}
+
+	public Object interpret(LogicalAndExpression e) {
+		return null;
+	}
+
+	public Object interpret(LogicalNotExpression e) {
+		return null;
+	}
+
+	public Object interpret(BitwiseXorExpression e) {
+		return null;
+	}
+
+	public Object interpret(BitwiseOrExpression e) {
+		return null;
+	}
+
+	public Object interpret(BitwiseAndExpression e) {
+		return null;
+	}
+
+	public Object interpret(ShiftExpression e) {
+		return null;
+	}
+
+	public Object interpret(LogicalRelationExpression e) {
+		return null;
+
+	}
+
+	public Object interpret(NumericalAddSubtractExpression e) {
+		return null;
+	}
+
+	public Object interpret(NumericalMultiplyDivideExpression e) {
+		return null;
+	}
+
+	public Object interpret(NumericalUnaryExpression e) {
+		return null;
+	}
+
+	public Object interpret(TypeCastExpression e) {
+		return null;
+	}
+
+	public Object interpret(FeatureCall e) {
+		return null;
+	}
+
+	public Object interpret(ElementReferenceExpression e) {
+		return interpretExpression(e.getReference());
+	}
+
+	public Object interpret(ParenthesizedExpression e) {
+		return interpretExpression(e.getExpression());
+	}
+
+	public Object interpret(PrimitiveValueExpression e) {
+		return interpretExpression(e.getValue());
+	}
+
+	public Object interpret(BoolLiteral literal) {
+		return literal.isValue();
+	}
+
+	public Object interpret(IntLiteral literal) {
+		return literal.getValue();
+	}
+
+	public Object interpret(HexLiteral literal) {
+		return literal.getValue();
+	}
+
+	public Object interpret(RealLiteral literal) {
+		return literal.getValue();
+	}
+
+	public Object interpret(StringLiteral literal) {
+		return literal.getValue();
+	}
+
+	public Object interpret(NullLiteral literal) {
+		return null;
+	}
+
+	public Object interpret(EObject object) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object defaultValue(Type type) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

+ 27 - 38
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/validation/ExpressionsJavaValidator.java

@@ -14,21 +14,18 @@ package org.yakindu.base.expressions.validation;
 import java.util.Set;
 
 import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.util.EcoreUtil;
 import org.eclipse.xtext.validation.Check;
 import org.yakindu.base.expressions.expressions.Expression;
-import org.yakindu.base.expressions.inferrer.IExpressionsTypeInferrer;
 import org.yakindu.base.types.ComplexType;
-import org.yakindu.base.types.InferenceIssue;
-import org.yakindu.base.types.InferenceResult;
 import org.yakindu.base.types.ParameterizedType;
 import org.yakindu.base.types.Type;
 import org.yakindu.base.types.TypeParameter;
 import org.yakindu.base.types.TypedElement;
 import org.yakindu.base.types.TypesPackage;
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer;
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer.ITypeTraceAcceptor;
+import org.yakindu.base.types.typesystem.ITypeSystem;
 
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import com.google.inject.Inject;
 
@@ -37,7 +34,8 @@ import com.google.inject.Inject;
  * @author andreas muelder - Initial contribution and API
  * 
  */
-public class ExpressionsJavaValidator extends org.yakindu.base.expressions.validation.AbstractExpressionsJavaValidator {
+public class ExpressionsJavaValidator extends org.yakindu.base.expressions.validation.AbstractExpressionsJavaValidator
+		implements ITypeTraceAcceptor {
 
 	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";
@@ -61,7 +59,27 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 	private GenericsPrettyPrinter printer;
 
 	@Inject
-	private IExpressionsTypeInferrer typeInferrer;
+	private ITypeSystemInferrer typeInferrer;
+	@Inject
+	private ITypeSystem typeSystem;
+
+	@Check
+	public void checkExpression(Expression expression) {
+		typeInferrer.inferType(expression, this);
+	}
+
+	public void accept(TypeTrace trace) {
+		switch (trace.getSeverity()) {
+		case ERROR:
+			error(trace.getMessage(), null);
+			break;
+		case WARNING:
+			warning(trace.getMessage(), null);
+			break;
+		case INFO:
+			break;
+		}
+	}
 
 	@Check
 	public void checkIsRaw(TypedElement typedElement) {
@@ -133,7 +151,7 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 			TypeParameter parameter = typeParameter.get(i);
 			if (parameter.getBound() != null) {
 				Type argument = typedElement.getTypeArguments().get(i);
-				if (!isTypeCompatible(parameter.getBound(), argument)) {
+				if (!typeSystem.isSuperType(parameter.getBound(), argument)) {
 					error(String.format(ERROR_BOUND_MISSMATCH_MSG, argument.getName(),
 							(parameter.getBound()).getName(), type.getName()), typedElement,
 							TypesPackage.Literals.TYPED_ELEMENT__TYPE_ARGUMENTS, i, ERROR_BOUND_MISSMATCH_CODE);
@@ -152,33 +170,4 @@ public class ExpressionsJavaValidator extends org.yakindu.base.expressions.valid
 			}
 		}
 	}
-
-	@Check
-	public void checkExpressionIsTypeCompatible(Expression expression) {
-		try {
-			InferenceResult result = typeInferrer.inferType(expression);
-			report(result, null);
-		} catch (IllegalArgumentException e) {
-			// ignore unknown literals here, as this also happens when a
-			// linking problem occurred, which is handled in other locations
-		}
-	}
-	
-	protected void report(InferenceResult result, EStructuralFeature feature) {
-		if (result.getIssues().isEmpty())
-			return;
-		InferenceIssue error = Iterables.getLast(result.getIssues());
-		error(error.getMessage(), feature);
-	}
-
-	// TODO: USE ITypeSystem
-	private boolean isTypeCompatible(Type bound, Type argument) {
-		if (EcoreUtil.equals(bound, argument))
-			return true;
-		if (argument instanceof ComplexType && ((ComplexType) argument).getSuperTypes().size() > 0) {
-			ComplexType superType = ((ComplexType) argument).getSuperTypes().get(0);
-			return isTypeCompatible(bound, superType);
-		}
-		return false;
-	}
 }

+ 1 - 1
plugins/org.yakindu.base.types.scope/src/org/yakindu/base/types/scope/TypeSystemAwareScope.java

@@ -20,8 +20,8 @@ import org.eclipse.xtext.resource.IEObjectDescription;
 import org.eclipse.xtext.scoping.IScope;
 import org.eclipse.xtext.scoping.Scopes;
 import org.eclipse.xtext.scoping.impl.AbstractScope;
-import org.yakindu.base.types.ITypeSystem;
 import org.yakindu.base.types.ITypeSystemRegistry;
+import org.yakindu.base.types.typesystem.ITypeSystem;
 
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;

+ 0 - 2
plugins/org.yakindu.base.types/.settings/org.eclipse.core.resources.prefs

@@ -1,5 +1,3 @@
 eclipse.preferences.version=1
 encoding//model/types.ecorediag=UTF-8
-encoding//src/org/yakindu/base/types/AbstractTypeSystem.java=UTF-8
-encoding//src/org/yakindu/base/types/ITypeSystem.java=UTF-8
 encoding/<project>=UTF-8

+ 5 - 1
plugins/org.yakindu.base.types/META-INF/MANIFEST.MF

@@ -12,6 +12,9 @@ Export-Package: org.yakindu.base.base,
  org.yakindu.base.base.util,
  org.yakindu.base.types,
  org.yakindu.base.types.impl,
+ org.yakindu.base.types.inferrer,
+ org.yakindu.base.types.interpreter,
+ org.yakindu.base.types.typesystem,
  org.yakindu.base.types.util
 Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.emf.ecore;visibility:=reexport,
@@ -20,6 +23,7 @@ Require-Bundle: org.eclipse.core.runtime,
  com.google.inject;bundle-version="2.0.0",
  org.eclipse.xtend.lib,
  com.google.guava,
- org.eclipse.xtext.xbase.lib
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.xtext.util;bundle-version="2.7.2"
 Bundle-ActivationPolicy: lazy
 

+ 1 - 1
plugins/org.yakindu.base.types/plugin.xml

@@ -17,7 +17,7 @@
          point="org.yakindu.base.types.typesystem">
       <contribution
             scheme="default"
-            typesystem="org.yakindu.base.types.DefaultTypeSystem">
+            typesystem="org.yakindu.base.types.typesystem.DefaultTypeSystem">
       </contribution>
    </extension>
    <extension point="org.eclipse.emf.ecore.generated_package">

+ 0 - 100
plugins/org.yakindu.base.types/src/org/yakindu/base/types/AbstractTypeSystem.java

@@ -1,100 +0,0 @@
-/**
- * Copyright (c) 2014 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;
-
-import org.eclipse.emf.ecore.util.EcoreUtil;
-
-/**
- * Abstract base implementation of an {@link ITypeSystem}. Delivers only utility
- * methods that are helpful to create a {@link ITypeSystem} implementation, and
- * does not implement any of the {@link ITypeSystem} methods itself.
- * 
- * @author Alexander Nyßen (alexander.nyssen@itemis.de) - Initial contribution
- *         and API
- * 
- */
-public abstract class AbstractTypeSystem implements ITypeSystem {
-
-	/**
-	 * Computes the {@link PrimitiveType} that within the base type hierarchy of
-	 * the two given {@link PrimitiveType}s is their closest ancestor. This may
-	 * also be one of the two given {@link PrimitiveType}s in case they are
-	 * equal or one is the ancestor of the other.
-	 * 
-	 * @param firstType
-	 *            The first {@link PrimitiveType} to evaluate
-	 * @param secondType
-	 *            The second {@link PrimitiveType} to evaluate
-	 * @return The first type if it is equal or an ancestor of the second one,
-	 *         otherwise the nearest common ancestor if it exists or
-	 *         <code>null</code> null otherwise.
-	 */
-	protected Type computeCommonType(PrimitiveType firstType,
-			PrimitiveType secondType) {
-		if (isEqualOrAncestor(firstType, secondType)) {
-			return secondType;
-		} else {
-			// compute common ancestor, if exists
-			PrimitiveType baseType = secondType;
-			while (baseType != null) {
-				if (isEqualOrAncestor(baseType, firstType)) {
-					return baseType;
-				}
-				baseType = baseType.getBaseType();
-			}
-			return null;
-		}
-	}
-
-	/**
-	 * Checks whether the first given type is equal to or an ancestor of the
-	 * second type within its base type hierarchy.
-	 * 
-	 * @param first
-	 *            The first {@link PrimitiveType} to evaluate
-	 * @param second
-	 *            The second {@link PrimitiveType} to evaluate
-	 * @return <code>true</code> if the first type is equal to or an ancestor of
-	 *         the second type, <code>false</code> otherwise.
-	 */
-	private boolean isEqualOrAncestor(PrimitiveType firstType,
-			PrimitiveType secondType) {
-		PrimitiveType baseType = secondType;
-		// iterate the base type hierarchy of the second type and see if the
-		// first type can be found within
-		while (baseType != null) {
-			if (EcoreUtil.equals(firstType, baseType)) {
-				return true;
-			}
-			baseType = secondType.getBaseType();
-		}
-		return false;
-	}
-
-	/**
-	 * Returns the top-most type within the base type hierarchy of the given
-	 * {@link PrimitiveType}.
-	 * 
-	 * @param primitiveType
-	 *            The {@link PrimitiveType} whose base type is to be retrieved
-	 * @return The top-most base type for the given {@link PrimitiveType}, or
-	 *         the type itself if no base type is specified
-	 */
-	protected PrimitiveType getBaseType(PrimitiveType primitiveType) {
-		PrimitiveType baseType = primitiveType;
-		while (baseType.getBaseType() != null) {
-			baseType = baseType.getBaseType();
-		}
-		return baseType;
-	}
-
-}

+ 0 - 615
plugins/org.yakindu.base.types/src/org/yakindu/base/types/DefaultTypeSystem.java

@@ -1,615 +0,0 @@
-/**
- * Copyright (c) 2014 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;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-
-import com.google.inject.Singleton;
-
-/**
- * Default implementation of an {@link ITypeSystem}.. The type system offers
- * exactly five types, namely the primitives <code>void</code>,
- * <code>boolean</code>, <code>integer</code>, <code>real</code>,
- * <code>string</code>.
- * 
- * @author Alexander Ny��en (alexander.nyssen@itemis.de) - Initial contribution
- *         and API
- * @author oliver bohl - String constants extract
- * 
- * @author andreas muelder - Added type casts
- * 
- */
-@Singleton
-public class DefaultTypeSystem extends AbstractTypeSystem implements ITypeSystem {
-
-	public static final String COULD_NOT_INFER_A_TYPE_FOR_THE_OPERATION_NO_TYPE = "Could not infer a type for the operation %s, because no type was inferred for its operand.";
-	public static final String COULD_NOT_INFER_A_TYPE_FOR_THE_OPERATION_NOT_INFERRED = "Could not infer a type for the operation %s, because types were not inferred for all of its operands.";
-
-	public static final String OPERATOR_MAY_ONLY_BE_APPLIED_ON_A_PRIMITIVE_TYPE = "Operator %s may only be applied on a primitive type.";
-
-	public static final String BITWISE_OPERATOR_MAY_ONLY_BE_APPLIED_ON_INTEGER_TYPES = "Bitwise operator '%s' may only be applied on integer types, not on %s.";
-	public static final String BITWISE_OPERATOR_MAY_ONLY_BE_APPLIED_ON_INTEGER_TYPES_2 = "Bitwise operator '%s' may only be applied on integer types, not on %s and %s.";
-
-	public static final String ARITHMETIC_OPERATORS_MAY_ONLY_BE_APPLIED_ON_NUMERIC_TYPES = "Arithmetic operator '%s' may only be applied on numeric types, not on %s";
-	public static final String ARITHMETIC_OPERATORS_MAY_ONLY_BE_APPLIED_ON_NUMERIC_TYPES_2 = "Arithmetic operator '%s' may only be applied on numeric types, not on %s and %s.";
-
-	public static final String LOGICAL_OPERATORS_MAY_ONLY_BE_APPLIED_ON_BOOLEAN_TYPES = "Logical operator '%s' may only be applied on boolean types, not on %s.";
-	public static final String LOGICAL_OPERATORS_MAY_ONLY_BE_APPLIED_ON_BOOLEAN_TYPES_2 = "Logical operator '%s' may only be applied on boolean types, not on %s and %s.";
-
-	public static final String COMPARSION_OPERATOR_MAY_ONLY_BE_APPLIED_ON_PRIMITIVE_TYPES = "Comparison operator '%s' may only be applied on primitive types, not on %s and %s.";
-	public static final String COMPARSION_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES = "Comparison operator '%s' may only be applied on compatible types, not on %s and %s.";
-
-	public static final String ASSIGNMENT_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES = "Assignment operator '%s' may only be applied on compatible types, not on %s and %s.";
-	public static final String ASSIGNMENT_AND_EQUALITY_OPERATIONS_MAY_ONLY_BE_APPLIED_ON_TYPES_OF_THE_SAME_KIND = "Assignment and equality operations may only be applied on types of the same kind, not on %s and %s.";
-
-	public static String NO_VALID_TYPE_CAN_BE_INFERRED_FOR_CONDITIONAL_EXPRESSION_BECAUSE_FIRST_OPERAND_NOT_BOOLEAN = "No valid type can be inferred for conditional expression, because type of first operand is not boolean.";
-
-	public static String CANNOT_CAST_FROM_TO = "Cannot cast from %s to %s.";
-
-	/**
-	 * Dummy resource. Xtext linker expects types to be contained in a resource.
-	 */
-	private static Resource resource;
-	private static PrimitiveType voidType;
-	private static PrimitiveType stringType;
-	private static PrimitiveType realType;
-	private static PrimitiveType integerType;
-	private static PrimitiveType booleanType;
-
-	protected static synchronized Resource getResource() {
-		if (resource == null) {
-			resource = new ResourceImpl();
-			// use old uri for backwards compatibility
-			resource.setURI(URI.createURI("platform:/plugin/org.yakindu.sct.model.stext/libraries/Primitives.types"));
-		}
-		return resource;
-	}
-
-	private PrimitiveType nullType;
-
-	public Type getBooleanType() {
-		synchronized (DefaultTypeSystem.class) {
-			if (booleanType == null) {
-				booleanType = TypesFactory.eINSTANCE.createPrimitiveType();
-				booleanType.setName("boolean");
-				getResource().getContents().add(booleanType);
-			}
-			return booleanType;
-		}
-	}
-
-	public Type getIntegerType() {
-		synchronized (DefaultTypeSystem.class) {
-			if (integerType == null) {
-				integerType = TypesFactory.eINSTANCE.createPrimitiveType();
-				integerType.setName("integer");
-				getResource().getContents().add(integerType);
-			}
-			return integerType;
-		}
-	}
-
-	public Type getRealType() {
-		synchronized (DefaultTypeSystem.class) {
-			if (realType == null) {
-				realType = TypesFactory.eINSTANCE.createPrimitiveType();
-				realType.setName("real");
-				getResource().getContents().add(realType);
-			}
-			return realType;
-		}
-	}
-
-	public Type getStringType() {
-		synchronized (DefaultTypeSystem.class) {
-			if (stringType == null) {
-				stringType = TypesFactory.eINSTANCE.createPrimitiveType();
-				stringType.setName("string");
-				getResource().getContents().add(stringType);
-			}
-			return stringType;
-		}
-	}
-
-	public Type getVoidType() {
-		synchronized (DefaultTypeSystem.class) {
-			if (voidType == null) {
-				voidType = TypesFactory.eINSTANCE.createPrimitiveType();
-				voidType.setName("void");
-				getResource().getContents().add(voidType);
-			}
-			return voidType;
-		}
-	}
-
-	private Type getNullType() {
-		synchronized (DefaultTypeSystem.class) {
-			if (nullType == null) {
-				nullType = TypesFactory.eINSTANCE.createPrimitiveType();
-				nullType.setName("null");
-				getResource().getContents().add(nullType);
-			}
-			return nullType;
-		}
-	}
-
-	public InferenceResult inferTypeForLiteral(Object literal) {
-		if (literal instanceof String) {
-			return new InferenceResult(getStringType());
-		} else if (literal instanceof Boolean) {
-			return new InferenceResult(getBooleanType());
-		} else if (literal instanceof Integer) {
-			return new InferenceResult(getIntegerType());
-		} else if (literal instanceof Double) {
-			return new InferenceResult(getRealType());
-		} else if (literal == null) {
-			return new InferenceResult(getNullType());
-		}
-		throw new IllegalArgumentException("Literal of unknown kind " + literal);
-	}
-
-	public InferenceResult inferType(InferredType operandType, ITypeSystemOperator unaryOperator) {
-		// some defense programming
-		if (operandType == null) {
-			throw new NullPointerException("operandType may not be null.");
-		}
-
-		// if the operand type could not be inferred, there is not much we can
-		// do here
-		if (operandType.getType() == null) {
-			return new InferenceResult(null, new InferenceIssue(String.format(
-					COULD_NOT_INFER_A_TYPE_FOR_THE_OPERATION_NO_TYPE, unaryOperator.getSymbol()), IStatus.ERROR));
-		}
-
-		// check we have a primitive type
-		if (!(operandType.getType() instanceof PrimitiveType)) {
-			return new InferenceResult(null, new InferenceIssue(
-
-			String.format(OPERATOR_MAY_ONLY_BE_APPLIED_ON_A_PRIMITIVE_TYPE, unaryOperator.getSymbol()), IStatus.ERROR));
-		}
-
-		// infer type based on given operator
-		UnaryOperators o = (UnaryOperators) unaryOperator;
-		switch (o) {
-		case COMPLEMENT:
-			if (!isIntegerType(operandType.getType())) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						BITWISE_OPERATOR_MAY_ONLY_BE_APPLIED_ON_INTEGER_TYPES, o.getSymbol(), operandType.getType()
-								.getName()), IStatus.ERROR));
-			}
-			return new InferenceResult(operandType);
-		case NEGATIVE:
-		case POSITIVE:
-			if (!isIntegerType(operandType.getType()) && !isRealType(operandType.getType())) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						ARITHMETIC_OPERATORS_MAY_ONLY_BE_APPLIED_ON_NUMERIC_TYPES, o.getSymbol(), operandType.getType()
-								.getName()), IStatus.ERROR));
-			}
-			return new InferenceResult(operandType);
-		case LOGICAL_NOT:
-			if (!isBooleanType(operandType.getType())) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						LOGICAL_OPERATORS_MAY_ONLY_BE_APPLIED_ON_BOOLEAN_TYPES, o.getSymbol(), operandType.getType()
-								.getName()), IStatus.ERROR));
-
-			}
-			return new InferenceResult(operandType);
-		default:
-			throw new IllegalArgumentException("Unsupported unary operator: " + unaryOperator);
-		}
-	}
-
-	public InferenceResult inferType(InferredType firstOperandType, InferredType secondOperandType,
-			ITypeSystemOperator binaryOperator) {
-		// some defense programming
-		if (firstOperandType == null || secondOperandType == null) {
-			throw new NullPointerException("Operand types may not be null.");
-		}
-
-		// if the operand type could not be inferred, there is not much we can
-		// do here
-		if (firstOperandType.getType() == null || secondOperandType.getType() == null) {
-			return new InferenceResult(null, new InferenceIssue(String.format(
-					COULD_NOT_INFER_A_TYPE_FOR_THE_OPERATION_NOT_INFERRED, binaryOperator.getSymbol()), IStatus.ERROR));
-		}
-		// TODO:
-		if (firstOperandType.getType() instanceof TypeParameter || secondOperandType.getType() instanceof TypeParameter)
-			return null;
-
-		// infer type base on operator (fist pass: check types are valid, second
-		// pass: compute result type)
-		BinaryOperators o = (BinaryOperators) binaryOperator;
-		switch (o) {
-		case BITWISE_OR:
-		case BITWISE_XOR:
-		case BITWISE_AND:
-		case RIGHT_SHIFT:
-		case LEFT_SHIFT:
-		case ASSIGN_BITWISE_AND:
-		case ASSIGN_BITWISE_OR:
-		case ASSIGN_BITWISE_XOR:
-		case ASSIGN_LEFT_SHIFT:
-		case ASSIGN_RIGHT_SHIFT:
-			// check only integer types are used
-			if (!isIntegerType(firstOperandType.getType()) || !isIntegerType(secondOperandType.getType())) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						BITWISE_OPERATOR_MAY_ONLY_BE_APPLIED_ON_INTEGER_TYPES_2, o.getSymbol(), firstOperandType
-								.getType().getName(), secondOperandType.getType().getName()), IStatus.ERROR));
-			}
-			// second pass: compute common type
-			switch (o) {
-			case BITWISE_OR:
-			case BITWISE_XOR:
-			case BITWISE_AND:
-				// compute union type
-				return union(firstOperandType, secondOperandType);
-			case RIGHT_SHIFT:
-			case LEFT_SHIFT:
-			case ASSIGN_LEFT_SHIFT:
-			case ASSIGN_RIGHT_SHIFT:
-			case ASSIGN_BITWISE_AND:
-			case ASSIGN_BITWISE_OR:
-			case ASSIGN_BITWISE_XOR:
-				// return type of assignment target
-				return new InferenceResult(firstOperandType);
-			default:
-				throw new IllegalStateException("Unsupported operator kind.");
-			}
-		case ADD:
-		case SUBTRACT:
-		case MULTIPLY:
-		case DIV:
-		case MOD:
-			// only numeric types
-			if (!isNumericType(firstOperandType.getType()) || !isNumericType(secondOperandType.getType())) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						ARITHMETIC_OPERATORS_MAY_ONLY_BE_APPLIED_ON_NUMERIC_TYPES_2, o.getSymbol(), firstOperandType
-								.getType().getName(), secondOperandType.getType().getName()), IStatus.ERROR));
-			}
-
-			// second pass: compute type
-			switch (o) {
-			case ADD:
-			case SUBTRACT:
-			case MULTIPLY:
-			case DIV:
-			case MOD:
-				return union(firstOperandType, secondOperandType);
-			case ASSIGN_ADD:
-			case ASSIGN_SUBTRACT:
-			case ASSIGN_MULTIPLY:
-			case ASSIGN_DIV:
-			case ASSIGN_MOD:
-				// return type of assignment target
-				return new InferenceResult(firstOperandType);
-			default:
-				throw new IllegalStateException("Unsupported operator kind.");
-			}
-		case ASSIGN_ADD:
-		case ASSIGN_SUBTRACT:
-		case ASSIGN_MULTIPLY:
-		case ASSIGN_DIV:
-		case ASSIGN_MOD:
-			// only numeric types
-			if (!EcoreUtil.equals(firstOperandType.getType(), secondOperandType.getType())) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						ASSIGNMENT_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES, o.getSymbol(), firstOperandType
-								.getType().getName(), secondOperandType.getType().getName()), IStatus.ERROR));
-			}
-
-			// second pass: compute type
-			switch (o) {
-			case ADD:
-			case SUBTRACT:
-			case MULTIPLY:
-			case DIV:
-			case MOD:
-				return union(firstOperandType, secondOperandType);
-			case ASSIGN_ADD:
-			case ASSIGN_SUBTRACT:
-			case ASSIGN_MULTIPLY:
-			case ASSIGN_DIV:
-			case ASSIGN_MOD:
-				// return type of assignment target
-				return new InferenceResult(firstOperandType);
-			default:
-				throw new IllegalStateException("Unsupported operator kind.");
-			}
-		case LOGICAL_OR:
-		case LOGICAL_AND:
-			// only boolean types allowed
-			if (!isBooleanType(firstOperandType.getType()) || !isBooleanType(secondOperandType.getType())) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						LOGICAL_OPERATORS_MAY_ONLY_BE_APPLIED_ON_BOOLEAN_TYPES_2, o.getSymbol(), firstOperandType
-								.getType().getName(), secondOperandType.getType().getName()), IStatus.ERROR));
-			}
-
-			// second pass: compute type
-			switch (o) {
-			case LOGICAL_OR:
-			case LOGICAL_AND:
-				return union(firstOperandType, secondOperandType);
-			default:
-				throw new IllegalStateException("Unsupported operator kind.");
-			}
-		case GREATER:
-		case GREATER_EQUAL:
-		case SMALLER:
-		case SMALLER_EQUAL:
-			// check we have primitive types
-			if (!(firstOperandType.getType() instanceof PrimitiveType)
-					|| !(secondOperandType.getType() instanceof PrimitiveType)) {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						COMPARSION_OPERATOR_MAY_ONLY_BE_APPLIED_ON_PRIMITIVE_TYPES, o.getSymbol(), firstOperandType
-								.getType().getName(), secondOperandType.getType().getName()), IStatus.ERROR));
-			}
-			// check types have the same base type
-			if (!EcoreUtil.equals(getBaseType((PrimitiveType) firstOperandType.getType()),
-					getBaseType((PrimitiveType) secondOperandType.getType()))) {
-				// exclude coercion case (integer -> real)
-				if (!(isNumericType(firstOperandType.getType()) && isNumericType(secondOperandType.getType()))) {
-					return new InferenceResult(null, new InferenceIssue(String.format(
-							COMPARSION_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES, o.getSymbol(),
-							firstOperandType.getType(), secondOperandType.getType(), secondOperandType.getType()
-									.getName()), IStatus.ERROR));
-				}
-
-			}
-			// expression has boolean type
-			return new InferenceResult(new InferredType(getBooleanType()));
-		case EQUAL:
-		case NOT_EQUAL:
-		case ASSIGN:
-			// complex types are allowed here
-			if (firstOperandType.getType() instanceof PrimitiveType
-					&& secondOperandType.getType() instanceof PrimitiveType) {
-				// check primitive types have the same base type
-				if (!EcoreUtil.equals(getBaseType((PrimitiveType) firstOperandType.getType()),
-						getBaseType((PrimitiveType) secondOperandType.getType()))) {
-					// handle coercion
-					if (!(isNumericType(firstOperandType.getType()) && isNumericType(secondOperandType.getType()))) {
-
-						return new InferenceResult(null, o.equals(BinaryOperators.ASSIGN) ? new InferenceIssue(
-								String.format(ASSIGNMENT_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES, o
-										.getSymbol(), firstOperandType.getType().getName(), secondOperandType.getType()
-										.getName()), IStatus.ERROR)
-
-						: new InferenceIssue(String.format(COMPARSION_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES,
-								o.getSymbol(), firstOperandType.getType().getName(), secondOperandType.getType()
-										.getName()),
-
-						IStatus.ERROR));
-					} else {
-						if (o.equals(BinaryOperators.ASSIGN) && !isRealType(firstOperandType.getType())
-								&& isRealType(secondOperandType.getType())) {
-							// may only assign integer to real, not vice versa
-							return new InferenceResult(null, new InferenceIssue(String.format(
-									ASSIGNMENT_OPERATOR_MAY_ONLY_BE_APPLIED_ON_COMPATIBLE_TYPES, o.getSymbol(),
-									firstOperandType.getType().getName(), secondOperandType.getType().getName()),
-									IStatus.ERROR));
-						}
-					}
-				}
-			} else if (firstOperandType.getType() instanceof ComplexType
-					&& secondOperandType.getType() instanceof ComplexType) {
-				// no further checks for complex types required here
-				// (computation of type in second pass will result in null, if
-				// they are not compatible)
-			} else if ((firstOperandType.getType() == getNullType() && secondOperandType.getType() instanceof ComplexType)
-					|| (firstOperandType.getType() instanceof ComplexType && secondOperandType.getType() == getNullType())) {
-				// no further checks required
-			} else {
-				return new InferenceResult(null, new InferenceIssue(String.format(
-						ASSIGNMENT_AND_EQUALITY_OPERATIONS_MAY_ONLY_BE_APPLIED_ON_TYPES_OF_THE_SAME_KIND,
-						firstOperandType.getType().getName(), secondOperandType.getType().getName()), IStatus.ERROR));
-			}
-
-			// second pass, compute types
-			switch (o) {
-			case ASSIGN:
-				// type of assignment target
-				return new InferenceResult(firstOperandType);
-			case EQUAL:
-			case NOT_EQUAL:
-				// boolean type
-				return new InferenceResult(new InferredType(getBooleanType()));
-			default:
-				throw new IllegalStateException("Unsupported operator kind.");
-			}
-		case CAST:
-			if (firstOperandType.getType() instanceof PrimitiveType
-					&& secondOperandType.getType() instanceof PrimitiveType) {
-				if (!EcoreUtil.equals(firstOperandType.getType(), secondOperandType.getType())) {
-					if (!isNumericType(firstOperandType) || !isNumericType(secondOperandType)) {
-						return new InferenceResult(null, new InferenceIssue(String.format(CANNOT_CAST_FROM_TO,
-								firstOperandType.getType().getName(), secondOperandType.getType().getName()),
-								IStatus.ERROR));
-					}
-				}
-			}
-			return new InferenceResult(secondOperandType);
-		default:
-			throw new IllegalArgumentException("Unsupported binary operator: " + binaryOperator);
-		}
-	}
-
-	public InferenceResult inferType(InferredType firstOperandType, InferredType secondOperandType,
-			InferredType thirdOperandType, ITypeSystemOperator ternaryOperator) {
-		// some defense programming
-		if (firstOperandType == null || secondOperandType == null || thirdOperandType == null) {
-			throw new NullPointerException("Operand types may not be null");
-		}
-
-		// if the operand type could not be inferred, there is not much we can
-		// do here
-		if (firstOperandType.getType() == null || secondOperandType.getType() == null
-				|| thirdOperandType.getType() == null) {
-			return new InferenceResult(null, new InferenceIssue(String.format(
-					COULD_NOT_INFER_A_TYPE_FOR_THE_OPERATION_NOT_INFERRED, ternaryOperator.getSymbol()), IStatus.ERROR));
-		}
-
-		// infer type based on operator
-		TernaryOperators o = (TernaryOperators) ternaryOperator;
-		switch (o) {
-		case CONDITIONAL:
-			// first operand has to be boolean, second and third determine the
-			// inferred type of the expression
-			List<InferenceIssue> issues = new ArrayList<InferenceIssue>();
-			if (!isBooleanType(firstOperandType.getType())) {
-				issues.add(new InferenceIssue(
-						NO_VALID_TYPE_CAN_BE_INFERRED_FOR_CONDITIONAL_EXPRESSION_BECAUSE_FIRST_OPERAND_NOT_BOOLEAN,
-						IStatus.ERROR));
-			}
-			// compute a union of the second and third operand types
-			InferenceResult unionResult = union(secondOperandType, thirdOperandType);
-			unionResult.getIssues().addAll(issues);
-			return unionResult;
-		default:
-			throw new IllegalArgumentException("Unsupported ternary operator: " + ternaryOperator);
-		}
-	}
-
-	public InferenceResult union(InferredType firstType, InferredType secondType) {
-		// defense programming
-		if (firstType == null || secondType == null) {
-			throw new NullPointerException("firstType and secondType may not be null.");
-		}
-
-		// if the operand type could not be inferred, there is not much we can
-		// do here
-		if (firstType.getType() == null || secondType.getType() == null) {
-			return new InferenceResult(null, new InferenceIssue(
-					"Could not infer a type union, because not all given types were properly inferred in advance.",
-					IStatus.ERROR));
-		}
-
-		// infer the union of both given types
-		if (firstType.getType() instanceof PrimitiveType && secondType.getType() instanceof PrimitiveType) {
-			Type commonType = computeCommonType((PrimitiveType) firstType.getType(),
-					(PrimitiveType) secondType.getType());
-			if (commonType != null) {
-				return new InferenceResult(new InferredType(commonType));
-			} else {
-				// handle coercion of types
-				if (isNumericType(firstType) && isNumericType(secondType)) {
-					// integer to real coercion
-					if (isRealType(firstType)) {
-						return new InferenceResult(firstType);
-					} else {
-						return new InferenceResult(secondType);
-					}
-				}
-			}
-		}
-		return new InferenceResult(null, new InferenceIssue("Cannot compute a type union for the given types: "
-				+ firstType + ", " + secondType, IStatus.ERROR));
-	}
-
-	public List<Type> getTypes() {
-		List<Type> types = new ArrayList<Type>();
-		types.add(getVoidType());
-		types.add(getBooleanType());
-		types.add(getIntegerType());
-		types.add(getRealType());
-		types.add(getStringType());
-		types.add(getNullType());
-		return types;
-	}
-
-	public boolean isVoidType(Type type) {
-		return EcoreUtil.equals(getVoidType(), type);
-	}
-
-	public boolean isVoidType(InferredType type) {
-		return isVoidType(type.getType());
-	}
-
-	public boolean isBooleanType(InferredType type) {
-		return isBooleanType(type.getType());
-	}
-
-	public boolean isBooleanType(Type type) {
-		return EcoreUtil.equals(getBooleanType(), type);
-	}
-
-	public boolean isRealType(Type type) {
-		return EcoreUtil.equals(getRealType(), type);
-	}
-
-	public boolean isRealType(InferredType type) {
-		return isRealType(type.getType());
-	}
-
-	public boolean isIntegerType(Type type) {
-		return EcoreUtil.equals(getIntegerType(), type);
-	}
-
-	public boolean isIntegerType(InferredType type) {
-		return isIntegerType(type.getType());
-	}
-
-	public boolean isStringType(Type type) {
-		return EcoreUtil.equals(getStringType(), type);
-	}
-
-	public boolean isStringType(InferredType type) {
-		return isStringType(type.getType());
-	}
-
-	public boolean isNumericType(Type type) {
-		boolean isNumeric = EcoreUtil.equals(getIntegerType(), type) || EcoreUtil.equals(getRealType(), type);
-		if (!isNumeric && type instanceof PrimitiveType) {
-			PrimitiveType baseType = ((PrimitiveType) type).getBaseType();
-			if (baseType != null) {
-				return isNumericType(baseType);
-			}
-		}
-		return isNumeric;
-	}
-
-	public boolean isNumericType(InferredType type) {
-		return isNumericType(type.getType());
-	}
-
-	public Object defaultValue(Type type) {
-		if (isBooleanType(type))
-			return true;
-		if (isIntegerType(type))
-			return 0L;
-		if (isRealType(type))
-			return 0.0;
-		if (isVoidType(type))
-			return null;
-		if (isStringType(type))
-			return "\"\"";
-		if (type instanceof EnumerationType) {
-			return ((EnumerationType) type).getEnumerator().get(0);
-		}
-		if (type instanceof ComplexType) {
-			return "{}";
-		}
-		return null;
-
-	}
-
-	public Object defaultValue(InferredType type) {
-		return defaultValue(type.getType());
-	}
-
-}

+ 1 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/DefaultTypeSystemRegistry.java

@@ -5,6 +5,7 @@ import java.util.Map;
 
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.Platform;
+import org.yakindu.base.types.typesystem.ITypeSystem;
 
 import com.google.inject.Singleton;
 

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

@@ -1,203 +0,0 @@
-/**
- * Copyright (c) 2013 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;
-
-import java.util.List;
-
-import com.google.inject.ImplementedBy;
-
-/**
- * Generic type system representation, which is responsible of listing the
- * available types ({@link #getTypes()}) and inferring types for certain
- * operations (or feature calls - not yet supported).
- * 
- * @author Alexander Ny��en - Initial contribution and API
- */
-@ImplementedBy(DefaultTypeSystem.class)
-public interface ITypeSystem {
-
-	public enum UnaryOperators implements ITypeSystemOperator {
-		LOGICAL_NOT("!"), POSITIVE("+"), NEGATIVE("-"), COMPLEMENT("~");
-
-		private String symbol;
-
-		UnaryOperators(String symbol) {
-			this.symbol = symbol;
-		}
-
-		public String getSymbol() {
-			return symbol;
-		}
-	};
-
-	public enum BinaryOperators implements ITypeSystemOperator {
-		LOGICAL_OR("||"), LOGICAL_AND("&&"), BITWISE_OR("|"), BITWISE_AND("&"), BITWISE_XOR("^"), SMALLER("<"), SMALLER_EQUAL(
-				"<="), GREATER(">"), GREATER_EQUAL(">="), EQUAL("=="), NOT_EQUAL("!="), MULTIPLY("*"), DIV("/"), MOD(
-				"%"), ADD("+"), SUBTRACT("-"), LEFT_SHIFT("<<"), RIGHT_SHIFT(">>"), ASSIGN("="), ASSIGN_MULTIPLY("*="), ASSIGN_DIV(
-				"/="), ASSIGN_MOD("%="), ASSIGN_ADD("+="), ASSIGN_SUBTRACT("-="), ASSIGN_LEFT_SHIFT("<<="), ASSIGN_RIGHT_SHIFT(
-				">>="), ASSIGN_BITWISE_AND("&="), ASSIGN_BITWISE_XOR("^="), ASSIGN_BITWISE_OR("|="), CAST("as");
-
-		private String symbol;
-
-		BinaryOperators(String symbol) {
-			this.symbol = symbol;
-		}
-
-		public String getSymbol() {
-			return symbol;
-		}
-	};
-
-	public enum TernaryOperators implements ITypeSystemOperator {
-		CONDITIONAL("?");
-
-		private String symbol;
-
-		TernaryOperators(String symbol) {
-			this.symbol = symbol;
-		}
-
-		public String getSymbol() {
-			return symbol;
-		}
-	};
-
-	public interface ITypeSystemOperator {
-		public String getSymbol();
-	}
-
-	public Type getVoidType();
-
-	public Type getBooleanType();
-
-	public Type getIntegerType();
-
-	public Type getRealType();
-
-	public Type getStringType();
-
-	public boolean isVoidType(InferredType inferredType);
-
-	public boolean isBooleanType(InferredType inferredType);
-
-	public boolean isIntegerType(InferredType inferredType);
-
-	public boolean isRealType(InferredType inferredType);
-
-	public boolean isStringType(InferredType inferredType);
-
-	public boolean isVoidType(Type type);
-
-	public boolean isBooleanType(Type type);
-
-	public boolean isIntegerType(Type type);
-
-	public boolean isRealType(Type type);
-
-	public boolean isStringType(Type type);
-
-	public Object defaultValue(InferredType type);
-
-	public Object defaultValue(Type type);
-
-	/**
-	 * Returns a list of all types known in this type system.
-	 * 
-	 * @return The list of all types known in the type system
-	 */
-	public List<Type> getTypes();
-
-	/**
-	 * Infer a type for a given literal. The literal may represent a primitive
-	 * value (primitive type literal) or an instance specification (complex type
-	 * literal).
-	 * 
-	 * @param literal
-	 *            The literal for which to infer a type
-	 * @return An {@link InferenceResult} containing the {@link InferredType}
-	 *         for the literal (or <code>null</code> in case no type could be
-	 *         inferred) and potential {@link InferenceIssue}s that occurred
-	 *         during the type inference. The result may also contain both, an
-	 *         inferred type and issues.
-	 */
-	public InferenceResult inferTypeForLiteral(Object literal);
-
-	/**
-	 * Responsible of inferring the type for a given unary expression (e.g. a
-	 * complement), where the type of the operand is already inferred.
-	 * 
-	 * @param operandType
-	 *            The inferred type of the operand of the unary expression
-	 * @param unaryOperator
-	 *            The unary operator by which the expression is identified
-	 * @return An {@link InferenceResult} containing the {@link InferredType} of
-	 *         the expression (or <code>null</code> in case no type could be
-	 *         inferred) and potential {@link InferenceIssue}s that occurred
-	 *         during the type inference. The result may also contain both, an
-	 *         inferred type and issues.
-	 */
-	public InferenceResult inferType(InferredType operandType, ITypeSystemOperator unaryOperator);
-
-	/**
-	 * Responsible of inferring the type for a given binary expression (e.g. an
-	 * assignment), where the types of the two operands are already inferred.
-	 * 
-	 * @param firstOperandType
-	 *            The inferred type of the first operand of the binary
-	 *            expression
-	 * @param secondOperandType
-	 *            The inferred type of the second operand of the binary
-	 *            expression
-	 * @param binaryOperator
-	 *            The binary operator by which the expression is identified
-	 * @return An {@link InferenceResult} containing the {@link InferredType} of
-	 *         the expression (or <code>null</code> in case no type could be
-	 *         inferred) and potential {@link InferenceIssue}s that occurred
-	 *         during the type inference. The result may also contain both, an
-	 *         inferred type and issues.
-	 */
-	public InferenceResult inferType(InferredType firstOperandType, InferredType secondOperandType,
-			ITypeSystemOperator binaryOperator);
-
-	/**
-	 * Responsible of inferring the type for a given ternary expression (e.g. a
-	 * conditional expression), where the types of the three operands are
-	 * already inferred.
-	 * 
-	 * @param firstOperandType
-	 *            The inferred type of the first operand of the ternary
-	 *            expression, e.g. the condition part the inferred type of the
-	 *            condition expression
-	 * @param secondOperandType
-	 *            The inferred type of the second operand of a ternary
-	 *            expression, e.g. in case of a conditional expression, the
-	 *            inferred type of the <code>true</code> case
-	 * @param thirdOperandType
-	 *            The inferred type of the third operator of a ternary
-	 *            expression, e.g. in case of a conditional expression, the
-	 *            inferred type of the <code>false</code> case
-	 * @param ternaryOperator
-	 *            The ternary operator by which the ternary expression is
-	 *            identified, e.g. '?' for conditionals.
-	 * @return An {@link InferenceResult} containing the {@link InferredType} of
-	 *         the expression (or <code>null</code> in case no type could be
-	 *         inferred) and potential {@link InferenceIssue}s that occurred
-	 *         during the inference. The result may also contain both, an
-	 *         inferred type and issues, if for instance the condition part of a
-	 *         conditional expression is not of type boolean but the true and
-	 *         false cases provide valid type information that can be used to
-	 *         calculate the type of the expression.
-	 */
-	public InferenceResult inferType(InferredType firstOperandType, InferredType secondOperandType,
-			InferredType thirdOperandType, ITypeSystemOperator ternaryOperator);
-
-}

+ 2 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/ITypeSystemRegistry.java

@@ -1,5 +1,7 @@
 package org.yakindu.base.types;
 
+import org.yakindu.base.types.typesystem.ITypeSystem;
+
 import com.google.inject.ImplementedBy;
 
 @ImplementedBy(DefaultTypeSystemRegistry.class)

+ 0 - 83
plugins/org.yakindu.base.types/src/org/yakindu/base/types/InferenceIssue.java

@@ -1,83 +0,0 @@
-/**
- * Copyright (c) 2013 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;
-
-import org.eclipse.core.runtime.IStatus;
-
-/**
- * Representation of an inference problem, consisting of a message and a
- * severity.
- * 
- * @author Alexander Nyßen - Initial contribution and API
- */
-public class InferenceIssue {
-
-	private String message;
-	private int severity;
-
-	/**
-	 * Constructs a new {@link InferenceIssue} with the given message and
-	 * severity.
-	 * 
-	 * @param message
-	 *            The message depicting the cause of the inference issue. May
-	 *            not be <code>null</null>.
-	 * @param severity
-	 *            The severity of this {@link InferenceIssue}. May be one of
-	 *            {@link IStatus#OK}, {@link IStatus#WARNING}, or
-	 *            {@link IStatus#ERROR}.
-	 */
-	public InferenceIssue(String message, int severity) {
-		if (message == null) {
-			throw new NullPointerException("Message may not be null.");
-		}
-		if (severity != IStatus.OK && severity != IStatus.WARNING && severity != IStatus.ERROR) {
-			throw new IllegalArgumentException(
-					"Unsupported severity. Has to be one of IStatus#OK, IStatus#WARNING, or IStatus#ERROR");
-		}
-		this.severity = severity;
-		this.message = message;
-	}
-
-	/**
-	 * Returns the message that indicates the cause of this
-	 * {@link InferenceIssue}.
-	 * 
-	 * @return A {@link String} depicting the message. Will never return
-	 *         <code>null</code>
-	 */
-	public String getMessage() {
-		return message;
-	}
-
-	/**
-	 * Returns the severity of this {@link InferenceIssue}. Will be one of the
-	 * {@link IStatus#OK}, {@link IStatus#WARNING}, or {@link IStatus#ERROR}.
-	 * 
-	 * @return {@link IStatus#OK}, {@link IStatus#WARNING}, or
-	 *         {@link IStatus#ERROR}
-	 */
-	public int getSeverity() {
-		return severity;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		return obj instanceof InferenceIssue && ((InferenceIssue) obj).message.equals(message)
-				&& severity == ((InferenceIssue) obj).severity;
-	}
-
-	@Override
-	public int hashCode() {
-		return message.hashCode() + severity;
-	};
-}

+ 0 - 73
plugins/org.yakindu.base.types/src/org/yakindu/base/types/InferenceResult.java

@@ -1,73 +0,0 @@
-/**
- * Copyright (c) 2013 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;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.yakindu.base.types.Type;
-import org.yakindu.base.types.TypeConstraint;
-
-import com.google.common.collect.Lists;
-
-/**
- * Representation of a (type) inference result, which is consists of an
- * {@link InferredType} and a list of {@link InferenceIssue}.
- * <p>
- * Note that the {@link InferredType} may be null. In such a case the list of
- * issues should document, why a type could not be inferred. The list of issues
- * may also be non-empty, even if a type could be inferred. As an example
- * consider the case where a base type could be inferred (e.g. integer), while
- * issues indicate that value range constraints (modeled via
- * {@link TypeConstraint}s) are violated.
- * 
- * @author Alexander Nyßen - Initial contribution and API
- * 
- */
-public class InferenceResult {
-	private InferredType inferredType;
-	private Collection<InferenceIssue> inferenceIssues;
-
-	/**
-	 * Constructs an {@link InferenceResult} from a concrete {@link Type}. The
-	 * {@link InferenceResult} returned as result will contain an
-	 * {@link InferredType} that contains the given {@link Type} and no
-	 * {@link TypeConstraint}s and an empty list of {@link InferenceIssue}s.
-	 * 
-	 * @param type
-	 *            The {@link Type} to construct the {@link InferenceResult} for.
-	 */
-	public InferenceResult(Type type) {
-		this(new InferredType(type));
-	}
-
-	public InferenceResult(InferredType inferredType) {
-		this(inferredType, Lists.<InferenceIssue> newArrayList());
-	}
-
-	public InferenceResult(InferredType inferredType, InferenceIssue inferenceIssue) {
-		this(inferredType, Collections.singletonList(inferenceIssue));
-	}
-
-	public InferenceResult(InferredType inferredType, Collection<InferenceIssue> inferenceIssues) {
-		this.inferredType = inferredType;
-		this.inferenceIssues = inferenceIssues;
-	}
-
-	public InferredType getType() {
-		return inferredType;
-	}
-
-	public Collection<InferenceIssue> getIssues() {
-		return inferenceIssues;
-	}
-}

+ 0 - 103
plugins/org.yakindu.base.types/src/org/yakindu/base/types/InferredType.java

@@ -1,103 +0,0 @@
-/**
- * Copyright (c) 2013 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;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.yakindu.base.types.Type;
-import org.yakindu.base.types.TypeConstraint;
-
-/**
- * Representation of an inferred type, which is formed by a {@link Type} and a
- * set of {@link TypeConstraint}s.
- * <p>
- * Note that the {@link Type} included in an {@link InferredType} does not
- * necessarily have to be a concrete type that is provided via
- * {@link ITypeSystem#getTypes()}, and should thus never be used by clients
- * directly. In fact, the it may be an (abstract) type that is used by an
- * {@link ITypeSystem} for purposes of type inference only. As an example
- * consider a type system that offers a set of different integer types, which
- * have different value ranges (modeled by {@link TypeConstraint}s) but no
- * common base type. In such a case, the {@link ITypeSystem} may synthesize an
- * abstract integer base type and use it during type inference (together with
- * {@link TypeConstraint}s that narrow the range of supported values). In the
- * end, {@link ITypeSystem#getTypes(InferredType))} may then use the synthesized
- * integer base type (and the computed constraints) to decide which of its
- * concrete integer types may be used and return them to the client.
- * 
- * @author Alexander Nyßen - Initial contribution and API
- */
-public class InferredType {
-
-	private Type type;
-	private Collection<? extends TypeConstraint> constraints;
-
-	public InferredType(Type type) {
-		this(type, Collections.<TypeConstraint> emptyList());
-	}
-
-	public InferredType(Type type, Collection<TypeConstraint> constraints) {
-		if (type == null) {
-			throw new NullPointerException("Type may not be null.");
-		}
-		if (constraints == null) {
-			throw new NullPointerException("Constraints may be empty but not null.");
-		}
-		this.type = type;
-		this.constraints = constraints;
-	}
-
-	public Type getType() {
-		return type;
-	}
-
-	public Collection<? extends TypeConstraint> getConstraints() {
-		return constraints;
-	}
-
-	@Override
-	public String toString() {
-		return type.getName(); // TODO handle constraints...
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (!(obj instanceof InferredType)) {
-			return false;
-		}
-		// check types
-		InferredType other = (InferredType) obj;
-		if (!EcoreUtil.equals(type, other.type)) {
-			return false;
-		}
-		// check constraints
-		for (TypeConstraint t1 : constraints) {
-			boolean foundEqual = false;
-			for (TypeConstraint t2 : other.constraints) {
-				if (EcoreUtil.equals(t1, t2)) {
-					foundEqual = true;
-				}
-			}
-			if (!foundEqual) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	@Override
-	public int hashCode() {
-		return type.hashCode();
-	}
-}

+ 0 - 30
plugins/org.yakindu.base.types/src/org/yakindu/base/types/TypeSystemUtils.xtend

@@ -1,30 +0,0 @@
-/**
- * Copyright (c) 2014 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
-
-import java.util.Collection
-import org.yakindu.base.types.EnumerationType
-
-class TypeSystemUtils {
-	
-	def Collection<EnumerationType> getEnumerationTypes(ITypeSystem ts){
-		return ts.types.filter(typeof (EnumerationType)).toList
-	}
-	
-	def Collection<PrimitiveType> getPrimitiveTypes(ITypeSystem ts){
-		return ts.types.filter(typeof (PrimitiveType)).toList
-	}
-	
-	def Collection<ComplexType> getComplexTypes(ITypeSystem ts){
-		return ts.types.filter(typeof (ComplexType)).toList
-	}
-}

+ 125 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/inferrer/AbstractTypeSystemInferrer.java

@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2014 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.types.inferrer;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.util.PolymorphicDispatcher;
+import org.yakindu.base.types.Type;
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer.ITypeTraceAcceptor.TypeTrace;
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer.ITypeTraceAcceptor.TypeTrace.Severity;
+import org.yakindu.base.types.typesystem.ITypeSystem;
+
+import com.google.inject.Inject;
+
+/**
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public abstract class AbstractTypeSystemInferrer implements ITypeSystemInferrer {
+
+	private static final String METHOD_NAME = "infer";
+
+	@Inject
+	private ITypeSystem typeSystem;
+
+	private ITypeTraceAcceptor acceptor;
+
+	private PolymorphicDispatcher<Object> dispatcher;
+
+	public AbstractTypeSystemInferrer() {
+		initDispatcher();
+	}
+
+	protected Type getType(String name) {
+		return typeSystem.getType(name);
+	}
+
+	protected Type getCommonType(EObject object1, EObject object2) {
+		return typeSystem.getCommonType(inferType(object1), inferType(object2));
+	}
+
+	@Override
+	public final Type inferType(EObject object, ITypeTraceAcceptor acceptor) {
+		this.acceptor = acceptor;
+		info("infering type for object " + object);
+		Collection<Type> types = typeSystem.getTypes();
+		for (Type type : types) {
+			if (object instanceof Type && typeSystem.isSame((Type) object, type))
+				return type;
+		}
+		return (Type) (EObject) dispatcher.invoke(object);
+	}
+
+	public final Type inferType(EObject object) {
+		return inferType(object, acceptor == null ? new ListBasedTypeTraceAcceptor() : acceptor);
+	}
+
+	protected void initDispatcher() {
+		dispatcher = new PolymorphicDispatcher<Object>(METHOD_NAME, 1, 1, Collections.singletonList(this),
+				new PolymorphicDispatcher.ErrorHandler<Object>() {
+					@Override
+					public Object handle(Object[] params, Throwable throwable) {
+						if (throwable instanceof NoSuchMethodError) {
+							warning("No infer method for type " + Arrays.toString(params));
+						} else {
+							error(throwable.getMessage());
+						}
+						return null;
+					}
+				});
+	}
+
+	protected void assertType(Type type1, String msg, Type... types) {
+		boolean same = false;
+		for (Type type : types) {
+			if (typeSystem.isSame(type1, type)) {
+				same = true;
+			}
+		}
+		if (!same) {
+			error(msg != null ? msg : "Expected one of " + Arrays.toString(types) + " but was " + type1);
+		}
+	}
+
+	protected void assertSame(Type type1, Type type2, String msg) {
+		if (!typeSystem.isSame(type1, type2)) {
+			error(msg != null ? msg : "Types not the same : " + type1 + " and " + type2);
+		}
+	}
+
+	protected void assertCompatibleType(Type type1, Type type2, String msg) {
+		if (!typeSystem.haveCommonType(type1, type2)) {
+			error(msg != null ? msg : "Incompatible types " + type1 + " and " + type2);
+		}
+	}
+
+	protected void assertIsSuperType(Type subType, Type superType, String msg) {
+		if (!typeSystem.isSuperType(subType, superType)) {
+			error(msg != null ? msg : "Incompatible types " + subType + " and " + superType);
+		}
+	}
+
+	protected void info(String msg) {
+		acceptor.accept(new TypeTrace(Severity.INFO, msg));
+	}
+
+	protected void warning(String msg) {
+		acceptor.accept(new TypeTrace(Severity.WARNING, msg));
+	}
+
+	protected void error(String msg) {
+		acceptor.accept(new TypeTrace(Severity.ERROR, msg));
+	}
+}

+ 97 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/inferrer/ITypeSystemInferrer.java

@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2014 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.types.inferrer;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.yakindu.base.types.Type;
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer.ITypeTraceAcceptor.TypeTrace.Severity;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/**
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public interface ITypeSystemInferrer {
+
+	public Type inferType(EObject object, ITypeTraceAcceptor acceptor);
+	
+	public Type inferType(EObject object);
+
+	public interface ITypeTraceAcceptor {
+
+		public static class TypeTrace {
+			public static enum Severity {
+				ERROR, WARNING, INFO
+			}
+
+			public TypeTrace(Severity severity, String message) {
+				super();
+				this.severity = severity;
+				this.message = message;
+			}
+
+			private Severity severity;
+			private String message;
+
+			public Severity getSeverity() {
+				return severity;
+			}
+
+			public void setSeverity(Severity severity) {
+				this.severity = severity;
+			}
+
+			public String getMessage() {
+				return message;
+			}
+
+			public void setMessage(String message) {
+				this.message = message;
+			}
+
+			@Override
+			public String toString() {
+				return "TypeTrace [" + severity + ", message=" + message + "]";
+			}
+		}
+
+		public void accept(TypeTrace trace);
+	}
+
+	public static final class ListBasedTypeTraceAcceptor implements ITypeTraceAcceptor {
+
+		private List<TypeTrace> traces = Lists.newArrayList();
+
+		@Override
+		public void accept(TypeTrace trace) {
+			traces.add(trace);
+		}
+
+		public List<TypeTrace> getTraces() {
+			return traces;
+		}
+
+		public List<TypeTrace> getTraces(final Severity severity) {
+			return Lists.newArrayList(Iterables.filter(traces, new Predicate<TypeTrace>() {
+				@Override
+				public boolean apply(TypeTrace input) {
+					return input.getSeverity() == severity;
+				}
+			}));
+		}
+
+	}
+}

+ 63 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/interpreter/AbstractTypeSystemInterpreter.java

@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2014 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.types.interpreter;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.util.PolymorphicDispatcher;
+import org.yakindu.base.types.typesystem.ITypeSystem;
+
+import com.google.inject.Inject;
+
+/**
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public abstract class AbstractTypeSystemInterpreter implements ITypeSystemInterpreter {
+
+	private static final String METHOD_NAME = "interpret";
+
+	private PolymorphicDispatcher<Object> dispatcher;
+
+	public AbstractTypeSystemInterpreter() {
+		initDispatcher();
+	}
+
+	public final Object interpretExpression(EObject object) {
+		return dispatcher.invoke(object);
+	}
+
+	protected void initDispatcher() {
+		dispatcher = new PolymorphicDispatcher<Object>(METHOD_NAME, 1, 1, Collections.singletonList(this),
+				new PolymorphicDispatcher.ErrorHandler<Object>() {
+					@Override
+					public Object handle(Object[] params, Throwable throwable) {
+						if (throwable instanceof NoSuchMethodError) {
+							warning("No infer method for type " + Arrays.toString(params));
+						} else {
+							error(throwable.getMessage());
+						}
+						return null;
+					}
+				});
+	}
+
+	protected void warning(String msg) {
+		// Howto report?
+	}
+
+	protected void error(String msg) {
+		// Howto report?
+	}
+
+}

+ 37 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/interpreter/DefaultTypeSystemInterpreter.java

@@ -0,0 +1,37 @@
+package org.yakindu.base.types.interpreter;
+
+import org.eclipse.emf.ecore.EObject;
+import org.yakindu.base.types.Type;
+import org.yakindu.base.types.typesystem.DefaultTypeSystem;
+import org.yakindu.base.types.typesystem.ITypeSystem;
+
+import com.google.inject.Inject;
+
+public class DefaultTypeSystemInterpreter extends AbstractTypeSystemInterpreter {
+
+	@Inject
+	private ITypeSystem typeSystem;
+
+	@Override
+	public Object interpret(EObject object) {
+		throw new IllegalArgumentException("not yet implemented");
+	}
+
+	@Override
+	public Object defaultValue(Type type) {
+		if (typeSystem.isSame(type, typeSystem.getType(DefaultTypeSystem.INTEGER))) {
+			return 0L;
+		}
+		if (typeSystem.isSame(type, typeSystem.getType(DefaultTypeSystem.REAL))) {
+			return 0.0D;
+		}
+		if (typeSystem.isSame(type, typeSystem.getType(DefaultTypeSystem.BOOLEAN))) {
+			return false;
+		}
+		if (typeSystem.isSame(type, typeSystem.getType(DefaultTypeSystem.STRING))) {
+			return "";
+		}
+		throw new IllegalArgumentException("not yet implemented");
+	}
+
+}

+ 28 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/interpreter/ITypeSystemInterpreter.java

@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2014 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.types.interpreter;
+
+import org.eclipse.emf.ecore.EObject;
+import org.yakindu.base.types.Type;
+
+import com.google.inject.ImplementedBy;
+
+/**
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+@ImplementedBy(DefaultTypeSystemInterpreter.class)
+public interface ITypeSystemInterpreter {
+
+	public Object interpret(EObject object);
+
+	public Object defaultValue(Type type);
+}

+ 107 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/AbstractTypeSystem.java

@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2014 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.types.typesystem;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.yakindu.base.types.Type;
+
+/**
+ * Abstract base implementation if {@link ITypeSystem}. Provides convenience
+ * methods to determine type compatibility.
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public abstract class AbstractTypeSystem implements ITypeSystem {
+
+	private Map<String, Type> typeRegistry = new HashMap<String, Type>();
+	private Map<Type, Type> extendsRegistry = new HashMap<Type, Type>();
+
+	// Types must be contained in a resource to avoid dangling reference errors
+	private Resource resource = new ResourceImpl();
+
+	protected abstract void declareTypes();
+
+	public AbstractTypeSystem() {
+		declareTypes();
+	}
+
+	public Type getType(String type) {
+		return typeRegistry.get(type);
+	}
+
+	public Type getSuperType(Type type) {
+		return extendsRegistry.get(type);
+	}
+
+	public boolean isSuperType(Type subtype, Type supertype) {
+		List<Type> typehierachy = new ArrayList<Type>();
+		typehierachy.add(subtype);
+		collectSupertypes(subtype, typehierachy);
+		for (Type eObject : typehierachy) {
+			if (isSame(eObject, supertype))
+				return true;
+		}
+		return false;
+	}
+
+	private void collectSupertypes(Type subtypeClass, List<Type> typehierachy) {
+		if (subtypeClass == null)
+			return;
+		Type superType = getSuperType(subtypeClass);
+		if (superType != null) {
+			typehierachy.add(superType);
+			collectSupertypes(superType, typehierachy);
+		}
+
+	}
+
+	public Collection<Type> getTypes() {
+		return Collections.unmodifiableCollection(typeRegistry.values());
+	}
+
+	public void declareType(Type type, String name) {
+		resource.getContents().add(type);
+		typeRegistry.put(name, type);
+	}
+
+	public void declareSuperType(Type baseType, Type superType) {
+		extendsRegistry.put(baseType, superType);
+	}
+
+	public boolean haveCommonType(Type type1, Type type2) {
+		return getCommonType(type1, type2) != null;
+	}
+
+	public boolean isSame(Type type1, Type type2) {
+		return EcoreUtil.equals(type1, type2);
+	}
+
+	public Type getCommonType(Type type1, Type type2) {
+		if (isSame(type1, type2))
+			return type1;
+		if (isSuperType(type1, type2)) {
+			return type2;
+		}
+		if (isSuperType(type2, type1))
+			return type1;
+		return null;
+	}
+}

+ 53 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/DefaultTypeSystem.java

@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2014 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.types.typesystem;
+
+import org.yakindu.base.types.PrimitiveType;
+import org.yakindu.base.types.Type;
+import org.yakindu.base.types.TypesFactory;
+
+import com.google.inject.Singleton;
+
+/**
+ * The Statechart Tools default type system.
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+@Singleton
+public class DefaultTypeSystem extends AbstractTypeSystem {
+
+	public static final String NULL = "null";
+	public static final String STRING = "string";
+	public static final String REAL = "real";
+	public static final String INTEGER = "integer";
+	public static final String BOOLEAN = "boolean";
+	public static final String VOID = "void";
+
+	@Override
+	protected void declareTypes() {
+		declarePrimitive(STRING);
+		declarePrimitive(REAL);
+		declarePrimitive(INTEGER);
+		declarePrimitive(BOOLEAN);
+		declarePrimitive(VOID);
+
+		declareSuperType(getType(INTEGER), getType(REAL));
+	}
+
+	public Type declarePrimitive(String name) {
+		PrimitiveType primitive = TypesFactory.eINSTANCE.createPrimitiveType();
+		primitive.setName(name);
+		declareType(primitive, name);
+		return primitive;
+
+	}
+}

+ 44 - 0
plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/ITypeSystem.java

@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2014 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.types.typesystem;
+
+import java.util.Collection;
+
+import org.yakindu.base.types.Type;
+
+import com.google.inject.ImplementedBy;
+
+/**
+ * A Implementation of {@link ITypeSystem} defines all existing types and the
+ * type compatibility.
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+@ImplementedBy(DefaultTypeSystem.class)
+public interface ITypeSystem {
+
+	public void declareType(Type type, String name);
+
+	public void declareSuperType(Type baseType, Type superType);
+
+	public Collection<Type> getTypes();
+
+	public Type getType(String name);
+
+	public boolean isSame(Type type1, Type type2);
+
+	public Type getCommonType(Type type1, Type type2);
+
+	public boolean haveCommonType(Type type1, Type type2);
+	
+	public boolean isSuperType(Type subtype, Type supertype);
+}