Write KotlinSyntheticClass to anonymous and local classes
This commit is contained in:
@@ -35,7 +35,6 @@ import java.util.List;
|
|||||||
import static org.jetbrains.asm4.Opcodes.ACC_STATIC;
|
import static org.jetbrains.asm4.Opcodes.ACC_STATIC;
|
||||||
import static org.jetbrains.asm4.Opcodes.RETURN;
|
import static org.jetbrains.asm4.Opcodes.RETURN;
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTopLevelOrInnerClass;
|
|
||||||
|
|
||||||
public abstract class ClassBodyCodegen extends MemberCodegen {
|
public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||||
protected final JetClassOrObject myClass;
|
protected final JetClassOrObject myClass;
|
||||||
@@ -70,9 +69,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
|||||||
|
|
||||||
generateStaticInitializer();
|
generateStaticInitializer();
|
||||||
|
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL && isTopLevelOrInnerClass(descriptor)) {
|
generateKotlinAnnotation();
|
||||||
generateKotlinAnnotation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void generateDeclaration();
|
protected abstract void generateDeclaration();
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDec
|
|||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||||
|
|
||||||
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||||
private static final String VALUES = "$VALUES";
|
private static final String VALUES = "$VALUES";
|
||||||
@@ -209,6 +210,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateKotlinAnnotation() {
|
protected void generateKotlinAnnotation() {
|
||||||
|
if (isAnonymousObject(descriptor)) {
|
||||||
|
writeKotlinSyntheticClassAnnotation(v, KotlinSyntheticClass.Kind.ANONYMOUS_OBJECT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isTopLevelOrInnerClass(descriptor)) {
|
||||||
|
// LOCAL_CLASS is also written to inner classes of local classes
|
||||||
|
writeKotlinSyntheticClassAnnotation(v, KotlinSyntheticClass.Kind.LOCAL_CLASS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||||
|
|
||||||
DescriptorSerializer serializer = new DescriptorSerializer(new JavaSerializerExtension(v.getSerializationBindings()));
|
DescriptorSerializer serializer = new DescriptorSerializer(new JavaSerializerExtension(v.getSerializationBindings()));
|
||||||
|
|
||||||
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.codegen.context.ClassContext;
|
import org.jetbrains.jet.codegen.context.ClassContext;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
|
||||||
import static org.jetbrains.asm4.Opcodes.*;
|
import static org.jetbrains.asm4.Opcodes.*;
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
import static org.jetbrains.jet.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
||||||
@@ -52,6 +53,10 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateKotlinAnnotation() {
|
protected void generateKotlinAnnotation() {
|
||||||
writeKotlinSyntheticClassAnnotation(v, KotlinSyntheticClass.Kind.TRAIT_IMPL);
|
// We write LOCAL_CLASS to local trait-impl, because we don't want PSI classes to be constructed for such files
|
||||||
|
// (currently PSI for synthetic class is built only if this class is a trait-impl, see DecompiledUtils.kt)
|
||||||
|
writeKotlinSyntheticClassAnnotation(v, DescriptorUtils.isTopLevelOrInnerClass(descriptor)
|
||||||
|
? KotlinSyntheticClass.Kind.TRAIT_IMPL
|
||||||
|
: KotlinSyntheticClass.Kind.LOCAL_CLASS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,10 @@ public class LambdaTransformer {
|
|||||||
superName,
|
superName,
|
||||||
interfaces
|
interfaces
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: load synthetic class kind from the transformed class and write the same kind to the copy of that class here
|
||||||
|
// See AsmUtil.writeKotlinSyntheticClassAnnotation
|
||||||
|
|
||||||
ParametersBuilder builder = ParametersBuilder.newBuilder();
|
ParametersBuilder builder = ParametersBuilder.newBuilder();
|
||||||
Parameters parameters = getLambdaParameters(builder, invocation);
|
Parameters parameters = getLambdaParameters(builder, invocation);
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,30 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
|
|||||||
ANONYMOUS_FUNCTION);
|
ANONYMOUS_FUNCTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testLocalClass() {
|
||||||
|
doTest("fun foo() { class Local }",
|
||||||
|
"Local",
|
||||||
|
LOCAL_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLocalTraitImpl() {
|
||||||
|
doTest("fun foo() { trait Local { fun bar() = 42 } }",
|
||||||
|
"Local",
|
||||||
|
LOCAL_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInnerClassOfLocalClass() {
|
||||||
|
doTest("fun foo() { class Local { inner class Inner } }",
|
||||||
|
"Inner",
|
||||||
|
LOCAL_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnonymousObject() {
|
||||||
|
doTest("val o = object {}",
|
||||||
|
"$",
|
||||||
|
ANONYMOUS_OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
private void doTest(@NotNull String code, @NotNull final String classNamePart, @NotNull KotlinSyntheticClass.Kind expectedKind) {
|
private void doTest(@NotNull String code, @NotNull final String classNamePart, @NotNull KotlinSyntheticClass.Kind expectedKind) {
|
||||||
loadText("package " + PACKAGE_NAME + "\n\n" + code);
|
loadText("package " + PACKAGE_NAME + "\n\n" + code);
|
||||||
List<OutputFile> output = generateClassesInFile().asList();
|
List<OutputFile> output = generateClassesInFile().asList();
|
||||||
|
|||||||
+2
@@ -55,6 +55,8 @@ public final class JvmAnnotationNames {
|
|||||||
CALLABLE_REFERENCE_WRAPPER,
|
CALLABLE_REFERENCE_WRAPPER,
|
||||||
LOCAL_FUNCTION,
|
LOCAL_FUNCTION,
|
||||||
ANONYMOUS_FUNCTION,
|
ANONYMOUS_FUNCTION,
|
||||||
|
LOCAL_CLASS,
|
||||||
|
ANONYMOUS_OBJECT,
|
||||||
;
|
;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public @interface KotlinSyntheticClass {
|
|||||||
|
|
||||||
Kind kind();
|
Kind kind();
|
||||||
|
|
||||||
|
// Inner classes of local classes have kind LOCAL_CLASS
|
||||||
|
// Local trait-impl also has kind LOCAL_CLASS
|
||||||
public static enum Kind {
|
public static enum Kind {
|
||||||
PACKAGE_PART,
|
PACKAGE_PART,
|
||||||
TRAIT_IMPL,
|
TRAIT_IMPL,
|
||||||
@@ -33,5 +35,7 @@ public @interface KotlinSyntheticClass {
|
|||||||
CALLABLE_REFERENCE_WRAPPER,
|
CALLABLE_REFERENCE_WRAPPER,
|
||||||
LOCAL_FUNCTION,
|
LOCAL_FUNCTION,
|
||||||
ANONYMOUS_FUNCTION,
|
ANONYMOUS_FUNCTION,
|
||||||
|
LOCAL_CLASS,
|
||||||
|
ANONYMOUS_OBJECT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user