Introduce FunctionImpl and ExtensionFunctionImpl classes

Old FunctionImpl0,1,2,... will be dropped since they had no purpose
This commit is contained in:
Alexander Udalov
2014-05-12 22:03:45 +04:00
parent 845e3323f9
commit 41eb0deaa0
9 changed files with 224 additions and 171 deletions
@@ -30,6 +30,7 @@ import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext; 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.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
import org.jetbrains.jet.lang.resolve.name.Name; 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.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method; 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 java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.AsmUtil.*;
@@ -53,7 +55,8 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
private final PsiElement fun; private final PsiElement fun;
private final FunctionDescriptor funDescriptor; private final FunctionDescriptor funDescriptor;
private final ClassDescriptor samInterface; private final ClassDescriptor samInterface;
private final Type superClass; private final JetType superClassType;
private final List<JetType> superInterfaceTypes;
private final CodegenContext context; private final CodegenContext context;
private final FunctionGenerationStrategy strategy; private final FunctionGenerationStrategy strategy;
private final CalculatedClosure closure; private final CalculatedClosure closure;
@@ -68,7 +71,6 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
@NotNull PsiElement fun, @NotNull PsiElement fun,
@NotNull FunctionDescriptor funDescriptor, @NotNull FunctionDescriptor funDescriptor,
@Nullable ClassDescriptor samInterface, @Nullable ClassDescriptor samInterface,
@NotNull Type closureSuperClass,
@NotNull CodegenContext parentContext, @NotNull CodegenContext parentContext,
@NotNull KotlinSyntheticClass.Kind syntheticClassKind, @NotNull KotlinSyntheticClass.Kind syntheticClassKind,
@NotNull LocalLookup localLookup, @NotNull LocalLookup localLookup,
@@ -80,12 +82,36 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
this.fun = fun; this.fun = fun;
this.funDescriptor = funDescriptor; this.funDescriptor = funDescriptor;
this.samInterface = samInterface; this.samInterface = samInterface;
this.superClass = closureSuperClass;
this.context = parentContext.intoClosure(funDescriptor, localLookup, typeMapper); this.context = parentContext.intoClosure(funDescriptor, localLookup, typeMapper);
this.syntheticClassKind = syntheticClassKind; this.syntheticClassKind = syntheticClassKind;
this.strategy = strategy; this.strategy = strategy;
ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor); ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor);
if (samInterface == null) {
this.superInterfaceTypes = new ArrayList<JetType>();
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); this.closure = bindingContext.get(CLOSURE, classDescriptor);
assert closure != null : "Closure must be calculated for class: " + 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()); ClassBuilder cv = state.getFactory().newVisitor(asmType, fun.getContainingFile());
FunctionDescriptor interfaceFunction; FunctionDescriptor interfaceFunction;
String[] superInterfaces;
if (samInterface == null) { if (samInterface == null) {
interfaceFunction = getInvokeFunction(funDescriptor); interfaceFunction = getInvokeFunction(funDescriptor);
superInterfaces = ArrayUtil.EMPTY_STRING_ARRAY;
} }
else { else {
interfaceFunction = SingleAbstractMethodUtils.getAbstractMethodOfSamInterface(samInterface); 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, cv.defineClass(fun,
V1_6, V1_6,
ACC_FINAL | ACC_SUPER | visibilityFlag, ACC_FINAL | ACC_SUPER | visibilityFlag,
asmType.getInternalName(), asmType.getInternalName(),
getGenericSignature(), sw.makeJavaGenericSignature(),
superClass.getInternalName(), superClassAsmType.getInternalName(),
superInterfaces superInterfaceAsmTypes
); );
cv.visitSource(fun.getContainingFile().getName(), null); cv.visitSource(fun.getContainingFile().getName(), null);
@@ -127,7 +161,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
FunctionCodegen fc = new FunctionCodegen(context, cv, state, getParentCodegen()); FunctionCodegen fc = new FunctionCodegen(context, cv, state, getParentCodegen());
fc.generateMethod(fun, jvmMethodSignature, funDescriptor, strategy); fc.generateMethod(fun, jvmMethodSignature, funDescriptor, strategy);
this.constructor = generateConstructor(cv); this.constructor = generateConstructor(cv, superClassAsmType);
if (isConst(closure)) { if (isConst(closure)) {
generateConstInstance(cv); generateConstInstance(cv);
@@ -212,10 +246,10 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
} }
@NotNull @NotNull
private Method generateConstructor(@NotNull ClassBuilder cv) { private Method generateConstructor(@NotNull ClassBuilder cv, @NotNull Type superClassAsmType) {
List<FieldInfo> args = calculateConstructorParameters(typeMapper, closure, asmType); List<FieldInfo> 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( public static Method generateConstructor(
@@ -296,23 +330,6 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
return argTypes; return argTypes;
} }
@NotNull
private String getGenericSignature() {
ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor);
Collection<JetType> 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) { public static FunctionDescriptor getInvokeFunction(FunctionDescriptor funDescriptor) {
int paramCount = funDescriptor.getValueParameters().size(); int paramCount = funDescriptor.getValueParameters().size();
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
@@ -1310,15 +1310,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
FunctionDescriptor descriptor = bindingContext.get(FUNCTION, declaration); FunctionDescriptor descriptor = bindingContext.get(FUNCTION, declaration);
assert descriptor != null : "Function is not resolved to descriptor: " + declaration.getText(); assert descriptor != null : "Function is not resolved to descriptor: " + declaration.getText();
String functionImplClassPrefix = descriptor.getReceiverParameter() != null ? "ExtensionFunctionImpl" : "FunctionImpl"; ClosureCodegen closureCodegen = new ClosureCodegen(
Type closureSuperClass = state, declaration, descriptor, samInterfaceClass, context, kind, this,
samInterfaceClass == null ? new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), parentCodegen
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.gen(); closureCodegen.gen();
return closureCodegen.putInstanceOnStack(v, this); return closureCodegen.putInstanceOnStack(v, this);
@@ -2414,16 +2409,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
assert functionDescriptor != null : "Callable reference is not resolved to descriptor: " + expression.getText(); 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 = CallableReferenceGenerationStrategy strategy =
new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall(expression.getCallableReference())); 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, KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER,
this, strategy, getParentCodegen()); this, strategy, getParentCodegen());
@@ -17,48 +17,30 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; 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.MutableClassDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor; 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.reflect.ReflectionTypes;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.*;
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.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class JvmFunctionImplTypes { public class JvmFunctionImplTypes {
private final ReflectionTypes reflectionTypes; private final ReflectionTypes reflectionTypes;
private final ModuleDescriptor fakeModule;
private volatile List<Functions> functionsList; private final ClassDescriptor functionImpl;
private final ClassDescriptor extensionFunctionImpl;
private volatile List<KFunctions> kFunctionsList; private volatile List<KFunctions> kFunctionsList;
private volatile Map<ClassDescriptor, ClassDescriptor> 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 { private static class KFunctions {
public final ClassDescriptor kFunctionImpl; public final ClassDescriptor kFunctionImpl;
@@ -78,39 +60,35 @@ public class JvmFunctionImplTypes {
public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) { public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) {
this.reflectionTypes = reflectionTypes; this.reflectionTypes = reflectionTypes;
this.fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"), Collections.<ImportPath>emptyList(), ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"),
JavaToKotlinClassMap.getInstance()); Collections.<ImportPath>emptyList(), JavaToKotlinClassMap.getInstance());
}
@NotNull MutablePackageFragmentDescriptor kotlinJvmInternal =
private List<Functions> getFunctionsImplList() { new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.jvm.internal"));
if (functionsList == null) {
MutablePackageFragmentDescriptor kotlin = new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin"));
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
ImmutableList.Builder<Functions> builder = ImmutableList.builder(); MutableClassDescriptor functionImpl = createClass(kotlinJvmInternal, "FunctionImpl");
for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) { TypeParameterDescriptor funR = createTypeParameter(functionImpl, Variance.OUT_VARIANCE, "R", 0);
builder.add(new Functions(
createFunctionImpl(kotlin, "FunctionImpl" + i, builtIns.getFunction(i)), MutableClassDescriptor extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl");
createFunctionImpl(kotlin, "ExtensionFunctionImpl" + i, builtIns.getExtensionFunction(i)) TypeParameterDescriptor extFunT = createTypeParameter(extensionFunctionImpl, Variance.IN_VARIANCE, "T", 0);
)); TypeParameterDescriptor extFunR = createTypeParameter(extensionFunctionImpl, Variance.OUT_VARIANCE, "R", 1);
}
functionsList = builder.build(); this.functionImpl = initializeFunctionImplClass(functionImpl, Arrays.asList(funR));
} this.extensionFunctionImpl = initializeFunctionImplClass(extensionFunctionImpl, Arrays.asList(extFunT, extFunR));
return functionsList;
} }
@NotNull @NotNull
private List<KFunctions> getKFunctionsImplList() { private List<KFunctions> getKFunctionsImplList() {
if (kFunctionsList == null) { 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<KFunctions> builder = ImmutableList.builder(); ImmutableList.Builder<KFunctions> builder = ImmutableList.builder();
for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) { for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) {
builder.add(new KFunctions( builder.add(new KFunctions(
createFunctionImpl(reflect, "KFunctionImpl" + i, reflectionTypes.getKFunction(i)), createKFunctionImpl(reflect, "KFunctionImpl" + i, reflectionTypes.getKFunction(i)),
createFunctionImpl(reflect, "KMemberFunctionImpl" + i, reflectionTypes.getKMemberFunction(i)), createKFunctionImpl(reflect, "KMemberFunctionImpl" + i, reflectionTypes.getKMemberFunction(i)),
createFunctionImpl(reflect, "KExtensionFunctionImpl" + i, reflectionTypes.getKExtensionFunction(i)) createKFunctionImpl(reflect, "KExtensionFunctionImpl" + i, reflectionTypes.getKExtensionFunction(i))
)); ));
} }
kFunctionsList = builder.build(); kFunctionsList = builder.build();
@@ -119,29 +97,54 @@ public class JvmFunctionImplTypes {
} }
@NotNull @NotNull
private Map<ClassDescriptor, ClassDescriptor> getKFunctionToImplMap() { private static ClassDescriptor createKFunctionImpl(
if (kFunctionToImplMap == null) { @NotNull PackageFragmentDescriptor containingDeclaration,
ImmutableMap.Builder<ClassDescriptor, ClassDescriptor> builder = ImmutableMap.builder(); @NotNull String name,
for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) { @NotNull ClassDescriptor functionInterface
KFunctions kFunctions = getKFunctionsImplList().get(i); ) {
builder.put(reflectionTypes.getKFunction(i), kFunctions.kFunctionImpl); return initializeFunctionImplClass(createClass(containingDeclaration, name),
builder.put(reflectionTypes.getKMemberFunction(i), kFunctions.kMemberFunctionImpl); functionInterface.getDefaultType().getConstructor().getParameters());
builder.put(reflectionTypes.getKExtensionFunction(i), kFunctions.kExtensionFunctionImpl);
}
kFunctionToImplMap = builder.build();
}
return kFunctionToImplMap;
} }
@Nullable @NotNull
public ClassDescriptor kFunctionTypeToImpl(@NotNull JetType functionType) { public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) {
//noinspection SuspiciousMethodCalls ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
return getKFunctionToImplMap().get(functionType.getConstructor().getDeclarationDescriptor());
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(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 @NotNull
public JetType getSuperTypeForClosure(@NotNull FunctionDescriptor descriptor, boolean kFunction) { public JetType getSupertypeForCallableReference(@NotNull FunctionDescriptor descriptor) {
int arity = descriptor.getValueParameters().size(); int arity = descriptor.getValueParameters().size();
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
@@ -151,7 +154,7 @@ public class JvmFunctionImplTypes {
if (receiverParameter != null) { if (receiverParameter != null) {
typeArguments.add(new TypeProjectionImpl(receiverParameter.getType())); typeArguments.add(new TypeProjectionImpl(receiverParameter.getType()));
} }
else if (kFunction && expectedThisObject != null) { else if (expectedThisObject != null) {
typeArguments.add(new TypeProjectionImpl(expectedThisObject.getType())); typeArguments.add(new TypeProjectionImpl(expectedThisObject.getType()));
} }
@@ -163,26 +166,15 @@ public class JvmFunctionImplTypes {
typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType())); typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType()));
ClassDescriptor classDescriptor; ClassDescriptor classDescriptor;
if (kFunction) { KFunctions kFunctions = getKFunctionsImplList().get(arity);
KFunctions kFunctions = getKFunctionsImplList().get(arity); if (expectedThisObject != null) {
if (expectedThisObject != null) { classDescriptor = kFunctions.kMemberFunctionImpl;
classDescriptor = kFunctions.kMemberFunctionImpl; }
} else if (receiverParameter != null) {
else if (receiverParameter != null) { classDescriptor = kFunctions.kExtensionFunctionImpl;
classDescriptor = kFunctions.kExtensionFunctionImpl;
}
else {
classDescriptor = kFunctions.kFunctionImpl;
}
} }
else { else {
Functions functions = getFunctionsImplList().get(arity); classDescriptor = kFunctions.kFunctionImpl;
if (receiverParameter != null) {
classDescriptor = functions.extensionFunctionImpl;
}
else {
classDescriptor = functions.functionImpl;
}
} }
return new JetTypeImpl( return new JetTypeImpl(
@@ -195,21 +187,32 @@ public class JvmFunctionImplTypes {
} }
@NotNull @NotNull
private static ClassDescriptor createFunctionImpl( private static MutableClassDescriptor createClass(@NotNull PackageFragmentDescriptor packageFragment, @NotNull String name) {
@NotNull PackageFragmentDescriptor containingDeclaration, 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 String name,
@NotNull ClassDescriptor functionInterface int index
) { ) {
MutableClassDescriptor functionImpl = new MutableClassDescriptor( TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
containingDeclaration, classDescriptor, Annotations.EMPTY, false, variance, Name.identifier(name), index
containingDeclaration.getMemberScope(),
ClassKind.CLASS,
false,
Name.identifier(name)
); );
typeParameter.setInitialized();
return typeParameter;
}
@NotNull
private static ClassDescriptor initializeFunctionImplClass(
@NotNull MutableClassDescriptor functionImpl,
@NotNull List<TypeParameterDescriptor> typeParameters
) {
functionImpl.setModality(Modality.FINAL); functionImpl.setModality(Modality.FINAL);
functionImpl.setVisibility(Visibilities.PUBLIC); functionImpl.setVisibility(Visibilities.PUBLIC);
functionImpl.setTypeParameterDescriptors(functionInterface.getDefaultType().getConstructor().getParameters()); functionImpl.setTypeParameterDescriptors(typeParameters);
functionImpl.createTypeConstructor(); functionImpl.createTypeConstructor();
return functionImpl; return functionImpl;
@@ -98,10 +98,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
} }
@NotNull @NotNull
private ClassDescriptor recordClassForFunction(@NotNull FunctionDescriptor funDescriptor, @NotNull JetType superType) { private ClassDescriptor recordClassForFunction(@NotNull FunctionDescriptor funDescriptor, @NotNull Collection<JetType> supertypes) {
ClassDescriptorImpl classDescriptor = ClassDescriptorImpl classDescriptor =
new ClassDescriptorImpl(funDescriptor.getContainingDeclaration(), Name.special("<closure>"), Modality.FINAL, new ClassDescriptorImpl(funDescriptor.getContainingDeclaration(), Name.special("<closure>"), Modality.FINAL, supertypes);
Collections.singleton(superType));
classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null); classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null);
bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor); bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor);
@@ -264,8 +263,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
if (functionDescriptor == null) return; if (functionDescriptor == null) return;
String name = inventAnonymousClassName(expression); String name = inventAnonymousClassName(expression);
JetType superType = functionImplTypes.getSuperTypeForClosure(functionDescriptor, false); Collection<JetType> supertypes = functionImplTypes.getSupertypesForClosure(functionDescriptor);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
recordClosure(functionLiteral, classDescriptor, name); recordClosure(functionLiteral, classDescriptor, name);
pushClassDescriptor(classDescriptor); pushClassDescriptor(classDescriptor);
@@ -312,11 +311,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
ResolvedCall<?> referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference()); ResolvedCall<?> referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference());
if (referencedFunction == null) return; if (referencedFunction == null) return;
JetType superType = JetType supertype =
functionImplTypes.getSuperTypeForClosure((FunctionDescriptor) referencedFunction.getResultingDescriptor(), true); functionImplTypes.getSupertypeForCallableReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
String name = inventAnonymousClassName(expression); String name = inventAnonymousClassName(expression);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, Collections.singleton(supertype));
recordClosure(expression, classDescriptor, name); recordClosure(expression, classDescriptor, name);
pushClassDescriptor(classDescriptor); pushClassDescriptor(classDescriptor);
@@ -366,8 +365,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
} }
else { else {
String name = inventAnonymousClassName(function); String name = inventAnonymousClassName(function);
JetType superType = functionImplTypes.getSuperTypeForClosure(functionDescriptor, false); Collection<JetType> supertypes = functionImplTypes.getSupertypesForClosure(functionDescriptor);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
recordClosure(function, classDescriptor, name); recordClosure(function, classDescriptor, name);
pushClassDescriptor(classDescriptor); pushClassDescriptor(classDescriptor);
@@ -6,22 +6,22 @@ fun check(expected: String, obj: Any?) {
fun box(): String { fun box(): String {
check("kotlin.FunctionImpl0<kotlin.Unit>") check("kotlin.Function0<kotlin.Unit>")
{ () : Unit -> } { () : Unit -> }
check("kotlin.FunctionImpl0<java.lang.Integer>") check("kotlin.Function0<java.lang.Integer>")
{ () : Int -> 42 } { () : Int -> 42 }
check("kotlin.FunctionImpl1<java.lang.String, java.lang.Long>") check("kotlin.Function1<java.lang.String, java.lang.Long>")
{ (s: String) : Long -> 42.toLong() } { (s: String) : Long -> 42.toLong() }
check("kotlin.FunctionImpl2<java.lang.Integer, java.lang.Integer, kotlin.Unit>") check("kotlin.Function2<java.lang.Integer, java.lang.Integer, kotlin.Unit>")
{ (x: Int, y: Int) : Unit -> } { (x: Int, y: Int) : Unit -> }
check("kotlin.ExtensionFunctionImpl0<java.lang.Integer, kotlin.Unit>") check("kotlin.ExtensionFunction0<java.lang.Integer, kotlin.Unit>")
{ Int.() : Unit -> } { Int.() : Unit -> }
check("kotlin.ExtensionFunctionImpl0<kotlin.Unit, java.lang.Integer>") check("kotlin.ExtensionFunction0<kotlin.Unit, java.lang.Integer>")
{ Unit.() : Int -> 42 } { Unit.() : Int -> 42 }
check("kotlin.ExtensionFunctionImpl1<java.lang.String, java.lang.String, java.lang.Long>") check("kotlin.ExtensionFunction1<java.lang.String, java.lang.String, java.lang.Long>")
{ String.(s: String) : Long -> 42.toLong() } { String.(s: String) : Long -> 42.toLong() }
check("kotlin.ExtensionFunctionImpl2<java.lang.Integer, java.lang.Integer, java.lang.Integer, kotlin.Unit>") check("kotlin.ExtensionFunction2<java.lang.Integer, java.lang.Integer, java.lang.Integer, kotlin.Unit>")
{ Int.(x: Int, y: Int) : Unit -> } { Int.(x: Int, y: Int) : Unit -> }
return "OK" return "OK"
@@ -2,7 +2,7 @@ import java.util.Date
fun assertGenericSuper(expected: String, function: Any?) { fun assertGenericSuper(expected: String, function: Any?) {
val clazz = (function as java.lang.Object).getClass()!! val clazz = (function as java.lang.Object).getClass()!!
val genericSuper = clazz.getGenericSuperclass()!! val genericSuper = clazz.getGenericInterfaces()[0]!!
if ("$genericSuper" != expected) if ("$genericSuper" != expected)
throw AssertionError("Fail, expected: $expected, actual: $genericSuper") throw AssertionError("Fail, expected: $expected, actual: $genericSuper")
} }
@@ -19,15 +19,15 @@ val extensionFun = { Any.() : Unit -> }
val extensionWithArgFun = { Long.(x: Any) : Date -> Date() } val extensionWithArgFun = { Long.(x: Any) : Date -> Date() }
fun box(): String { fun box(): String {
assertGenericSuper("kotlin.FunctionImpl0<kotlin.Unit>", unitFun) assertGenericSuper("kotlin.Function0<kotlin.Unit>", unitFun)
assertGenericSuper("kotlin.FunctionImpl0<java.lang.Integer>", intFun) assertGenericSuper("kotlin.Function0<java.lang.Integer>", intFun)
assertGenericSuper("kotlin.FunctionImpl1<java.lang.String, kotlin.Unit>", stringParamFun) assertGenericSuper("kotlin.Function1<java.lang.String, kotlin.Unit>", stringParamFun)
assertGenericSuper("kotlin.FunctionImpl1<java.util.List<? extends java.lang.String>, java.util.List<? extends java.lang.String>>", listFun) assertGenericSuper("kotlin.Function1<java.util.List<? extends java.lang.String>, java.util.List<? extends java.lang.String>>", listFun)
assertGenericSuper("kotlin.FunctionImpl1<java.util.List<java.lang.Double>, java.util.List<java.lang.Integer>>", mutableListFun) assertGenericSuper("kotlin.Function1<java.util.List<java.lang.Double>, java.util.List<java.lang.Integer>>", mutableListFun)
assertGenericSuper("kotlin.FunctionImpl1<java.lang.Comparable<? super java.lang.String>, kotlin.Unit>", funWithIn) assertGenericSuper("kotlin.Function1<java.lang.Comparable<? super java.lang.String>, kotlin.Unit>", funWithIn)
assertGenericSuper("kotlin.ExtensionFunctionImpl0<java.lang.Object, kotlin.Unit>", extensionFun) assertGenericSuper("kotlin.ExtensionFunction0<java.lang.Object, kotlin.Unit>", extensionFun)
assertGenericSuper("kotlin.ExtensionFunctionImpl1<java.lang.Long, java.lang.Object, java.util.Date>", extensionWithArgFun) assertGenericSuper("kotlin.ExtensionFunction1<java.lang.Long, java.lang.Object, java.util.Date>", extensionWithArgFun)
return "OK" return "OK"
} }
@@ -265,11 +265,11 @@ public class DescriptorUtils {
return isKindOf(descriptor, ClassKind.ANNOTATION_CLASS); 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); return isKindOf(descriptor, ClassKind.TRAIT);
} }
public static boolean isClass(@NotNull DeclarationDescriptor descriptor) { public static boolean isClass(@Nullable DeclarationDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.CLASS); return isKindOf(descriptor, ClassKind.CLASS);
} }
@@ -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<in T, out R> : Serializable {
override fun toString() = "${getClass().getGenericInterfaces()[0]}"
}
@@ -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<out R> : Serializable {
override fun toString() = "${getClass().getGenericInterfaces()[0]}"
}