From 38a56ba8e8b28d1524f8bbddedf741318427bf37 Mon Sep 17 00:00:00 2001 From: Pavel Mikhailovskii Date: Fri, 13 Jan 2023 01:07:10 +0000 Subject: [PATCH] KT-55308, KT-55769 Sort InnerClasses entries. Add DONT_SORT_DECLARATIONS directive --- .../backend/jvm/codegen/ClassCodegen.kt | 7 +- .../codegen/bytecodeListing/kt55769.ir.txt | 40 +++++ .../codegen/bytecodeListing/kt55769.kt | 15 ++ .../codegen/bytecodeListing/kt55769.txt | 37 ++++ .../codegen/BytecodeListingTestGenerated.java | 6 + .../IrBytecodeListingTestGenerated.java | 6 + .../handlers/BytecodeListingHandler.kt | 2 + .../test/directives/CodegenTestDirectives.kt | 5 + .../BytecodeListingTextCollectingVisitor.kt | 5 +- .../testData/converter/abstractEnum_ir.txt | 100 +++++++++++ .../testData/converter/nestedClasses2_ir.txt | 42 ++--- .../nestedClassesNonRootPackage_ir.txt | 42 ++--- .../testData/converter/nestedClasses_ir.txt | 166 ++++++++++++++++++ .../kotlinRunner/NestedClasses.it_ir.txt | 16 +- 14 files changed, 432 insertions(+), 57 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/kt55769.ir.txt create mode 100644 compiler/testData/codegen/bytecodeListing/kt55769.kt create mode 100644 compiler/testData/codegen/bytecodeListing/kt55769.txt create mode 100644 plugins/kapt3/kapt3-compiler/testData/converter/abstractEnum_ir.txt create mode 100644 plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses_ir.txt diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 2b220ce8b80..f2c23f78927 100644 --- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -80,10 +80,7 @@ class ClassCodegen private constructor( private val state get() = context.state - // TODO: the order of entries in this set depends on the order in which methods are generated; this means it is unstable - // under incremental compilation, as calls to `inline fun`s declared in this class cause them to be generated out of order. - private val innerClasses = linkedSetOf() - + private val innerClasses = mutableSetOf() val typeMapper = if (context.state.oldInnerClassesLogic) context.defaultTypeMapper @@ -476,7 +473,7 @@ class ClassCodegen private constructor( } } - for (klass in innerClasses) { + for (klass in innerClasses.sortedBy { it.fqNameWhenAvailable?.asString() }) { val innerJavaClassId = klass.mapToJava() val innerClass = innerJavaClassId?.internalName ?: typeMapper.classInternalName(klass) val outerClass = diff --git a/compiler/testData/codegen/bytecodeListing/kt55769.ir.txt b/compiler/testData/codegen/bytecodeListing/kt55769.ir.txt new file mode 100644 index 00000000000..e99de99760b --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/kt55769.ir.txt @@ -0,0 +1,40 @@ +@kotlin.Metadata +public final enum class A$B$C { + // source: 'kt55769.kt' + public final inner class A$B + public final inner class A$B$C + public final enum static field C1: A$B$C + public final enum static field C2: A$B$C + public final enum static field C3: A$B$C + private synthetic final static field $VALUES: A$B$C[] + private method (p0: java.lang.String, p1: int): void + public static method values(): A$B$C[] + public static method valueOf(p0: java.lang.String): A$B$C + private synthetic final static method $values(): A$B$C[] + static method (): void +} + +@kotlin.Metadata +public final class A$B { + // source: 'kt55769.kt' + public final inner class A$B + public final inner class A$B$C + public method (): void +} + +@kotlin.Metadata +public final class A { + // source: 'kt55769.kt' + public final inner class A$B + public method (): void +} + +@kotlin.Metadata +public final class Main { + // source: 'kt55769.kt' + public final inner class A$B + public final inner class A$B$C + private final @org.jetbrains.annotations.NotNull field field: A$B$C + public method (): void + public final @org.jetbrains.annotations.NotNull method getField(): A$B$C +} diff --git a/compiler/testData/codegen/bytecodeListing/kt55769.kt b/compiler/testData/codegen/bytecodeListing/kt55769.kt new file mode 100644 index 00000000000..d9533054e89 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/kt55769.kt @@ -0,0 +1,15 @@ +// DONT_SORT_DECLARATIONS + +class Main { + val field = A.B.C.C1 +} + +class A { + class B { + enum class C { + C1, + C2, + C3 + } + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/kt55769.txt b/compiler/testData/codegen/bytecodeListing/kt55769.txt new file mode 100644 index 00000000000..2cb23ab64c4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/kt55769.txt @@ -0,0 +1,37 @@ +@kotlin.Metadata +public final enum class A$B$C { + // source: 'kt55769.kt' + public final inner class A$B$C + public final inner class A$B + public final enum static field C1: A$B$C + public final enum static field C2: A$B$C + public final enum static field C3: A$B$C + private synthetic final static field $VALUES: A$B$C[] + static method (): void + private method (p0: java.lang.String, p1: int): void + public static method values(): A$B$C[] + public static method valueOf(p0: java.lang.String): A$B$C +} + +@kotlin.Metadata +public final class A$B { + // source: 'kt55769.kt' + public final inner class A$B$C + public final inner class A$B + public method (): void +} + +@kotlin.Metadata +public final class A { + // source: 'kt55769.kt' + public final inner class A$B + public method (): void +} + +@kotlin.Metadata +public final class Main { + // source: 'kt55769.kt' + private final @org.jetbrains.annotations.NotNull field field: A$B$C + public final @org.jetbrains.annotations.NotNull method getField(): A$B$C + public method (): void +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeListingTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeListingTestGenerated.java index c2a1b22e428..aa14f2929d0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeListingTestGenerated.java @@ -211,6 +211,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/kt47328.kt"); } + @Test + @TestMetadata("kt55769.kt") + public void testKt55769() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/kt55769.kt"); + } + @Test @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeListingTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeListingTestGenerated.java index 5b1fb4a9139..21c69427ef1 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeListingTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeListingTestGenerated.java @@ -217,6 +217,12 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/kt47328.kt"); } + @Test + @TestMetadata("kt55769.kt") + public void testKt55769() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/kt55769.kt"); + } + @Test @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BytecodeListingHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BytecodeListingHandler.kt index 1bc8a156b7a..6abe0b944ea 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BytecodeListingHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/BytecodeListingHandler.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.test.backend.handlers import org.jetbrains.kotlin.codegen.BytecodeListingTextCollectingVisitor import org.jetbrains.kotlin.test.directives.CodegenTestDirectives import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.CHECK_BYTECODE_LISTING +import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.DONT_SORT_DECLARATIONS import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_ANNOTATIONS import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.WITH_SIGNATURES import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.FIR_IDENTICAL @@ -36,6 +37,7 @@ class BytecodeListingHandler(testServices: TestServices) : JvmBinaryArtifactHand BytecodeListingTextCollectingVisitor.Filter.ForCodegenTests, withSignatures = WITH_SIGNATURES in module.directives, withAnnotations = IGNORE_ANNOTATIONS !in module.directives, + sortDeclarations = DONT_SORT_DECLARATIONS !in module.directives, ) multiModuleInfoDumper.builderForModule(module).append(dump) } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/CodegenTestDirectives.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/CodegenTestDirectives.kt index 8ba03daabb8..9375d424486 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/CodegenTestDirectives.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/CodegenTestDirectives.kt @@ -81,6 +81,11 @@ object CodegenTestDirectives : SimpleDirectivesContainer() { applicability = Global ) + val DONT_SORT_DECLARATIONS by directive( + description = "Do not sort declarations", + applicability = Global + ) + val RUN_DEX_CHECKER by directive( description = "Run DxChecker and D8Checker" ) diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/BytecodeListingTextCollectingVisitor.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/BytecodeListingTextCollectingVisitor.kt index 6d22ba52823..ae579671490 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/BytecodeListingTextCollectingVisitor.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/BytecodeListingTextCollectingVisitor.kt @@ -22,14 +22,15 @@ class BytecodeListingTextCollectingVisitor( factory: ClassFileFactory, filter: Filter = Filter.EMPTY, withSignatures: Boolean = false, - withAnnotations: Boolean = true + withAnnotations: Boolean = true, + sortDeclarations: Boolean = true ) = factory.getClassFiles() .sortedBy { it.relativePath } .mapNotNull { val cr = ClassReader(it.asByteArray()) val node = ClassNode(Opcodes.API_VERSION) cr.accept(node, ClassReader.SKIP_CODE) - val visitor = BytecodeListingTextCollectingVisitor(filter, withSignatures, withAnnotations = withAnnotations) + val visitor = BytecodeListingTextCollectingVisitor(filter, withSignatures, withAnnotations = withAnnotations, sortDeclarations = sortDeclarations) node.accept(visitor) if (!filter.shouldWriteClass(node)) null else visitor.text diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/abstractEnum_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/abstractEnum_ir.txt new file mode 100644 index 00000000000..6338a5a0396 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/abstractEnum_ir.txt @@ -0,0 +1,100 @@ +@kotlin.Metadata() +public enum E { + /*public static final*/ X /* = new E() */, + /*public static final*/ Y /* = new E() */; + + E() { + } + + public abstract void a(); + + public final void b() { + } + + @kotlin.Metadata() + public static final class NestedClass { + + public NestedClass() { + super(); + } + } + + @kotlin.Metadata() + public static final class Obj { + @org.jetbrains.annotations.NotNull() + public static final E.Obj INSTANCE = null; + + private Obj() { + super(); + } + } +} + +//////////////////// + + +@kotlin.Metadata() +public enum E2 { + /*public static final*/ X /* = new E2() */, + /*public static final*/ Y /* = new E2() */; + + E2(int n) { + } + + E2(java.lang.String s) { + } + + public abstract void a(); +} + +//////////////////// + + +@kotlin.Metadata() +public enum E3 { + /*public static final*/ X /* = new E3() */, + /*public static final*/ Y /* = new E3() */; + @org.jetbrains.annotations.NotNull() + private final java.lang.String a = null; + + E3(java.lang.String a) { + } + + @org.jetbrains.annotations.NotNull() + public final java.lang.String getA() { + return null; + } +} + +//////////////////// + + +@kotlin.Metadata() +public enum E4 { + /*public static final*/ X /* = new E4() */; + @org.jetbrains.annotations.NotNull() + private final java.lang.String a = null; + private final int b = 0; + private final long c = 0L; + private final boolean d = false; + + E4(java.lang.String a, int b, long c, boolean d) { + } + + @org.jetbrains.annotations.NotNull() + public final java.lang.String getA() { + return null; + } + + public final int getB() { + return 0; + } + + public final long getC() { + return 0L; + } + + public final boolean getD() { + return false; + } +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt index a8108b745c2..d7cdba03e0b 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt @@ -29,6 +29,22 @@ public final class A$B { } } + @kotlin.Metadata() + public static final class D$$$E { + + public D$$$E() { + super(); + } + } + + @kotlin.Metadata() + public static final class D$$E { + + public D$$E() { + super(); + } + } + @kotlin.Metadata() public static final class D$E { @kotlin.jvm.JvmField() @@ -60,22 +76,6 @@ public final class A$B { } } } - - @kotlin.Metadata() - public static final class D$$E { - - public D$$E() { - super(); - } - } - - @kotlin.Metadata() - public static final class D$$$E { - - public D$$$E() { - super(); - } - } } //////////////////// @@ -88,11 +88,6 @@ public final class Experiment { super(); } - @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) - @kotlin.Metadata() - public static abstract @interface Type { - } - @Experiment.Type() @kotlin.Metadata() public static final class Group { @@ -141,6 +136,11 @@ public final class Experiment { return null; } } + + @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) + @kotlin.Metadata() + public static abstract @interface Type { + } } //////////////////// diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt index d2b149fafd7..51d4e4a4db1 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt @@ -31,6 +31,22 @@ public final class A$B { } } + @kotlin.Metadata() + public static final class D$$$E { + + public D$$$E() { + super(); + } + } + + @kotlin.Metadata() + public static final class D$$E { + + public D$$E() { + super(); + } + } + @kotlin.Metadata() public static final class D$E { @kotlin.jvm.JvmField() @@ -62,22 +78,6 @@ public final class A$B { } } } - - @kotlin.Metadata() - public static final class D$$E { - - public D$$E() { - super(); - } - } - - @kotlin.Metadata() - public static final class D$$$E { - - public D$$$E() { - super(); - } - } } //////////////////// @@ -91,11 +91,6 @@ public final class Experiment { super(); } - @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) - @kotlin.Metadata() - public static abstract @interface Type { - } - @test.Experiment.Type() @kotlin.Metadata() public static final class Group { @@ -140,6 +135,11 @@ public final class Experiment { return null; } } + + @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) + @kotlin.Metadata() + public static abstract @interface Type { + } } //////////////////// diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses_ir.txt new file mode 100644 index 00000000000..3eb5d7e1bed --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses_ir.txt @@ -0,0 +1,166 @@ +@kotlin.Metadata() +public final class A { + @org.jetbrains.annotations.Nullable() + private final A x = null; + + public A() { + super(); + } + + @org.jetbrains.annotations.Nullable() + public final A getX() { + return null; + } + + @org.jetbrains.annotations.Nullable() + public final A f1(@org.jetbrains.annotations.NotNull() + A a, @org.jetbrains.annotations.NotNull() + A.B b) { + return null; + } + + @kotlin.Metadata() + public static abstract interface B { + + @org.jetbrains.annotations.Nullable() + public abstract A.B getY(); + + @kotlin.Metadata() + public static final class DefaultImpls { + + public DefaultImpls() { + super(); + } + } + } + + @kotlin.Metadata() + public static final class C { + @org.jetbrains.annotations.NotNull() + public static final A.C INSTANCE = null; + + private C() { + super(); + } + } +} + +//////////////////// + + +@kotlin.Metadata() +public final class A2 { + + public A2() { + super(); + } + + @kotlin.Metadata() + public static final class B { + + public B() { + super(); + } + + @kotlin.Metadata() + public static final class C { + + public C() { + super(); + } + + @kotlin.Metadata() + public static final class D { + + public D() { + super(); + } + + @kotlin.Metadata() + public static final class Cme { + + public Cme() { + super(); + } + } + + @kotlin.Metadata() + public static final class E { + + public E() { + super(); + } + } + } + } + } +} + +//////////////////// + + +@kotlin.Metadata() +public final class Foo { + + public Foo() { + super(); + } +} + +//////////////////// + + +@kotlin.Metadata() +public final class Test { + + public Test() { + super(); + } + + @kotlin.Metadata() + public final class Inner { + + public Inner() { + super(); + } + } + + @kotlin.Metadata() + public static final class Nested { + + public Nested() { + super(); + } + + @kotlin.Metadata() + public static final class NestedNested { + + public NestedNested() { + super(); + } + } + } + + @kotlin.Metadata() + public static enum NestedEnum { + /*public static final*/ BLACK /* = new NestedEnum() */, + /*public static final*/ WHITE /* = new NestedEnum() */; + + NestedEnum() { + } + } + + @kotlin.Metadata() + public static abstract interface NestedInterface { + } + + @kotlin.Metadata() + public static final class NestedObject { + @org.jetbrains.annotations.NotNull() + public static final Test.NestedObject INSTANCE = null; + + private NestedObject() { + super(); + } + } +} diff --git a/plugins/kapt3/kapt3-compiler/testData/kotlinRunner/NestedClasses.it_ir.txt b/plugins/kapt3/kapt3-compiler/testData/kotlinRunner/NestedClasses.it_ir.txt index d03a726e7fc..b2d99551d85 100644 --- a/plugins/kapt3/kapt3-compiler/testData/kotlinRunner/NestedClasses.it_ir.txt +++ b/plugins/kapt3/kapt3-compiler/testData/kotlinRunner/NestedClasses.it_ir.txt @@ -37,6 +37,14 @@ public final class Simple { } } + @kotlin.Metadata() + public final class InnerClass { + + public InnerClass() { + super(); + } + } + @kotlin.Metadata() public static final class NestedClass { @@ -52,12 +60,4 @@ public final class Simple { } } } - - @kotlin.Metadata() - public final class InnerClass { - - public InnerClass() { - super(); - } - } }