Introduce FunctionImpl and ExtensionFunctionImpl classes
Old FunctionImpl0,1,2,... will be dropped since they had no purpose
This commit is contained in:
@@ -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<JetType> 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>();
|
||||
|
||||
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<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(
|
||||
@@ -296,23 +330,6 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||
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) {
|
||||
int paramCount = funDescriptor.getValueParameters().size();
|
||||
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
|
||||
|
||||
@@ -1310,15 +1310,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> 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<StackValue, StackValue> 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());
|
||||
|
||||
|
||||
@@ -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<Functions> functionsList;
|
||||
private final ClassDescriptor functionImpl;
|
||||
private final ClassDescriptor extensionFunctionImpl;
|
||||
|
||||
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 {
|
||||
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("<fake module for functions impl>"), Collections.<ImportPath>emptyList(),
|
||||
JavaToKotlinClassMap.getInstance());
|
||||
}
|
||||
ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"),
|
||||
Collections.<ImportPath>emptyList(), JavaToKotlinClassMap.getInstance());
|
||||
|
||||
@NotNull
|
||||
private List<Functions> 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<Functions> 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<KFunctions> 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<KFunctions> 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<ClassDescriptor, ClassDescriptor> getKFunctionToImplMap() {
|
||||
if (kFunctionToImplMap == null) {
|
||||
ImmutableMap.Builder<ClassDescriptor, ClassDescriptor> 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<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) {
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
|
||||
|
||||
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
|
||||
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<TypeParameterDescriptor> typeParameters
|
||||
) {
|
||||
functionImpl.setModality(Modality.FINAL);
|
||||
functionImpl.setVisibility(Visibilities.PUBLIC);
|
||||
functionImpl.setTypeParameterDescriptors(functionInterface.getDefaultType().getConstructor().getParameters());
|
||||
functionImpl.setTypeParameterDescriptors(typeParameters);
|
||||
functionImpl.createTypeConstructor();
|
||||
|
||||
return functionImpl;
|
||||
|
||||
+9
-10
@@ -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<JetType> supertypes) {
|
||||
ClassDescriptorImpl classDescriptor =
|
||||
new ClassDescriptorImpl(funDescriptor.getContainingDeclaration(), Name.special("<closure>"), Modality.FINAL,
|
||||
Collections.singleton(superType));
|
||||
new ClassDescriptorImpl(funDescriptor.getContainingDeclaration(), Name.special("<closure>"), Modality.FINAL, supertypes);
|
||||
classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>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<JetType> 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<JetType> supertypes = functionImplTypes.getSupertypesForClosure(functionDescriptor);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
|
||||
recordClosure(function, classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
|
||||
@@ -6,22 +6,22 @@ fun check(expected: String, obj: Any?) {
|
||||
|
||||
|
||||
fun box(): String {
|
||||
check("kotlin.FunctionImpl0<kotlin.Unit>")
|
||||
check("kotlin.Function0<kotlin.Unit>")
|
||||
{ () : Unit -> }
|
||||
check("kotlin.FunctionImpl0<java.lang.Integer>")
|
||||
check("kotlin.Function0<java.lang.Integer>")
|
||||
{ () : 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() }
|
||||
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 -> }
|
||||
|
||||
check("kotlin.ExtensionFunctionImpl0<java.lang.Integer, kotlin.Unit>")
|
||||
check("kotlin.ExtensionFunction0<java.lang.Integer, kotlin.Unit>")
|
||||
{ Int.() : Unit -> }
|
||||
check("kotlin.ExtensionFunctionImpl0<kotlin.Unit, java.lang.Integer>")
|
||||
check("kotlin.ExtensionFunction0<kotlin.Unit, java.lang.Integer>")
|
||||
{ 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() }
|
||||
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 -> }
|
||||
|
||||
return "OK"
|
||||
|
||||
@@ -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<kotlin.Unit>", unitFun)
|
||||
assertGenericSuper("kotlin.FunctionImpl0<java.lang.Integer>", intFun)
|
||||
assertGenericSuper("kotlin.FunctionImpl1<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.FunctionImpl1<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.Function0<kotlin.Unit>", unitFun)
|
||||
assertGenericSuper("kotlin.Function0<java.lang.Integer>", intFun)
|
||||
assertGenericSuper("kotlin.Function1<java.lang.String, kotlin.Unit>", stringParamFun)
|
||||
assertGenericSuper("kotlin.Function1<java.util.List<? extends java.lang.String>, java.util.List<? extends java.lang.String>>", listFun)
|
||||
assertGenericSuper("kotlin.Function1<java.util.List<java.lang.Double>, java.util.List<java.lang.Integer>>", mutableListFun)
|
||||
assertGenericSuper("kotlin.Function1<java.lang.Comparable<? super java.lang.String>, kotlin.Unit>", funWithIn)
|
||||
|
||||
assertGenericSuper("kotlin.ExtensionFunctionImpl0<java.lang.Object, kotlin.Unit>", extensionFun)
|
||||
assertGenericSuper("kotlin.ExtensionFunctionImpl1<java.lang.Long, java.lang.Object, java.util.Date>", extensionWithArgFun)
|
||||
assertGenericSuper("kotlin.ExtensionFunction0<java.lang.Object, kotlin.Unit>", extensionFun)
|
||||
assertGenericSuper("kotlin.ExtensionFunction1<java.lang.Long, java.lang.Object, java.util.Date>", extensionWithArgFun)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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]}"
|
||||
}
|
||||
Reference in New Issue
Block a user