diff --git a/.gitignore b/.gitignore index 0be1843eb48..1af2e47cf73 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ out .idea/dictionaries/yozh.xml .idea/codeStyleSettings.xml .idea/workspace.xml +tmp diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 53af0cdc730..1b1bb5db25c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -57,26 +57,18 @@ public class CodegenUtil { return (ClassDescriptor) outerDescriptor; } - public static boolean hasOuterTypeInfo(ClassDescriptor descriptor) { - ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(descriptor); - if(outerClassDescriptor == null) - return false; - - if(outerClassDescriptor.getTypeConstructor().getParameters().size() > 0) - return true; - - return hasOuterTypeInfo(outerClassDescriptor); - } - - public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) { - if(!exceptOwn) { - if(!isInterface(type)) - if(hasTypeInfoField(type)) - return true; + public static boolean hasDerivedTypeInfoField(JetType type) { + for (JetType jetType : type.getConstructor().getSupertypes()) { + if(hasTypeInfoField(jetType)) + return true; } - for (JetType jetType : type.getConstructor().getSupertypes()) { - if(hasDerivedTypeInfoField(jetType, false)) + return false; + } + + public static boolean requireTypeInfoConstructorArg(JetType type) { + for (TypeParameterDescriptor parameter : type.getConstructor().getParameters()) { + if(parameter.isReified()) return true; } @@ -87,22 +79,10 @@ public class CodegenUtil { if(isInterface(type)) return false; - List parameters = type.getConstructor().getParameters(); - for (TypeParameterDescriptor parameter : parameters) { - if(parameter.isReified()) - return true; - } + if(requireTypeInfoConstructorArg(type)) + return true; - for (JetType jetType : type.getConstructor().getSupertypes()) { - if(hasTypeInfoField(jetType)) - return true; - } - - ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(type.getConstructor().getDeclarationDescriptor()); - if(outerClassDescriptor == null || isClassObject(type.getConstructor().getDeclarationDescriptor())) - return false; - - return hasTypeInfoField(outerClassDescriptor.getDefaultType()); + return hasDerivedTypeInfoField(type); } public static FunctionDescriptor createInvoke(ExpressionAsFunctionDescriptor fd) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java index b27e9ab18ce..9c60a5b170e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java @@ -12,11 +12,11 @@ import java.util.List; /** * @author yole + * @author alex.tkachman */ public class ConstructorFrameMap extends FrameMap { private int myOuterThisIndex = -1; - private int myFirstTypeParameter = -1; - private int myTypeParameterCount = 0; + private int myTypeInfoIndex = -1; public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, ClassDescriptor classDescriptor, OwnerKind kind) { enterTemp(); // this @@ -27,15 +27,8 @@ public class ConstructorFrameMap extends FrameMap { } if (classDescriptor != null) { - List parameters = classDescriptor.getTypeConstructor().getParameters(); - for (TypeParameterDescriptor parameter : parameters) { - if(parameter.isReified()) { - int index = enterTemp(); - myTypeParameterCount++; - if(myFirstTypeParameter == -1) { - myFirstTypeParameter = index; - } - } + if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) { + myTypeInfoIndex = enterTemp(); } } @@ -54,11 +47,7 @@ public class ConstructorFrameMap extends FrameMap { return myOuterThisIndex; } - public int getFirstTypeParameter() { - return myFirstTypeParameter; - } - - public int getTypeParameterCount() { - return myTypeParameterCount; + public int getTypeInfoIndex() { + return myTypeInfoIndex; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index a24e486308e..9eef892f33e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -979,7 +979,7 @@ public class ExpressionCodegen extends JetVisitor { } else if (descriptor instanceof TypeParameterDescriptor) { TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor; - loadTypeParameterTypeInfo(typeParameterDescriptor); + loadTypeParameterTypeInfo(typeParameterDescriptor, null); v.invokevirtual("jet/typeinfo/TypeInfo", "getClassObject", "()Ljava/lang/Object;"); v.checkcast(asmType(typeParameterDescriptor.getClassObjectType())); @@ -2033,26 +2033,32 @@ public class ExpressionCodegen extends JetVisitor { private void pushTypeArguments(ResolvedCall resolvedCall) { if(resolvedCall != null) { - Map typeArguments = resolvedCall.getTypeArguments(); - CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor(); - for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) { - if(typeParameterDescriptor.isReified()) { - JetType jetType = typeArguments.get(typeParameterDescriptor); - generateTypeInfo(jetType); + if(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor) { + ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) resolvedCall.getResultingDescriptor(); + ClassDescriptor containingDeclaration = constructorDescriptor.getContainingDeclaration(); + if(CodegenUtil.requireTypeInfoConstructorArg(containingDeclaration.getDefaultType())) { + generateTypeInfo(containingDeclaration.getDefaultType(), resolvedCall.getTypeArguments()); + } + } + else { + Map typeArguments = resolvedCall.getTypeArguments(); + CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor(); + for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) { + if(typeParameterDescriptor.isReified()) { + JetType jetType = typeArguments.get(typeParameterDescriptor); + generateTypeInfo(jetType, typeArguments); + } } } } else { throw new UnsupportedOperationException(); -// for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) { -// pushTypeArgument(jetTypeArgument); -// } } } public void pushTypeArgument(JetTypeProjection jetTypeArgument) { JetType typeArgument = bindingContext.get(BindingContext.TYPE, jetTypeArgument.getTypeReference()); - generateTypeInfo(typeArgument); + generateTypeInfo(typeArgument, null); } private Type generateJavaConstructorCall(JetCallExpression expression) { @@ -2091,7 +2097,7 @@ public class ExpressionCodegen extends JetVisitor { if(isArray) { JetType elementType = typeMapper.getGenericsElementType(arrayType); if(elementType != null) { - generateTypeInfo(elementType); + generateTypeInfo(elementType, null); gen(args.get(0).getArgumentExpression(), Type.INT_TYPE); v.invokevirtual("jet/typeinfo/TypeInfo", "newArray", "(I)[Ljava/lang/Object;"); } @@ -2195,7 +2201,7 @@ public class ExpressionCodegen extends JetVisitor { } for (TypeParameterDescriptor typeParameterDescriptor : getterDescriptor.getTypeParameters()) { if(typeParameterDescriptor.isReified()) { - generateTypeInfo(resolvedGetCall.getTypeArguments().get(typeParameterDescriptor)); + generateTypeInfo(resolvedGetCall.getTypeArguments().get(typeParameterDescriptor), null); index++; } } @@ -2215,7 +2221,7 @@ public class ExpressionCodegen extends JetVisitor { } for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) { if(typeParameterDescriptor.isReified()) { - generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor)); + generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor), null); index++; } } @@ -2503,7 +2509,7 @@ If finally block is present, its last expression is the value of try expression. } } else { - generateTypeInfo(jetType); + generateTypeInfo(jetType, null); expressionToGen.put(TYPE_OBJECT, v); if (leaveExpressionOnStack) { v.dupX1(); @@ -2512,7 +2518,7 @@ If finally block is present, its last expression is the value of try expression. } } - public void generateTypeInfo(JetType jetType) { + public void generateTypeInfo(JetType jetType, Map typeArguments) { String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType); if(knownTypeInfo != null) { v.getstatic("jet/typeinfo/TypeInfo", knownTypeInfo, "Ljet/typeinfo/TypeInfo;"); @@ -2521,7 +2527,7 @@ If finally block is present, its last expression is the value of try expression. DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof TypeParameterDescriptor) { - loadTypeParameterTypeInfo((TypeParameterDescriptor) declarationDescriptor); + loadTypeParameterTypeInfo((TypeParameterDescriptor) declarationDescriptor, typeArguments); return; } @@ -2551,7 +2557,7 @@ If finally block is present, its last expression is the value of try expression. TypeProjection argument = arguments.get(i); v.dup(); v.iconst(i); - generateTypeInfo(argument.getType()); + generateTypeInfo(argument.getType(), typeArguments); genTypeInfoToProjection(v, argument.getProjectionKind()); v.astore(TYPE_OBJECT); } @@ -2573,12 +2579,21 @@ If finally block is present, its last expression is the value of try expression. throw new UnsupportedOperationException(variance.toString()); } - private void loadTypeParameterTypeInfo(TypeParameterDescriptor typeParameterDescriptor) { + private void loadTypeParameterTypeInfo(TypeParameterDescriptor typeParameterDescriptor, @Nullable Map typeArguments) { final StackValue value = typeParameterExpressions.get(typeParameterDescriptor); if (value != null) { value.put(TYPE_TYPEINFO, v); return; } + + if(typeArguments != null) { + JetType jetType = typeArguments.get(typeParameterDescriptor); + if(jetType != null && !jetType.equals(typeParameterDescriptor.getDefaultType())) { + generateTypeInfo(jetType, typeArguments); + return; + } + } + DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration(); if (context.getThisDescriptor() != null) { ClassDescriptor descriptor = context.getThisDescriptor(); @@ -2589,8 +2604,13 @@ If finally block is present, its last expression is the value of try expression. if (containingDeclaration == context.getThisDescriptor()) { if(!CodegenUtil.isInterface(descriptor)) { if (CodegenUtil.hasTypeInfoField(defaultType)) { - v.load(0, TYPE_OBJECT); - v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); + if(!(context instanceof CodegenContext.ConstructorContext)) { + v.load(0, TYPE_OBJECT); + v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); + } + else { + v.load(((ConstructorFrameMap)myFrameMap).getTypeInfoIndex(), TYPE_OBJECT); + } } else { v.getstatic(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); @@ -2603,11 +2623,11 @@ If finally block is present, its last expression is the value of try expression. } else { v.load(0, TYPE_OBJECT); - v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;"); while(descriptor != containingDeclaration) { descriptor = CodegenUtil.getOuterClassDescriptor(descriptor); - v.invokevirtual("jet/typeinfo/TypeInfo", "getOuterTypeInfo", "()Ljet/typeinfo/TypeInfo;"); + v.invokeinterface("jet/JetObject", "getOuterObject", "()Ljet/JetObject;"); } + v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;"); } v.aconst(ownerType); v.iconst(typeParameterDescriptor.getIndex()); @@ -2737,7 +2757,7 @@ If finally block is present, its last expression is the value of try expression. v.anew(tupleType); v.dup(); - generateTypeInfo(new ProjectionErasingJetType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression))); + generateTypeInfo(new ProjectionErasingJetType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression)), null); for (JetExpression entry : entries) { gen(entry, TYPE_OBJECT); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index a53849fd83b..24918f4c652 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -8,17 +8,12 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.StdlibNames; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeProjection; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; -import org.objectweb.asm.signature.SignatureVisitor; -import org.objectweb.asm.signature.SignatureWriter; -import org.objectweb.asm.util.CheckSignatureAdapter; import java.util.List; import java.util.Set; @@ -66,6 +61,13 @@ public class FunctionCodegen { List typeParameters = (functionDescriptor instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)functionDescriptor).getCorrespondingProperty(): functionDescriptor).getTypeParameters(); int flags = ACC_PUBLIC; // TODO. + + if (!functionDescriptor.getValueParameters().isEmpty() + && functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1) + .getVarargElementType() != null) + { + flags |= ACC_VARARGS; + } OwnerKind kind = context.getContextKind(); @@ -114,7 +116,7 @@ public class FunctionCodegen { ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i); av.visit(StdlibNames.JET_PARAMETER_NAME_FIELD, parameterDescriptor.getName()); if(parameterDescriptor.hasDefaultValue()) { - av.visit(StdlibNames.JET_PARAMETER_HAS_DEFAULT_FIELD, true); + av.visit(StdlibNames.JET_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true); } if(parameterDescriptor.getOutType().isNullable()) { av.visit(StdlibNames.JET_PARAMETER_NULLABLE_FIELD, true); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index e40e22d5a47..a637350f361 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -16,6 +16,9 @@ import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; +import org.objectweb.asm.signature.SignatureVisitor; +import org.objectweb.asm.signature.SignatureWriter; +import org.objectweb.asm.util.CheckSignatureAdapter; import java.util.*; @@ -75,7 +78,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ? Opcodes.ACC_INTERFACE : 0/*Opcodes.ACC_SUPER*/), jvmName(), - null, + genericSignature(), superClass, interfaces.toArray(new String[interfaces.size()]) ); @@ -92,6 +95,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } + @Nullable + private String genericSignature() { + List typeParameters = descriptor.getTypeConstructor().getParameters(); + + SignatureWriter signatureWriter = new SignatureWriter(); + SignatureVisitor signatureVisitor = JetTypeMapper.DEBUG_SIGNATURE_WRITER + ? new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, signatureWriter) + : signatureWriter; + for (TypeParameterDescriptor typeParameter : typeParameters) { + signatureVisitor.visitFormalTypeParameter(typeParameter.getName()); + SignatureVisitor classBoundVisitor = signatureVisitor.visitClassBound(); + // TODO: wrong + JetTypeMapper.visitAsmType(classBoundVisitor, JetTypeMapper.TYPE_OBJECT); + } + SignatureVisitor superclassSignatureVisitor = signatureVisitor.visitSuperclass(); + // TODO: wrong + superclassSignatureVisitor.visitClassType("java/lang/Object"); + // TODO: add interfaces + superclassSignatureVisitor.visitEnd(); + + // TODO: return null if class is not generic and does not have generic superclasses + + return signatureWriter.toString(); + } + private String jvmName() { return typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(); } @@ -277,8 +305,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); } - List typeParameters = descriptor.getTypeConstructor().getParameters(); - for (int n = typeParameters.size(); n > 0; n--) { + if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType())) { parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); } @@ -337,12 +364,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final InstructionAdapter iv = new InstructionAdapter(mv); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state); - for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) { - if(constructorDescriptor != null) - codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); - else - codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); - } +// for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) { +// if(constructorDescriptor != null) +// codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); +// else +// codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); +// } String classname = typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(); final Type classType = Type.getType("L" + classname + ";"); @@ -371,7 +398,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); } for(TypeProjection typeParameterDescriptor : superType.getArguments()) { - codegen.generateTypeInfo(typeParameterDescriptor.getType()); + codegen.generateTypeInfo(typeParameterDescriptor.getType(), null); parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); } Method superCallMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); @@ -419,10 +446,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, classType); iv.load(frameMap.getOuterThisIndex(), type); iv.putfield(classname, fieldName, interfaceDesc); + + Type outerType = typeMapper.mapType(outerDescriptor.getDefaultType()); + MethodVisitor outer = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getOuterObject", "()Ljet/JetObject;", null, null); + outer.visitCode(); + outer.visitVarInsn(Opcodes.ALOAD, 0); + outer.visitFieldInsn(Opcodes.GETFIELD, classname, "this$0", outerType.getDescriptor()); + outer.visitInsn(Opcodes.ARETURN); + outer.visitMaxs(0, 0); + outer.visitEnd(); } - if (CodegenUtil.hasTypeInfoField(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) { - generateTypeInfoInitializer(frameMap.getFirstTypeParameter(), frameMap.getTypeParameterCount(), iv); + if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) { + iv.load(0, JetTypeMapper.TYPE_OBJECT); + iv.load(frameMap.getTypeInfoIndex(), JetTypeMapper.TYPE_OBJECT); + iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V"); } if(closure != null) { @@ -663,46 +701,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - protected void generateTypeInfoInitializer(int firstTypeParameter, int typeParamCount, InstructionAdapter iv) { - iv.load(0, JetTypeMapper.TYPE_OBJECT); - - iv.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION)); - iv.iconst(0); - - if(CodegenUtil.hasOuterTypeInfo(descriptor)) { - iv.load(1, JetTypeMapper.TYPE_OBJECT); - iv.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;"); - } - - if(typeParamCount != 0) { - iv.iconst(typeParamCount); - iv.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION); - - for (int i = 0; i < typeParamCount; i++) { - iv.dup(); - iv.iconst(i); - iv.load(firstTypeParameter + i, JetTypeMapper.TYPE_OBJECT); - iv.checkcast(JetTypeMapper.TYPE_TYPEINFOPROJECTION); - iv.astore(JetTypeMapper.TYPE_OBJECT); - } - - if(CodegenUtil.hasOuterTypeInfo(descriptor)) { - iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;"); - } - else - iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;"); - } - else { - if(CodegenUtil.hasOuterTypeInfo(descriptor)) { - iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;"); - } - else - iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;"); - } - - iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V"); - } - protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) { for (JetDeclaration declaration : myClass.getDeclarations()) { if (declaration instanceof JetProperty) { @@ -799,15 +797,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return; JetType defaultType = descriptor.getDefaultType(); - if(CodegenUtil.hasTypeInfoField(defaultType)) { - if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) { + if(CodegenUtil.requireTypeInfoConstructorArg(defaultType)) { + if(!CodegenUtil.hasDerivedTypeInfoField(defaultType)) { v.newField(myClass, Opcodes.ACC_PROTECTED, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null); MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null); - InstructionAdapter iv = null; if (v.generateCode()) { mv.visitCode(); - iv = new InstructionAdapter(mv); + InstructionAdapter iv = new InstructionAdapter(mv); String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;"); @@ -819,7 +816,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null); if (v.generateCode()) { mv.visitCode(); - iv = new InstructionAdapter(mv); + InstructionAdapter iv = new InstructionAdapter(mv); String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(1, JetTypeMapper.TYPE_OBJECT); @@ -856,14 +853,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { public void generate(InstructionAdapter v) { v.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION)); v.iconst(0); - ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(descriptor); - if(outerClassDescriptor == null || CodegenUtil.isClassObject(descriptor)) { - v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;"); - } - else { - v.getstatic(typeMapper.mapType(outerClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;"); - v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;"); - } + v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;"); v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;"); } }); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 8ed9283d6f0..0e62029178e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -86,7 +86,11 @@ public class JetTypeMapper { public static final Type TYPE_LONG_ITERATOR = Type.getObjectType("jet/LongIterator"); public static final Type TYPE_FLOAT_ITERATOR = Type.getObjectType("jet/FloatIterator"); public static final Type TYPE_DOUBLE_ITERATOR = Type.getObjectType("jet/DoubleIterator"); - + + public JetStandardLibrary getStandardLibrary() { + return standardLibrary; + } + public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) { this.standardLibrary = standardLibrary; this.bindingContext = bindingContext; @@ -234,10 +238,10 @@ public class JetTypeMapper { return mapType(jetType, kind, signatureVisitor, false); } - @NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable SignatureVisitor signatureVisitor, boolean typeParameter) { + @NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable SignatureVisitor signatureVisitor, boolean boxPrimitive) { Type known = knowTypes.get(jetType); if (known != null) { - return mapKnownAsmType(jetType, known, signatureVisitor, typeParameter); + return mapKnownAsmType(jetType, known, signatureVisitor, boxPrimitive); } DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); @@ -249,8 +253,7 @@ public class JetTypeMapper { if (signatureVisitor != null) { SignatureVisitor arraySignatureVisitor = signatureVisitor.visitArrayType(); - // TODO: box - mapType(memberType, kind, arraySignatureVisitor); + mapType(memberType, kind, arraySignatureVisitor, true); } if (!isGenericsArray(jetType)) { @@ -261,6 +264,9 @@ public class JetTypeMapper { } if (JetStandardClasses.getAny().equals(descriptor)) { + if (signatureVisitor != null) { + visitAsmType(signatureVisitor, TYPE_OBJECT); + } return TYPE_OBJECT; } @@ -305,7 +311,7 @@ public class JetTypeMapper { return asmType; } - private void visitAsmType(SignatureVisitor visitor, Type asmType) { + public static void visitAsmType(SignatureVisitor visitor, Type asmType) { switch (asmType.getSort()) { case Type.OBJECT: visitor.visitClassType(asmType.getInternalName()); @@ -377,7 +383,7 @@ public class JetTypeMapper { return asmType; } - private static final boolean DEBUG_SIGNATURE_WRITER = true; + public static final boolean DEBUG_SIGNATURE_WRITER = true; public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) { if(functionDescriptor == null) @@ -573,10 +579,8 @@ public class JetTypeMapper { parameterTypes.add(mapType(CodegenUtil.getOuterClassDescriptor(classDescriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); } - List typeParameters = classDescriptor.getTypeConstructor().getParameters(); - for (TypeParameterDescriptor typeParameter : typeParameters) { - if(typeParameter.isReified()) - parameterTypes.add(TYPE_TYPEINFO); + if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) { + parameterTypes.add(TYPE_TYPEINFO); } for (ValueParameterDescriptor parameter : parameters) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 837c1503717..9a6f2c5210a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor; +import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeUtils; @@ -145,7 +146,7 @@ public class NamespaceCodegen { } DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor(); - if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor)) { + if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor) && !JetStandardClasses.getAny().equals(declarationDescriptor)) { // TODO: we need some better checks here v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); return; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index d8591fe5e4a..f9167601b55 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; @@ -629,7 +630,7 @@ public abstract class StackValue { for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) { if(typeParameterDescriptor.isReified()) { - codegen.generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor)); + codegen.generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor), null); } } @@ -1010,7 +1011,8 @@ public abstract class StackValue { return codegen.typeMapper.mapType(callableMethod.getReceiverClass()); } else { - return codegen.typeMapper.mapType(callableMethod.getThisType()); + JetType thisType = callableMethod.getThisType(); + return codegen.typeMapper.mapType(thisType); } } else { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java index 4c0f906e5ab..8fcd6d57500 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java @@ -5,14 +5,12 @@ import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.JetStandardLibrary; -import org.jetbrains.jet.lang.types.JetType; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; @@ -30,7 +28,7 @@ public class ArrayIterator implements IntrinsicMethod { ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal(); JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary(); if(containingDeclaration.equals(standardLibrary.getArray())) { - codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType()); + codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType(), null); v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/typeinfo/TypeInfo;)Ljet/Iterator;"); return StackValue.onStack(JetTypeMapper.TYPE_ITERATOR); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index 0f28be38590..94240f21b34 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -104,6 +104,4 @@ public class JavaPackageScope extends JetScopeImpl { private String getQualifiedName(String name) { return (packageFQN.isEmpty() ? "" : packageFQN + ".") + name; } - - } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java index 752d0da55d3..1b8e6b06abc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/CallableDescriptor.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.descriptors; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeSubstitutor; @@ -24,6 +25,7 @@ public interface CallableDescriptor extends DeclarationDescriptor { /** * Method may return null for not yet fully initialized object or if error occurred. */ + @Nullable JetType getReturnType(); @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptor.java index fcf17af68d9..e05dd66a7f5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptor.java @@ -21,6 +21,7 @@ public interface DeclarationDescriptor extends Annotated, Named { @Nullable DeclarationDescriptor getContainingDeclaration(); + @Nullable DeclarationDescriptor substitute(TypeSubstitutor substitutor); R accept(DeclarationDescriptorVisitor visitor, D data); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java index fec39dc6493..974d490667a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java @@ -2,14 +2,16 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; import java.util.List; import java.util.Set; /** + * Introduces a simple wrapper for internal scope. + * * @author abreslav */ public abstract class AbstractScopeAdapter implements JetScope { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/StdlibNames.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/StdlibNames.java index 5f54c4a96d1..fcc779f5c99 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/StdlibNames.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/StdlibNames.java @@ -12,7 +12,7 @@ public class StdlibNames { public static final String JET_PARAMETER_DESCRIPTOR = "Ljet/typeinfo/JetParameter;"; public static final String JET_PARAMETER_NAME_FIELD = "name"; - public static final String JET_PARAMETER_HAS_DEFAULT_FIELD = "hasDefault"; + public static final String JET_PARAMETER_HAS_DEFAULT_VALUE_FIELD = "hasDefaultValue"; public static final String JET_PARAMETER_NULLABLE_FIELD = "nullable"; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index e8ed22f23a0..b5d04a21d8e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -86,7 +86,7 @@ public class CallResolver { FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, call, expectedType); return functionDescriptor == null ? null : functionDescriptor.getReturnType(); } - + @Nullable public ResolvedCall resolveCallWithGivenName( @NotNull BindingTrace trace, @@ -95,7 +95,8 @@ public class CallResolver { @NotNull final JetReferenceExpression functionReference, @NotNull String name, @NotNull JetType expectedType) { - List> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, call, name, trace.getBindingContext(), dataFlowInfo); + List> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks( + scope, call, name, trace.getBindingContext(), dataFlowInfo); return doResolveCall(trace, scope, call, expectedType, tasks, functionReference); } @@ -406,7 +407,11 @@ public class CallResolver { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @NotNull - private OverloadResolutionResults performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task, @NotNull TracingStrategy tracing) { + private OverloadResolutionResults performResolution( + @NotNull BindingTrace trace, + @NotNull JetScope scope, @NotNull JetType expectedType, + @NotNull ResolutionTask task, @NotNull TracingStrategy tracing + ) { for (ResolvedCallImpl candidateCall : task.getCandidates()) { D candidate = candidateCall.getCandidateDescriptor(); TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java index ecde91cc4ed..dc2f978517c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java @@ -9,6 +9,8 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import java.util.Collection; /** + * Stores candidates for call resolution. + * * @author abreslav */ /*package*/ class ResolutionTask { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java index 661dc9913ea..72137c2d6ca 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java @@ -17,8 +17,8 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.NamespaceType; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import java.util.Collection; import java.util.Collections; @@ -32,8 +32,11 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor /*package*/ abstract class TaskPrioritizer { public static void splitLexicallyLocalDescriptors( - Collection> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, Collection> local, Collection> nonlocal) { - + @NotNull Collection> allDescriptors, + @NotNull DeclarationDescriptor containerOfTheCurrentLocality, + @NotNull Collection> local, + @NotNull Collection> nonlocal + ) { for (ResolvedCallImpl resolvedCall : allDescriptors) { if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) { local.add(resolvedCall); @@ -56,7 +59,9 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor return null; } - public List> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) { + @NotNull + public List> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, + @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) { List> result = Lists.newArrayList(); ReceiverDescriptor explicitReceiver = call.getExplicitReceiver(); @@ -68,7 +73,7 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor return result; } - + private void doComputeTasks(JetScope scope, ReceiverDescriptor receiver, Call call, String name, List> result, @NotNull AutoCastService autoCastService) { DataFlowInfo dataFlowInfo = autoCastService.getDataFlowInfo(); List implicitReceivers = Lists.newArrayList(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java index 040a218e534..b3b722941fc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java @@ -50,20 +50,17 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; JetReferenceExpression nameReference = valueArgument.getArgumentName().getReferenceExpression(); ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName()); if (valueParameterDescriptor == null) { -// temporaryTrace.getErrorHandler().genericError(nameNode, "Cannot find a parameter with this name"); temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference)); error = true; } else { if (!usedParameters.add(valueParameterDescriptor)) { -// temporaryTrace.getErrorHandler().genericError(nameNode, "An argument is already passed for this parameter"); temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference)); } temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor); put(candidateCall, valueParameterDescriptor, valueArgument, varargs); } if (somePositioned) { -// temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed"); temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference)); error = true; } @@ -71,7 +68,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; else { somePositioned = true; if (someNamed) { -// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed"); temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement())); error = true; } @@ -89,13 +85,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; usedParameters.add(valueParameterDescriptor); } else { -// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate)); temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); error = true; } } else { -// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate)); temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); error = true; } @@ -108,7 +102,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0); if (valueParameters.isEmpty()) { -// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate)); temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); error = true; } @@ -124,13 +117,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1); if (valueParameterDescriptor.getVarargElementType() != null) { -// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list"); temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral)); error = true; } else { if (!usedParameters.add(valueParameterDescriptor)) { -// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate)); temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); error = true; } @@ -142,7 +133,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; for (int i = 1; i < functionLiteralArguments.size(); i++) { JetExpression argument = functionLiteralArguments.get(i); -// temporaryTrace.getErrorHandler().genericError(argument.getNode(), "Only one function literal is allowed outside a parenthesized argument list"); temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument)); error = true; } @@ -176,7 +166,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; error = true; } - assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor(); + assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() : + "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor(); return error; } @@ -196,8 +187,4 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; candidateCall.recordValueArgument(valueParameterDescriptor, argument); } } - -// private static String getTooManyArgumentsMessage(Descriptor candidate) { -// return "Too many arguments for " + DescriptorRenderer.TEXT.render(candidate); -// } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintResolutionListener.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintResolutionListener.java index 783f6591e32..6cbf129fb73 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintResolutionListener.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintResolutionListener.java @@ -10,6 +10,28 @@ import java.util.Set; */ public interface ConstraintResolutionListener { + public static final ConstraintResolutionListener DO_NOTHING = new ConstraintResolutionListener() { + @Override + public void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue) { + } + + @Override + public void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue) { + } + + @Override + public void done(ConstraintSystemSolution solution, Set typeParameterDescriptors) { + } + + @Override + public void log(Object message) { + } + + @Override + public void error(Object message) { + } + }; + void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue); void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue); void done(ConstraintSystemSolution solution, Set typeParameterDescriptors); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java index aa3123b79c8..73746161e66 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java @@ -51,6 +51,11 @@ public interface JetScope { @Nullable PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName); + /** + * All visible descriptors from current scope. + * + * @return All visible descriptors from current scope. + */ @NotNull Collection getAllDescriptors(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java new file mode 100644 index 00000000000..ce42890942b --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java @@ -0,0 +1,54 @@ +package org.jetbrains.jet.lang.resolve.scopes; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * @author Nikolay Krasko + */ +public final class JetScopeUtils { + private JetScopeUtils() {} + + /** + * Get receivers in order of locality, so that the closest (the most local) receiver goes first + * A wrapper for {@link JetScope#getImplicitReceiversHierarchy(java.util.List)} + * + * @param scope Scope for getting receivers hierarchy. + * @return receivers hierarchy. + */ + @NotNull + public static Collection getImplicitReceiversHierarchy(@NotNull JetScope scope) { + List descriptors = Lists.newArrayList(); + scope.getImplicitReceiversHierarchy(descriptors); + return descriptors; + } + + /** + * Get all extension descriptors among visible descriptors for current scope. + * + * @param scope Scope for query extensions. + * @return extension descriptors. + */ + public static Collection getAllExtensions(@NotNull JetScope scope) { + final Set result = Sets.newHashSet(); + + for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) { + if (descriptor instanceof CallableDescriptor) { + CallableDescriptor callDescriptor = (CallableDescriptor) descriptor; + if (callDescriptor.getReceiverParameter().exists()) { + result.add(callDescriptor); + } + } + } + + return result; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index 9dcd5d3d314..c27e9f998cd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -12,9 +12,9 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.TypeResolver; import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; @@ -40,7 +40,8 @@ import java.util.Map; @NotNull JetType expectedType, @NotNull JetType expectedReturnType, boolean namespacesAllowed) { - return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); + return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, + labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); } // @NotNull diff --git a/compiler/testData/codegen/regressions/kt259.jet b/compiler/testData/codegen/regressions/kt259.jet index 59a99b1bcbb..ad996781b9f 100644 --- a/compiler/testData/codegen/regressions/kt259.jet +++ b/compiler/testData/codegen/regressions/kt259.jet @@ -1,4 +1,5 @@ class A() {} + open class B() { fun isT (a : Any?) : Boolean { return a is T @@ -167,7 +168,6 @@ fun t26 () : Boolean { } fun box() : String { -/* if(!t1()) { return "t1 failed" } @@ -243,7 +243,6 @@ fun box() : String { if(!t25()) { return "t25 failed" } - */ if(!t26()) { return "t26 failed" } diff --git a/compiler/testData/codegen/regressions/kt785.jet b/compiler/testData/codegen/regressions/kt785.jet new file mode 100644 index 00000000000..1b10c8c73d7 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt785.jet @@ -0,0 +1,13 @@ +class A() { + var x : Int = 0 + + var z = { () => + x++ + } +} + +fun box() : String { + val a = A() + a.z() //problem is here + return if (a.x == 1) "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/regressions/kt789.jet b/compiler/testData/codegen/regressions/kt789.jet new file mode 100644 index 00000000000..e071cfdf507 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt789.jet @@ -0,0 +1,12 @@ +namespace foo + +import java.util.*; + +import std.util.* + +fun box() : String { + val a = ArrayList(); + a.add(1) + a.add(2) + return if((a.size == 2) && (a.get(1) == 2) && (a.get(0) == 1)) "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/typeInfo/inheritance.jet b/compiler/testData/codegen/typeInfo/inheritance.jet index 225bda1f665..3ee02657f34 100644 --- a/compiler/testData/codegen/typeInfo/inheritance.jet +++ b/compiler/testData/codegen/typeInfo/inheritance.jet @@ -1,4 +1,4 @@ -open class A () { +open class A () { fun plus(e: T) = B (e) } @@ -6,4 +6,6 @@ class B (val e: T) : A() { fun add() = B (e) } -fun box() = if( A().plus("239").add().e == "239" ) "OK" else "fail" \ No newline at end of file +fun box() : String { + return if(A().plus("239").add().e == "239" ) "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/typeInfo/inner.jet b/compiler/testData/codegen/typeInfo/inner.jet index 49db9252b35..62dad284a09 100644 --- a/compiler/testData/codegen/typeInfo/inner.jet +++ b/compiler/testData/codegen/typeInfo/inner.jet @@ -4,7 +4,6 @@ class Box() { } class Inner2() : Inner() { - } fun inner() = Inner2() diff --git a/compiler/testData/compileJavaAgainstKotlin/IntArray.java b/compiler/testData/compileJavaAgainstKotlin/IntArray.java deleted file mode 100644 index e0bdaa635ee..00000000000 --- a/compiler/testData/compileJavaAgainstKotlin/IntArray.java +++ /dev/null @@ -1,6 +0,0 @@ - -class IntArray { - { - int[] r = namespace.doNothing(new int[0]); - } -} diff --git a/compiler/testData/compileJavaAgainstKotlin/IntArray.kt b/compiler/testData/compileJavaAgainstKotlin/IntArray.kt deleted file mode 100644 index 2abd2b34c5a..00000000000 --- a/compiler/testData/compileJavaAgainstKotlin/IntArray.kt +++ /dev/null @@ -1 +0,0 @@ -fun doNothing(array: IntArray) = array diff --git a/compiler/testData/compileJavaAgainstKotlin/class/Simple.java b/compiler/testData/compileJavaAgainstKotlin/class/Simple.java new file mode 100644 index 00000000000..0a211b69295 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/class/Simple.java @@ -0,0 +1,7 @@ + +class Simple { + { + jet.typeinfo.TypeInfo blabla = null; + new Impossible(blabla); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/class/Simple.kt b/compiler/testData/compileJavaAgainstKotlin/class/Simple.kt new file mode 100644 index 00000000000..854e4e56c6f --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/class/Simple.kt @@ -0,0 +1 @@ +class Impossible

() diff --git a/compiler/testData/compileJavaAgainstKotlin/method/Any.java b/compiler/testData/compileJavaAgainstKotlin/method/Any.java new file mode 100644 index 00000000000..fb9763ee19f --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/Any.java @@ -0,0 +1,6 @@ + +class Any { + { + Object r = namespace.anyany(new Object(), null); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/method/Any.kt b/compiler/testData/compileJavaAgainstKotlin/method/Any.kt new file mode 100644 index 00000000000..2483cfdeb0e --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/Any.kt @@ -0,0 +1,2 @@ +// extra parameter is to preserve generic signature +fun anyany(a: Any, ignore: java.util.List) = a diff --git a/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntArray.java b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntArray.java new file mode 100644 index 00000000000..e53cd061eca --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntArray.java @@ -0,0 +1,7 @@ + +class ArrayOfIntArray { + { + int[][] a = new int[0][]; + int[][] r = namespace.ohMy(a); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntArray.kt b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntArray.kt new file mode 100644 index 00000000000..a64acfd5de4 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntArray.kt @@ -0,0 +1 @@ +fun ohMy(p: Array) = p diff --git a/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntegerArray.java b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntegerArray.java new file mode 100644 index 00000000000..4294970558f --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntegerArray.java @@ -0,0 +1,7 @@ + +class ArrayOfIntArray { + { + Integer[][] a = new Integer[0][]; + Integer[][] r = namespace.ohMy(a, null); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntegerArray.kt b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntegerArray.kt new file mode 100644 index 00000000000..78f9664434c --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/ArrayOfIntegerArray.kt @@ -0,0 +1,2 @@ +// extra parameter is to make sure generic signature is generated +fun ohMy(p: Array>, ignore: java.util.List) = p diff --git a/compiler/testData/compileJavaAgainstKotlin/GenericArray.java b/compiler/testData/compileJavaAgainstKotlin/method/GenericArray.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/GenericArray.java rename to compiler/testData/compileJavaAgainstKotlin/method/GenericArray.java diff --git a/compiler/testData/compileJavaAgainstKotlin/GenericArray.kt b/compiler/testData/compileJavaAgainstKotlin/method/GenericArray.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/GenericArray.kt rename to compiler/testData/compileJavaAgainstKotlin/method/GenericArray.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/Hello.java b/compiler/testData/compileJavaAgainstKotlin/method/Hello.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/Hello.java rename to compiler/testData/compileJavaAgainstKotlin/method/Hello.java diff --git a/compiler/testData/compileJavaAgainstKotlin/Hello.kt b/compiler/testData/compileJavaAgainstKotlin/method/Hello.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/Hello.kt rename to compiler/testData/compileJavaAgainstKotlin/method/Hello.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/Int.java b/compiler/testData/compileJavaAgainstKotlin/method/Int.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/Int.java rename to compiler/testData/compileJavaAgainstKotlin/method/Int.java diff --git a/compiler/testData/compileJavaAgainstKotlin/Int.kt b/compiler/testData/compileJavaAgainstKotlin/method/Int.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/Int.kt rename to compiler/testData/compileJavaAgainstKotlin/method/Int.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/method/IntArray.java b/compiler/testData/compileJavaAgainstKotlin/method/IntArray.java new file mode 100644 index 00000000000..e32c42f8ace --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/IntArray.java @@ -0,0 +1,6 @@ + +class IntArray { + { + int[] r = namespace.doNothing(new int[0], null); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/method/IntArray.kt b/compiler/testData/compileJavaAgainstKotlin/method/IntArray.kt new file mode 100644 index 00000000000..70f76451481 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/IntArray.kt @@ -0,0 +1,2 @@ +// extra parameter is to make sure generic signature is not erased +fun doNothing(array: IntArray, ignore: java.util.List) = array diff --git a/compiler/testData/compileJavaAgainstKotlin/IntWithDefault.java b/compiler/testData/compileJavaAgainstKotlin/method/IntWithDefault.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/IntWithDefault.java rename to compiler/testData/compileJavaAgainstKotlin/method/IntWithDefault.java diff --git a/compiler/testData/compileJavaAgainstKotlin/IntWithDefault.kt b/compiler/testData/compileJavaAgainstKotlin/method/IntWithDefault.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/IntWithDefault.kt rename to compiler/testData/compileJavaAgainstKotlin/method/IntWithDefault.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/method/IntegerArray.java b/compiler/testData/compileJavaAgainstKotlin/method/IntegerArray.java new file mode 100644 index 00000000000..3f73cc43ca1 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/IntegerArray.java @@ -0,0 +1,6 @@ + +class IntArray { + { + Integer[] r = namespace.doNothing(new Integer[0], null); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/method/IntegerArray.kt b/compiler/testData/compileJavaAgainstKotlin/method/IntegerArray.kt new file mode 100644 index 00000000000..6d241620970 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/IntegerArray.kt @@ -0,0 +1,2 @@ +// extra parameter is to make sure generic signature is preserved +fun doNothing(array: Array, ignore: java.util.List) = array diff --git a/compiler/testData/compileJavaAgainstKotlin/ListOfInt.java b/compiler/testData/compileJavaAgainstKotlin/method/ListOfInt.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/ListOfInt.java rename to compiler/testData/compileJavaAgainstKotlin/method/ListOfInt.java diff --git a/compiler/testData/compileJavaAgainstKotlin/ListOfInt.kt b/compiler/testData/compileJavaAgainstKotlin/method/ListOfInt.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/ListOfInt.kt rename to compiler/testData/compileJavaAgainstKotlin/method/ListOfInt.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/ListOfString.java b/compiler/testData/compileJavaAgainstKotlin/method/ListOfString.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/ListOfString.java rename to compiler/testData/compileJavaAgainstKotlin/method/ListOfString.java diff --git a/compiler/testData/compileJavaAgainstKotlin/ListOfString.kt b/compiler/testData/compileJavaAgainstKotlin/method/ListOfString.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/ListOfString.kt rename to compiler/testData/compileJavaAgainstKotlin/method/ListOfString.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/ListOfT.java b/compiler/testData/compileJavaAgainstKotlin/method/ListOfT.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/ListOfT.java rename to compiler/testData/compileJavaAgainstKotlin/method/ListOfT.java diff --git a/compiler/testData/compileJavaAgainstKotlin/ListOfT.kt b/compiler/testData/compileJavaAgainstKotlin/method/ListOfT.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/ListOfT.kt rename to compiler/testData/compileJavaAgainstKotlin/method/ListOfT.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/MapOfKString.java b/compiler/testData/compileJavaAgainstKotlin/method/MapOfKString.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/MapOfKString.java rename to compiler/testData/compileJavaAgainstKotlin/method/MapOfKString.java diff --git a/compiler/testData/compileJavaAgainstKotlin/MapOfKString.kt b/compiler/testData/compileJavaAgainstKotlin/method/MapOfKString.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/MapOfKString.kt rename to compiler/testData/compileJavaAgainstKotlin/method/MapOfKString.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/MapOfStringIntQ.java b/compiler/testData/compileJavaAgainstKotlin/method/MapOfStringIntQ.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/MapOfStringIntQ.java rename to compiler/testData/compileJavaAgainstKotlin/method/MapOfStringIntQ.java diff --git a/compiler/testData/compileJavaAgainstKotlin/MapOfStringIntQ.kt b/compiler/testData/compileJavaAgainstKotlin/method/MapOfStringIntQ.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/MapOfStringIntQ.kt rename to compiler/testData/compileJavaAgainstKotlin/method/MapOfStringIntQ.kt diff --git a/compiler/testData/compileJavaAgainstKotlin/method/Vararg.java b/compiler/testData/compileJavaAgainstKotlin/method/Vararg.java new file mode 100644 index 00000000000..c40d5079407 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/Vararg.java @@ -0,0 +1,9 @@ +import java.util.List; +import java.util.ArrayList; + +class Vararg { + { + List list = new ArrayList(); + List r = namespace.gg(list, 3, 4, 5, 6); + } +} diff --git a/compiler/testData/compileJavaAgainstKotlin/method/Vararg.kt b/compiler/testData/compileJavaAgainstKotlin/method/Vararg.kt new file mode 100644 index 00000000000..7a584e978d5 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/method/Vararg.kt @@ -0,0 +1,3 @@ +import java.util.List; + +fun gg(list: List, vararg ints: Int) = list diff --git a/compiler/testData/compileJavaAgainstKotlin/Void.java b/compiler/testData/compileJavaAgainstKotlin/method/Void.java similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/Void.java rename to compiler/testData/compileJavaAgainstKotlin/method/Void.java diff --git a/compiler/testData/compileJavaAgainstKotlin/Void.kt b/compiler/testData/compileJavaAgainstKotlin/method/Void.kt similarity index 100% rename from compiler/testData/compileJavaAgainstKotlin/Void.kt rename to compiler/testData/compileJavaAgainstKotlin/method/Void.kt diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 25c697c6484..88e445a6bb1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -24,7 +24,7 @@ public class ClassGenTest extends CodegenTestCase { public void testArrayListInheritance() throws Exception { loadFile("classes/inheritingFromArrayList.jet"); - + System.out.println(generateToText()); final Class aClass = loadClass("Foo", generateClassesInFile()); assertInstanceOf(aClass.newInstance(), List.class); } diff --git a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java index 7b5a7a33e7a..431400d66bd 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java @@ -81,6 +81,10 @@ public class FunctionGenTest extends CodegenTestCase { blackBoxFile("regressions/kt395.jet"); } + public void testKt785 () { +// blackBoxFile("regressions/kt785.jet"); + } + public void testFunction () throws InvocationTargetException, IllegalAccessException { blackBoxFile("functions/functionExpression.jet"); } diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index cd1bb67e1c3..da0d87d46fc 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -80,6 +80,10 @@ public class StdlibTest extends CodegenTestCase { blackBoxFile("regressions/kt528.kt"); } + public void testKt789 () { +// blackBoxFile("regressions/kt789.jet"); + } + public void testCollectionSize () throws Exception { loadText("import std.util.*; fun box() = if(java.util.Arrays.asList(0, 1, 2)?.size == 3) \"OK\" else \"fail\""); // System.out.println(generateToText()); diff --git a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java index 85b9dae07d8..b2396c96af6 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java @@ -140,7 +140,7 @@ public class TypeInfoTest extends CodegenTestCase { public void testInner() throws Exception { blackBoxFile("typeInfo/inner.jet"); -// System.out.println(generateToText()); + System.out.println(generateToText()); } public void testInheritance() throws Exception { @@ -148,4 +148,3 @@ public class TypeInfoTest extends CodegenTestCase { System.out.println(generateToText()); } } - diff --git a/examples/src/benchmarks/FList.java b/examples/src/benchmarks/FList.java new file mode 100644 index 00000000000..694dd70ac96 --- /dev/null +++ b/examples/src/benchmarks/FList.java @@ -0,0 +1,86 @@ +import java.util.NoSuchElementException; + +abstract public class FList { + abstract T getHead(); + + abstract FList getTail(); + + abstract FList plus(T element); + + static class Empty extends FList { + + @Override + T getHead() { + throw new NoSuchElementException(); + } + + @Override + FList getTail() { + throw new NoSuchElementException(); + } + + @Override + FList plus(T element) { + return new OneElementList(element); + } + } + + static class OneElementList extends FList { + private T element; + + public OneElementList(T element) { + super(); + this.element = element; + } + + @Override + T getHead() { + return element; + } + + @Override + FList getTail() { + return new Empty(); + } + + @Override + FList plus(T element) { + return new StandardList(element, this); + } + } + + private static class StandardList extends FList { + private T head; + private FList tail; + + public StandardList(T head, FList tail) { + this.head = head; + this.tail = tail; + } + + @Override + T getHead() { + return head; + } + + @Override + FList getTail() { + return tail; + } + + @Override + FList plus(T element) { + return new StandardList(element, this); + } + } + + public static void main(String[] args) { + for(int k = 0; k != 10; ++k) { + long start = System.currentTimeMillis(); + FList list = new Empty(); + for(int i = 0; i != 5000000; ++i) + list = list.plus(i); + System.out.println(System.currentTimeMillis()-start); + } + } +} diff --git a/examples/src/benchmarks/FList.kt b/examples/src/benchmarks/FList.kt new file mode 100644 index 00000000000..5d806215920 --- /dev/null +++ b/examples/src/benchmarks/FList.kt @@ -0,0 +1,70 @@ +namespace flist + +abstract class FList { + abstract val head : T + abstract val tail : FList + + abstract fun plus(element: T) : FList +} + +class EmptyFList() : FList { + override val head: T + get() = throw java.util.NoSuchElementException() + + override val tail : EmptyFList + get() = EmptyFList() + + override fun plus(element: T) : FList = OneElementFList(element) +} + +class OneElementFList (override val head: T): FList { + override val tail : EmptyFList + get() = EmptyFList() + + override fun plus(element: T) : FList = StandardFList(element, this) +} + +class StandardFList (override val head: T, override val tail: FList) : FList { + override fun plus(element: T) : FList = StandardFList(element, this) +} + +fun FList.plus2(element: T): FList = + when(this) { + is EmptyFList => OneElementFList(element) + else => StandardFList(element, this) + } + +fun FList.plus3(element: T) : FList = + if(this is EmptyFList<*>) + OneElementFList(element) + else + StandardFList(element, this) + +fun main(args: Array) { + for(k in 0..3) { + val start0 = System.currentTimeMillis() + + var flist0 : FList = EmptyFList() + for(i in 0..5000000) + flist0 = flist0 + i + + System.out?.println(System.currentTimeMillis() - start0) + + val start = System.currentTimeMillis() + + var flist : FList = EmptyFList() + for(i in 0..5000000) + flist = flist.plus2(i) + + System.out?.println(System.currentTimeMillis() - start) + + val start2 = System.currentTimeMillis() + + var flist2 : FList = EmptyFList() + for(i in 0..5000000) + flist2 = flist2.plus3(i) + + System.out?.println(System.currentTimeMillis() - start2) + System.out?.println() + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java index 6f7a57c8492..eaec4204faf 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.plugin.completion; import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.patterns.PlatformPatterns; import com.intellij.patterns.PsiElementPattern; @@ -11,6 +12,7 @@ import com.intellij.psi.filters.position.FilterPattern; import com.intellij.psi.filters.position.LeftNeighbour; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.completion.handlers.JetKeywordInsertHandler; /** * A keyword contributor for Kotlin @@ -21,7 +23,9 @@ import org.jetbrains.annotations.NotNull; public class JetKeywordCompletionContributor extends CompletionContributor { private static class JetTopKeywordCompletionProvider extends CompletionProvider { - + + private final static InsertHandler KEYWORDS_INSERT_HANDLER = new JetKeywordInsertHandler(); + private final static String[] COMPLETE_KEYWORD = new String[] { "namespace", "as", "type", "class", "this", "super", "val", "var", "fun", "for", "null", "true", "false", "is", "in", "throw", "return", "break", "continue", "object", "if", "try", "else", "while", @@ -32,18 +36,19 @@ public class JetKeywordCompletionContributor extends CompletionContributor { "import", "where", "by", "get", "set", "abstract", "enum", "open", "annotation", "override", "private", "public", "internal", "protected", "catch", "out", "vararg", "inline", "finally", "final", "ref" }; - + @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) { for (String keyword : COMPLETE_KEYWORD) { - result.addElement(LookupElementBuilder.create(keyword).setBold()); + + result.addElement(LookupElementBuilder.create(keyword).setInsertHandler(KEYWORDS_INSERT_HANDLER).setBold()); } for (String softKeyword : COMPLETE_SOFT_KEYWORDS) { - result.addElement(LookupElementBuilder.create(softKeyword)); + result.addElement(LookupElementBuilder.create(softKeyword).setInsertHandler(KEYWORDS_INSERT_HANDLER)); } } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java new file mode 100644 index 00000000000..68aafbc70a1 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetFunctionInsertHandler.java @@ -0,0 +1,38 @@ +package org.jetbrains.jet.plugin.completion.handlers; + +import com.intellij.codeInsight.completion.InsertHandler; +import com.intellij.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.editor.Editor; + +/** + * Inserts '()' after function proposal insert. + * + * @author Nikolay Krasko + */ +public class JetFunctionInsertHandler implements InsertHandler { + + public enum CaretPosition { IN_BRACKETS, AFTER_BRACKETS } + + private final CaretPosition caretPosition; + + public JetFunctionInsertHandler(CaretPosition caretPosition) { + this.caretPosition = caretPosition; + } + + @Override + public void handleInsert(InsertionContext context, LookupElement item) { + int startOffset = context.getStartOffset(); + int lookupStringLength = item.getLookupString().length(); + int endOffset = startOffset + lookupStringLength; + + context.getDocument().insertString(endOffset, "()"); + + Editor editor = context.getEditor(); + if (caretPosition == CaretPosition.IN_BRACKETS) { + editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1); + } else { + editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 2); + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetKeywordInsertHandler.java b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetKeywordInsertHandler.java new file mode 100644 index 00000000000..2424d1a2c7a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/handlers/JetKeywordInsertHandler.java @@ -0,0 +1,34 @@ +package org.jetbrains.jet.plugin.completion.handlers; + +import com.google.common.collect.Sets; +import com.intellij.codeInsight.completion.InsertHandler; +import com.intellij.codeInsight.completion.InsertionContext; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; + +import java.util.Set; + +/** + * @author Nikolay Krasko + */ +public class JetKeywordInsertHandler implements InsertHandler { + + private final static Set NO_SPACE_AFTER = Sets.newHashSet("this", "super", "This", "true", "false", "null"); + + @Override + public void handleInsert(InsertionContext context, LookupElement item) { + String keyword = item.getLookupString(); + + // Add space after keyword + if (!NO_SPACE_AFTER.contains(keyword)) { + Editor editor = context.getEditor(); + Document document = editor.getDocument(); + + int offset = context.getStartOffset() + keyword.length(); + context.setAddCompletionChar(false); + document.insertString(offset, " "); + editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1); + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java index 9fb52fa377c..54e27ce690f 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java @@ -1,6 +1,9 @@ package org.jetbrains.jet.plugin.references; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.util.Iconable; @@ -14,17 +17,34 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution; import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler; import org.jetbrains.jet.resolve.DescriptorRenderer; import java.util.List; +import java.util.Set; /** * @author yole */ class JetSimpleNameReference extends JetPsiReference { + + private final static JetFunctionInsertHandler EMPTY_FUNCTION_HANDLER = new JetFunctionInsertHandler( + JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS); + + private final static JetFunctionInsertHandler PARAMS_FUNCTION_HANDLER = new JetFunctionInsertHandler( + JetFunctionInsertHandler.CaretPosition.IN_BRACKETS); + private final JetSimpleNameExpression myExpression; public JetSimpleNameReference(JetSimpleNameExpression jetSimpleNameExpression) { @@ -53,9 +73,14 @@ class JetSimpleNameReference extends JetPsiReference { JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); JetFile file = (JetFile) myExpression.getContainingFile(); BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file); + final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression); - if (expressionType != null) { - return collectLookupElements(bindingContext, expressionType.getMemberScope()); + final JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, receiverExpression); + + if (expressionType != null && resolutionScope != null) { + return collectLookupElements(bindingContext, + includeExternalCallableExtensions(expressionType.getMemberScope().getAllDescriptors(), + resolutionScope, new ExpressionReceiver(receiverExpression, expressionType))); } } else { @@ -63,7 +88,8 @@ class JetSimpleNameReference extends JetPsiReference { BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file); JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, myExpression); if (resolutionScope != null) { - return collectLookupElements(bindingContext, resolutionScope); + return collectLookupElements(bindingContext, + excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope)); } } @@ -76,17 +102,53 @@ class JetSimpleNameReference extends JetPsiReference { return myExpression.getReferencedNameElement().replace(element); } - private Object[] collectLookupElements(BindingContext bindingContext, JetScope scope) { + private Iterable excludeNotCallableExtensions( + @NotNull Iterable descriptors, @NotNull final JetScope scope + ) { + final Set descriptorsSet = Sets.newHashSet(descriptors); + descriptorsSet.removeAll( + Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate() { + @Override + public boolean apply(CallableDescriptor callableDescriptor) { + return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor); + } + })); + + return descriptorsSet; + } + + private Iterable includeExternalCallableExtensions( + @NotNull Iterable descriptors, + @NotNull final JetScope externalScope, + @NotNull final ReceiverDescriptor receiverDescriptor + ) { + Set descriptorsSet = Sets.newHashSet(descriptors); + + descriptorsSet.addAll(Collections2.filter(JetScopeUtils.getAllExtensions(externalScope), + new Predicate() { + @Override + public boolean apply(CallableDescriptor callableDescriptor) { + return checkReceiverResolution(receiverDescriptor, callableDescriptor); + } + })); + + return descriptorsSet; + } + + private Object[] collectLookupElements(BindingContext bindingContext, Iterable descriptors) { List result = Lists.newArrayList(); - for (final DeclarationDescriptor descriptor : scope.getAllDescriptors()) { + + for (final DeclarationDescriptor descriptor : descriptors) { LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName()); String typeText = ""; String tailText = ""; boolean tailTextGrayed = false; + if (descriptor instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; JetType returnType = functionDescriptor.getReturnType(); typeText = DescriptorRenderer.TEXT.renderType(returnType); + tailText = "(" + StringUtil.join(functionDescriptor.getValueParameters(), new Function() { @Override public String fun(ValueParameterDescriptor valueParameterDescriptor) { @@ -94,6 +156,14 @@ class JetSimpleNameReference extends JetPsiReference { DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType()); } }, ",") + ")"; + + // TODO: A special case when it's impossible to resolve type parameters from arguments. Need '<' caret '>' + // TODO: Support omitting brackets for one argument functions + if (functionDescriptor.getValueParameters().isEmpty()) { + element = element.setInsertHandler(EMPTY_FUNCTION_HANDLER); + } else { + element = element.setInsertHandler(PARAMS_FUNCTION_HANDLER); + } } else if (descriptor instanceof VariableDescriptor) { JetType outType = ((VariableDescriptor) descriptor).getOutType(); @@ -117,4 +187,29 @@ class JetSimpleNameReference extends JetPsiReference { } return result.toArray(); } + + /* + * Checks if receiver declaration could be resolved to call expected receiver. + */ + private static boolean checkReceiverResolution ( + @NotNull ReceiverDescriptor expectedReceiver, + @NotNull CallableDescriptor receiverArgument + ) { + ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING); + for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) { + constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); + } + + ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter(); + if (expectedReceiver.exists() && receiverParameter.exists()) { + constraintSystem.addSubtypingConstraint(expectedReceiver.getType(), receiverParameter.getType()); + } + else if (expectedReceiver.exists() || receiverParameter.exists()) { + // Only one of receivers exist + return false; + } + + ConstraintSystemSolution solution = constraintSystem.solve(); + return solution.getStatus().isSuccessful(); + } } diff --git a/idea/testData/completion/basic/extensions/ExtensionInExtendedClass.kt b/idea/testData/completion/basic/extensions/ExtensionInExtendedClass.kt new file mode 100644 index 00000000000..d4f4b62aa8a --- /dev/null +++ b/idea/testData/completion/basic/extensions/ExtensionInExtendedClass.kt @@ -0,0 +1,12 @@ +namespace Test + +class Some() { + fun methodName() { + + } +} + +fun Some.first() { +} + +// EXIST: first diff --git a/idea/testData/completion/basic/extensions/ExtensionInExtendedClassThis.kt b/idea/testData/completion/basic/extensions/ExtensionInExtendedClassThis.kt new file mode 100644 index 00000000000..a8f97b0ee84 --- /dev/null +++ b/idea/testData/completion/basic/extensions/ExtensionInExtendedClassThis.kt @@ -0,0 +1,10 @@ +class Some() { + fun methodName() { + this. + } +} + +fun Some.first() { +} + +// EXIST: first \ No newline at end of file diff --git a/idea/testData/completion/basic/extensions/ExtensionInExtension.kt b/idea/testData/completion/basic/extensions/ExtensionInExtension.kt new file mode 100644 index 00000000000..9365ddaa7e4 --- /dev/null +++ b/idea/testData/completion/basic/extensions/ExtensionInExtension.kt @@ -0,0 +1,11 @@ +fun Some.first() { +} + +class Some() { +} + +fun Some.second() { + +} + +// EXIST: first, second \ No newline at end of file diff --git a/idea/testData/completion/basic/extensions/ExtensionInExtensionThis.kt b/idea/testData/completion/basic/extensions/ExtensionInExtensionThis.kt new file mode 100644 index 00000000000..f5eabe4ee0b --- /dev/null +++ b/idea/testData/completion/basic/extensions/ExtensionInExtensionThis.kt @@ -0,0 +1,11 @@ +fun Some.first() { +} + +class Some() { +} + +fun Some.second() { + this. +} + +// EXIST: first, second \ No newline at end of file diff --git a/idea/testData/completion/basic/extensions/InvalidTypeParameters.kt b/idea/testData/completion/basic/extensions/InvalidTypeParameters.kt new file mode 100644 index 00000000000..7dd4fee1e9a --- /dev/null +++ b/idea/testData/completion/basic/extensions/InvalidTypeParameters.kt @@ -0,0 +1,17 @@ +class SomeObject() { + var field : T? = null +} + +class A {} +class C {} + +fun , U> SomeObject.compareTo(other : SomeObject) : Int { + return 0; +} + +fun some() { + val test = SomeObject + test. +} + +// ABSENT: compareTo \ No newline at end of file diff --git a/idea/testData/completion/basic/extensions/IrrelevantExtension.kt b/idea/testData/completion/basic/extensions/IrrelevantExtension.kt new file mode 100644 index 00000000000..808583c66eb --- /dev/null +++ b/idea/testData/completion/basic/extensions/IrrelevantExtension.kt @@ -0,0 +1,11 @@ +fun Some.simpleKotlinExtension() { +} + +class Some() { +} + +fun test() { + +} + +// ABSENT: simpleKotlinExtension \ No newline at end of file diff --git a/idea/testData/completion/basic/extensions/JavaTypeExtension.kt b/idea/testData/completion/basic/extensions/JavaTypeExtension.kt new file mode 100644 index 00000000000..9f8e7ff4945 --- /dev/null +++ b/idea/testData/completion/basic/extensions/JavaTypeExtension.kt @@ -0,0 +1,10 @@ +fun java.lang.Iterable.first() : T? { + return this.iterator()?.next() +} + +fun main(args : Array) { + val test = java.util.HashSet() + test. +} + +// EXIST: first diff --git a/idea/testData/completion/basic/extensions/KotlinGenericTypeExtension.kt b/idea/testData/completion/basic/extensions/KotlinGenericTypeExtension.kt new file mode 100644 index 00000000000..8352c7c5cd2 --- /dev/null +++ b/idea/testData/completion/basic/extensions/KotlinGenericTypeExtension.kt @@ -0,0 +1,12 @@ +fun Some.close() { +} + +class Some() { +} + +fun test() { + val s = Some() + s. +} + +// EXIST: close \ No newline at end of file diff --git a/idea/testData/completion/basic/extensions/KotlinTypeExtension.kt b/idea/testData/completion/basic/extensions/KotlinTypeExtension.kt new file mode 100644 index 00000000000..0707b815317 --- /dev/null +++ b/idea/testData/completion/basic/extensions/KotlinTypeExtension.kt @@ -0,0 +1,12 @@ +fun Some.simpleKotlinExtension() { +} + +class Some() { +} + +fun test() { + val s = Some() + s. +} + +// EXIST: simpleKotlinExtension \ No newline at end of file diff --git a/idea/testData/completion/handlers/NoParamsFunction.kt b/idea/testData/completion/handlers/NoParamsFunction.kt new file mode 100644 index 00000000000..120b5e55d02 --- /dev/null +++ b/idea/testData/completion/handlers/NoParamsFunction.kt @@ -0,0 +1,8 @@ +fun test() { +} + +fun other() { + te +} + +// INSERT: test \ No newline at end of file diff --git a/idea/testData/completion/handlers/NoParamsFunction.kt.after b/idea/testData/completion/handlers/NoParamsFunction.kt.after new file mode 100644 index 00000000000..920873c0b51 --- /dev/null +++ b/idea/testData/completion/handlers/NoParamsFunction.kt.after @@ -0,0 +1,8 @@ +fun test() { +} + +fun other() { + test() +} + +// INSERT: test \ No newline at end of file diff --git a/idea/testData/completion/handlers/ParamsFunction.kt b/idea/testData/completion/handlers/ParamsFunction.kt new file mode 100644 index 00000000000..c7910930150 --- /dev/null +++ b/idea/testData/completion/handlers/ParamsFunction.kt @@ -0,0 +1,6 @@ +fun test(a: Int) { +} + +fun other() { + te +} \ No newline at end of file diff --git a/idea/testData/completion/handlers/ParamsFunction.kt.after b/idea/testData/completion/handlers/ParamsFunction.kt.after new file mode 100644 index 00000000000..175892cc3a5 --- /dev/null +++ b/idea/testData/completion/handlers/ParamsFunction.kt.after @@ -0,0 +1,6 @@ +fun test(a: Int) { +} + +fun other() { + test() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/ExtensionsCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/ExtensionsCompletionTest.java new file mode 100644 index 00000000000..5484200d560 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/completion/ExtensionsCompletionTest.java @@ -0,0 +1,43 @@ +package org.jetbrains.jet.completion; + +import junit.framework.Test; +import junit.framework.TestSuite; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.JetTestCaseBuilder; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.io.File; + +/** + * @author Nikolay Krasko + */ +public class ExtensionsCompletionTest extends JetCompletionTestBase { + +// public ExtensionsCompletionTest() { +// this("/completion/basic/extensions", "IrrelevantExtension"); +// // this("/completion/basic/extensions", "InvalidTypeParameters"); +// // this("/completion/basic/extensions", "ExtensionInExtensionThis"); +// } + + protected ExtensionsCompletionTest(@NotNull String path, @NotNull String name) { + super(path, name); + } + + @NotNull + public static TestSuite suite() { + TestSuite suite = new TestSuite(); + + JetTestCaseBuilder.appendTestsInDirectory( + PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/extensions", false, + JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() { + + @NotNull + @Override + public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) { + return new ExtensionsCompletionTest(dataPath, name); + } + }, suite); + + return suite; + } +} diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java index 995363c1be8..4bb6dd31b89 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java @@ -12,31 +12,9 @@ import java.io.File; * @author Nikolay.Krasko */ public class JetBasicCompletionTest extends JetCompletionTestBase { - private final String myPath; - private final String myName; - public JetBasicCompletionTest(@NotNull String path, @NotNull String name) { - myPath = path; - myName = name; - - // Set name explicitly because otherwise there will be "TestCase.fName cannot be null" - setName("testCompletionExecute"); - } - - public void testCompletionExecute() throws Exception { - doTest(); - } - - @Override - protected String getTestDataPath() { - return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() + - File.separator; - } - - @NotNull - @Override - public String getName() { - return "test" + myName; + protected JetBasicCompletionTest(@NotNull String path, @NotNull String name) { + super(path, name); } @NotNull diff --git a/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java b/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java index 39372cd71c2..624eb685c3e 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java +++ b/idea/tests/org/jetbrains/jet/completion/JetCompletionTestBase.java @@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.PluginTestCaseBase; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; @@ -20,6 +21,32 @@ import java.util.List; * @author Nikolay.Krasko */ public abstract class JetCompletionTestBase extends LightCompletionTestCase { + private final String myPath; + private final String myName; + + protected JetCompletionTestBase(@NotNull String path, @NotNull String name) { + myPath = path; + myName = name; + + // Set name explicitly because otherwise there will be "TestCase.fName cannot be null" + setName("testCompletionExecute"); + } + + public void testCompletionExecute() throws Exception { + doTest(); + } + + @Override + protected String getTestDataPath() { + return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() + + File.separator; + } + + @NotNull + @Override + public String getName() { + return "test" + myName; + } private CompletionType type; diff --git a/idea/tests/org/jetbrains/jet/completion/KeywordsCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/KeywordsCompletionTest.java index 4a0e14d9ed4..cc45d46b28b 100644 --- a/idea/tests/org/jetbrains/jet/completion/KeywordsCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/KeywordsCompletionTest.java @@ -15,31 +15,8 @@ import java.io.File; */ public class KeywordsCompletionTest extends JetCompletionTestBase { - private final String myPath; - private final String myName; - - public KeywordsCompletionTest(@NotNull String path, @NotNull String name) { - myPath = path; - myName = name; - - // Set name explicitly because otherwise there will be "TestCase.fName cannot be null" - setName("testCompletionExecute"); - } - - public void testCompletionExecute() throws Exception { - doTest(); - } - - @Override - protected String getTestDataPath() { - return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() + - File.separator; - } - - @NotNull - @Override - public String getName() { - return "test" + myName; + protected KeywordsCompletionTest(@NotNull String path, @NotNull String name) { + super(path, name); } @NotNull diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/FunctionsHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/FunctionsHandlerTest.java new file mode 100644 index 00000000000..f265bde4714 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/completion/handlers/FunctionsHandlerTest.java @@ -0,0 +1,28 @@ +package org.jetbrains.jet.completion.handlers; + +import com.intellij.codeInsight.completion.LightCompletionTestCase; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.io.File; + +/** + * @author Nikolay Krasko + */ +public class FunctionsHandlerTest extends LightCompletionTestCase { + + public void testNoParamsFunction() { + configureByFile("NoParamsFunction.kt"); + checkResultByFile("NoParamsFunction.kt.after"); + } + + public void testFunctionWithParams() { + configureByFile("ParamsFunction.kt"); + checkResultByFile("ParamsFunction.kt.after"); + } + + @Override + protected String getTestDataPath() { + return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() + + File.separator; + } +} diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/KeywordsHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/KeywordsHandlerTest.java new file mode 100644 index 00000000000..4b6193b2549 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/completion/handlers/KeywordsHandlerTest.java @@ -0,0 +1,31 @@ +package org.jetbrains.jet.completion.handlers; + +import com.intellij.codeInsight.completion.LightCompletionTestCase; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.io.File; +import java.io.IOException; + +/** + * @author Nikolay Krasko + */ +public class KeywordsHandlerTest extends LightCompletionTestCase { + + public void testSpaceAfter() throws IOException { + configureFromFileText("Test.kt", "protecte"); + complete(); + checkResultByText("protected "); + } + + public void testNoSpaceAfter() throws IOException { + configureFromFileText("Test.kt", "nul"); + complete(); + checkResultByText("null"); + } + + @Override + protected String getTestDataPath() { + return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() + + File.separator; + } +} diff --git a/stdlib/src/jet/DefaultJetObject.java b/stdlib/src/jet/DefaultJetObject.java index 4070c14eb5d..736606a70d6 100644 --- a/stdlib/src/jet/DefaultJetObject.java +++ b/stdlib/src/jet/DefaultJetObject.java @@ -23,4 +23,9 @@ public class DefaultJetObject implements JetObject { public final TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } diff --git a/stdlib/src/jet/IntRange.java b/stdlib/src/jet/IntRange.java index 71d49ed0a73..13811dbba40 100644 --- a/stdlib/src/jet/IntRange.java +++ b/stdlib/src/jet/IntRange.java @@ -47,7 +47,12 @@ public final class IntRange implements Range, Iterable, JetObj public TypeInfo getTypeInfo() { return typeInfo; } - + + @Override + public JetObject getOuterObject() { + return null; + } + public static IntRange count(int length) { return new IntRange(0, length); } @@ -95,5 +100,10 @@ public final class IntRange implements Range, Iterable, JetObj public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } } diff --git a/stdlib/src/jet/JetObject.java b/stdlib/src/jet/JetObject.java index c06fd1f755a..96f17a323b6 100644 --- a/stdlib/src/jet/JetObject.java +++ b/stdlib/src/jet/JetObject.java @@ -4,7 +4,9 @@ import jet.typeinfo.TypeInfo; /** * @author abreslav + * @author alex.tkachman */ public interface JetObject { TypeInfo getTypeInfo(); + JetObject getOuterObject(); } diff --git a/stdlib/src/jet/LongRange.java b/stdlib/src/jet/LongRange.java index e0a358599fb..ed94c76cb31 100644 --- a/stdlib/src/jet/LongRange.java +++ b/stdlib/src/jet/LongRange.java @@ -48,6 +48,11 @@ public final class LongRange implements Range, Iterable, JetObject { return typeInfo; } + @Override + public JetObject getOuterObject() { + return null; + } + public static IntRange count(int length) { return new IntRange(0, length); } @@ -95,5 +100,10 @@ public final class LongRange implements Range, Iterable, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } } diff --git a/stdlib/src/jet/Tuple0.java b/stdlib/src/jet/Tuple0.java index 34d12022230..a4823e1dd5e 100644 --- a/stdlib/src/jet/Tuple0.java +++ b/stdlib/src/jet/Tuple0.java @@ -31,4 +31,9 @@ public class Tuple0 implements JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } \ No newline at end of file diff --git a/stdlib/src/jet/runtime/ArrayIterator.java b/stdlib/src/jet/runtime/ArrayIterator.java index 55d4e0a9cd9..0b05941e507 100644 --- a/stdlib/src/jet/runtime/ArrayIterator.java +++ b/stdlib/src/jet/runtime/ArrayIterator.java @@ -37,7 +37,12 @@ public abstract class ArrayIterator implements Iterator, JetObject { @Override public TypeInfo getTypeInfo() { - return TypeInfo.getTypeInfo(GenericIterator.class, false, null, new TypeInfoProjection[] {(TypeInfoProjection) elementTypeInfo}); + return TypeInfo.getTypeInfo(GenericIterator.class, false, new TypeInfoProjection[] {(TypeInfoProjection) elementTypeInfo}); + } + + @Override + public JetObject getOuterObject() { + return null; } } @@ -69,6 +74,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static ByteIterator iterator(byte[] array) { @@ -99,6 +109,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static ShortIterator iterator(short[] array) { @@ -129,6 +144,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static IntIterator iterator(int[] array) { @@ -159,6 +179,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static LongIterator iterator(long[] array) { @@ -189,6 +214,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static FloatIterator iterator(float[] array) { @@ -219,6 +249,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static DoubleIterator iterator(double[] array) { @@ -249,6 +284,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static CharIterator iterator(char[] array) { @@ -279,6 +319,11 @@ public abstract class ArrayIterator implements Iterator, JetObject { public TypeInfo getTypeInfo() { return typeInfo; } + + @Override + public JetObject getOuterObject() { + return null; + } } public static BooleanIterator iterator(boolean[] array) { diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index 2fb20baa47e..a5ad5850ebe 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -79,14 +79,6 @@ public abstract class TypeInfo implements JetObject { return new TypeInfoImpl(klazz, nullable); } - public static TypeInfo getTypeInfo(Class klazz, boolean nullable, TypeInfo outerTypeInfo) { - return new TypeInfoImpl(klazz, nullable, outerTypeInfo); - } - - public static TypeInfo getTypeInfo(Class klazz, boolean nullable, TypeInfo outerTypeInfo, TypeInfoProjection[] projections) { - return new TypeInfoImpl(klazz, nullable, outerTypeInfo, projections); - } - public static TypeInfo getTypeInfo(Class klazz, boolean nullable, TypeInfoProjection[] projections) { return new TypeInfoImpl(klazz, nullable, projections); } @@ -99,15 +91,13 @@ public abstract class TypeInfo implements JetObject { public abstract int getProjectionCount(); - public abstract TypeInfo getOuterTypeInfo(); - public abstract TypeInfoProjection getProjection(int index); public abstract TypeInfo getArgumentType(Class klass, int index); protected abstract TypeInfo substitute(List myVars); - protected abstract TypeInfo substitute(TypeInfo outer, TypeInfoProjection[] projections); + protected abstract TypeInfo substitute(TypeInfoProjection[] projections); private static class TypeInfoVar extends TypeInfo { final int varIndex; @@ -151,11 +141,6 @@ public abstract class TypeInfo implements JetObject { return 0; } - @Override - public TypeInfo getOuterTypeInfo() { - return null; - } - @Override public TypeInfoProjection getProjection(int index) { throw new UnsupportedOperationException("Abstract TypeInfo"); @@ -172,7 +157,7 @@ public abstract class TypeInfo implements JetObject { } @Override - protected TypeInfo substitute(TypeInfo outer, TypeInfoProjection[] projections) { + protected TypeInfo substitute(TypeInfoProjection[] projections) { return projections[varIndex].getType(); } @@ -181,6 +166,11 @@ public abstract class TypeInfo implements JetObject { throw new UnsupportedOperationException("Abstract TypeInfo"); } + @Override + public JetObject getOuterObject() { + return null; + } + @Override public String toString() { return "T:" + signature.klazz.getName() + ":" + varIndex; @@ -192,22 +182,12 @@ public abstract class TypeInfo implements JetObject { private final Signature signature; private final boolean nullable; private final TypeInfoProjection[] projections; - private final TypeInfo outerTypeInfo; private TypeInfoImpl(Class theClass, boolean nullable) { - this(theClass, nullable, null, EMPTY); - } - - private TypeInfoImpl(Class theClass, boolean nullable, TypeInfo outerTypeInfo) { - this(theClass, nullable, outerTypeInfo, EMPTY); + this(theClass, nullable, EMPTY); } private TypeInfoImpl(Class theClass, boolean nullable, TypeInfoProjection[] projections) { - this(theClass, nullable, null, projections); - } - - private TypeInfoImpl(Class theClass, boolean nullable, TypeInfo outerTypeInfo, TypeInfoProjection[] projections) { - this.outerTypeInfo = outerTypeInfo; this.signature = Parser.parse(theClass); this.nullable = nullable; this.projections = projections; @@ -247,7 +227,7 @@ public abstract class TypeInfo implements JetObject { if(klass == this.signature.klazz) return projections[index].getType(); else { - return getSuperTypeInfo(klass).substitute(outerTypeInfo, projections).getArgumentType(klass, index); + return getSuperTypeInfo(klass).substitute(projections).getArgumentType(klass, index); } } @@ -283,14 +263,14 @@ public abstract class TypeInfo implements JetObject { } @Override - protected TypeInfo substitute(TypeInfo outer, TypeInfoProjection[] prj) { + protected TypeInfo substitute(TypeInfoProjection[] prj) { if(projections.length == 0) return new TypeInfoImpl(signature.klazz, nullable, EMPTY); else { TypeInfoProjection [] proj = new TypeInfoProjection[projections.length]; for(int i = 0; i != proj.length; ++i) { final int finalI = i; - final TypeInfo substitute = projections[finalI].getType().substitute(outer, prj); + final TypeInfo substitute = projections[finalI].getType().substitute(prj); proj[i] = new TypeInfoProjection(){ @Override @@ -359,11 +339,6 @@ public abstract class TypeInfo implements JetObject { return projections.length; } - @Override - public TypeInfo getOuterTypeInfo() { - return outerTypeInfo; - } - @Override public final String toString() { StringBuilder sb = new StringBuilder().append(signature.klazz.getName()); @@ -388,6 +363,11 @@ public abstract class TypeInfo implements JetObject { return typeInfo; } + @Override + public JetObject getOuterObject() { + return null; + } + public final boolean isSubtypeOf(TypeInfoImpl superType) { if (nullable && !superType.nullable) { return false; @@ -410,7 +390,6 @@ public abstract class TypeInfo implements JetObject { } public static class Signature { - final Signature outer; final Class klazz; List variables; @@ -419,8 +398,7 @@ public abstract class TypeInfo implements JetObject { final HashMap superSignatures = new HashMap(); - public Signature(Signature outer, Class klazz) { - this.outer = outer; + public Signature(Class klazz) { this.klazz = klazz; } @@ -502,7 +480,7 @@ public abstract class TypeInfo implements JetObject { if(value != null) { Parser parser = new Parser(value, klass.getClassLoader()); Class enclosingClass = klass.getEnclosingClass(); - Signature signature = new Signature(parse(enclosingClass), klass); + Signature signature = new Signature(klass); map.put(klass, signature); parser.parseVars(signature); parser.parseTypes(signature); @@ -517,7 +495,7 @@ public abstract class TypeInfo implements JetObject { // todo complete impl java.lang.reflect.Type genericSuperclass = klass.getGenericSuperclass(); - Signature signature = new Signature(parse(klass.getEnclosingClass()), klass); + Signature signature = new Signature(klass); TypeVariable[] typeParameters = klass.getTypeParameters(); if(typeParameters == null || typeParameters.length == 0) { @@ -682,14 +660,14 @@ public abstract class TypeInfo implements JetObject { if(klazz.equals(signature.klazz.getName())) return new TypeInfoVar(signature, nullable, signature.varNames.get(name)); else { - Signature sig = signature; - while(!klazz.equals(sig.klazz.getName())) { - sig = sig.outer; - if(sig == null) - throw new IllegalStateException(); - } +// Signature sig = signature; +// while(!klazz.equals(sig.klazz.getName())) { +// sig = sig.outer; +// if(sig == null) +// throw new IllegalStateException(); +// } - return new TypeInfoVar(sig, nullable, sig.varNames.get(name)); + throw new UnsupportedOperationException("outer type info does not supported"); } } @@ -716,7 +694,7 @@ public abstract class TypeInfo implements JetObject { private static class ArraySignature extends Signature { public ArraySignature(Class klass) { - super(null, klass); + super(klass); variables = new LinkedList(); varNames = new HashMap(); varNames.put("T", 0);