Type infrastructure simplified
This commit is contained in:
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.psi.*;
|
|||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,29 +24,48 @@ public class TypeResolver {
|
|||||||
public Type resolveType(@NotNull final JetScope scope, @NotNull final JetTypeReference typeReference) {
|
public Type resolveType(@NotNull final JetScope scope, @NotNull final JetTypeReference typeReference) {
|
||||||
final List<Attribute> attributes = AttributeResolver.INSTANCE.resolveAttributes(typeReference.getAttributes());
|
final List<Attribute> attributes = AttributeResolver.INSTANCE.resolveAttributes(typeReference.getAttributes());
|
||||||
|
|
||||||
|
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||||
|
return resolveTypeElement(scope, attributes, typeElement, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type resolveTypeElement(final JetScope scope, final List<Attribute> attributes, JetTypeElement typeElement, final boolean nullable) {
|
||||||
final Type[] result = new Type[1];
|
final Type[] result = new Type[1];
|
||||||
typeReference.getTypeElement().accept(new JetVisitor() {
|
typeElement.accept(new JetVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void visitUserType(JetUserType type) {
|
public void visitUserType(JetUserType type) {
|
||||||
ClassDescriptor classDescriptor = resolveClass(scope, type);
|
ClassDescriptor classDescriptor = resolveClass(scope, type);
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
result[0] = new ClassType(
|
result[0] = new TypeImpl(
|
||||||
attributes,
|
attributes,
|
||||||
classDescriptor,
|
classDescriptor.getTypeConstructor(),
|
||||||
resolveTypeProjections(scope, type.getTypeArguments())
|
nullable,
|
||||||
|
resolveTypeProjections(scope, type.getTypeArguments()),
|
||||||
|
JetStandardClasses.STUB
|
||||||
);
|
);
|
||||||
} else if (type.getTypeArguments().isEmpty()) {
|
}
|
||||||
|
else if (type.getTypeArguments().isEmpty()) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameterDescriptor(type.getReferencedName());
|
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameterDescriptor(type.getReferencedName());
|
||||||
if (typeParameterDescriptor != null) {
|
if (typeParameterDescriptor != null) {
|
||||||
result[0] = new TypeVariable(attributes, typeParameterDescriptor);
|
result[0] = new TypeImpl(
|
||||||
|
attributes,
|
||||||
|
typeParameterDescriptor.getTypeConstructor(),
|
||||||
|
nullable || hasNullableBound(typeParameterDescriptor),
|
||||||
|
Collections.<TypeProjection>emptyList(),
|
||||||
|
JetStandardClasses.STUB
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNullableType(JetNullableType nullableType) {
|
||||||
|
result[0] = resolveTypeElement(scope, attributes, nullableType.getInnerType(), true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitTupleType(JetTupleType type) {
|
public void visitTupleType(JetTupleType type) {
|
||||||
// TODO labels
|
// TODO labels
|
||||||
result[0] = TupleType.getTupleType(resolveTypes(scope, type.getComponentTypeRefs()));
|
result[0] = JetStandardClasses.getTupleType(resolveTypes(scope, type.getComponentTypeRefs()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -54,11 +74,20 @@ public class TypeResolver {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (result[0] == null) {
|
if (result[0] == null) {
|
||||||
return new ErrorType(typeReference);
|
return ErrorType.createErrorType(typeElement.getText());
|
||||||
}
|
}
|
||||||
return result[0];
|
return result[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasNullableBound(TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
|
for (Type bound : typeParameterDescriptor.getUpperBounds()) {
|
||||||
|
if (bound.isNullable()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private List<Type> resolveTypes(JetScope scope, List<JetTypeReference> argumentElements) {
|
private List<Type> resolveTypes(JetScope scope, List<JetTypeReference> argumentElements) {
|
||||||
final List<Type> arguments = new ArrayList<Type>();
|
final List<Type> arguments = new ArrayList<Type>();
|
||||||
for (JetTypeReference argumentElement : argumentElements) {
|
for (JetTypeReference argumentElement : argumentElements) {
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class ClassType extends TypeImpl {
|
|
||||||
@NotNull
|
|
||||||
private final ClassDescriptor classDescriptor;
|
|
||||||
|
|
||||||
public ClassType(@NotNull List<Attribute> attributes, @NotNull ClassDescriptor classDescriptor, @NotNull List<TypeProjection> arguments) {
|
|
||||||
super(attributes, classDescriptor.getTypeConstructor(), arguments);
|
|
||||||
assert classDescriptor.getTypeConstructor().getParameters().size() == arguments.size() : classDescriptor.getTypeConstructor().getParameters().size() + " != " + arguments.size();
|
|
||||||
|
|
||||||
this.classDescriptor = classDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassType(ClassDescriptor classDescriptor) {
|
|
||||||
this(Collections.<Attribute>emptyList(), classDescriptor, Collections.<TypeProjection>emptyList());
|
|
||||||
assert classDescriptor.getTypeConstructor().getParameters().size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ClassDescriptor getClassDescriptor() {
|
|
||||||
return classDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MemberDescriptor> getMembers() {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitClassType(this, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +1,26 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class ErrorType extends VisitableTypeImpl implements Type {
|
public class ErrorType {
|
||||||
private final String debugLabel;
|
private static final TypeMemberDomain ERROR_DOMAIN = new TypeMemberDomain() {
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClassDescriptor(@NotNull Type type) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private static final TypeConstructor ERROR = new TypeConstructor(Collections.<Attribute>emptyList(), "ERROR", Collections.<TypeParameterDescriptor>emptyList(), Collections.<Type>emptyList());
|
||||||
|
|
||||||
public ErrorType(JetTypeReference typeReference) {
|
public static Type createErrorType(String debugMessage) {
|
||||||
super(Collections.<Attribute>emptyList());
|
return new TypeImpl(ERROR, ERROR_DOMAIN);
|
||||||
this.debugLabel = typeReference.getText();
|
|
||||||
assert debugLabel != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static boolean isError(Type type) {
|
||||||
public TypeConstructor getConstructor() {
|
return type.getConstructor() == ERROR;
|
||||||
throw new UnsupportedOperationException("Not found: " + debugLabel); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TypeProjection> getArguments() {
|
|
||||||
throw new UnsupportedOperationException("Not found: " + debugLabel); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MemberDescriptor> getMembers() {
|
|
||||||
throw new UnsupportedOperationException("Not found: " + debugLabel); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitErrorType(this, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "!!!" + debugLabel + "!!!";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,34 @@ package org.jetbrains.jet.lang.types;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class JetStandardClasses {
|
public class JetStandardClasses {
|
||||||
|
private static final TypeConstructor NOTHING = new TypeConstructor(
|
||||||
|
Collections.<Attribute>emptyList(),
|
||||||
|
"Nothing",
|
||||||
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
|
new AbstractCollection<Type>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return o instanceof Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Type> iterator() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
private static final ClassDescriptor ANY = new ClassDescriptor(
|
private static final ClassDescriptor ANY = new ClassDescriptor(
|
||||||
Collections.<Attribute>emptyList(),
|
Collections.<Attribute>emptyList(),
|
||||||
"Any",
|
"Any",
|
||||||
@@ -17,7 +37,7 @@ public class JetStandardClasses {
|
|||||||
Collections.<Type>emptySet()
|
Collections.<Type>emptySet()
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final ClassType ANY_TYPE = new ClassType(ANY);
|
private static final Type ANY_TYPE = new TypeImpl(ANY.getTypeConstructor(), TypeMemberDomain.EMPTY);
|
||||||
|
|
||||||
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte");
|
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte");
|
||||||
private static final ClassDescriptor CHAR = new ClassDescriptor("Char");
|
private static final ClassDescriptor CHAR = new ClassDescriptor("Char");
|
||||||
@@ -48,13 +68,33 @@ public class JetStandardClasses {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final TypeMemberDomain STUB = new TypeMemberDomain() {
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClassDescriptor(@NotNull Type type) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Type BYTE_TYPE = new TypeImpl(getByte().getTypeConstructor(), STUB);
|
||||||
|
private static final Type CHAR_TYPE = new TypeImpl(getChar().getTypeConstructor(), STUB);
|
||||||
|
private static final Type SHORT_TYPE = new TypeImpl(getShort().getTypeConstructor(), STUB);
|
||||||
|
private static final Type INT_TYPE = new TypeImpl(getInt().getTypeConstructor(), STUB);
|
||||||
|
private static final Type LONG_TYPE = new TypeImpl(getLong().getTypeConstructor(), STUB);
|
||||||
|
private static final Type FLOAT_TYPE = new TypeImpl(getFloat().getTypeConstructor(), STUB);
|
||||||
|
private static final Type DOUBLE_TYPE = new TypeImpl(getDouble().getTypeConstructor(), STUB);
|
||||||
|
private static final Type BOOLEAN_TYPE = new TypeImpl(getBoolean().getTypeConstructor(), STUB);
|
||||||
|
private static final Type STRING_TYPE = new TypeImpl(getString().getTypeConstructor(), STUB);
|
||||||
|
private static final Type UNIT_TYPE = new TypeImpl(getTuple(0).getTypeConstructor(), STUB);
|
||||||
|
private static final Type NOTHING_TYPE = new TypeImpl(NOTHING, STUB);
|
||||||
|
private static final Type NULLABLE_NOTHING_TYPE = new TypeImpl(Collections.<Attribute>emptyList(), NOTHING, true, Collections.<TypeProjection>emptyList(), TypeMemberDomain.EMPTY);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ClassDescriptor getAny() {
|
public static ClassDescriptor getAny() {
|
||||||
return ANY;
|
return ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ClassType getAnyType() {
|
public static Type getAnyType() {
|
||||||
return ANY_TYPE;
|
return ANY_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,9 +148,92 @@ public class JetStandardClasses {
|
|||||||
return TUPLE[size];
|
return TUPLE[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
public static Type getIntType() {
|
||||||
public static ClassDescriptor getLabeledTuple(int size) {
|
return INT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getLongType() {
|
||||||
|
return LONG_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getDoubleType() {
|
||||||
|
return DOUBLE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getFloatType() {
|
||||||
|
return FLOAT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getCharType() {
|
||||||
|
return CHAR_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getBooleanType() {
|
||||||
|
return BOOLEAN_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getStringType() {
|
||||||
|
return STRING_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getByteType() {
|
||||||
|
return BYTE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getShortType() {
|
||||||
|
return SHORT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getUnitType() {
|
||||||
|
return UNIT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getNothingType() {
|
||||||
|
return NOTHING_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getNullableNothingType() {
|
||||||
|
return NULLABLE_NOTHING_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getTupleType(List<Attribute> attributes, List<Type> arguments) {
|
||||||
|
if (attributes.isEmpty() && arguments.isEmpty()) {
|
||||||
|
return getUnitType();
|
||||||
|
}
|
||||||
|
return new TypeImpl(attributes, getTuple(arguments.size()).getTypeConstructor(), false, toProjections(arguments), STUB);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getTupleType(List<Type> arguments) {
|
||||||
|
return getTupleType(Collections.<Attribute>emptyList(), arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getTupleType(Type... arguments) {
|
||||||
|
return getTupleType(Collections.<Attribute>emptyList(), Arrays.asList(arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getLabeledTupleType(List<Attribute> attributes, List<ParameterDescriptor> arguments) {
|
||||||
// TODO
|
// TODO
|
||||||
return getTuple(size);
|
return getTupleType(attributes, toTypes(arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getLabeledTupleType(List<ParameterDescriptor> arguments) {
|
||||||
|
// TODO
|
||||||
|
return getLabeledTupleType(Collections.<Attribute>emptyList(), arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<TypeProjection> toProjections(List<Type> arguments) {
|
||||||
|
List<TypeProjection> result = new ArrayList<TypeProjection>();
|
||||||
|
for (Type argument : arguments) {
|
||||||
|
result.add(new TypeProjection(ProjectionKind.OUT_ONLY, argument));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Type> toTypes(List<ParameterDescriptor> labeledEntries) {
|
||||||
|
List<Type> result = new ArrayList<Type>();
|
||||||
|
for (ParameterDescriptor entry : labeledEntries) {
|
||||||
|
result.add(entry.getType());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class JetStandardTypes {
|
|
||||||
private static final ClassType ANY_TYPE = new ClassType(JetStandardClasses.getAny());
|
|
||||||
private static final ClassType BYTE = new ClassType(JetStandardClasses.getByte());
|
|
||||||
private static final ClassType CHAR = new ClassType(JetStandardClasses.getChar());
|
|
||||||
private static final ClassType SHORT = new ClassType(JetStandardClasses.getShort());
|
|
||||||
private static final ClassType INT = new ClassType(JetStandardClasses.getInt());
|
|
||||||
private static final ClassType LONG = new ClassType(JetStandardClasses.getLong());
|
|
||||||
private static final ClassType FLOAT = new ClassType(JetStandardClasses.getFloat());
|
|
||||||
private static final ClassType DOUBLE = new ClassType(JetStandardClasses.getDouble());
|
|
||||||
private static final ClassType BOOLEAN = new ClassType(JetStandardClasses.getBoolean());
|
|
||||||
private static final ClassType STRING = new ClassType(JetStandardClasses.getString());
|
|
||||||
private static final TupleType UNIT = TupleType.UNIT;
|
|
||||||
|
|
||||||
public static ClassType getInt() {
|
|
||||||
return INT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getLong() {
|
|
||||||
return LONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getDouble() {
|
|
||||||
return DOUBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getFloat() {
|
|
||||||
return FLOAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getChar() {
|
|
||||||
return CHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getBoolean() {
|
|
||||||
return BOOLEAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getString() {
|
|
||||||
return STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getByte() {
|
|
||||||
return BYTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassType getShort() {
|
|
||||||
return SHORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TupleType getUnit() {
|
|
||||||
return UNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Type getAny() {
|
|
||||||
return ANY_TYPE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,6 +15,8 @@ import java.util.Map;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class JetTypeChecker {
|
public class JetTypeChecker {
|
||||||
|
public static final JetTypeChecker INSTANCE = new JetTypeChecker();
|
||||||
|
|
||||||
public Type getType(JetExpression expression) {
|
public Type getType(JetExpression expression) {
|
||||||
final Type[] result = new Type[1];
|
final Type[] result = new Type[1];
|
||||||
expression.accept(new JetVisitor() {
|
expression.accept(new JetVisitor() {
|
||||||
@@ -22,24 +24,26 @@ public class JetTypeChecker {
|
|||||||
public void visitConstantExpression(JetConstantExpression expression) {
|
public void visitConstantExpression(JetConstantExpression expression) {
|
||||||
IElementType elementType = expression.getNode().getElementType();
|
IElementType elementType = expression.getNode().getElementType();
|
||||||
if (elementType == JetNodeTypes.INTEGER_CONSTANT) {
|
if (elementType == JetNodeTypes.INTEGER_CONSTANT) {
|
||||||
result[0] = JetStandardTypes.getInt();
|
result[0] = JetStandardClasses.getIntType();
|
||||||
} else if (elementType == JetNodeTypes.LONG_CONSTANT) {
|
} else if (elementType == JetNodeTypes.LONG_CONSTANT) {
|
||||||
result[0] = JetStandardTypes.getLong();
|
result[0] = JetStandardClasses.getLongType();
|
||||||
} else if (elementType == JetNodeTypes.FLOAT_CONSTANT) {
|
} else if (elementType == JetNodeTypes.FLOAT_CONSTANT) {
|
||||||
String text = expression.getText();
|
String text = expression.getText();
|
||||||
assert text.length() > 0;
|
assert text.length() > 0;
|
||||||
char lastChar = text.charAt(text.length() - 1);
|
char lastChar = text.charAt(text.length() - 1);
|
||||||
if (lastChar == 'f' || lastChar == 'F') {
|
if (lastChar == 'f' || lastChar == 'F') {
|
||||||
result[0] = JetStandardTypes.getFloat();
|
result[0] = JetStandardClasses.getFloatType();
|
||||||
} else {
|
} else {
|
||||||
result[0] = JetStandardTypes.getDouble();
|
result[0] = JetStandardClasses.getDoubleType();
|
||||||
}
|
}
|
||||||
} else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) {
|
} else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) {
|
||||||
result[0] = JetStandardTypes.getBoolean();
|
result[0] = JetStandardClasses.getBooleanType();
|
||||||
} else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) {
|
} else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) {
|
||||||
result[0] = JetStandardTypes.getChar();
|
result[0] = JetStandardClasses.getCharType();
|
||||||
} else if (elementType == JetNodeTypes.STRING_CONSTANT) {
|
} else if (elementType == JetNodeTypes.STRING_CONSTANT) {
|
||||||
result[0] = JetStandardTypes.getString();
|
result[0] = JetStandardClasses.getStringType();
|
||||||
|
} else if (elementType == JetNodeTypes.NULL) {
|
||||||
|
result[0] = JetStandardClasses.getNullableNothingType();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported constant: " + expression);
|
throw new IllegalArgumentException("Unsupported constant: " + expression);
|
||||||
}
|
}
|
||||||
@@ -52,7 +56,7 @@ public class JetTypeChecker {
|
|||||||
for (JetExpression entry : entries) {
|
for (JetExpression entry : entries) {
|
||||||
types.add(getType(entry));
|
types.add(getType(entry));
|
||||||
}
|
}
|
||||||
result[0] = TupleType.getTupleType(types);
|
result[0] = JetStandardClasses.getTupleType(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -68,8 +72,10 @@ public class JetTypeChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
||||||
@Nullable
|
if (!supertype.isNullable() && subtype.isNullable()) {
|
||||||
Type closestSupertype = findCorrespondingSupertype(subtype, supertype);
|
return false;
|
||||||
|
}
|
||||||
|
@Nullable Type closestSupertype = findCorrespondingSupertype(subtype, supertype);
|
||||||
if (closestSupertype == null) {
|
if (closestSupertype == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -95,30 +101,24 @@ public class JetTypeChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type substituteForParameters(Type context, Type subject) {
|
private Type substituteForParameters(Type context, Type subject) {
|
||||||
Map<TypeParameterDescriptor, TypeProjection> parameterValues = new HashMap<TypeParameterDescriptor, TypeProjection>();
|
Map<TypeConstructor, TypeProjection> parameterValues = new HashMap<TypeConstructor, TypeProjection>();
|
||||||
|
|
||||||
List<TypeParameterDescriptor> parameters = context.getConstructor().getParameters();
|
List<TypeParameterDescriptor> parameters = context.getConstructor().getParameters();
|
||||||
List<TypeProjection> contextArguments = context.getArguments();
|
List<TypeProjection> contextArguments = context.getArguments();
|
||||||
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
||||||
TypeParameterDescriptor parameter = parameters.get(i);
|
TypeParameterDescriptor parameter = parameters.get(i);
|
||||||
TypeProjection value = contextArguments.get(i);
|
TypeProjection value = contextArguments.get(i);
|
||||||
parameterValues.put(parameter, value);
|
parameterValues.put(parameter.getTypeConstructor(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return substitute(parameterValues, subject);
|
return substitute(parameterValues, subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Type substitute(Map<TypeParameterDescriptor, TypeProjection> parameterValues, Type subject) {
|
private Type substitute(Map<TypeConstructor, TypeProjection> parameterValues, Type subject) {
|
||||||
if (subject instanceof TypeVariable) {
|
TypeProjection value = parameterValues.get(subject.getConstructor());
|
||||||
TypeVariable typeVariable = (TypeVariable) subject;
|
if (value != null) {
|
||||||
TypeProjection value = parameterValues.get(typeVariable.getTypeParameterDescriptor());
|
return value.getType();
|
||||||
if (value == null) {
|
|
||||||
return typeVariable;
|
|
||||||
}
|
|
||||||
Type type = value.getType();
|
|
||||||
assert type != null;
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
|
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
|
||||||
for (TypeProjection argument : subject.getArguments()) {
|
for (TypeProjection argument : subject.getArguments()) {
|
||||||
@@ -128,13 +128,7 @@ public class JetTypeChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type specializeType(Type type, List<TypeProjection> newArguments) {
|
private Type specializeType(Type type, List<TypeProjection> newArguments) {
|
||||||
return type.accept(new TypeVisitor<Type, List<TypeProjection>>() {
|
return new TypeImpl(type.getAttributes(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberDomain());
|
||||||
@Override
|
|
||||||
public Type visitClassType(ClassType classType, List<TypeProjection> newArguments) {
|
|
||||||
return new ClassType(classType.getAttributes(), classType.getClassDescriptor(), newArguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, newArguments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkSubtypeForTheSameConstructor(Type subtype, Type supertype) {
|
private boolean checkSubtypeForTheSameConstructor(Type subtype, Type supertype) {
|
||||||
@@ -212,7 +206,7 @@ public class JetTypeChecker {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean equalTypes(Type type1, Type type2) {
|
public boolean equalTypes(Type type1, Type type2) {
|
||||||
if (!type1.getConstructor().equals(type2.getConstructor())) {
|
if (!type1.getConstructor().equals(type2.getConstructor())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class NothingType extends TypeImpl {
|
|
||||||
|
|
||||||
public static final TypeConstructor NOTHING = new TypeConstructor(
|
|
||||||
Collections.<Attribute>emptyList(),
|
|
||||||
"Nothing",
|
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
|
||||||
new AbstractCollection<Type>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(Object o) {
|
|
||||||
return o instanceof Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<Type> iterator() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: attributes seem wrong here
|
|
||||||
public NothingType(List<Attribute> attributes) {
|
|
||||||
super(attributes, NOTHING, Collections.<TypeProjection>emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MemberDescriptor> getMembers() {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitNothingType(this, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class NullableType extends VisitableTypeImpl {
|
|
||||||
public NullableType(List<Attribute> attributes) {
|
|
||||||
super(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeConstructor getConstructor() {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TypeProjection> getArguments() {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MemberDescriptor> getMembers() {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitNullableType(this, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class ThisType extends TypeImpl {
|
|
||||||
public ThisType(List<Attribute> attributes, ClassDescriptor thisClass) {
|
|
||||||
super(attributes, thisClass.getTypeConstructor(), toArguments(thisClass.getTypeConstructor().getParameters()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<TypeProjection> toArguments(List<TypeParameterDescriptor> parameters) {
|
|
||||||
List<TypeProjection> result = new ArrayList<TypeProjection>();
|
|
||||||
for (TypeParameterDescriptor parameter : parameters) {
|
|
||||||
result.add(new TypeProjection(new TypeVariable(Collections.<Attribute>emptyList(), parameter)));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MemberDescriptor> getMembers() {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitThisType(this, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class TupleType extends TypeImpl {
|
|
||||||
|
|
||||||
public static final TupleType UNIT = new TupleType(Collections.<Attribute>emptyList(), Collections.<Type>emptyList());
|
|
||||||
|
|
||||||
public static TupleType getTupleType(List<Attribute> attributes, List<Type> arguments) {
|
|
||||||
if (attributes.isEmpty() && arguments.isEmpty()) {
|
|
||||||
return UNIT;
|
|
||||||
}
|
|
||||||
return new TupleType(attributes, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static TupleType getTupleType(List<Type> arguments) {
|
|
||||||
return getTupleType(Collections.<Attribute>emptyList(), arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TupleType getLabeledTupleType(List<Attribute> attributes, List<ParameterDescriptor> arguments) {
|
|
||||||
return getTupleType(attributes, toTypes(arguments));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static TupleType getLabeledTupleType(List<ParameterDescriptor> arguments) {
|
|
||||||
return getLabeledTupleType(Collections.<Attribute>emptyList(), arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private TupleType(List<Attribute> attributes, List<Type> arguments) {
|
|
||||||
super(attributes, JetStandardClasses.getTuple(arguments.size()).getTypeConstructor(), toProjections(arguments));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MemberDescriptor> getMembers() {
|
|
||||||
throw new UnsupportedOperationException("Not implemented"); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitTupleType(this, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<TypeProjection> toProjections(List<Type> arguments) {
|
|
||||||
List<TypeProjection> result = new ArrayList<TypeProjection>();
|
|
||||||
for (Type argument : arguments) {
|
|
||||||
result.add(new TypeProjection(ProjectionKind.OUT_ONLY, argument));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Type> toTypes(List<ParameterDescriptor> labeledEntries) {
|
|
||||||
List<Type> result = new ArrayList<Type>();
|
|
||||||
for (ParameterDescriptor entry : labeledEntries) {
|
|
||||||
result.add(entry.getType());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import java.util.Collection;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public interface Type extends Annotated {
|
public interface Type extends Annotated {
|
||||||
TypeConstructor getConstructor();
|
@NotNull TypeConstructor getConstructor();
|
||||||
List<TypeProjection> getArguments();
|
@NotNull List<TypeProjection> getArguments();
|
||||||
|
boolean isNullable();
|
||||||
|
|
||||||
Collection<MemberDescriptor> getMembers();
|
@NotNull TypeMemberDomain getMemberDomain();
|
||||||
|
|
||||||
<R, D> R accept(TypeVisitor<R, D> visitor, D data);
|
@NotNull Type getNullableVersion();
|
||||||
<R> R acceptNoData(TypeVisitor<R, ?> visitor);
|
|
||||||
void acceptVoid(TypeVisitor<?, ?> visitor);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,38 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public abstract class TypeImpl extends VisitableTypeImpl {
|
public final class TypeImpl extends AnnotatedImpl implements Type {
|
||||||
|
|
||||||
private final TypeConstructor constructor;
|
private final TypeConstructor constructor;
|
||||||
private final List<TypeProjection> arguments;
|
private final List<TypeProjection> arguments;
|
||||||
|
private final boolean nullable;
|
||||||
|
private final TypeMemberDomain memberDomain;
|
||||||
|
|
||||||
public TypeImpl(List<Attribute> attributes, TypeConstructor constructor, List<TypeProjection> arguments) {
|
public TypeImpl(List<Attribute> attributes, TypeConstructor constructor, boolean nullable, List<TypeProjection> arguments, TypeMemberDomain memberDomain) {
|
||||||
super(attributes);
|
super(attributes);
|
||||||
this.constructor = constructor;
|
this.constructor = constructor;
|
||||||
|
this.nullable = nullable;
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
|
this.memberDomain = memberDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeImpl(TypeConstructor constructor, TypeMemberDomain memberDomain) {
|
||||||
|
this(Collections.<Attribute>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getNullableVersion() {
|
||||||
|
if (isNullable()) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
// TODO: cache these?
|
||||||
|
return new TypeImpl(getAttributes(), constructor, true, arguments, memberDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -27,9 +45,19 @@ public abstract class TypeImpl extends VisitableTypeImpl {
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return nullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeMemberDomain getMemberDomain() {
|
||||||
|
return memberDomain;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return constructor + (arguments.isEmpty() ? "" : "<" + argumentsToString() + ">");
|
return constructor + (arguments.isEmpty() ? "" : "<" + argumentsToString() + ">") + (isNullable() ? "?" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuilder argumentsToString() {
|
private StringBuilder argumentsToString() {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface TypeMemberDomain {
|
||||||
|
TypeMemberDomain EMPTY = new TypeMemberDomain() {
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClassDescriptor(@NotNull Type type) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Nullable ClassDescriptor getClassDescriptor(@NotNull Type type);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ public class TypeParameterDescriptor extends NamedAnnotatedImpl {
|
|||||||
// TODO: Should we actually pass the attributes on to the type constructor?
|
// TODO: Should we actually pass the attributes on to the type constructor?
|
||||||
this.typeConstructor = new TypeConstructor(
|
this.typeConstructor = new TypeConstructor(
|
||||||
attributes,
|
attributes,
|
||||||
name,
|
"&" + name,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
upperBounds);
|
upperBounds);
|
||||||
}
|
}
|
||||||
@@ -35,4 +35,9 @@ public class TypeParameterDescriptor extends NamedAnnotatedImpl {
|
|||||||
public TypeConstructor getTypeConstructor() {
|
public TypeConstructor getTypeConstructor() {
|
||||||
return typeConstructor;
|
return typeConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return typeConstructor.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class TypeVariable extends TypeImpl {
|
|
||||||
|
|
||||||
private final TypeParameterDescriptor typeParameterDescriptor;
|
|
||||||
|
|
||||||
public TypeVariable(@NotNull List<Attribute> attributes, @NotNull TypeParameterDescriptor typeParameter) {
|
|
||||||
super(attributes, typeParameter.getTypeConstructor(), Collections.<TypeProjection>emptyList());
|
|
||||||
this.typeParameterDescriptor = typeParameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor() {
|
|
||||||
return typeParameterDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MemberDescriptor> getMembers() {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitTypeVariable(this, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "&" + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class TypeVisitor<R, D> {
|
|
||||||
public R visitNothingType(NothingType nothingType, D data) {
|
|
||||||
return visitType(nothingType, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitTupleType(TupleType tupleType, D data) {
|
|
||||||
return visitType(tupleType, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitTypeVariable(TypeVariable typeVariable, D data) {
|
|
||||||
return visitType(typeVariable, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitClassType(ClassType classType, D data) {
|
|
||||||
return visitType(classType, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitThisType(ThisType thisType, D data) {
|
|
||||||
return visitType(thisType, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitErrorType(ErrorType errorType, D data) {
|
|
||||||
return visitType(errorType, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitNullableType(NullableType nullableType, D data) {
|
|
||||||
return visitType(nullableType, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitType(Type type, D data) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public abstract class VisitableTypeImpl extends AnnotatedImpl implements Type {
|
|
||||||
public VisitableTypeImpl(List<Attribute> attributes) {
|
|
||||||
super(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R> R acceptNoData(TypeVisitor<R, ?> visitor) {
|
|
||||||
return accept(visitor, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void acceptVoid(TypeVisitor<?, ?> visitor) {
|
|
||||||
accept(visitor, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,33 +29,41 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testConstants() throws Exception {
|
public void testConstants() throws Exception {
|
||||||
assertType("1", JetStandardTypes.getInt());
|
assertType("1", JetStandardClasses.getIntType());
|
||||||
assertType("0x1", JetStandardTypes.getInt());
|
assertType("0x1", JetStandardClasses.getIntType());
|
||||||
assertType("0X1", JetStandardTypes.getInt());
|
assertType("0X1", JetStandardClasses.getIntType());
|
||||||
assertType("0b1", JetStandardTypes.getInt());
|
assertType("0b1", JetStandardClasses.getIntType());
|
||||||
assertType("0B1", JetStandardTypes.getInt());
|
assertType("0B1", JetStandardClasses.getIntType());
|
||||||
|
|
||||||
assertType("1l", JetStandardTypes.getLong());
|
assertType("1l", JetStandardClasses.getLongType());
|
||||||
assertType("1L", JetStandardTypes.getLong());
|
assertType("1L", JetStandardClasses.getLongType());
|
||||||
|
|
||||||
assertType("1.0", JetStandardTypes.getDouble());
|
assertType("1.0", JetStandardClasses.getDoubleType());
|
||||||
assertType("1.0d", JetStandardTypes.getDouble());
|
assertType("1.0d", JetStandardClasses.getDoubleType());
|
||||||
assertType("1.0D", JetStandardTypes.getDouble());
|
assertType("1.0D", JetStandardClasses.getDoubleType());
|
||||||
assertType("0x1.fffffffffffffp1023", JetStandardTypes.getDouble());
|
assertType("0x1.fffffffffffffp1023", JetStandardClasses.getDoubleType());
|
||||||
|
|
||||||
assertType("1.0f", JetStandardTypes.getFloat());
|
assertType("1.0f", JetStandardClasses.getFloatType());
|
||||||
assertType("1.0F", JetStandardTypes.getFloat());
|
assertType("1.0F", JetStandardClasses.getFloatType());
|
||||||
assertType("0x1.fffffffffffffp1023f", JetStandardTypes.getFloat());
|
assertType("0x1.fffffffffffffp1023f", JetStandardClasses.getFloatType());
|
||||||
|
|
||||||
assertType("true", JetStandardTypes.getBoolean());
|
assertType("true", JetStandardClasses.getBooleanType());
|
||||||
assertType("false", JetStandardTypes.getBoolean());
|
assertType("false", JetStandardClasses.getBooleanType());
|
||||||
|
|
||||||
assertType("'d'", JetStandardTypes.getChar());
|
assertType("'d'", JetStandardClasses.getCharType());
|
||||||
|
|
||||||
assertType("\"d\"", JetStandardTypes.getString());
|
assertType("\"d\"", JetStandardClasses.getStringType());
|
||||||
assertType("\"\"\"d\"\"\"", JetStandardTypes.getString());
|
assertType("\"\"\"d\"\"\"", JetStandardClasses.getStringType());
|
||||||
|
|
||||||
assertType("()", JetStandardTypes.getUnit());
|
assertType("()", JetStandardClasses.getUnitType());
|
||||||
|
|
||||||
|
assertType("null", JetStandardClasses.getNullableNothingType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTupleConstants() throws Exception {
|
||||||
|
assertType("()", JetStandardClasses.getUnitType());
|
||||||
|
|
||||||
|
assertType("(1, 'a')", JetStandardClasses.getTupleType(JetStandardClasses.getIntType(), JetStandardClasses.getCharType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBasicSubtyping() throws Exception {
|
public void testBasicSubtyping() throws Exception {
|
||||||
@@ -170,7 +178,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testImplicitConversions() throws Exception {
|
public void testImplicitConversions() throws Exception {
|
||||||
assertConvertibleTo("1", JetStandardTypes.getByte());
|
assertConvertibleTo("1", JetStandardClasses.getByteType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertSubtype(String type1, String type2) {
|
private static void assertSubtype(String type1, String type2) {
|
||||||
@@ -184,7 +192,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
private static void assertSubtypingRelation(String type1, String type2, boolean expected) {
|
private static void assertSubtypingRelation(String type1, String type2, boolean expected) {
|
||||||
Type typeNode1 = TypeResolver.INSTANCE.resolveType(ClassDefinitions.BASIC_SCOPE, JetChangeUtil.createType(getProject(), type1));
|
Type typeNode1 = TypeResolver.INSTANCE.resolveType(ClassDefinitions.BASIC_SCOPE, JetChangeUtil.createType(getProject(), type1));
|
||||||
Type typeNode2 = TypeResolver.INSTANCE.resolveType(ClassDefinitions.BASIC_SCOPE, JetChangeUtil.createType(getProject(), type2));
|
Type typeNode2 = TypeResolver.INSTANCE.resolveType(ClassDefinitions.BASIC_SCOPE, JetChangeUtil.createType(getProject(), type2));
|
||||||
boolean result = new JetTypeChecker().isSubtypeOf(
|
boolean result = JetTypeChecker.INSTANCE.isSubtypeOf(
|
||||||
typeNode1,
|
typeNode1,
|
||||||
typeNode2);
|
typeNode2);
|
||||||
String modifier = expected ? "not " : "";
|
String modifier = expected ? "not " : "";
|
||||||
@@ -195,21 +203,21 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
||||||
assertTrue(
|
assertTrue(
|
||||||
expression + " must be convertible to " + type,
|
expression + " must be convertible to " + type,
|
||||||
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
JetTypeChecker.INSTANCE.isConvertibleTo(jetExpression, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertNotConvertibleTo(String expression, Type type) {
|
private static void assertNotConvertibleTo(String expression, Type type) {
|
||||||
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
||||||
assertFalse(
|
assertFalse(
|
||||||
expression + " must not be convertible to " + type,
|
expression + " must not be convertible to " + type,
|
||||||
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
JetTypeChecker.INSTANCE.isConvertibleTo(jetExpression, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertType(String expression, Type expectedType) {
|
private static void assertType(String expression, Type expectedType) {
|
||||||
Project project = getProject();
|
Project project = getProject();
|
||||||
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||||
Type type = new JetTypeChecker().getType(jetExpression);
|
Type type = JetTypeChecker.INSTANCE.getType(jetExpression);
|
||||||
assertEquals(type, expectedType);
|
assertTrue(type + "!=" + expectedType, JetTypeChecker.INSTANCE.equalTypes(type, expectedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ClassDefinitions {
|
private static class ClassDefinitions {
|
||||||
|
|||||||
Reference in New Issue
Block a user