Write KotlinSyntheticClass to generated classes for functions
That is SAM wrappers, callable reference wrappers, local functions and anonymous functions
This commit is contained in:
@@ -665,7 +665,7 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull KotlinSyntheticClass.Kind kind) {
|
||||
AnnotationVisitor av = v.newAnnotation(Type.getObjectType(KotlinSyntheticClass.INTERNAL_NAME).getDescriptor(), true);
|
||||
AnnotationVisitor av = v.newAnnotation(Type.getObjectType(KotlinSyntheticClass.CLASS_NAME.getInternalName()).getDescriptor(), true);
|
||||
av.visit(ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
|
||||
av.visitEnum(KotlinSyntheticClass.KIND_FIELD_NAME.asString(),
|
||||
Type.getObjectType(KotlinSyntheticClass.KIND_INTERNAL_NAME).getDescriptor(),
|
||||
|
||||
@@ -48,6 +48,7 @@ import static org.jetbrains.asm4.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.jet.codegen.CodegenUtil.isConst;
|
||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
|
||||
public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||
private final PsiElement fun;
|
||||
@@ -59,6 +60,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||
private final CalculatedClosure closure;
|
||||
private final Type asmType;
|
||||
private final int visibilityFlag;
|
||||
private final KotlinSyntheticClass.Kind syntheticClassKind;
|
||||
|
||||
private Method constructor;
|
||||
|
||||
@@ -69,6 +71,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||
@Nullable ClassDescriptor samInterface,
|
||||
@NotNull Type closureSuperClass,
|
||||
@NotNull CodegenContext parentContext,
|
||||
@NotNull KotlinSyntheticClass.Kind syntheticClassKind,
|
||||
@NotNull LocalLookup localLookup,
|
||||
@NotNull FunctionGenerationStrategy strategy,
|
||||
@Nullable MemberCodegen parentCodegen
|
||||
@@ -80,6 +83,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||
this.samInterface = samInterface;
|
||||
this.superClass = closureSuperClass;
|
||||
this.context = parentContext.intoClosure(funDescriptor, localLookup, typeMapper);
|
||||
this.syntheticClassKind = syntheticClassKind;
|
||||
this.strategy = strategy;
|
||||
|
||||
ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor);
|
||||
@@ -121,6 +125,8 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
|
||||
);
|
||||
cv.visitSource(fun.getContainingFile().getName(), null);
|
||||
|
||||
writeKotlinSyntheticClassAnnotation(cv, syntheticClassKind);
|
||||
|
||||
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(funDescriptor).replaceName(interfaceFunction.getName().toString());
|
||||
generateBridge(cv, typeMapper.mapSignature(interfaceFunction).getAsmMethod(), jvmMethodSignature.getAsmMethod());
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
|
||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||
|
||||
public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implements LocalLookup, ParentCodegenAware {
|
||||
@@ -1288,7 +1289,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return StackValue.none();
|
||||
}
|
||||
|
||||
StackValue closure = genClosure(function, null);
|
||||
StackValue closure = genClosure(function, null, KotlinSyntheticClass.Kind.LOCAL_FUNCTION);
|
||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
|
||||
int index = lookupLocalIndex(descriptor);
|
||||
closure.put(OBJECT_TYPE, v);
|
||||
@@ -1304,18 +1305,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return gen(expression.getFunctionLiteral().getBodyExpression());
|
||||
}
|
||||
else {
|
||||
return genClosure(expression.getFunctionLiteral(), null);
|
||||
return genClosure(expression.getFunctionLiteral(), null, KotlinSyntheticClass.Kind.ANONYMOUS_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue genClosure(JetDeclarationWithBody declaration, @Nullable ClassDescriptor samInterfaceClass) {
|
||||
@NotNull
|
||||
private StackValue genClosure(
|
||||
JetDeclarationWithBody declaration,
|
||||
@Nullable ClassDescriptor samInterfaceClass,
|
||||
@NotNull KotlinSyntheticClass.Kind kind
|
||||
) {
|
||||
FunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||
assert descriptor != null : "Function is not resolved to descriptor: " + declaration.getText();
|
||||
|
||||
Type closureSuperClass = samInterfaceClass == null ? getFunctionImplType(descriptor) : OBJECT_TYPE;
|
||||
|
||||
ClosureCodegen closureCodegen = new ClosureCodegen(state, declaration, descriptor, samInterfaceClass, closureSuperClass, context,
|
||||
this, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), parentCodegen);
|
||||
kind, this, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), parentCodegen);
|
||||
|
||||
closureCodegen.gen();
|
||||
|
||||
@@ -1934,42 +1940,43 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return genSamInterfaceValue(argumentExpression, samInterface, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue genSamInterfaceValue(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull JavaClassDescriptor samInterface,
|
||||
@NotNull JetVisitor<StackValue, StackValue> visitor
|
||||
) {
|
||||
if (expression instanceof JetFunctionLiteralExpression) {
|
||||
return genClosure(((JetFunctionLiteralExpression) expression).getFunctionLiteral(), samInterface);
|
||||
return genClosure(((JetFunctionLiteralExpression) expression).getFunctionLiteral(), samInterface,
|
||||
KotlinSyntheticClass.Kind.SAM_LAMBDA);
|
||||
}
|
||||
else {
|
||||
Type asmType = state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) expression.getContainingFile());
|
||||
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
Type asmType = state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) expression.getContainingFile());
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
Type functionType = typeMapper.mapType(samInterface.getFunctionTypeForSamInterface());
|
||||
expression.accept(visitor, StackValue.none()).put(functionType, v);
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
|
||||
Label ifNonNull = new Label();
|
||||
Label afterAll = new Label();
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
Type functionType = typeMapper.mapType(samInterface.getFunctionTypeForSamInterface());
|
||||
expression.accept(visitor, StackValue.none()).put(functionType, v);
|
||||
|
||||
v.dup();
|
||||
v.ifnonnull(ifNonNull);
|
||||
Label ifNonNull = new Label();
|
||||
Label afterAll = new Label();
|
||||
|
||||
// if null: pop function value and wrapper objects, put null
|
||||
v.pop();
|
||||
v.pop2();
|
||||
v.aconst(null);
|
||||
v.goTo(afterAll);
|
||||
v.dup();
|
||||
v.ifnonnull(ifNonNull);
|
||||
|
||||
v.mark(ifNonNull);
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, functionType));
|
||||
// if null: pop function value and wrapper objects, put null
|
||||
v.pop();
|
||||
v.pop2();
|
||||
v.aconst(null);
|
||||
v.goTo(afterAll);
|
||||
|
||||
v.mark(afterAll);
|
||||
return StackValue.onStack(asmType);
|
||||
}
|
||||
v.mark(ifNonNull);
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, functionType));
|
||||
|
||||
v.mark(afterAll);
|
||||
return StackValue.onStack(asmType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -2456,8 +2463,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
Type closureSuperClass = typeMapper.mapType(kFunctionImpl);
|
||||
|
||||
CallableReferenceGenerationStrategy strategy = new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall);
|
||||
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this,
|
||||
strategy, getParentCodegen());
|
||||
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context,
|
||||
KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER,
|
||||
this, strategy, getParentCodegen());
|
||||
|
||||
closureCodegen.gen();
|
||||
|
||||
|
||||
@@ -38,7 +38,9 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import static org.jetbrains.asm4.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
|
||||
public class SamWrapperCodegen extends ParentCodegenAwareImpl {
|
||||
private static final String FUNCTION_FIELD_NAME = "function";
|
||||
@@ -75,6 +77,8 @@ public class SamWrapperCodegen extends ParentCodegenAwareImpl {
|
||||
);
|
||||
cv.visitSource(file.getName(), null);
|
||||
|
||||
writeKotlinSyntheticClassAnnotation(cv, KotlinSyntheticClass.Kind.SAM_WRAPPER);
|
||||
|
||||
// e.g. ASM type for Function2
|
||||
Type functionAsmType = state.getTypeMapper().mapType(functionType);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user