Subtyping works for parameterized superclasses
This commit is contained in:
@@ -35,7 +35,7 @@ public class ErrorType extends VisitableTypeImpl implements Type {
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(TypeVisitor<R, D> visitor, D data) {
|
||||
throw new UnsupportedOperationException("Not found: " + debugLabel); // TODO
|
||||
return visitor.visitErrorType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -63,7 +64,7 @@ public class JetTypeChecker {
|
||||
}
|
||||
|
||||
public boolean isConvertibleTo(JetExpression expression, Type type) {
|
||||
return false; //To change body of created methods use File | Settings | File Templates.
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
||||
@@ -107,7 +108,18 @@ public class JetTypeChecker {
|
||||
return substitute(parameterValues, subject);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Type substitute(Map<TypeParameterDescriptor, TypeProjection> parameterValues, Type subject) {
|
||||
if (subject instanceof TypeVariable) {
|
||||
TypeVariable typeVariable = (TypeVariable) subject;
|
||||
TypeProjection value = parameterValues.get(typeVariable.getTypeParameterDescriptor());
|
||||
if (value == null) {
|
||||
return typeVariable;
|
||||
}
|
||||
Type type = value.getType();
|
||||
assert type != null;
|
||||
return type;
|
||||
}
|
||||
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
|
||||
for (TypeProjection argument : subject.getArguments()) {
|
||||
newArguments.add(new TypeProjection(argument.getProjectionKind(), substitute(parameterValues, argument.getType())));
|
||||
@@ -116,8 +128,13 @@ public class JetTypeChecker {
|
||||
}
|
||||
|
||||
private Type specializeType(Type type, List<TypeProjection> newArguments) {
|
||||
// TODO
|
||||
return type;
|
||||
return type.accept(new TypeVisitor<Type, List<TypeProjection>>() {
|
||||
@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) {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,15 @@ import java.util.List;
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -28,6 +28,10 @@ public class TypeVisitor<R, D> {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -158,9 +158,12 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
assertNotSubtype("Base_T<in Int>", "Base_T<out Int>");
|
||||
assertNotSubtype("Base_T<*>", "Base_T<out Int>");
|
||||
|
||||
assertNotSubtype("Derived_T<Any>", "Base_T<Any>");
|
||||
assertSubtype("Derived_outT<Any>", "Base_outT<Any>");
|
||||
assertSubtype("Derived_T<Int>", "Base_T<Int>");
|
||||
assertSubtype("Derived_outT<Int>", "Base_outT<Int>");
|
||||
assertSubtype("Derived_inT<Int>", "Base_inT<Int>");
|
||||
|
||||
assertNotSubtype("Derived_T<Int>", "Base_T<Any>");
|
||||
|
||||
assertSubtype("Derived_outT<Int>", "Base_outT<Any>");
|
||||
assertSubtype("Derived_T<Int>", "Base_T<out Any>");
|
||||
assertSubtype("Derived_T<Any>", "Base_T<in Int>");
|
||||
|
||||
Reference in New Issue
Block a user