From 41eb0deaa09e9e41960564867eb87bcc2c63a611 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 12 May 2014 22:03:45 +0400 Subject: [PATCH] Introduce FunctionImpl and ExtensionFunctionImpl classes Old FunctionImpl0,1,2,... will be dropped since they had no purpose --- .../jetbrains/jet/codegen/ClosureCodegen.java | 79 +++++--- .../jet/codegen/ExpressionCodegen.java | 22 +- .../jet/codegen/JvmFunctionImplTypes.java | 191 +++++++++--------- .../binding/CodegenAnnotatingVisitor.java | 19 +- .../box/functions/functionNtoString.kt | 16 +- .../functionLiteralGenericSignature.kt | 18 +- .../jet/lang/resolve/DescriptorUtils.java | 4 +- .../jvm/internal/ExtensionFunctionImpl.kt | 23 +++ .../src/kotlin/jvm/internal/FunctionImpl.kt | 23 +++ 9 files changed, 224 insertions(+), 171 deletions(-) create mode 100644 core/runtime.jvm/src/kotlin/jvm/internal/ExtensionFunctionImpl.kt create mode 100644 core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 4156f9c3588..51bb690f0ef 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.name.Name; @@ -40,7 +41,8 @@ import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.Method; -import java.util.Collection; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static org.jetbrains.jet.codegen.AsmUtil.*; @@ -53,7 +55,8 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { private final PsiElement fun; private final FunctionDescriptor funDescriptor; private final ClassDescriptor samInterface; - private final Type superClass; + private final JetType superClassType; + private final List superInterfaceTypes; private final CodegenContext context; private final FunctionGenerationStrategy strategy; private final CalculatedClosure closure; @@ -68,7 +71,6 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { @NotNull PsiElement fun, @NotNull FunctionDescriptor funDescriptor, @Nullable ClassDescriptor samInterface, - @NotNull Type closureSuperClass, @NotNull CodegenContext parentContext, @NotNull KotlinSyntheticClass.Kind syntheticClassKind, @NotNull LocalLookup localLookup, @@ -80,12 +82,36 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { this.fun = fun; this.funDescriptor = funDescriptor; this.samInterface = samInterface; - this.superClass = closureSuperClass; this.context = parentContext.intoClosure(funDescriptor, localLookup, typeMapper); this.syntheticClassKind = syntheticClassKind; this.strategy = strategy; ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor); + + if (samInterface == null) { + this.superInterfaceTypes = new ArrayList(); + + JetType superClassType = null; + for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) { + ClassifierDescriptor classifier = supertype.getConstructor().getDeclarationDescriptor(); + if (DescriptorUtils.isTrait(classifier)) { + superInterfaceTypes.add(supertype); + } + else { + assert superClassType == null : "Closure class can't have more than one superclass: " + funDescriptor; + superClassType = supertype; + } + } + assert superClassType != null : "Closure class should have a superclass: " + funDescriptor; + + this.superClassType = superClassType; + } + else { + // TODO: getDefaultType() is incorrect here + this.superInterfaceTypes = Collections.singletonList(samInterface.getDefaultType()); + this.superClassType = KotlinBuiltIns.getInstance().getAnyType(); + } + this.closure = bindingContext.get(CLOSURE, classDescriptor); assert closure != null : "Closure must be calculated for class: " + classDescriptor; @@ -98,24 +124,32 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { ClassBuilder cv = state.getFactory().newVisitor(asmType, fun.getContainingFile()); FunctionDescriptor interfaceFunction; - String[] superInterfaces; - if (samInterface == null) { interfaceFunction = getInvokeFunction(funDescriptor); - superInterfaces = ArrayUtil.EMPTY_STRING_ARRAY; } else { interfaceFunction = SingleAbstractMethodUtils.getAbstractMethodOfSamInterface(samInterface); - superInterfaces = new String[] { typeMapper.mapType(samInterface).getInternalName() }; + } + + BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS); + sw.writeSuperclass(); + Type superClassAsmType = typeMapper.mapSupertype(superClassType, sw); + sw.writeSuperclassEnd(); + String[] superInterfaceAsmTypes = new String[superInterfaceTypes.size()]; + for (int i = 0; i < superInterfaceTypes.size(); i++) { + JetType superInterfaceType = superInterfaceTypes.get(i); + sw.writeInterface(); + superInterfaceAsmTypes[i] = typeMapper.mapSupertype(superInterfaceType, sw).getInternalName(); + sw.writeInterfaceEnd(); } cv.defineClass(fun, V1_6, ACC_FINAL | ACC_SUPER | visibilityFlag, asmType.getInternalName(), - getGenericSignature(), - superClass.getInternalName(), - superInterfaces + sw.makeJavaGenericSignature(), + superClassAsmType.getInternalName(), + superInterfaceAsmTypes ); cv.visitSource(fun.getContainingFile().getName(), null); @@ -127,7 +161,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { FunctionCodegen fc = new FunctionCodegen(context, cv, state, getParentCodegen()); fc.generateMethod(fun, jvmMethodSignature, funDescriptor, strategy); - this.constructor = generateConstructor(cv); + this.constructor = generateConstructor(cv, superClassAsmType); if (isConst(closure)) { generateConstInstance(cv); @@ -212,10 +246,10 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { } @NotNull - private Method generateConstructor(@NotNull ClassBuilder cv) { + private Method generateConstructor(@NotNull ClassBuilder cv, @NotNull Type superClassAsmType) { List args = calculateConstructorParameters(typeMapper, closure, asmType); - return generateConstructor(cv, args, fun, superClass, state, visibilityFlag); + return generateConstructor(cv, args, fun, superClassAsmType, state, visibilityFlag); } public static Method generateConstructor( @@ -296,23 +330,6 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { return argTypes; } - @NotNull - private String getGenericSignature() { - ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor); - Collection supertypes = classDescriptor.getTypeConstructor().getSupertypes(); - assert supertypes.size() == 1 : "Closure must have exactly one supertype: " + funDescriptor; - JetType supertype = supertypes.iterator().next(); - - BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS); - sw.writeSuperclass(); - typeMapper.mapSupertype(supertype, sw); - sw.writeSuperclassEnd(); - - String signature = sw.makeJavaGenericSignature(); - assert signature != null : "Closure superclass must have a generic signature: " + funDescriptor; - return signature; - } - public static FunctionDescriptor getInvokeFunction(FunctionDescriptor funDescriptor) { int paramCount = funDescriptor.getValueParameters().size(); KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 5e4a06a001f..7c9b6620a2f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1310,15 +1310,10 @@ public class ExpressionCodegen extends JetVisitor implem FunctionDescriptor descriptor = bindingContext.get(FUNCTION, declaration); assert descriptor != null : "Function is not resolved to descriptor: " + declaration.getText(); - String functionImplClassPrefix = descriptor.getReceiverParameter() != null ? "ExtensionFunctionImpl" : "FunctionImpl"; - Type closureSuperClass = - samInterfaceClass == null ? - Type.getObjectType("kotlin/" + functionImplClassPrefix + descriptor.getValueParameters().size()) : - OBJECT_TYPE; - - ClosureCodegen closureCodegen = new ClosureCodegen(state, declaration, descriptor, samInterfaceClass, closureSuperClass, context, - kind, this, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), parentCodegen); - + ClosureCodegen closureCodegen = new ClosureCodegen( + state, declaration, descriptor, samInterfaceClass, context, kind, this, + new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), parentCodegen + ); closureCodegen.gen(); return closureCodegen.putInstanceOnStack(v, this); @@ -2414,16 +2409,9 @@ public class ExpressionCodegen extends JetVisitor implem FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); assert functionDescriptor != null : "Callable reference is not resolved to descriptor: " + expression.getText(); - JetType kFunctionType = bindingContext.get(EXPRESSION_TYPE, expression); - assert kFunctionType != null : "Callable reference is not type checked: " + expression.getText(); - ClassDescriptor kFunctionImpl = state.getJvmFunctionImplTypes().kFunctionTypeToImpl(kFunctionType); - assert kFunctionImpl != null : "Impl type is not found for the function type: " + kFunctionType; - - Type closureSuperClass = typeMapper.mapType(kFunctionImpl); - CallableReferenceGenerationStrategy strategy = new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall(expression.getCallableReference())); - ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, + ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, context, KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER, this, strategy, getParentCodegen()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java b/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java index 516cffbc1e2..0cf312e4d07 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JvmFunctionImplTypes.java @@ -17,48 +17,30 @@ package org.jetbrains.jet.codegen; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.reflect.ReflectionTypes; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.JetTypeImpl; -import org.jetbrains.jet.lang.types.TypeProjection; -import org.jetbrains.jet.lang.types.TypeProjectionImpl; +import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; public class JvmFunctionImplTypes { private final ReflectionTypes reflectionTypes; - private final ModuleDescriptor fakeModule; - private volatile List functionsList; + private final ClassDescriptor functionImpl; + private final ClassDescriptor extensionFunctionImpl; + private volatile List kFunctionsList; - private volatile Map kFunctionToImplMap; - - private static class Functions { - public final ClassDescriptor functionImpl; - public final ClassDescriptor extensionFunctionImpl; - - public Functions( - @NotNull ClassDescriptor functionImpl, - @NotNull ClassDescriptor extensionFunctionImpl - ) { - this.functionImpl = functionImpl; - this.extensionFunctionImpl = extensionFunctionImpl; - } - } private static class KFunctions { public final ClassDescriptor kFunctionImpl; @@ -78,39 +60,35 @@ public class JvmFunctionImplTypes { public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) { this.reflectionTypes = reflectionTypes; - this.fakeModule = new ModuleDescriptorImpl(Name.special(""), Collections.emptyList(), - JavaToKotlinClassMap.getInstance()); - } + ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special(""), + Collections.emptyList(), JavaToKotlinClassMap.getInstance()); - @NotNull - private List getFunctionsImplList() { - if (functionsList == null) { - MutablePackageFragmentDescriptor kotlin = new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin")); - KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); + MutablePackageFragmentDescriptor kotlinJvmInternal = + new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.jvm.internal")); - ImmutableList.Builder builder = ImmutableList.builder(); - for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) { - builder.add(new Functions( - createFunctionImpl(kotlin, "FunctionImpl" + i, builtIns.getFunction(i)), - createFunctionImpl(kotlin, "ExtensionFunctionImpl" + i, builtIns.getExtensionFunction(i)) - )); - } - functionsList = builder.build(); - } - return functionsList; + MutableClassDescriptor functionImpl = createClass(kotlinJvmInternal, "FunctionImpl"); + TypeParameterDescriptor funR = createTypeParameter(functionImpl, Variance.OUT_VARIANCE, "R", 0); + + MutableClassDescriptor extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl"); + TypeParameterDescriptor extFunT = createTypeParameter(extensionFunctionImpl, Variance.IN_VARIANCE, "T", 0); + TypeParameterDescriptor extFunR = createTypeParameter(extensionFunctionImpl, Variance.OUT_VARIANCE, "R", 1); + + this.functionImpl = initializeFunctionImplClass(functionImpl, Arrays.asList(funR)); + this.extensionFunctionImpl = initializeFunctionImplClass(extensionFunctionImpl, Arrays.asList(extFunT, extFunR)); } @NotNull private List getKFunctionsImplList() { if (kFunctionsList == null) { - MutablePackageFragmentDescriptor reflect = new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.reflect")); + MutablePackageFragmentDescriptor reflect = + new MutablePackageFragmentDescriptor(DescriptorUtils.getContainingModule(functionImpl), new FqName("kotlin.reflect")); ImmutableList.Builder builder = ImmutableList.builder(); for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) { builder.add(new KFunctions( - createFunctionImpl(reflect, "KFunctionImpl" + i, reflectionTypes.getKFunction(i)), - createFunctionImpl(reflect, "KMemberFunctionImpl" + i, reflectionTypes.getKMemberFunction(i)), - createFunctionImpl(reflect, "KExtensionFunctionImpl" + i, reflectionTypes.getKExtensionFunction(i)) + createKFunctionImpl(reflect, "KFunctionImpl" + i, reflectionTypes.getKFunction(i)), + createKFunctionImpl(reflect, "KMemberFunctionImpl" + i, reflectionTypes.getKMemberFunction(i)), + createKFunctionImpl(reflect, "KExtensionFunctionImpl" + i, reflectionTypes.getKExtensionFunction(i)) )); } kFunctionsList = builder.build(); @@ -119,29 +97,54 @@ public class JvmFunctionImplTypes { } @NotNull - private Map getKFunctionToImplMap() { - if (kFunctionToImplMap == null) { - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) { - KFunctions kFunctions = getKFunctionsImplList().get(i); - builder.put(reflectionTypes.getKFunction(i), kFunctions.kFunctionImpl); - builder.put(reflectionTypes.getKMemberFunction(i), kFunctions.kMemberFunctionImpl); - builder.put(reflectionTypes.getKExtensionFunction(i), kFunctions.kExtensionFunctionImpl); - } - kFunctionToImplMap = builder.build(); - } - return kFunctionToImplMap; + private static ClassDescriptor createKFunctionImpl( + @NotNull PackageFragmentDescriptor containingDeclaration, + @NotNull String name, + @NotNull ClassDescriptor functionInterface + ) { + return initializeFunctionImplClass(createClass(containingDeclaration, name), + functionInterface.getDefaultType().getConstructor().getParameters()); } - @Nullable - public ClassDescriptor kFunctionTypeToImpl(@NotNull JetType functionType) { - //noinspection SuspiciousMethodCalls - return getKFunctionToImplMap().get(functionType.getConstructor().getDeclarationDescriptor()); + @NotNull + public Collection getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) { + ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); + + List typeArguments = new ArrayList(2); + + ClassDescriptor classDescriptor; + if (receiverParameter != null) { + classDescriptor = extensionFunctionImpl; + typeArguments.add(new TypeProjectionImpl(receiverParameter.getType())); + } + else { + classDescriptor = functionImpl; + } + + //noinspection ConstantConditions + typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType())); + + JetType functionImplType = new JetTypeImpl( + classDescriptor.getDefaultType().getAnnotations(), + classDescriptor.getTypeConstructor(), + false, + typeArguments, + classDescriptor.getMemberScope(typeArguments) + ); + + JetType functionType = KotlinBuiltIns.getInstance().getFunctionType( + Annotations.EMPTY, + receiverParameter == null ? null : receiverParameter.getType(), + DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()), + descriptor.getReturnType() + ); + + return Arrays.asList(functionImplType, functionType); } @NotNull - public JetType getSuperTypeForClosure(@NotNull FunctionDescriptor descriptor, boolean kFunction) { + public JetType getSupertypeForCallableReference(@NotNull FunctionDescriptor descriptor) { int arity = descriptor.getValueParameters().size(); ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); @@ -151,7 +154,7 @@ public class JvmFunctionImplTypes { if (receiverParameter != null) { typeArguments.add(new TypeProjectionImpl(receiverParameter.getType())); } - else if (kFunction && expectedThisObject != null) { + else if (expectedThisObject != null) { typeArguments.add(new TypeProjectionImpl(expectedThisObject.getType())); } @@ -163,26 +166,15 @@ public class JvmFunctionImplTypes { typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType())); ClassDescriptor classDescriptor; - if (kFunction) { - KFunctions kFunctions = getKFunctionsImplList().get(arity); - if (expectedThisObject != null) { - classDescriptor = kFunctions.kMemberFunctionImpl; - } - else if (receiverParameter != null) { - classDescriptor = kFunctions.kExtensionFunctionImpl; - } - else { - classDescriptor = kFunctions.kFunctionImpl; - } + KFunctions kFunctions = getKFunctionsImplList().get(arity); + if (expectedThisObject != null) { + classDescriptor = kFunctions.kMemberFunctionImpl; + } + else if (receiverParameter != null) { + classDescriptor = kFunctions.kExtensionFunctionImpl; } else { - Functions functions = getFunctionsImplList().get(arity); - if (receiverParameter != null) { - classDescriptor = functions.extensionFunctionImpl; - } - else { - classDescriptor = functions.functionImpl; - } + classDescriptor = kFunctions.kFunctionImpl; } return new JetTypeImpl( @@ -195,21 +187,32 @@ public class JvmFunctionImplTypes { } @NotNull - private static ClassDescriptor createFunctionImpl( - @NotNull PackageFragmentDescriptor containingDeclaration, + private static MutableClassDescriptor createClass(@NotNull PackageFragmentDescriptor packageFragment, @NotNull String name) { + return new MutableClassDescriptor(packageFragment, packageFragment.getMemberScope(), ClassKind.CLASS, false, Name.identifier(name)); + } + + @NotNull + private static TypeParameterDescriptor createTypeParameter( + @NotNull ClassDescriptor classDescriptor, + @NotNull Variance variance, @NotNull String name, - @NotNull ClassDescriptor functionInterface + int index ) { - MutableClassDescriptor functionImpl = new MutableClassDescriptor( - containingDeclaration, - containingDeclaration.getMemberScope(), - ClassKind.CLASS, - false, - Name.identifier(name) + TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification( + classDescriptor, Annotations.EMPTY, false, variance, Name.identifier(name), index ); + typeParameter.setInitialized(); + return typeParameter; + } + + @NotNull + private static ClassDescriptor initializeFunctionImplClass( + @NotNull MutableClassDescriptor functionImpl, + @NotNull List typeParameters + ) { functionImpl.setModality(Modality.FINAL); functionImpl.setVisibility(Visibilities.PUBLIC); - functionImpl.setTypeParameterDescriptors(functionInterface.getDefaultType().getConstructor().getParameters()); + functionImpl.setTypeParameterDescriptors(typeParameters); functionImpl.createTypeConstructor(); return functionImpl; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java index f376207ce78..dbceafbfbe0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java @@ -98,10 +98,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { } @NotNull - private ClassDescriptor recordClassForFunction(@NotNull FunctionDescriptor funDescriptor, @NotNull JetType superType) { + private ClassDescriptor recordClassForFunction(@NotNull FunctionDescriptor funDescriptor, @NotNull Collection supertypes) { ClassDescriptorImpl classDescriptor = - new ClassDescriptorImpl(funDescriptor.getContainingDeclaration(), Name.special(""), Modality.FINAL, - Collections.singleton(superType)); + new ClassDescriptorImpl(funDescriptor.getContainingDeclaration(), Name.special(""), Modality.FINAL, supertypes); classDescriptor.initialize(JetScope.EMPTY, Collections.emptySet(), null); bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor); @@ -264,8 +263,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { if (functionDescriptor == null) return; String name = inventAnonymousClassName(expression); - JetType superType = functionImplTypes.getSuperTypeForClosure(functionDescriptor, false); - ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType); + Collection supertypes = functionImplTypes.getSupertypesForClosure(functionDescriptor); + ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes); recordClosure(functionLiteral, classDescriptor, name); pushClassDescriptor(classDescriptor); @@ -312,11 +311,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { ResolvedCall referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference()); if (referencedFunction == null) return; - JetType superType = - functionImplTypes.getSuperTypeForClosure((FunctionDescriptor) referencedFunction.getResultingDescriptor(), true); + JetType supertype = + functionImplTypes.getSupertypeForCallableReference((FunctionDescriptor) referencedFunction.getResultingDescriptor()); String name = inventAnonymousClassName(expression); - ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType); + ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, Collections.singleton(supertype)); recordClosure(expression, classDescriptor, name); pushClassDescriptor(classDescriptor); @@ -366,8 +365,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { } else { String name = inventAnonymousClassName(function); - JetType superType = functionImplTypes.getSuperTypeForClosure(functionDescriptor, false); - ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType); + Collection supertypes = functionImplTypes.getSupertypesForClosure(functionDescriptor); + ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes); recordClosure(function, classDescriptor, name); pushClassDescriptor(classDescriptor); diff --git a/compiler/testData/codegen/box/functions/functionNtoString.kt b/compiler/testData/codegen/box/functions/functionNtoString.kt index 3bf89dd8225..d2dc8e2f89c 100644 --- a/compiler/testData/codegen/box/functions/functionNtoString.kt +++ b/compiler/testData/codegen/box/functions/functionNtoString.kt @@ -6,22 +6,22 @@ fun check(expected: String, obj: Any?) { fun box(): String { - check("kotlin.FunctionImpl0") + check("kotlin.Function0") { () : Unit -> } - check("kotlin.FunctionImpl0") + check("kotlin.Function0") { () : Int -> 42 } - check("kotlin.FunctionImpl1") + check("kotlin.Function1") { (s: String) : Long -> 42.toLong() } - check("kotlin.FunctionImpl2") + check("kotlin.Function2") { (x: Int, y: Int) : Unit -> } - check("kotlin.ExtensionFunctionImpl0") + check("kotlin.ExtensionFunction0") { Int.() : Unit -> } - check("kotlin.ExtensionFunctionImpl0") + check("kotlin.ExtensionFunction0") { Unit.() : Int -> 42 } - check("kotlin.ExtensionFunctionImpl1") + check("kotlin.ExtensionFunction1") { String.(s: String) : Long -> 42.toLong() } - check("kotlin.ExtensionFunctionImpl2") + check("kotlin.ExtensionFunction2") { Int.(x: Int, y: Int) : Unit -> } return "OK" diff --git a/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt b/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt index 73cc8114b41..4cde37f7cd1 100644 --- a/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt +++ b/compiler/testData/codegen/box/reflection/functionLiteralGenericSignature.kt @@ -2,7 +2,7 @@ import java.util.Date fun assertGenericSuper(expected: String, function: Any?) { val clazz = (function as java.lang.Object).getClass()!! - val genericSuper = clazz.getGenericSuperclass()!! + val genericSuper = clazz.getGenericInterfaces()[0]!! if ("$genericSuper" != expected) throw AssertionError("Fail, expected: $expected, actual: $genericSuper") } @@ -19,15 +19,15 @@ val extensionFun = { Any.() : Unit -> } val extensionWithArgFun = { Long.(x: Any) : Date -> Date() } fun box(): String { - assertGenericSuper("kotlin.FunctionImpl0", unitFun) - assertGenericSuper("kotlin.FunctionImpl0", intFun) - assertGenericSuper("kotlin.FunctionImpl1", stringParamFun) - assertGenericSuper("kotlin.FunctionImpl1, java.util.List>", listFun) - assertGenericSuper("kotlin.FunctionImpl1, java.util.List>", mutableListFun) - assertGenericSuper("kotlin.FunctionImpl1, kotlin.Unit>", funWithIn) + assertGenericSuper("kotlin.Function0", unitFun) + assertGenericSuper("kotlin.Function0", intFun) + assertGenericSuper("kotlin.Function1", stringParamFun) + assertGenericSuper("kotlin.Function1, java.util.List>", listFun) + assertGenericSuper("kotlin.Function1, java.util.List>", mutableListFun) + assertGenericSuper("kotlin.Function1, kotlin.Unit>", funWithIn) - assertGenericSuper("kotlin.ExtensionFunctionImpl0", extensionFun) - assertGenericSuper("kotlin.ExtensionFunctionImpl1", extensionWithArgFun) + assertGenericSuper("kotlin.ExtensionFunction0", extensionFun) + assertGenericSuper("kotlin.ExtensionFunction1", extensionWithArgFun) return "OK" } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 830dd711e78..9205806bb2c 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -265,11 +265,11 @@ public class DescriptorUtils { return isKindOf(descriptor, ClassKind.ANNOTATION_CLASS); } - public static boolean isTrait(@NotNull DeclarationDescriptor descriptor) { + public static boolean isTrait(@Nullable DeclarationDescriptor descriptor) { return isKindOf(descriptor, ClassKind.TRAIT); } - public static boolean isClass(@NotNull DeclarationDescriptor descriptor) { + public static boolean isClass(@Nullable DeclarationDescriptor descriptor) { return isKindOf(descriptor, ClassKind.CLASS); } diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/ExtensionFunctionImpl.kt b/core/runtime.jvm/src/kotlin/jvm/internal/ExtensionFunctionImpl.kt new file mode 100644 index 00000000000..e918b300be4 --- /dev/null +++ b/core/runtime.jvm/src/kotlin/jvm/internal/ExtensionFunctionImpl.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kotlin.jvm.internal + +import java.io.Serializable + +public abstract class ExtensionFunctionImpl : Serializable { + override fun toString() = "${getClass().getGenericInterfaces()[0]}" +} diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt b/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt new file mode 100644 index 00000000000..e38a2c17818 --- /dev/null +++ b/core/runtime.jvm/src/kotlin/jvm/internal/FunctionImpl.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kotlin.jvm.internal + +import java.io.Serializable + +public abstract class FunctionImpl : Serializable { + override fun toString() = "${getClass().getGenericInterfaces()[0]}" +}