Browse Source

Added "Any" type to type system to describe the type of an unbound type parameter.

Thomas Kutz 9 years ago
parent
commit
47444bf341

+ 10 - 2
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/inferrer/ExpressionsTypeInferrer.java

@@ -16,6 +16,7 @@ import static org.yakindu.base.types.typesystem.ITypeSystem.NULL;
 import static org.yakindu.base.types.typesystem.ITypeSystem.REAL;
 import static org.yakindu.base.types.typesystem.ITypeSystem.STRING;
 import static org.yakindu.base.types.typesystem.ITypeSystem.VOID;
+import static org.yakindu.base.types.typesystem.ITypeSystem.ANY;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -210,7 +211,11 @@ public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implemen
 		InferenceResult result = inferTypeDispatch(e.getFeature());
 		if (result != null && result.getType() instanceof TypeParameter) {
 			InferenceResult ownerResult = inferTypeDispatch(e.getOwner());
-			result = InferenceResult.from(ownerResult.getBindings().get(0).getType(), ownerResult.getBindings().get(0).getBindings());
+			if (ownerResult.getBindings().isEmpty()) {
+				result = getResultFor(ANY);
+			} else {
+				result = InferenceResult.from(ownerResult.getBindings().get(0).getType(), ownerResult.getBindings().get(0).getBindings());
+			}
 		}
 		return result;
 	}
@@ -289,7 +294,10 @@ public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implemen
 		List<InferenceResult> bindings = new ArrayList<>();
 		EList<TypeSpecifier> arguments = specifier.getTypeArguments();
 		for (TypeSpecifier typeSpecifier : arguments) {
-			bindings.add(inferTypeDispatch(typeSpecifier));
+			InferenceResult binding = inferTypeDispatch(typeSpecifier);
+			if (binding != null) {
+				bindings.add(binding);
+			}
 		}
 		return InferenceResult.from(inferTypeDispatch(specifier.getType()).getType(), bindings);
 

+ 8 - 2
plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/GenericTypeSystem.java

@@ -21,7 +21,6 @@ import com.google.inject.Singleton;
 public class GenericTypeSystem extends AbstractTypeSystem {
 	
 	private static final GenericTypeSystem INSTANCE = new GenericTypeSystem();
-
 	
 	protected GenericTypeSystem() {}
 	
@@ -36,10 +35,17 @@ public class GenericTypeSystem extends AbstractTypeSystem {
 		declarePrimitive(INTEGER);
 		declarePrimitive(BOOLEAN);
 		declarePrimitive(VOID);
+
 		declarePrimitive(NULL);
+		getType(NULL).setAbstract(true);
 
+		declarePrimitive(ANY);
+		getType(ANY).setAbstract(true);
+		
+		declareSuperType(getType(ANY), getType(STRING));
+		declareSuperType(getType(ANY), getType(BOOLEAN));
+		declareSuperType(getType(ANY), getType(INTEGER));
 		declareSuperType(getType(INTEGER), getType(REAL));
 
-		getType(NULL).setAbstract(true);
 	}
 }

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

@@ -32,6 +32,7 @@ public interface ITypeSystem {
 	public static final String BOOLEAN = "boolean";
 	public static final String VOID = "void";
 	public static final String NULL = "null";
+	public static final String ANY = "any";
 
 	public Collection<Type> getTypes();
 

+ 18 - 0
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/TypeInferrerTest.java

@@ -16,6 +16,8 @@ import org.eclipse.xtext.junit4.InjectWith;
 import org.eclipse.xtext.junit4.XtextRunner;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.yakindu.base.expressions.expressions.Expression;
+import org.yakindu.base.types.inferrer.ITypeSystemInferrer.InferenceResult;
 import org.yakindu.sct.model.stext.stext.EventRaisingExpression;
 import org.yakindu.sct.model.stext.stext.VariableDefinition;
 import org.yakindu.sct.model.stext.test.util.AbstractTypeInferrerTest;
@@ -747,4 +749,20 @@ public class TypeInferrerTest extends AbstractTypeInferrerTest {
 
 		expectIssue(inferType("(true) ? 4 : false"), "Could not determine a common type for integer and boolean.");
 	}
+	
+	@Test
+	public void testParameterizedType() {
+		assertTrue(isIntegerType(
+				inferTypeResultForExpression("t.x", "internal var t:ComplexParameterizedType<integer>").getType()));
+		assertTrue(isIntegerType(inferTypeResultForExpression("t.x.x",
+				"internal var t:ComplexParameterizedType<ComplexParameterizedType<integer> >").getType()));
+
+		assertTrue(
+				isAnyType(inferTypeResultForExpression("t.x", "internal var t:ComplexParameterizedType<>").getType()));
+
+		assertTrue(isAnyType(inferTypeResultForExpression("t.x", "internal var t:ComplexParameterizedType").getType()));
+
+		assertTrue(isAnyType(inferTypeResultForExpression("t.x.x",
+				"internal var t:ComplexParameterizedType<ComplexParameterizedType<> >").getType()));
+	}
 }

+ 9 - 5
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/util/AbstractTypeInferrerTest.java

@@ -84,23 +84,27 @@ public abstract class AbstractTypeInferrerTest extends AbstractSTextTest {
 	}
 
 	protected boolean isVoidType(Type type) {
-		return isType(type, "void");
+		return isType(type, ITypeSystem.VOID);
 	}
 
 	protected boolean isIntegerType(Type type) {
-		return isType(type, "integer");
+		return isType(type, ITypeSystem.INTEGER);
 	}
 
 	protected boolean isRealType(Type type) {
-		return isType(type, "real");
+		return isType(type, ITypeSystem.REAL);
 	}
 
 	protected boolean isBooleanType(Type type) {
-		return isType(type, "boolean");
+		return isType(type, ITypeSystem.BOOLEAN);
 	}
 
 	protected boolean isStringType(Type type) {
-		return isType(type, "string");
+		return isType(type, ITypeSystem.STRING);
+	}
+	
+	protected boolean isAnyType(Type type) {
+		return isType(type, ITypeSystem.ANY);
 	}
 	
 	protected void expectIssue(Type object, String message) {

+ 29 - 1
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/util/STextTestScopeProvider.java

@@ -29,6 +29,7 @@ import org.yakindu.base.types.EnumerationType;
 import org.yakindu.base.types.Enumerator;
 import org.yakindu.base.types.Property;
 import org.yakindu.base.types.Type;
+import org.yakindu.base.types.TypeParameter;
 import org.yakindu.base.types.TypeSpecifier;
 import org.yakindu.base.types.TypesFactory;
 import org.yakindu.base.types.typesystem.GenericTypeSystem;
@@ -74,7 +75,14 @@ public class STextTestScopeProvider extends STextScopeProvider {
 		for (Declaration feature : complexType.getFeatures()) {
 			descriptions.add(createEObjectDesc(feature));
 		}
-
+		
+		ComplexType cmplxParamType = createComplexParameterizedType();
+		descriptions.add(createEObjectDesc(cmplxParamType));
+		
+		for (Declaration feature : cmplxParamType.getFeatures()) {
+			descriptions.add(createEObjectDesc(feature));
+		}
+		
 		return new SimpleScope(descriptions);
 	}
 
@@ -130,5 +138,25 @@ public class STextTestScopeProvider extends STextScopeProvider {
 		enumerator.setName(name);
 		return enumerator;
 	}
+	
+	protected ComplexType createComplexParameterizedType() {
+		ComplexType complexType = TypesFactory.eINSTANCE.createComplexType();
+		complexType.setName("ComplexParameterizedType");
+		
+		TypeParameter typeParam = TypesFactory.eINSTANCE.createTypeParameter();
+		complexType.getParameter().add(typeParam);
+
+		Property featureX = TypesFactory.eINSTANCE.createProperty();
+		featureX.setName("x");
+		TypeSpecifier typeSpec = TypesFactory.eINSTANCE.createTypeSpecifier();
+		typeSpec.setType(typeParam);
+		featureX.setTypeSpecifier(typeSpec);
+		complexType.getFeatures().add(featureX);
+
+		Resource resource = new ResourceImpl(URI.createURI("types2"));
+		resource.getContents().add(complexType);
+
+		return complexType;
+	}
 
 }