Andreas Mülder 11 лет назад
Родитель
Сommit
26f17cdfd8

+ 39 - 34
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/ExpressionsTypeInferrer.java

@@ -40,6 +40,7 @@ import org.yakindu.base.expressions.expressions.RealLiteral;
 import org.yakindu.base.expressions.expressions.ShiftExpression;
 import org.yakindu.base.expressions.expressions.ShiftExpression;
 import org.yakindu.base.expressions.expressions.StringLiteral;
 import org.yakindu.base.expressions.expressions.StringLiteral;
 import org.yakindu.base.expressions.expressions.TypeCastExpression;
 import org.yakindu.base.expressions.expressions.TypeCastExpression;
+import org.yakindu.base.expressions.expressions.UnaryOperator;
 import org.yakindu.base.types.Type;
 import org.yakindu.base.types.Type;
 import org.yakindu.base.types.inferrer.AbstractTypeSystemInferrer;
 import org.yakindu.base.types.inferrer.AbstractTypeSystemInferrer;
 
 
@@ -50,85 +51,85 @@ import org.yakindu.base.types.inferrer.AbstractTypeSystemInferrer;
 public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implements ExpressionsTypeInferrerMessages {
 public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implements ExpressionsTypeInferrerMessages {
 
 
 	public Type infer(AssignmentExpression e) {
 	public Type infer(AssignmentExpression e) {
-		Type type1 = inferType(e.getVarRef());
-		Type type2 = inferType(e.getExpression());
+		Type type1 = inferTypeDispatch(e.getVarRef());
+		Type type2 = inferTypeDispatch(e.getExpression());
 		assertIsSuperType(type2, type1, String.format(ASSIGNMENT_OPERATOR, e.getOperator(), type1, type2));
 		assertIsSuperType(type2, type1, String.format(ASSIGNMENT_OPERATOR, e.getOperator(), type1, type2));
-		return inferType(e.getVarRef());
+		return inferTypeDispatch(e.getVarRef());
 	}
 	}
 
 
 	public Type infer(ConditionalExpression e) {
 	public Type infer(ConditionalExpression e) {
-		Type type1 = inferType(e.getTrueCase());
-		Type type2 = inferType(e.getFalseCase());
+		Type type1 = inferTypeDispatch(e.getTrueCase());
+		Type type2 = inferTypeDispatch(e.getFalseCase());
 		assertCompatibleType(type1, type2, String.format(COMMON_TYPE, type1, type2));
 		assertCompatibleType(type1, type2, String.format(COMMON_TYPE, type1, type2));
-		assertType(inferType(e.getCondition()), CONDITIONAL_BOOLEAN, getType(BOOLEAN));
+		assertType(inferTypeDispatch(e.getCondition()), CONDITIONAL_BOOLEAN, getType(BOOLEAN));
 		return getCommonType(type1, type2);
 		return getCommonType(type1, type2);
 	}
 	}
 
 
 	public Type infer(LogicalOrExpression e) {
 	public Type infer(LogicalOrExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertType(type1, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
 		assertType(type1, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
 		assertType(type2, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
 		assertType(type2, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
 		return getType(BOOLEAN);
 		return getType(BOOLEAN);
 	}
 	}
 
 
 	public Type infer(LogicalAndExpression e) {
 	public Type infer(LogicalAndExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertType(type1, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
 		assertType(type1, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
 		assertType(type2, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
 		assertType(type2, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
 		return getType(BOOLEAN);
 		return getType(BOOLEAN);
 	}
 	}
 
 
 	public Type infer(LogicalNotExpression e) {
 	public Type infer(LogicalNotExpression e) {
-		Type type = inferType(e.getOperand());
+		Type type = inferTypeDispatch(e.getOperand());
 		assertType(type, String.format(LOGICAL_OPERATOR, "!", type), getType(BOOLEAN));
 		assertType(type, String.format(LOGICAL_OPERATOR, "!", type), getType(BOOLEAN));
 		return getType(BOOLEAN);
 		return getType(BOOLEAN);
 	}
 	}
 
 
 	public Type infer(BitwiseXorExpression e) {
 	public Type infer(BitwiseXorExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertType(type1, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
 		assertType(type1, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
 		assertType(type2, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
 		assertType(type2, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
 		return getType(INTEGER);
 		return getType(INTEGER);
 	}
 	}
 
 
 	public Type infer(BitwiseOrExpression e) {
 	public Type infer(BitwiseOrExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertType(type1, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
 		assertType(type1, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
 		assertType(type2, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
 		assertType(type2, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
 		return getType(INTEGER);
 		return getType(INTEGER);
 	}
 	}
 
 
 	public Type infer(BitwiseAndExpression e) {
 	public Type infer(BitwiseAndExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertType(type1, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
 		assertType(type1, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
 		assertType(type2, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
 		assertType(type2, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
 		return getType(INTEGER);
 		return getType(INTEGER);
 	}
 	}
 
 
 	public Type infer(ShiftExpression e) {
 	public Type infer(ShiftExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertType(type1, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
 		assertType(type1, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
 		assertType(type2, 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);
 		return getType(INTEGER);
 	}
 	}
 
 
 	public Type infer(LogicalRelationExpression e) {
 	public Type infer(LogicalRelationExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertCompatibleType(type1, type2, String.format(COMPARSION_OPERATOR, e.getOperator(), type1, type2));
 		assertCompatibleType(type1, type2, String.format(COMPARSION_OPERATOR, e.getOperator(), type1, type2));
 		return getType(BOOLEAN);
 		return getType(BOOLEAN);
 
 
 	}
 	}
 
 
 	public Type infer(NumericalAddSubtractExpression e) {
 	public Type infer(NumericalAddSubtractExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertCompatibleType(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
 		assertCompatibleType(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
 		assertType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
 		assertType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
 				getType(REAL));
 				getType(REAL));
@@ -136,8 +137,8 @@ public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implemen
 	}
 	}
 
 
 	public Type infer(NumericalMultiplyDivideExpression e) {
 	public Type infer(NumericalMultiplyDivideExpression e) {
-		Type type1 = inferType(e.getLeftOperand());
-		Type type2 = inferType(e.getRightOperand());
+		Type type1 = inferTypeDispatch(e.getLeftOperand());
+		Type type2 = inferTypeDispatch(e.getRightOperand());
 		assertCompatibleType(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
 		assertCompatibleType(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
 		assertType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
 		assertType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
 				getType(REAL));
 				getType(REAL));
@@ -145,32 +146,36 @@ public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implemen
 	}
 	}
 
 
 	public Type infer(NumericalUnaryExpression e) {
 	public Type infer(NumericalUnaryExpression e) {
-		Type type1 = inferType(e.getOperand());
-		assertType(type1, String.format(BITWISE_OPERATOR, '~', type1), getType(INTEGER));
+		Type type1 = inferTypeDispatch(e.getOperand());
+		if (e.getOperator() == UnaryOperator.COMPLEMENT)
+			assertType(type1, String.format(BITWISE_OPERATOR, '~', type1), getType(INTEGER));
+		else {
+			assertType(type1, String.format(BITWISE_OPERATOR, '~', type1), getType(INTEGER), getType(REAL));
+		}
 		return type1;
 		return type1;
 	}
 	}
 
 
 	public Type infer(TypeCastExpression e) {
 	public Type infer(TypeCastExpression e) {
-		Type type1 = inferType(e.getOperand());
-		Type type2 = inferType(e.getType());
+		Type type1 = inferTypeDispatch(e.getOperand());
+		Type type2 = inferTypeDispatch(e.getType());
 		assertCompatibleType(type1, type2, String.format(CAST_OPERATORS, type1, type2));
 		assertCompatibleType(type1, type2, String.format(CAST_OPERATORS, type1, type2));
-		return e.getType();
+		return inferTypeDispatch(e.getType());
 	}
 	}
 
 
 	public Type infer(FeatureCall e) {
 	public Type infer(FeatureCall e) {
-		return inferType(e.getFeature());
+		return inferTypeDispatch(e.getFeature());
 	}
 	}
 
 
 	public Type infer(ElementReferenceExpression e) {
 	public Type infer(ElementReferenceExpression e) {
-		return inferType(e.getReference());
+		return inferTypeDispatch(e.getReference());
 	}
 	}
 
 
 	public Type infer(ParenthesizedExpression e) {
 	public Type infer(ParenthesizedExpression e) {
-		return inferType(e.getExpression());
+		return inferTypeDispatch(e.getExpression());
 	}
 	}
 
 
 	public Type infer(PrimitiveValueExpression e) {
 	public Type infer(PrimitiveValueExpression e) {
-		return inferType(e.getValue());
+		return inferTypeDispatch(e.getValue());
 	}
 	}
 
 
 	public Type infer(BoolLiteral literal) {
 	public Type infer(BoolLiteral literal) {

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

@@ -26,4 +26,5 @@ Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.xtext.xbase.lib,
  org.eclipse.xtext.xbase.lib,
  org.eclipse.xtext.util
  org.eclipse.xtext.util
 Bundle-ActivationPolicy: lazy
 Bundle-ActivationPolicy: lazy
+Import-Package: org.apache.log4j
 
 

+ 34 - 9
plugins/org.yakindu.base.types/src/org/yakindu/base/types/inferrer/AbstractTypeSystemInferrer.java

@@ -13,6 +13,8 @@ package org.yakindu.base.types.inferrer;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
 
 
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtext.util.PolymorphicDispatcher;
 import org.eclipse.xtext.util.PolymorphicDispatcher;
@@ -21,6 +23,9 @@ import org.yakindu.base.types.inferrer.ITypeSystemInferrer.ITypeTraceAcceptor.Ty
 import org.yakindu.base.types.inferrer.ITypeSystemInferrer.ITypeTraceAcceptor.TypeTrace.Severity;
 import org.yakindu.base.types.inferrer.ITypeSystemInferrer.ITypeTraceAcceptor.TypeTrace.Severity;
 import org.yakindu.base.types.typesystem.ITypeSystem;
 import org.yakindu.base.types.typesystem.ITypeSystem;
 
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import com.google.inject.Inject;
 import com.google.inject.Inject;
 
 
 /**
 /**
@@ -38,8 +43,11 @@ public abstract class AbstractTypeSystemInferrer implements ITypeSystemInferrer
 
 
 	private PolymorphicDispatcher<Object> dispatcher;
 	private PolymorphicDispatcher<Object> dispatcher;
 
 
+	private LoadingCache<EObject, Type> typeCache;
+
 	public AbstractTypeSystemInferrer() {
 	public AbstractTypeSystemInferrer() {
 		initDispatcher();
 		initDispatcher();
+		initTypeCache();
 	}
 	}
 
 
 	protected Type getType(String name) {
 	protected Type getType(String name) {
@@ -47,23 +55,40 @@ public abstract class AbstractTypeSystemInferrer implements ITypeSystemInferrer
 	}
 	}
 
 
 	protected Type getCommonType(EObject object1, EObject object2) {
 	protected Type getCommonType(EObject object1, EObject object2) {
-		return typeSystem.getCommonType(inferType(object1), inferType(object2));
+		return typeSystem.getCommonType(inferTypeDispatch(object1), inferTypeDispatch(object2));
 	}
 	}
 
 
 	@Override
 	@Override
 	public final Type inferType(EObject object, ITypeTraceAcceptor acceptor) {
 	public final Type inferType(EObject object, ITypeTraceAcceptor acceptor) {
-		this.acceptor = acceptor;
+		this.acceptor = (acceptor != null ? acceptor : new ListBasedTypeTraceAcceptor());
 		info("infering type for object " + object);
 		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;
+		Type result = inferTypeDispatch(object);
+		typeCache.invalidateAll();
+		return result;
+	}
+
+	protected Type inferTypeDispatch(EObject object) {
+		try {
+			return typeCache.get(object);
+		} catch (IllegalStateException e) {
+			// Detection of recursive loads
+		} catch (Exception e) {
+			e.printStackTrace();
 		}
 		}
-		return (Type) (EObject) dispatcher.invoke(object);
+		return null;
 	}
 	}
 
 
-	public final Type inferType(EObject object) {
-		return inferType(object, acceptor == null ? new ListBasedTypeTraceAcceptor() : acceptor);
+	private void initTypeCache() {
+		typeCache = CacheBuilder.newBuilder().maximumSize(1000).build(new CacheLoader<EObject, Type>() {
+			public Type load(EObject key) {
+				Collection<Type> types = typeSystem.getTypes();
+				for (Type type : types) {
+					if (key instanceof Type && typeSystem.isSame((Type) key, type))
+						return type;
+				}
+				return (Type) (EObject) dispatcher.invoke(key);
+			}
+		});
 	}
 	}
 
 
 	protected void initDispatcher() {
 	protected void initDispatcher() {

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

@@ -28,8 +28,6 @@ public interface ITypeSystemInferrer {
 
 
 	public Type inferType(EObject object, ITypeTraceAcceptor acceptor);
 	public Type inferType(EObject object, ITypeTraceAcceptor acceptor);
 	
 	
-	public Type inferType(EObject object);
-
 	public interface ITypeTraceAcceptor {
 	public interface ITypeTraceAcceptor {
 
 
 		public static class TypeTrace {
 		public static class TypeTrace {

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

@@ -39,6 +39,7 @@ public class DefaultTypeSystem extends AbstractTypeSystem {
 		declarePrimitive(INTEGER);
 		declarePrimitive(INTEGER);
 		declarePrimitive(BOOLEAN);
 		declarePrimitive(BOOLEAN);
 		declarePrimitive(VOID);
 		declarePrimitive(VOID);
+		declarePrimitive(NULL);
 
 
 		declareSuperType(getType(INTEGER), getType(REAL));
 		declareSuperType(getType(INTEGER), getType(REAL));
 	}
 	}