Don't create KClass and KPackage instances in <clinit>

This proved to be a fragile technique, which probably doesn't even improve
performance in most cases but has lots of unexpected problems: unconditional
initialization of reflection classes, increasing the size of the bytecode, bugs
with <clinit> in annotations on JVM 6, inability to support conversion of a
class from Kotlin to Java without recompiling clients which use it
reflectively, etc.
This commit is contained in:
Alexander Udalov
2015-10-06 21:55:49 +03:00
parent fe737886cd
commit a4732b442d
24 changed files with 51 additions and 161 deletions
@@ -314,7 +314,7 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
if (generateBody) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
generateCallableReferenceDeclarationContainer(iv, descriptor, typeMapper);
generateCallableReferenceDeclarationContainer(iv, descriptor, state);
iv.areturn(K_DECLARATION_CONTAINER_TYPE);
FunctionCodegen.endVisit(iv, "function reference getOwner", element);
}
@@ -348,24 +348,28 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
public static void generateCallableReferenceDeclarationContainer(
@NotNull InstructionAdapter iv,
@NotNull CallableDescriptor descriptor,
@NotNull JetTypeMapper typeMapper
@NotNull GenerationState state
) {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
// TODO: getDefaultType() here is wrong and won't work for arrays
StackValue value = generateClassLiteralReference(typeMapper, ((ClassDescriptor) container).getDefaultType());
StackValue value = generateClassLiteralReference(state.getTypeMapper(), ((ClassDescriptor) container).getDefaultType());
value.put(K_CLASS_TYPE, iv);
}
else if (container instanceof PackageFragmentDescriptor) {
String packageClassInternalName = PackageClassUtils.getPackageClassInternalName(
((PackageFragmentDescriptor) container).getFqName()
);
iv.getstatic(packageClassInternalName, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, K_PACKAGE_TYPE.getDescriptor());
iv.aconst(Type.getObjectType(packageClassInternalName));
iv.aconst(state.getModuleName());
// TODO: create KPackage with a useful class, not the old package facade
iv.invokestatic(REFLECTION, "createKotlinPackage",
Type.getMethodDescriptor(K_PACKAGE_TYPE, getType(Class.class), getType(String.class)), false);
}
else if (container instanceof ScriptDescriptor) {
// TODO: correct container for scripts (KScript?)
StackValue value = generateClassLiteralReference(
typeMapper, ((ScriptDescriptor) container).getClassDescriptor().getDefaultType()
state.getTypeMapper(), ((ScriptDescriptor) container).getClassDescriptor().getDefaultType()
);
value.put(K_CLASS_TYPE, iv);
}
@@ -36,7 +36,10 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
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.*;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicPropertyGetter;
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics;
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsPackage;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -90,7 +93,8 @@ import java.util.*;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.couldUseDirectAccessToProperty;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
@@ -2806,30 +2810,18 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
if (typeParameterDescriptor.isReified()) {
// Emit reified type parameters as Kotlin classes.
// ReifiedTypeInliner will rewrite the following GETSTATIC to proper bytecode instructions
// if the class literal for actual type should be emitted with wrapped Java class.
v.visitLdcInsn(typeParameterDescriptor.getName().asString());
v.invokestatic(
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.CLASS_LITERAL_MARKER_METHOD_NAME,
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
);
v.getstatic(classAsmType.getInternalName(), JvmAbi.KOTLIN_CLASS_FIELD_NAME, K_CLASS_TYPE.getDescriptor());
}
else {
throw new AssertionError("Non-reified type parameter under ::class should be rejected by type checker: " +
typeParameterDescriptor.getName().asString());
}
}
else if (shouldUseJavaClassForClassLiteral(descriptor)) {
putJavaLangClassInstance(v, classAsmType);
wrapJavaClassIntoKClass(v);
}
else {
v.getstatic(classAsmType.getInternalName(), JvmAbi.KOTLIN_CLASS_FIELD_NAME, K_CLASS_TYPE.getDescriptor());
assert typeParameterDescriptor.isReified() :
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
v.visitLdcInsn(typeParameterDescriptor.getName().asString());
v.invokestatic(
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME,
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
);
}
putJavaLangClassInstance(v, classAsmType);
wrapJavaClassIntoKClass(v);
return Unit.INSTANCE$;
}
});
@@ -86,7 +86,8 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCall;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getSecondaryConstructors;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.kotlin.types.Variance.INVARIANT;
@@ -227,8 +228,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor, null);
generateReflectionObjectFieldIfNeeded();
generateEnumEntries();
}
@@ -413,18 +412,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private void generateReflectionObjectFieldIfNeeded() {
if (isAnnotationClass(descriptor)) {
// There's a bug in JDK 6 and 7 that prevents us from generating a static field in an annotation class:
// http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6857918
// TODO: make reflection work on annotation classes somehow
return;
}
generateReflectionObjectField(state, classAsmType, v, method("createKotlinClass", K_CLASS_TYPE, getType(Class.class)),
JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v);
}
private boolean isGenericToArrayPresent() {
Collection<FunctionDescriptor> functions =
descriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier("toArray"), NoLookupLocation.FROM_BACKEND);
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
@@ -212,13 +211,6 @@ public class JvmCodegenUtil {
InlineUtil.isInlinedArgument((JetFunction) declaration, bindingContext, false);
}
public static boolean shouldUseJavaClassForClassLiteral(@NotNull ClassifierDescriptor descriptor) {
ModuleDescriptor module = DescriptorUtils.getContainingModule(descriptor);
return descriptor instanceof JavaClassDescriptor ||
module == module.getBuiltIns().getBuiltInsModule() ||
DescriptorUtils.isAnnotationClass(descriptor);
}
@NotNull
public static String getModuleName(ModuleDescriptor module) {
return StringsKt.removeSurrounding(module.getName().asString(), "<", ">");
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.getFileClassType
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.PackageParts
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
@@ -38,9 +37,7 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.MemberComparator
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
@@ -53,7 +50,6 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.util.*
public class MultifileClassCodegen(
@@ -141,7 +137,6 @@ public class MultifileClassCodegen(
tasks: Map<CallableMemberDescriptor, () -> Unit>,
partFqNames: List<FqName>
) {
generateKotlinPackageReflectionField()
MemberCodegen.generateModuleNameField(state, classBuilder)
for (member in tasks.keySet().sortedWith(MemberComparator.INSTANCE)) {
@@ -261,16 +256,6 @@ public class MultifileClassCodegen(
}
}
private fun generateKotlinPackageReflectionField() {
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)
val method = AsmUtil.method("createKotlinPackage",
AsmTypes.K_PACKAGE_TYPE, AsmTypes.getType(Class::class.java), AsmTypes.getType(String::class.java))
val iv = InstructionAdapter(mv)
MemberCodegen.generateReflectionObjectField(state, facadeClassType, classBuilder, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv)
iv.areturn(Type.VOID_TYPE)
FunctionCodegen.endVisit(mv, "package facade static initializer", null)
}
private fun writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames: List<FqName>) {
if (state.classBuilderMode != ClassBuilderMode.FULL) return
if (files.any { it.isScript }) return
@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackageParts;
@@ -65,17 +64,11 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
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.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
import static org.jetbrains.kotlin.codegen.AsmUtil.method;
import static org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassFqName;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PACKAGE_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackageCodegen {
@@ -256,7 +249,6 @@ public class PackageCodegen {
@NotNull Map<CallableMemberDescriptor, Runnable> tasks,
@NotNull List<JvmSerializationBindings> bindings
) {
generateKotlinPackageReflectionField();
MemberCodegen.generateModuleNameField(state, v);
for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(tasks.keySet())) {
@@ -268,15 +260,6 @@ public class PackageCodegen {
writeKotlinPackageAnnotationIfNeeded(JvmSerializationBindings.union(bindings));
}
private void generateKotlinPackageReflectionField() {
MethodVisitor mv = v.newMethod(NO_ORIGIN, ACC_STATIC, "<clinit>", "()V", null, null);
Method method = method("createKotlinPackage", K_PACKAGE_TYPE, getType(Class.class), getType(String.class));
InstructionAdapter iv = new InstructionAdapter(mv);
MemberCodegen.generateReflectionObjectField(state, packageClassType, v, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv);
iv.areturn(Type.VOID_TYPE);
FunctionCodegen.endVisit(mv, "package facade static initializer", null);
}
private void writeKotlinPackageAnnotationIfNeeded(@NotNull JvmSerializationBindings bindings) {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
return;
@@ -103,7 +103,7 @@ public class PropertyReferenceCodegen(
}
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
ClosureCodegen.generateCallableReferenceDeclarationContainer(this, target, typeMapper)
ClosureCodegen.generateCallableReferenceDeclarationContainer(this, target, state)
}
generateMethod("property reference getName", ACC_PUBLIC, method("getName", JAVA_STRING_TYPE)) {
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
@@ -38,10 +37,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.method;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLASS_FOR_SCRIPT;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForScriptDescriptor;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -101,9 +99,6 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
null,
"java/lang/Object",
ArrayUtil.EMPTY_STRING_ARRAY);
generateReflectionObjectField(state, classType, v, method("createKotlinClass", K_CLASS_TYPE, getType(Class.class)),
JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v);
}
@Override
@@ -27,7 +27,9 @@ import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.codegen.MemberCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
@@ -298,7 +300,7 @@ public class InlineCodegenUtil {
public static boolean isCapturedFieldName(@NotNull String fieldName) {
// TODO: improve this heuristic
return (fieldName.startsWith(CAPTURED_FIELD_PREFIX) && !fieldName.equals(JvmAbi.KOTLIN_CLASS_FIELD_NAME)) ||
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) ||
THIS$0.equals(fieldName) ||
RECEIVER$0.equals(fieldName);
}
@@ -17,13 +17,10 @@
package org.jetbrains.kotlin.codegen.inline
import com.google.common.collect.ImmutableSet
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -40,14 +37,12 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
public val SAFE_CHECKCAST_MARKER_METHOD_NAME: String = "reifySafeCheckcast"
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass"
public val CLASS_LITERAL_MARKER_METHOD_NAME: String = "reifyClassLiteral"
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME: String = "needClassReification"
private val PARAMETRISED_MARKERS = ImmutableSet.of(
NEW_ARRAY_MARKER_METHOD_NAME,
CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME,
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME,
CLASS_LITERAL_MARKER_METHOD_NAME
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME
)
private fun isParametrisedReifiedMarker(insn: AbstractInsnNode) =
@@ -148,7 +143,6 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = true)
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, jetType, asmType)
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
CLASS_LITERAL_MARKER_METHOD_NAME -> processClassLiteral(insn, instructions, jetType, asmType)
else -> false
}) {
instructions.remove(insn.getPrevious()!!)
@@ -202,30 +196,6 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
return true
}
private fun processClassLiteral(insn: MethodInsnNode, instructions: InsnList, type: JetType, parameter: Type): Boolean {
val next = insn.next
if (next !is FieldInsnNode || next.opcode != Opcodes.GETSTATIC) return false
val descriptor = type.constructor.declarationDescriptor!!
if (JvmCodegenUtil.shouldUseJavaClassForClassLiteral(descriptor)) {
instructions.insertBefore(
next,
if (AsmUtil.isPrimitive(parameter))
FieldInsnNode(Opcodes.GETSTATIC, AsmUtil.boxType(parameter).internalName, "TYPE", "Ljava/lang/Class;")
else
LdcInsnNode(parameter)
)
val foreignKotlinClassDesc = Type.getMethodDescriptor(AsmTypes.K_CLASS_TYPE, AsmTypes.JAVA_CLASS_TYPE)
instructions.insertBefore(
next, MethodInsnNode(Opcodes.INVOKESTATIC, AsmTypes.REFLECTION, "foreignKotlinClass", foreignKotlinClassDesc, false)
)
instructions.remove(next)
}
else {
next.owner = AsmUtil.boxType(parameter).internalName
}
return true
}
private fun getParameterName(insn: MethodInsnNode): String? {
val prev = insn.getPrevious()!!
@@ -1,7 +1,7 @@
import kotlin.reflect.jvm.kotlin
class A {
// There's a synthetic "$kotlinClass" field here
enum class A {
// There's a synthetic field "$VALUES" here
}
fun box(): String {
@@ -1,10 +1,8 @@
@kotlin.jvm.internal.KotlinClass Example {
public synthetic field $kotlinClass: kotlin.reflect.KClass
private synthetic @org.jetbrains.annotations.NotNull field prop: java.lang.String
private field prop2: int
private synthetic field useSite: int
private field useSite2: int
method <clinit>(): void
public @org.jetbrains.annotations.NotNull method getProp(): java.lang.String
public synthetic method getProp2(): int
public synthetic method setProp2(p0: int): void
@@ -1,8 +1,6 @@
@kotlin.jvm.internal.KotlinClass A {
public synthetic field $kotlinClass: kotlin.reflect.KClass
private @AnnField @AnnParameterField @AnnTypeField field a: int
private @AnnField @AnnTypeField field x: int
method <clinit>(): void
private synthetic deprecated @AnnProperty @AnnFieldProperty @AnnParameterProperty method a$annotations(): void
public method getA(): int
private synthetic deprecated @AnnProperty @AnnFieldProperty method x$annotations(): void
@@ -20,4 +18,4 @@
@kotlin.annotation.Target @java.lang.annotation.Retention @java.lang.annotation.Target @kotlin.jvm.internal.KotlinClass AnnProperty
@kotlin.annotation.Target @java.lang.annotation.Retention @java.lang.annotation.Target @kotlin.jvm.internal.KotlinClass AnnTypeField
@kotlin.annotation.Target @java.lang.annotation.Retention @java.lang.annotation.Target @kotlin.jvm.internal.KotlinClass AnnTypeField
@@ -22,8 +22,6 @@
@kotlin.jvm.internal.KotlinLocalClass @kotlin.jvm.internal.KotlinClass LiteralsKt$foo$3 {
inner class LiteralsKt$foo$3
public synthetic field $kotlinClass: kotlin.reflect.KClass
method <clinit>(): void
method <init>(): void
}
@@ -45,15 +43,11 @@
}
@kotlin.jvm.internal.KotlinClass My {
public synthetic field $kotlinClass: kotlin.reflect.KClass
method <clinit>(): void
public method <init>(): void
}
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
public synthetic field $kotlinPackage: kotlin.reflect.KPackage
public synthetic field $moduleName: java.lang.String
method <clinit>(): void
public @kotlin.jvm.internal.KotlinDelegatedMethod method bar(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): int
public @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method foo(p0: int): My
}
}
@@ -1,9 +1,7 @@
@kotlin.jvm.internal.KotlinClass A {
public synthetic field $kotlinClass: kotlin.reflect.KClass
private @AnnField field p: int
private @AnnField field x: int
private field y: int
method <clinit>(): void
private synthetic deprecated @AnnProp @AnnProp2 method p$annotations(): void
public @AnnGetter method getP(): int
public @AnnSetter method setP(@AnnParam p0: int): void
@@ -24,4 +22,4 @@
@java.lang.annotation.Retention @kotlin.jvm.internal.KotlinClass AnnProp2
@java.lang.annotation.Retention @kotlin.jvm.internal.KotlinClass AnnSetter
@java.lang.annotation.Retention @kotlin.jvm.internal.KotlinClass AnnSetter
@@ -1,6 +1,4 @@
@kotlin.jvm.internal.KotlinClass A {
public synthetic field $kotlinClass: kotlin.reflect.KClass
method <clinit>(): void
public @org.jetbrains.annotations.NotNull method f(@Ann p0: java.lang.String): java.lang.String
public @org.jetbrains.annotations.NotNull method getP(@Ann p0: java.lang.String): java.lang.String
public method <init>(): void
@@ -14,9 +12,7 @@
}
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
public synthetic field $kotlinPackage: kotlin.reflect.KPackage
public synthetic field $moduleName: java.lang.String
method <clinit>(): void
public @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method getTopLevelP(@Ann p0: java.lang.String): java.lang.String
public @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method topLevelF(@Ann p0: java.lang.String): java.lang.String
}
}
@@ -17,7 +17,6 @@ fun box(): String {
/*
3 return's are defined in functions
2 are from package facade
1 is from package clinit
*/
// 6 RETURN
// 5 RETURN
@@ -22,7 +22,7 @@ import org.jetbrains.asm4.ClassVisitor
import org.jetbrains.asm4.MethodVisitor
import org.jetbrains.asm4.Opcodes
import org.jetbrains.kotlin.test.ConfigurationKind
import java.util.ArrayList
import java.util.*
public class MethodOrderTest: CodegenTestCase() {
public fun testDelegatedMethod() {
@@ -44,7 +44,7 @@ public class MethodOrderTest: CodegenTestCase() {
}
""",
"\$obj$1",
listOf("<clinit>()V", "f3()V", "<init>()V", "f0()V", "f1()V", "f2()V", "f4()V", "f5()V")
listOf("f3()V", "<init>()V", "f0()V", "f1()V", "f2()V", "f4()V", "f5()V")
)
}
@@ -76,7 +76,7 @@ public class MethodOrderTest: CodegenTestCase() {
}
""",
"\$f$1",
listOf("<clinit>()V", "run()V", "<init>(LKlass;Ljava/lang/Object;Ljava/lang/String;IDLjava/lang/Object;J)V")
listOf("run()V", "<init>(LKlass;Ljava/lang/Object;Ljava/lang/String;IDLjava/lang/Object;J)V")
)
}
@@ -97,7 +97,6 @@ public class MethodOrderTest: CodegenTestCase() {
""",
"Outer",
listOf(
"<clinit>()V",
"c()V",
"<init>(ILjava/lang/String;)V",
"access\$getB$0(LOuter;)Ljava/lang/String;",
@@ -52,8 +52,6 @@ public final class JvmAbi {
public static final String INSTANCE_FIELD = "INSTANCE";
public static final String DEPRECATED_INSTANCE_FIELD = "INSTANCE$";
public static final String KOTLIN_CLASS_FIELD_NAME = "$kotlinClass";
public static final String KOTLIN_PACKAGE_FIELD_NAME = "$kotlinPackage";
public static final String MODULE_NAME_FIELD = "$moduleName";
public static final String DEFAULT_MODULE_NAME = "main";
public static final ClassId REFLECTION_FACTORY_IMPL = ClassId.topLevel(new FqName("kotlin.reflect.jvm.internal.ReflectionFactoryImpl"));
@@ -30,10 +30,10 @@ class MyDelegateThrowsException {
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = delegatedPropertyInClass.kt, 5)
local = a: delegatedPropertyInClass.A = {delegatedPropertyInClass.A@uniqueID} (sp = delegatedPropertyInClass.kt, 6)
field = prop$delegate: delegatedPropertyInClass.MyDelegate = {delegatedPropertyInClass.MyDelegate@uniqueID} (sp = delegatedPropertyInClass.kt, 12)
- No fields to display
- Class has no fields
field = prop: int = 1 (sp = delegatedPropertyInClass.kt, 12)
field = propEx$delegate: delegatedPropertyInClass.MyDelegateThrowsException = {delegatedPropertyInClass.MyDelegateThrowsException@uniqueID} (sp = delegatedPropertyInClass.kt, 13)
- No fields to display
- Class has no fields
field = propEx: int = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (sp = delegatedPropertyInClass.kt, 13)
field = detailMessage: java.lang.String = null (sp = Throwable.!EXT!)
field = cause: java.lang.Throwable = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (sp = Throwable.!EXT!)
@@ -26,7 +26,7 @@ class MyDelegate {
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = delegatedPropertyInClassWoRenderer.kt, 5)
local = a: delegatedPropertyInClassWoRenderer.A = {delegatedPropertyInClassWoRenderer.A@uniqueID} (sp = delegatedPropertyInClassWoRenderer.kt, 6)
field = prop: int = {delegatedPropertyInClassWoRenderer.MyDelegate@uniqueID} (sp = delegatedPropertyInClassWoRenderer.kt, 12)
- No fields to display
- Class has no fields
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
+1 -1
View File
@@ -38,7 +38,7 @@ class MyClass
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = frameSimple.kt, 5)
local = val1: int = 1 (sp = frameSimple.kt, 6)
local = val2: frameSimple.MyClass = {frameSimple.MyClass@uniqueID} (sp = frameSimple.kt, 7)
- No fields to display
- Class has no fields
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
+1 -1
View File
@@ -18,7 +18,7 @@ class A {
frame = main():6, ToStringRendererKt {toStringRenderer}
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = toStringRenderer.kt, 3)
local = a: toStringRenderer.A = {toStringRenderer.A@uniqueID}myA (sp = toStringRenderer.kt, 4)
- No fields to display
- Class has no fields
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
@@ -468,8 +468,8 @@ public class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
// Check that outputs are located properly
val facadeWithA = findFileInOutputDir(findModule("module1"), "test/TestPackage.class")
val facadeWithB = findFileInOutputDir(findModule("module2"), "test/TestPackage.class")
UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithA), "<clinit>", "a", "getA")
UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithB), "<clinit>", "b", "getB", "setB")
UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithA), "a", "getA")
UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithB), "b", "getB", "setB")
checkWhen(touch("module1/src/a.kt"), null, packageClasses("module1", "module1/src/a.kt", "test.TestPackage"))
checkWhen(touch("module2/src/b.kt"), null, packageClasses("module2", "module2/src/b.kt", "test.TestPackage"))