Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-05-13 20:54:57 +04:00
9 changed files with 86 additions and 28 deletions
@@ -425,14 +425,7 @@ public class ClassCodegen {
null); null);
mv.visitCode(); mv.visitCode();
InstructionAdapter v = new InstructionAdapter(mv); InstructionAdapter v = new InstructionAdapter(mv);
String owner = JetTypeMapper.jvmNameForImplementation(descriptor); ExpressionCodegen.loadTypeInfo(descriptor, v);
if (descriptor.getTypeConstructor().getParameters().size() > 0) {
v.load(0, JetTypeMapper.TYPE_OBJECT);
v.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
}
else {
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
}
v.areturn(JetTypeMapper.TYPE_TYPEINFO); v.areturn(JetTypeMapper.TYPE_TYPEINFO);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
@@ -76,6 +76,17 @@ public class ExpressionCodegen extends JetVisitor {
this.bindingContext = bindingContext; this.bindingContext = bindingContext;
} }
static void loadTypeInfo(ClassDescriptor descriptor, InstructionAdapter v) {
String owner = JetTypeMapper.jvmNameForImplementation(descriptor);
if (descriptor.getTypeConstructor().getParameters().size() > 0) {
v.load(0, JetTypeMapper.TYPE_OBJECT);
v.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
}
else {
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
}
}
private void gen(JetElement expr) { private void gen(JetElement expr) {
if (expr == null) throw new CompilationException(); if (expr == null) throw new CompilationException();
expr.accept(this); expr.accept(this);
@@ -1301,7 +1312,7 @@ public class ExpressionCodegen extends JetVisitor {
throw new UnsupportedOperationException("don't know how to handle non-class types in is"); throw new UnsupportedOperationException("don't know how to handle non-class types in is");
} }
if (jetType.getArguments().size() > 0) { if (jetType.getArguments().size() > 0) {
newTypeInfo(jetType); generateTypeInfo(jetType);
gen(expression.getLeftHandSide(), OBJECT_TYPE); gen(expression.getLeftHandSide(), OBJECT_TYPE);
v.invokevirtual("jet/typeinfo/TypeInfo", "isInstance", "(Ljava/lang/Object;)Z"); v.invokevirtual("jet/typeinfo/TypeInfo", "isInstance", "(Ljava/lang/Object;)Z");
} }
@@ -1314,11 +1325,23 @@ public class ExpressionCodegen extends JetVisitor {
myStack.push(expression.isNot() ? StackValue.not(value) : value); myStack.push(expression.isNot() ? StackValue.not(value) : value);
} }
private void newTypeInfo(JetType jetType) { private void generateTypeInfo(JetType jetType) {
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof TypeParameterDescriptor) {
DeclarationDescriptor containingDeclaration = declarationDescriptor.getContainingDeclaration();
if (containingDeclaration == contextType && contextType instanceof ClassDescriptor) {
int index = indexOfTypeParameter((ClassDescriptor) contextType, (TypeParameterDescriptor) declarationDescriptor);
loadTypeInfo((ClassDescriptor) contextType, v);
v.iconst(index);
v.invokevirtual("jet/typeinfo/TypeInfo", "getTypeParameter", "(I)Ljet/typeinfo/TypeInfo;");
return;
}
throw new UnsupportedOperationException("don't know what this type parameter resolves to");
}
v.anew(JetTypeMapper.TYPE_TYPEINFO); v.anew(JetTypeMapper.TYPE_TYPEINFO);
v.dup(); v.dup();
v.aconst(typeMapper.jvmType((ClassDescriptor) declarationDescriptor, OwnerKind.INTERFACE));
v.aconst(typeMapper.jvmType((ClassDescriptor) jetType.getConstructor().getDeclarationDescriptor(), OwnerKind.INTERFACE));
List<TypeProjection> arguments = jetType.getArguments(); List<TypeProjection> arguments = jetType.getArguments();
if (arguments.size() > 0) { if (arguments.size() > 0) {
v.iconst(arguments.size()); v.iconst(arguments.size());
@@ -1328,7 +1351,7 @@ public class ExpressionCodegen extends JetVisitor {
TypeProjection argument = arguments.get(i); TypeProjection argument = arguments.get(i);
v.dup(); v.dup();
v.iconst(i); v.iconst(i);
newTypeInfo(argument.getType()); generateTypeInfo(argument.getType());
v.astore(JetTypeMapper.TYPE_OBJECT); v.astore(JetTypeMapper.TYPE_OBJECT);
} }
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V"); v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V");
@@ -1338,6 +1361,15 @@ public class ExpressionCodegen extends JetVisitor {
} }
} }
private int indexOfTypeParameter(ClassDescriptor classDescriptor, TypeParameterDescriptor typeParameterDescriptor) {
List<TypeParameterDescriptor> parameters = classDescriptor.getTypeConstructor().getParameters();
int index = parameters.indexOf(typeParameterDescriptor);
if (index < 0) {
throw new UnsupportedOperationException("can't find type parameter index");
}
return index;
}
private static class CompilationException extends RuntimeException { private static class CompilationException extends RuntimeException {
} }
} }
@@ -16,8 +16,9 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<Annotation> annotations, @NotNull List<Annotation> annotations,
@NotNull Variance variance, @NotNull Variance variance,
@NotNull String name) { @NotNull String name,
TypeParameterDescriptor typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, variance, name); int index) {
TypeParameterDescriptor typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, variance, name, index);
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound()); typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound());
return typeParameterDescriptor; return typeParameterDescriptor;
} }
@@ -26,10 +27,12 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<Annotation> annotations, @NotNull List<Annotation> annotations,
@NotNull Variance variance, @NotNull Variance variance,
@NotNull String name) { @NotNull String name,
return new TypeParameterDescriptor(containingDeclaration, annotations, variance, name); int index) {
return new TypeParameterDescriptor(containingDeclaration, annotations, variance, name, index);
} }
private final int index;
private final Variance variance; private final Variance variance;
private final Set<JetType> upperBounds; private final Set<JetType> upperBounds;
private final TypeConstructor typeConstructor; private final TypeConstructor typeConstructor;
@@ -40,8 +43,10 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<Annotation> annotations, @NotNull List<Annotation> annotations,
@NotNull Variance variance, @NotNull Variance variance,
@NotNull String name) { @NotNull String name,
int index) {
super(containingDeclaration, annotations, name); super(containingDeclaration, annotations, name);
this.index = index;
this.variance = variance; this.variance = variance;
this.upperBounds = Sets.newLinkedHashSet(); this.upperBounds = Sets.newLinkedHashSet();
// TODO: Should we actually pass the annotations on to the type constructor? // TODO: Should we actually pass the annotations on to the type constructor?
@@ -114,4 +119,8 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
} }
return type; return type;
} }
public int getIndex() {
return index;
}
} }
@@ -85,16 +85,19 @@ public class ClassDescriptorResolver {
// TODO : Where-clause // TODO : Where-clause
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList(); List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
int index = 0;
for (JetTypeParameter typeParameter : classElement.getTypeParameters()) { for (JetTypeParameter typeParameter : classElement.getTypeParameters()) {
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification( TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
descriptor, descriptor,
AnnotationResolver.INSTANCE.resolveAnnotations(typeParameter.getModifierList()), AnnotationResolver.INSTANCE.resolveAnnotations(typeParameter.getModifierList()),
typeParameter.getVariance(), typeParameter.getVariance(),
JetPsiUtil.safeName(typeParameter.getName()) JetPsiUtil.safeName(typeParameter.getName()),
index
); );
scopeForMemberResolution.addTypeParameterDescriptor(typeParameterDescriptor); scopeForMemberResolution.addTypeParameterDescriptor(typeParameterDescriptor);
trace.recordDeclarationResolution(typeParameter, typeParameterDescriptor); trace.recordDeclarationResolution(typeParameter, typeParameterDescriptor);
typeParameters.add(typeParameterDescriptor); typeParameters.add(typeParameterDescriptor);
index++;
} }
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
@@ -323,13 +326,14 @@ public class ClassDescriptorResolver {
public List<TypeParameterDescriptor> resolveTypeParameters(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, List<JetTypeParameter> typeParameters) { public List<TypeParameterDescriptor> resolveTypeParameters(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, List<JetTypeParameter> typeParameters) {
// TODO : Where-clause // TODO : Where-clause
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>(); List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>();
for (JetTypeParameter typeParameter : typeParameters) { for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
result.add(resolveTypeParameter(containingDescriptor, extensibleScope, typeParameter)); JetTypeParameter typeParameter = typeParameters.get(i);
result.add(resolveTypeParameter(containingDescriptor, extensibleScope, typeParameter, i));
} }
return result; return result;
} }
private TypeParameterDescriptor resolveTypeParameter(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, JetTypeParameter typeParameter) { private TypeParameterDescriptor resolveTypeParameter(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, JetTypeParameter typeParameter, int index) {
// TODO: other bounds from where-clause // TODO: other bounds from where-clause
JetTypeReference extendsBound = typeParameter.getExtendsBound(); JetTypeReference extendsBound = typeParameter.getExtendsBound();
JetType bound = extendsBound == null JetType bound = extendsBound == null
@@ -339,7 +343,8 @@ public class ClassDescriptorResolver {
containingDescriptor, containingDescriptor,
AnnotationResolver.INSTANCE.resolveAnnotations(typeParameter.getModifierList()), AnnotationResolver.INSTANCE.resolveAnnotations(typeParameter.getModifierList()),
typeParameter.getVariance(), typeParameter.getVariance(),
JetPsiUtil.safeName(typeParameter.getName()) JetPsiUtil.safeName(typeParameter.getName()),
index
); );
typeParameterDescriptor.addUpperBound(bound); typeParameterDescriptor.addUpperBound(bound);
extensibleScope.addTypeParameterDescriptor(typeParameterDescriptor); extensibleScope.addTypeParameterDescriptor(typeParameterDescriptor);
@@ -125,7 +125,8 @@ public class JavaDescriptorResolver {
owner, owner,
Collections.<Annotation>emptyList(), // TODO Collections.<Annotation>emptyList(), // TODO
Variance.INVARIANT, Variance.INVARIANT,
typeParameter.getName() typeParameter.getName(),
typeParameter.getIndex()
); );
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes(); PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
if (referencedTypes.length == 0){ if (referencedTypes.length == 0){
@@ -102,7 +102,7 @@ public class JetStandardClasses {
parameters.add(TypeParameterDescriptor.createWithDefaultBound( parameters.add(TypeParameterDescriptor.createWithDefaultBound(
classDescriptor, classDescriptor,
Collections.<Annotation>emptyList(), Collections.<Annotation>emptyList(),
Variance.OUT_VARIANCE, "T" + j)); Variance.OUT_VARIANCE, "T" + j, j));
} }
TUPLE[i] = classDescriptor.initialize( TUPLE[i] = classDescriptor.initialize(
true, true,
@@ -140,7 +140,7 @@ public class JetStandardClasses {
parameters.add(0, TypeParameterDescriptor.createWithDefaultBound( parameters.add(0, TypeParameterDescriptor.createWithDefaultBound(
receiverFunction, receiverFunction,
Collections.<Annotation>emptyList(), Collections.<Annotation>emptyList(),
Variance.IN_VARIANCE, "T")); Variance.IN_VARIANCE, "T", 0));
RECEIVER_FUNCTION[i] = receiverFunction.initialize( RECEIVER_FUNCTION[i] = receiverFunction.initialize(
false, false,
parameters, parameters,
@@ -154,12 +154,12 @@ public class JetStandardClasses {
parameters.add(TypeParameterDescriptor.createWithDefaultBound( parameters.add(TypeParameterDescriptor.createWithDefaultBound(
function, function,
Collections.<Annotation>emptyList(), Collections.<Annotation>emptyList(),
Variance.IN_VARIANCE, "P" + j)); Variance.IN_VARIANCE, "P" + j, j + 1));
} }
parameters.add(TypeParameterDescriptor.createWithDefaultBound( parameters.add(TypeParameterDescriptor.createWithDefaultBound(
function, function,
Collections.<Annotation>emptyList(), Collections.<Annotation>emptyList(),
Variance.OUT_VARIANCE, "R")); Variance.OUT_VARIANCE, "R", parameterCount + 1));
return parameters; return parameters;
} }
@@ -0,0 +1,8 @@
class Wrapper<T>() {
fun isSameWrapper(wrapper: Any) = wrapper is Wrapper<T>
}
fun foo() {
val wrapper = new Wrapper<Int>()
return wrapper.isSameWrapper(new Wrapper<String>())
}
@@ -59,6 +59,12 @@ public class TypeInfoTest extends CodegenTestCase {
assertFalse((Boolean) foo.invoke(null, newRunnable())); assertFalse((Boolean) foo.invoke(null, newRunnable()));
} }
public void testIsWithGenericParameters() throws Exception {
loadFile();
Method foo = generateFunction();
assertFalse((Boolean) foo.invoke(null));
}
private Runnable newRunnable() { private Runnable newRunnable() {
return new Runnable() { return new Runnable() {
@Override @Override
+4
View File
@@ -47,6 +47,10 @@ public class TypeInfo<T> implements JetObject {
return true; return true;
} }
public TypeInfo getTypeParameter(int index) {
return typeParameters[index];
}
@Override @Override
public TypeInfo<?> getTypeInfo() { public TypeInfo<?> getTypeInfo() {
if (typeInfo == null) { if (typeInfo == null) {