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) { if (generateBody) {
mv.visitCode(); mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
generateCallableReferenceDeclarationContainer(iv, descriptor, typeMapper); generateCallableReferenceDeclarationContainer(iv, descriptor, state);
iv.areturn(K_DECLARATION_CONTAINER_TYPE); iv.areturn(K_DECLARATION_CONTAINER_TYPE);
FunctionCodegen.endVisit(iv, "function reference getOwner", element); FunctionCodegen.endVisit(iv, "function reference getOwner", element);
} }
@@ -348,24 +348,28 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
public static void generateCallableReferenceDeclarationContainer( public static void generateCallableReferenceDeclarationContainer(
@NotNull InstructionAdapter iv, @NotNull InstructionAdapter iv,
@NotNull CallableDescriptor descriptor, @NotNull CallableDescriptor descriptor,
@NotNull JetTypeMapper typeMapper @NotNull GenerationState state
) { ) {
DeclarationDescriptor container = descriptor.getContainingDeclaration(); DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof ClassDescriptor) { if (container instanceof ClassDescriptor) {
// TODO: getDefaultType() here is wrong and won't work for arrays // 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); value.put(K_CLASS_TYPE, iv);
} }
else if (container instanceof PackageFragmentDescriptor) { else if (container instanceof PackageFragmentDescriptor) {
String packageClassInternalName = PackageClassUtils.getPackageClassInternalName( String packageClassInternalName = PackageClassUtils.getPackageClassInternalName(
((PackageFragmentDescriptor) container).getFqName() ((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) { else if (container instanceof ScriptDescriptor) {
// TODO: correct container for scripts (KScript?) // TODO: correct container for scripts (KScript?)
StackValue value = generateClassLiteralReference( StackValue value = generateClassLiteralReference(
typeMapper, ((ScriptDescriptor) container).getClassDescriptor().getDefaultType() state.getTypeMapper(), ((ScriptDescriptor) container).getClassDescriptor().getDefaultType()
); );
value.put(K_CLASS_TYPE, iv); 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.context.*;
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension; import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.kotlin.codegen.inline.*; 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.pseudoInsns.PseudoInsnsPackage;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState; 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.builtins.KotlinBuiltIns.isInt;
import static org.jetbrains.kotlin.codegen.AsmUtil.*; 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.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory; import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.BindingContext.*;
@@ -2806,30 +2810,18 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) { if (descriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor; TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
if (typeParameterDescriptor.isReified()) { assert typeParameterDescriptor.isReified() :
// Emit reified type parameters as Kotlin classes. "Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
// ReifiedTypeInliner will rewrite the following GETSTATIC to proper bytecode instructions v.visitLdcInsn(typeParameterDescriptor.getName().asString());
// if the class literal for actual type should be emitted with wrapped Java class. v.invokestatic(
v.visitLdcInsn(typeParameterDescriptor.getName().asString()); IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME,
v.invokestatic( Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
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());
} }
putJavaLangClassInstance(v, classAsmType);
wrapJavaClassIntoKClass(v);
return Unit.INSTANCE$; 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.calls.callUtil.CallUtilPackage.getResolvedCall;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns; import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getSecondaryConstructors; 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.DiagnosticsPackage.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN; import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.kotlin.types.Variance.INVARIANT; 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); AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor, null);
generateReflectionObjectFieldIfNeeded();
generateEnumEntries(); 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() { private boolean isGenericToArrayPresent() {
Collection<FunctionDescriptor> functions = Collection<FunctionDescriptor> functions =
descriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier("toArray"), NoLookupLocation.FROM_BACKEND); 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.descriptors.*;
import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames; 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.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt; import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
@@ -212,13 +211,6 @@ public class JvmCodegenUtil {
InlineUtil.isInlinedArgument((JetFunction) declaration, bindingContext, false); 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 @NotNull
public static String getModuleName(ModuleDescriptor module) { public static String getModuleName(ModuleDescriptor module) {
return StringsKt.removeSurrounding(module.getName().asString(), "<", ">"); 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.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.getFileClassType 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.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.PackageParts import org.jetbrains.kotlin.load.kotlin.PackageParts
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider 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.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.MemberComparator 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.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin 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.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.util.* import java.util.*
public class MultifileClassCodegen( public class MultifileClassCodegen(
@@ -141,7 +137,6 @@ public class MultifileClassCodegen(
tasks: Map<CallableMemberDescriptor, () -> Unit>, tasks: Map<CallableMemberDescriptor, () -> Unit>,
partFqNames: List<FqName> partFqNames: List<FqName>
) { ) {
generateKotlinPackageReflectionField()
MemberCodegen.generateModuleNameField(state, classBuilder) MemberCodegen.generateModuleNameField(state, classBuilder)
for (member in tasks.keySet().sortedWith(MemberComparator.INSTANCE)) { 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>) { private fun writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames: List<FqName>) {
if (state.classBuilderMode != ClassBuilderMode.FULL) return if (state.classBuilderMode != ClassBuilderMode.FULL) return
if (files.any { it.isScript }) 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.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.fileClasses.FileClasses; import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo; 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.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackageParts; 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.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type; 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 java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses; 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.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.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackageCodegen { public class PackageCodegen {
@@ -256,7 +249,6 @@ public class PackageCodegen {
@NotNull Map<CallableMemberDescriptor, Runnable> tasks, @NotNull Map<CallableMemberDescriptor, Runnable> tasks,
@NotNull List<JvmSerializationBindings> bindings @NotNull List<JvmSerializationBindings> bindings
) { ) {
generateKotlinPackageReflectionField();
MemberCodegen.generateModuleNameField(state, v); MemberCodegen.generateModuleNameField(state, v);
for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(tasks.keySet())) { for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(tasks.keySet())) {
@@ -268,15 +260,6 @@ public class PackageCodegen {
writeKotlinPackageAnnotationIfNeeded(JvmSerializationBindings.union(bindings)); 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) { private void writeKotlinPackageAnnotationIfNeeded(@NotNull JvmSerializationBindings bindings) {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) { if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
return; return;
@@ -103,7 +103,7 @@ public class PropertyReferenceCodegen(
} }
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) { 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)) { 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.PropertyDescriptor;
import org.jetbrains.kotlin.descriptors.ScriptDescriptor; import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; 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.Collections;
import java.util.List; 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.CLASS_FOR_SCRIPT;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForScriptDescriptor; 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.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN; import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -101,9 +99,6 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
null, null,
"java/lang/Object", "java/lang/Object",
ArrayUtil.EMPTY_STRING_ARRAY); ArrayUtil.EMPTY_STRING_ARRAY);
generateReflectionObjectField(state, classType, v, method("createKotlinClass", K_CLASS_TYPE, getType(Class.class)),
JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v);
} }
@Override @Override
@@ -27,7 +27,9 @@ import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.backend.common.output.OutputFile; import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.codegen.MemberCodegen; import org.jetbrains.kotlin.codegen.MemberCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding; 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.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
@@ -298,7 +300,7 @@ public class InlineCodegenUtil {
public static boolean isCapturedFieldName(@NotNull String fieldName) { public static boolean isCapturedFieldName(@NotNull String fieldName) {
// TODO: improve this heuristic // 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) || THIS$0.equals(fieldName) ||
RECEIVER$0.equals(fieldName); RECEIVER$0.equals(fieldName);
} }
@@ -17,13 +17,10 @@
package org.jetbrains.kotlin.codegen.inline package org.jetbrains.kotlin.codegen.inline
import com.google.common.collect.ImmutableSet 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.context.MethodContext
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.JetType
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes 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 SAFE_CHECKCAST_MARKER_METHOD_NAME: String = "reifySafeCheckcast"
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof" public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass" 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" public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME: String = "needClassReification"
private val PARAMETRISED_MARKERS = ImmutableSet.of( private val PARAMETRISED_MARKERS = ImmutableSet.of(
NEW_ARRAY_MARKER_METHOD_NAME, NEW_ARRAY_MARKER_METHOD_NAME,
CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME, CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME,
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME, INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME
CLASS_LITERAL_MARKER_METHOD_NAME
) )
private fun isParametrisedReifiedMarker(insn: AbstractInsnNode) = 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) SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = true)
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, jetType, asmType) INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, jetType, asmType)
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType) JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
CLASS_LITERAL_MARKER_METHOD_NAME -> processClassLiteral(insn, instructions, jetType, asmType)
else -> false else -> false
}) { }) {
instructions.remove(insn.getPrevious()!!) instructions.remove(insn.getPrevious()!!)
@@ -202,30 +196,6 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
return true 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? { private fun getParameterName(insn: MethodInsnNode): String? {
val prev = insn.getPrevious()!! val prev = insn.getPrevious()!!
@@ -1,7 +1,7 @@
import kotlin.reflect.jvm.kotlin import kotlin.reflect.jvm.kotlin
class A { enum class A {
// There's a synthetic "$kotlinClass" field here // There's a synthetic field "$VALUES" here
} }
fun box(): String { fun box(): String {
@@ -1,10 +1,8 @@
@kotlin.jvm.internal.KotlinClass Example { @kotlin.jvm.internal.KotlinClass Example {
public synthetic field $kotlinClass: kotlin.reflect.KClass
private synthetic @org.jetbrains.annotations.NotNull field prop: java.lang.String private synthetic @org.jetbrains.annotations.NotNull field prop: java.lang.String
private field prop2: int private field prop2: int
private synthetic field useSite: int private synthetic field useSite: int
private field useSite2: int private field useSite2: int
method <clinit>(): void
public @org.jetbrains.annotations.NotNull method getProp(): java.lang.String public @org.jetbrains.annotations.NotNull method getProp(): java.lang.String
public synthetic method getProp2(): int public synthetic method getProp2(): int
public synthetic method setProp2(p0: int): void public synthetic method setProp2(p0: int): void
@@ -1,8 +1,6 @@
@kotlin.jvm.internal.KotlinClass A { @kotlin.jvm.internal.KotlinClass A {
public synthetic field $kotlinClass: kotlin.reflect.KClass
private @AnnField @AnnParameterField @AnnTypeField field a: int private @AnnField @AnnParameterField @AnnTypeField field a: int
private @AnnField @AnnTypeField field x: int private @AnnField @AnnTypeField field x: int
method <clinit>(): void
private synthetic deprecated @AnnProperty @AnnFieldProperty @AnnParameterProperty method a$annotations(): void private synthetic deprecated @AnnProperty @AnnFieldProperty @AnnParameterProperty method a$annotations(): void
public method getA(): int public method getA(): int
private synthetic deprecated @AnnProperty @AnnFieldProperty method x$annotations(): void 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 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 { @kotlin.jvm.internal.KotlinLocalClass @kotlin.jvm.internal.KotlinClass LiteralsKt$foo$3 {
inner class LiteralsKt$foo$3 inner class LiteralsKt$foo$3
public synthetic field $kotlinClass: kotlin.reflect.KClass
method <clinit>(): void
method <init>(): void method <init>(): void
} }
@@ -45,15 +43,11 @@
} }
@kotlin.jvm.internal.KotlinClass My { @kotlin.jvm.internal.KotlinClass My {
public synthetic field $kotlinClass: kotlin.reflect.KClass
method <clinit>(): void
public method <init>(): void public method <init>(): void
} }
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage { @java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
public synthetic field $kotlinPackage: kotlin.reflect.KPackage
public synthetic field $moduleName: java.lang.String 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 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 public @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method foo(p0: int): My
} }
@@ -1,9 +1,7 @@
@kotlin.jvm.internal.KotlinClass A { @kotlin.jvm.internal.KotlinClass A {
public synthetic field $kotlinClass: kotlin.reflect.KClass
private @AnnField field p: int private @AnnField field p: int
private @AnnField field x: int private @AnnField field x: int
private field y: int private field y: int
method <clinit>(): void
private synthetic deprecated @AnnProp @AnnProp2 method p$annotations(): void private synthetic deprecated @AnnProp @AnnProp2 method p$annotations(): void
public @AnnGetter method getP(): int public @AnnGetter method getP(): int
public @AnnSetter method setP(@AnnParam p0: int): void 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 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 { @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 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 @org.jetbrains.annotations.NotNull method getP(@Ann p0: java.lang.String): java.lang.String
public method <init>(): void public method <init>(): void
@@ -14,9 +12,7 @@
} }
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage { @java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
public synthetic field $kotlinPackage: kotlin.reflect.KPackage
public synthetic field $moduleName: java.lang.String 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 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 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 3 return's are defined in functions
2 are from package facade 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.MethodVisitor
import org.jetbrains.asm4.Opcodes import org.jetbrains.asm4.Opcodes
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
import java.util.ArrayList import java.util.*
public class MethodOrderTest: CodegenTestCase() { public class MethodOrderTest: CodegenTestCase() {
public fun testDelegatedMethod() { public fun testDelegatedMethod() {
@@ -44,7 +44,7 @@ public class MethodOrderTest: CodegenTestCase() {
} }
""", """,
"\$obj$1", "\$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", "\$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", "Outer",
listOf( listOf(
"<clinit>()V",
"c()V", "c()V",
"<init>(ILjava/lang/String;)V", "<init>(ILjava/lang/String;)V",
"access\$getB$0(LOuter;)Ljava/lang/String;", "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 INSTANCE_FIELD = "INSTANCE";
public static final String DEPRECATED_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 MODULE_NAME_FIELD = "$moduleName";
public static final String DEFAULT_MODULE_NAME = "main"; public static final String DEFAULT_MODULE_NAME = "main";
public static final ClassId REFLECTION_FACTORY_IMPL = ClassId.topLevel(new FqName("kotlin.reflect.jvm.internal.ReflectionFactoryImpl")); 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 = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = delegatedPropertyInClass.kt, 5)
local = a: delegatedPropertyInClass.A = {delegatedPropertyInClass.A@uniqueID} (sp = delegatedPropertyInClass.kt, 6) local = a: delegatedPropertyInClass.A = {delegatedPropertyInClass.A@uniqueID} (sp = delegatedPropertyInClass.kt, 6)
field = prop$delegate: delegatedPropertyInClass.MyDelegate = {delegatedPropertyInClass.MyDelegate@uniqueID} (sp = delegatedPropertyInClass.kt, 12) 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 = prop: int = 1 (sp = delegatedPropertyInClass.kt, 12)
field = propEx$delegate: delegatedPropertyInClass.MyDelegateThrowsException = {delegatedPropertyInClass.MyDelegateThrowsException@uniqueID} (sp = delegatedPropertyInClass.kt, 13) 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 = propEx: int = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (sp = delegatedPropertyInClass.kt, 13)
field = detailMessage: java.lang.String = null (sp = Throwable.!EXT!) field = detailMessage: java.lang.String = null (sp = Throwable.!EXT!)
field = cause: java.lang.Throwable = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (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 = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = delegatedPropertyInClassWoRenderer.kt, 5)
local = a: delegatedPropertyInClassWoRenderer.A = {delegatedPropertyInClassWoRenderer.A@uniqueID} (sp = delegatedPropertyInClassWoRenderer.kt, 6) local = a: delegatedPropertyInClassWoRenderer.A = {delegatedPropertyInClassWoRenderer.A@uniqueID} (sp = delegatedPropertyInClassWoRenderer.kt, 6)
field = prop: int = {delegatedPropertyInClassWoRenderer.MyDelegate@uniqueID} (sp = delegatedPropertyInClassWoRenderer.kt, 12) 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' Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0 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 = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = frameSimple.kt, 5)
local = val1: int = 1 (sp = frameSimple.kt, 6) local = val1: int = 1 (sp = frameSimple.kt, 6)
local = val2: frameSimple.MyClass = {frameSimple.MyClass@uniqueID} (sp = frameSimple.kt, 7) 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' Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0 Process finished with exit code 0
+1 -1
View File
@@ -18,7 +18,7 @@ class A {
frame = main():6, ToStringRendererKt {toStringRenderer} frame = main():6, ToStringRendererKt {toStringRenderer}
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} (sp = toStringRenderer.kt, 3) 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) 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' Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0 Process finished with exit code 0
@@ -468,8 +468,8 @@ public class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
// Check that outputs are located properly // Check that outputs are located properly
val facadeWithA = findFileInOutputDir(findModule("module1"), "test/TestPackage.class") val facadeWithA = findFileInOutputDir(findModule("module1"), "test/TestPackage.class")
val facadeWithB = findFileInOutputDir(findModule("module2"), "test/TestPackage.class") val facadeWithB = findFileInOutputDir(findModule("module2"), "test/TestPackage.class")
UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithA), "<clinit>", "a", "getA") UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithA), "a", "getA")
UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithB), "<clinit>", "b", "getB", "setB") UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithB), "b", "getB", "setB")
checkWhen(touch("module1/src/a.kt"), null, packageClasses("module1", "module1/src/a.kt", "test.TestPackage")) 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")) checkWhen(touch("module2/src/b.kt"), null, packageClasses("module2", "module2/src/b.kt", "test.TestPackage"))