Support class literals (A::class)
This commit is contained in:
@@ -30,11 +30,11 @@ import kotlin.KotlinPackage;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||
import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
@@ -2610,6 +2610,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return lookupLocalIndex(declarationDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, StackValue data) {
|
||||
JetType type = bindingContext.get(EXPRESSION_TYPE, expression);
|
||||
assert type != null;
|
||||
|
||||
assert state.getReflectionTypes().getkClass().getTypeConstructor().equals(type.getConstructor())
|
||||
: "::class expression should be type checked to a KClass: " + type;
|
||||
|
||||
ClassifierDescriptor typeArgument = KotlinPackage.single(type.getArguments()).getType().getConstructor().getDeclarationDescriptor();
|
||||
assert typeArgument instanceof ClassDescriptor : "KClass argument should be a class: " + typeArgument;
|
||||
|
||||
return generateClassLiteralReference((ClassDescriptor) typeArgument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, StackValue data) {
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression.getCallableReference(), bindingContext);
|
||||
@@ -2690,10 +2704,22 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
v.visitLdcInsn(descriptor.getName().asString());
|
||||
StackValue receiverClass = generateClassLiteralReference(containingClass);
|
||||
receiverClass.put(receiverClass.type, v);
|
||||
v.invokestatic(REFLECTION, factoryMethod.getName(), factoryMethod.getDescriptor(), false);
|
||||
|
||||
Type classAsmType = typeMapper.mapClass(containingClass);
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (containingClass instanceof JavaClassDescriptor) {
|
||||
@NotNull
|
||||
private StackValue generateClassLiteralReference(@NotNull final ClassDescriptor descriptor) {
|
||||
return StackValue.operation(K_CLASS_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
Type classAsmType = typeMapper.mapClass(descriptor);
|
||||
if (descriptor instanceof JavaClassDescriptor) {
|
||||
v.aconst(classAsmType);
|
||||
v.invokestatic(REFLECTION, "foreignKotlinClass", Type.getMethodDescriptor(K_CLASS_TYPE, getType(Class.class)), false);
|
||||
}
|
||||
@@ -2701,8 +2727,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
v.getstatic(classAsmType.getInternalName(), JvmAbi.KOTLIN_CLASS_FIELD_NAME, K_CLASS_TYPE.getDescriptor());
|
||||
}
|
||||
|
||||
v.invokestatic(REFLECTION, factoryMethod.getName(), factoryMethod.getDescriptor(), false);
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -117,6 +117,8 @@ public class GenerationState {
|
||||
@Nullable
|
||||
private List<ScriptDescriptor> earlierScriptsForReplInterpreter;
|
||||
|
||||
private final ReflectionTypes reflectionTypes;
|
||||
|
||||
private final JvmRuntimeTypes runtimeTypes;
|
||||
|
||||
@NotNull
|
||||
@@ -187,7 +189,7 @@ public class GenerationState {
|
||||
this.disableParamAssertions = disableParamAssertions;
|
||||
this.generateClassFilter = generateClassFilter;
|
||||
|
||||
ReflectionTypes reflectionTypes = new ReflectionTypes(module);
|
||||
this.reflectionTypes = new ReflectionTypes(module);
|
||||
this.runtimeTypes = new JvmRuntimeTypes(reflectionTypes);
|
||||
}
|
||||
|
||||
@@ -259,6 +261,11 @@ public class GenerationState {
|
||||
return generateClassFilter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReflectionTypes getReflectionTypes() {
|
||||
return reflectionTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JvmRuntimeTypes getJvmRuntimeTypes() {
|
||||
return runtimeTypes;
|
||||
|
||||
Reference in New Issue
Block a user