From 15c3dd527c948aff58f1a80b0ab0e460a5d7138d Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 8 Mar 2022 12:40:12 +0100 Subject: [PATCH] KAPT+IR: Support data classes --- .../psi2ir/generators/ClassGenerator.kt | 6 +- .../generators/DataClassMembersGenerator.kt | 6 +- .../ir/util/DataClassMembersGenerator.kt | 11 +- .../testData/converter/nestedClasses2.kt | 1 - .../testData/converter/nestedClasses2_ir.txt | 279 +++++++++++++++++ .../converter/nestedClassesNonRootPackage.kt | 1 - .../nestedClassesNonRootPackage_ir.txt | 287 ++++++++++++++++++ 7 files changed, 580 insertions(+), 11 deletions(-) create mode 100644 plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt create mode 100644 plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt index 6311881f9d1..f3f1cc3a3dd 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt @@ -421,15 +421,15 @@ class ClassGenerator( } private fun generateAdditionalMembersForSingleFieldValueClasses(irClass: IrClass, ktClassOrObject: KtClassOrObject) { - DataClassMembersGenerator(declarationGenerator).generateSingleFieldValueClassMembers(ktClassOrObject, irClass) + DataClassMembersGenerator(declarationGenerator, context.configuration.generateBodies).generateSingleFieldValueClassMembers(ktClassOrObject, irClass) } private fun generateAdditionalMembersForMultiFieldValueClasses(irClass: IrClass, ktClassOrObject: KtClassOrObject) { - DataClassMembersGenerator(declarationGenerator).generateMultiFieldValueClassMembers(ktClassOrObject, irClass) + DataClassMembersGenerator(declarationGenerator, context.configuration.generateBodies).generateMultiFieldValueClassMembers(ktClassOrObject, irClass) } private fun generateAdditionalMembersForDataClass(irClass: IrClass, ktClassOrObject: KtClassOrObject) { - DataClassMembersGenerator(declarationGenerator).generateDataClassMembers(ktClassOrObject, irClass) + DataClassMembersGenerator(declarationGenerator, context.configuration.generateBodies).generateDataClassMembers(ktClassOrObject, irClass) } private fun generateAdditionalMembersForEnumClass(irClass: IrClass) { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt index 4be2db073c8..facbe96a783 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt @@ -42,7 +42,8 @@ import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound * function bodies; and provides ways to declare functions or parameters based on descriptors and binding context. */ class DataClassMembersGenerator( - declarationGenerator: DeclarationGenerator + declarationGenerator: DeclarationGenerator, + private val generateBodies: Boolean ) : DeclarationGeneratorExtension(declarationGenerator) { fun generateSingleFieldValueClassMembers(ktClassOrObject: KtClassOrObject, irClass: IrClass) { @@ -73,7 +74,8 @@ class DataClassMembersGenerator( val origin: IrDeclarationOrigin ) : DataClassMethodGenerator(ktClassOrObject, declarationGenerator.context.bindingContext) { - private val irDataClassMembersGenerator = object : DataClassMembersGenerator(context, context.symbolTable, irClass, origin) { + private val irDataClassMembersGenerator = + object : DataClassMembersGenerator(context, context.symbolTable, irClass, origin, generateBodies = generateBodies) { override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction = declareSimpleFunction(startOffset, endOffset, origin, functionDescriptor) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt index 6a92412bdb4..8f07c29c852 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt @@ -33,7 +33,8 @@ abstract class DataClassMembersGenerator( val symbolTable: ReferenceSymbolTable, val irClass: IrClass, val origin: IrDeclarationOrigin, - val forbidDirectFieldAccess: Boolean = false + val forbidDirectFieldAccess: Boolean = false, + val generateBodies: Boolean = false ) { private val irPropertiesByDescriptor: Map = irClass.properties.associateBy { it.descriptor } @@ -300,10 +301,12 @@ abstract class DataClassMembersGenerator( // Entry for psi2ir fun generateCopyFunction(function: FunctionDescriptor, constructorSymbol: IrConstructorSymbol) { buildMember(function) { - function.valueParameters.forEach { parameter -> - putDefault(parameter, irGetProperty(irThis(), getProperty(parameter, null)!!)) + if (generateBodies) { + function.valueParameters.forEach { parameter -> + putDefault(parameter, irGetProperty(irThis(), getProperty(parameter, null)!!)) + } + generateCopyFunction(constructorSymbol) } - generateCopyFunction(constructorSymbol) } } diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2.kt b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2.kt index c62bbce254b..47748c47fc6 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: JavaClass.java public class JavaClass { public class Foo { diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt new file mode 100644 index 00000000000..d59a60be5cd --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClasses2_ir.txt @@ -0,0 +1,279 @@ +import java.lang.System; + +@kotlin.Metadata() +public final class A$B { + @kotlin.jvm.JvmField() + public A$B.C c; + @kotlin.jvm.JvmField() + public A$B.D$E de; + @kotlin.jvm.JvmField() + public J$B.C jc; + @kotlin.jvm.JvmField() + public J$B.D$E jde; + @kotlin.jvm.JvmField() + public A$B.D$$E dee; + @kotlin.jvm.JvmField() + public A$B.D$$$E deee; + @kotlin.jvm.JvmField() + public J$B.D$$E jdee; + @kotlin.jvm.JvmField() + public J$B.D$$$E jdeee; + + public A$B() { + super(); + } + + @kotlin.Metadata() + public static final class C { + + public C() { + super(); + } + } + + @kotlin.Metadata() + public static final class D$E { + @kotlin.jvm.JvmField() + public A$B.D$E.F f; + @kotlin.jvm.JvmField() + public A$B.D$E.F$G fg; + @kotlin.jvm.JvmField() + public J$B.D$E.F jf; + @kotlin.jvm.JvmField() + public J$B.D$E.F$G jfg; + + public D$E() { + super(); + } + + @kotlin.Metadata() + public static final class F { + + public F() { + super(); + } + } + + @kotlin.Metadata() + public static final class F$G { + + public F$G() { + super(); + } + } + } + + @kotlin.Metadata() + public static final class D$$E { + + public D$$E() { + super(); + } + } + + @kotlin.Metadata() + public static final class D$$$E { + + public D$$$E() { + super(); + } + } +} + +//////////////////// + + +import java.lang.System; + +@kotlin.Metadata() +public final class Experiment { + + public Experiment() { + super(); + } + + @kotlin.Metadata() + @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) + public static abstract @interface Type { + } + + @kotlin.Metadata() + @Experiment.Type() + public static final class Group { + + @org.jetbrains.annotations.NotNull() + public final Experiment.Group copy(@org.jetbrains.annotations.NotNull() + java.lang.String s) { + return null; + } + + public Group(@org.jetbrains.annotations.NotNull() + java.lang.String s) { + super(); + } + } +} + +//////////////////// + + +import java.lang.System; + +@kotlin.Metadata() +public final class Foo { + + public Foo() { + super(); + } + + @kotlin.Metadata() + public static class Bar { + + public Bar() { + super(); + } + + @kotlin.Metadata() + public static final class Zoo { + @org.jetbrains.annotations.NotNull() + public static final Foo.Bar.Zoo INSTANCE = null; + + private Zoo() { + super(); + } + } + } +} + +//////////////////// + + +import java.lang.System; + +@kotlin.Metadata() +public abstract interface IFoo { + + @kotlin.Metadata() + public static abstract interface IBar { + + @kotlin.Metadata() + @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) + public static abstract @interface Anno { + + public abstract java.lang.Class[] value(); + } + + @kotlin.Metadata() + @IFoo.IBar.Anno(value = {IFoo.IBar.IZoo.class}) + public static abstract interface IZoo { + } + } +} + +//////////////////// + + +public class J$B { + + public J$B() { + super(); + } + + public class C { + + public C() { + super(); + } + } + + public class D$E { + + public D$E() { + super(); + } + + class F { + + F() { + super(); + } + } + + class F$G { + + F$G() { + super(); + } + } + } + + public class D$$E { + + public D$$E() { + super(); + } + } + + public class D$$$E { + + public D$$$E() { + super(); + } + } +} + +//////////////////// + + +public class JavaClass { + + public JavaClass() { + super(); + } + + public class Foo { + + public Foo() { + super(); + } + + public class Bar { + + public Bar() { + super(); + } + } + } +} + +//////////////////// + + +import java.lang.System; + +@kotlin.Metadata() +@IFoo.IBar.Anno(value = {IFoo.IBar.IZoo.class, Foo.Bar.class}) +public final class Test1 extends Foo.Bar implements IFoo.IBar, IFoo.IBar.IZoo { + @org.jetbrains.annotations.NotNull() + private final Foo.Bar.Zoo zoo = null; + + public Test1(@org.jetbrains.annotations.NotNull() + Foo.Bar.Zoo zoo) { + super(); + } + + @org.jetbrains.annotations.NotNull() + public final Foo.Bar.Zoo getZoo() { + return null; + } + + @org.jetbrains.annotations.NotNull() + public final java.lang.Thread.State a() { + return null; + } + + public final void b(@org.jetbrains.annotations.NotNull() + JavaClass.Foo foo, @org.jetbrains.annotations.NotNull() + JavaClass.Foo.Bar bar) { + } +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage.kt b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage.kt index b10777f1f09..22d71e13f2c 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: test/JavaClass.java package test; diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt new file mode 100644 index 00000000000..d720558f1e6 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nestedClassesNonRootPackage_ir.txt @@ -0,0 +1,287 @@ +package test; + +import java.lang.System; + +@kotlin.Metadata() +public final class A$B { + @kotlin.jvm.JvmField() + public test.A$B.C c; + @kotlin.jvm.JvmField() + public test.A$B.D$E de; + @kotlin.jvm.JvmField() + public test.J$B.C jc; + @kotlin.jvm.JvmField() + public test.J$B.D$E jde; + @kotlin.jvm.JvmField() + public test.A$B.D$$E dee; + @kotlin.jvm.JvmField() + public test.A$B.D$$$E deee; + @kotlin.jvm.JvmField() + public test.J$B.D$$E jdee; + @kotlin.jvm.JvmField() + public test.J$B.D$$$E jdeee; + + public A$B() { + super(); + } + + @kotlin.Metadata() + public static final class C { + + public C() { + super(); + } + } + + @kotlin.Metadata() + public static final class D$E { + @kotlin.jvm.JvmField() + public test.A$B.D$E.F f; + @kotlin.jvm.JvmField() + public test.A$B.D$E.F$G fg; + @kotlin.jvm.JvmField() + public test.J$B.D$E.F jf; + @kotlin.jvm.JvmField() + public test.J$B.D$E.F$G jfg; + + public D$E() { + super(); + } + + @kotlin.Metadata() + public static final class F { + + public F() { + super(); + } + } + + @kotlin.Metadata() + public static final class F$G { + + public F$G() { + super(); + } + } + } + + @kotlin.Metadata() + public static final class D$$E { + + public D$$E() { + super(); + } + } + + @kotlin.Metadata() + public static final class D$$$E { + + public D$$$E() { + super(); + } + } +} + +//////////////////// + +package test; + +import java.lang.System; + +@kotlin.Metadata() +public final class Experiment { + + public Experiment() { + super(); + } + + @kotlin.Metadata() + @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) + public static abstract @interface Type { + } + + @kotlin.Metadata() + @test.Experiment.Type() + public static final class Group { + + @org.jetbrains.annotations.NotNull() + public final test.Experiment.Group copy(@org.jetbrains.annotations.NotNull() + java.lang.String s) { + return null; + } + + public Group(@org.jetbrains.annotations.NotNull() + java.lang.String s) { + super(); + } + } +} + +//////////////////// + +package test; + +import java.lang.System; + +@kotlin.Metadata() +public final class Foo { + + public Foo() { + super(); + } + + @kotlin.Metadata() + public static class Bar { + + public Bar() { + super(); + } + + @kotlin.Metadata() + public static final class Zoo { + @org.jetbrains.annotations.NotNull() + public static final test.Foo.Bar.Zoo INSTANCE = null; + + private Zoo() { + super(); + } + } + } +} + +//////////////////// + +package test; + +import java.lang.System; + +@kotlin.Metadata() +public abstract interface IFoo { + + @kotlin.Metadata() + public static abstract interface IBar { + + @kotlin.Metadata() + @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) + public static abstract @interface Anno { + + public abstract java.lang.Class[] value(); + } + + @kotlin.Metadata() + @test.IFoo.IBar.Anno(value = {test.IFoo.IBar.IZoo.class}) + public static abstract interface IZoo { + } + } +} + +//////////////////// + +package test; + +public class J$B { + + public J$B() { + super(); + } + + public class C { + + public C() { + super(); + } + } + + public class D$E { + + public D$E() { + super(); + } + + class F { + + F() { + super(); + } + } + + class F$G { + + F$G() { + super(); + } + } + } + + public class D$$E { + + public D$$E() { + super(); + } + } + + public class D$$$E { + + public D$$$E() { + super(); + } + } +} + +//////////////////// + +package test; + +class JavaClass { + + JavaClass() { + super(); + } + + class Foo { + + Foo() { + super(); + } + + class Bar { + + Bar() { + super(); + } + } + } +} + +//////////////////// + +package test; + +import java.lang.System; + +@kotlin.Metadata() +@test.IFoo.IBar.Anno(value = {test.IFoo.IBar.IZoo.class, test.Foo.Bar.class}) +public final class Test1 extends test.Foo.Bar implements test.IFoo.IBar, test.IFoo.IBar.IZoo { + @org.jetbrains.annotations.NotNull() + private final test.Foo.Bar.Zoo zoo = null; + + public Test1(@org.jetbrains.annotations.NotNull() + test.Foo.Bar.Zoo zoo) { + super(); + } + + @org.jetbrains.annotations.NotNull() + public final test.Foo.Bar.Zoo getZoo() { + return null; + } + + @org.jetbrains.annotations.NotNull() + public final java.lang.Thread.State a() { + return null; + } + + public final void b(@org.jetbrains.annotations.NotNull() + test.JavaClass.Foo foo, @org.jetbrains.annotations.NotNull() + test.JavaClass.Foo.Bar bar) { + } +}