Use FunctionImplN instead of FunctionN in codegen
Superclass of closures should now be FunctionImplN instead of FunctionN. Since these -Impl classes are needed only in JVM, the corresponding descriptors and types are created in the back-end only.
This commit is contained in:
@@ -126,10 +126,10 @@ public class CodegenUtil {
|
||||
public static JvmClassName getInternalClassName(FunctionDescriptor descriptor) {
|
||||
int paramCount = descriptor.getValueParameters().size();
|
||||
if (descriptor.getReceiverParameter() != null) {
|
||||
return JvmClassName.byInternalName("jet/ExtensionFunction" + paramCount);
|
||||
return JvmClassName.byInternalName("jet/ExtensionFunctionImpl" + paramCount);
|
||||
}
|
||||
else {
|
||||
return JvmClassName.byInternalName("jet/Function" + paramCount);
|
||||
return JvmClassName.byInternalName("jet/FunctionImpl" + paramCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3122,7 +3122,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
v.dup2();
|
||||
v.load(indexIndex, Type.INT_TYPE);
|
||||
v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
|
||||
v.invokevirtual("jet/Function1", "invoke", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
v.invokeinterface("jet/Function1", "invoke", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
v.load(indexIndex, Type.INT_TYPE);
|
||||
v.iinc(indexIndex, 1);
|
||||
v.swap();
|
||||
|
||||
+50
-6
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
@@ -33,11 +34,10 @@ import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.codegen.CodegenUtil.peekFromStack;
|
||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||
@@ -56,6 +56,42 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
this.bindingContext = bindingTrace.getBindingContext();
|
||||
}
|
||||
|
||||
private static final List<ClassDescriptor> FUNCTIONS;
|
||||
private static final List<ClassDescriptor> EXTENSION_FUNCTIONS;
|
||||
|
||||
static {
|
||||
int n = KotlinBuiltIns.FUNCTION_TRAIT_COUNT;
|
||||
FUNCTIONS = new ArrayList<ClassDescriptor>(n);
|
||||
EXTENSION_FUNCTIONS = new ArrayList<ClassDescriptor>(n);
|
||||
|
||||
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Name functionImpl = Name.identifier("FunctionImpl" + i);
|
||||
FUNCTIONS.add(createFunctionImplDescriptor(functionImpl, builtIns.getFunction(i)));
|
||||
|
||||
Name extensionFunctionImpl = Name.identifier("ExtensionFunctionImpl" + i);
|
||||
EXTENSION_FUNCTIONS.add(createFunctionImplDescriptor(extensionFunctionImpl, builtIns.getExtensionFunction(i)));
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassDescriptor createFunctionImplDescriptor(Name name, ClassDescriptor functionInterface) {
|
||||
JetScope builtInsScope = KotlinBuiltIns.getInstance().getBuiltInsScope();
|
||||
|
||||
MutableClassDescriptor functionImpl = new MutableClassDescriptor(
|
||||
builtInsScope.getContainingDeclaration(),
|
||||
builtInsScope,
|
||||
ClassKind.CLASS,
|
||||
false,
|
||||
name
|
||||
);
|
||||
functionImpl.setModality(Modality.FINAL);
|
||||
functionImpl.setVisibility(Visibilities.PUBLIC);
|
||||
functionImpl.setTypeParameterDescriptors(functionInterface.getDefaultType().getConstructor().getParameters());
|
||||
functionImpl.createTypeConstructor();
|
||||
|
||||
return functionImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpression(JetCallExpression expression) {
|
||||
super.visitCallExpression(expression);
|
||||
@@ -92,9 +128,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
((ClassDescriptorImpl)classDescriptor).initialize(
|
||||
false,
|
||||
Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.singleton((funDescriptor.getReceiverParameter() != null
|
||||
? KotlinBuiltIns.getInstance().getExtensionFunction(arity)
|
||||
: KotlinBuiltIns.getInstance().getFunction(arity)).getDefaultType()), JetScope.EMPTY,
|
||||
Collections.singleton(getSuperTypeForClosure(funDescriptor, arity)),
|
||||
JetScope.EMPTY,
|
||||
Collections.<ConstructorDescriptor>emptySet(),
|
||||
null,
|
||||
false);
|
||||
@@ -104,6 +139,15 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
private JetType getSuperTypeForClosure(FunctionDescriptor funDescriptor, int arity) {
|
||||
if (funDescriptor.getReceiverParameter() != null) {
|
||||
return EXTENSION_FUNCTIONS.get(arity).getDefaultType();
|
||||
}
|
||||
else {
|
||||
return FUNCTIONS.get(arity).getDefaultType();
|
||||
}
|
||||
}
|
||||
|
||||
private String inventAnonymousClassName(JetElement declaration) {
|
||||
String top = peekFromStack(nameStack);
|
||||
Integer cnt = anonymousSubclassesCount.get(top);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class KotlinBuiltIns {
|
||||
BUILT_INS_DIR + "/Unit.jet"
|
||||
);
|
||||
|
||||
private static final int FUNCTION_TRAIT_COUNT = 23;
|
||||
public static final int FUNCTION_TRAIT_COUNT = 23;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class Works() : jet.Function0<Object>() {
|
||||
class Works() : jet.Function0<Object> {
|
||||
public override fun invoke():Object {
|
||||
return "Works" as Object
|
||||
}
|
||||
}
|
||||
class Broken() : jet.Function0<String>() {
|
||||
class Broken() : jet.Function0<String> {
|
||||
public override fun invoke():String {
|
||||
return "Broken"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ val getter: String
|
||||
|
||||
fun f() = { "OK" }()
|
||||
|
||||
val obj = object : Function0<String>() {
|
||||
val obj = object : Function0<String> {
|
||||
override fun invoke() = "OK"
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ val getter: String
|
||||
|
||||
fun f() = { "OK" }()
|
||||
|
||||
val obj = object : Function0<String>() {
|
||||
val obj = object : Function0<String> {
|
||||
override fun invoke() = "OK"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user