Prepare ClassBuilder for record components

^KT-43677 In Progress
This commit is contained in:
Denis.Zharkov
2020-11-26 13:06:29 +03:00
parent f6a3580c93
commit 26d525fa3c
6 changed files with 77 additions and 39 deletions
@@ -26,13 +26,13 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.*;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP; import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
public abstract class AbstractClassBuilder implements ClassBuilder { public abstract class AbstractClassBuilder implements ClassBuilder {
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {}; protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
public static final RecordComponentVisitor EMPTY_RECORD_VISITOR = new RecordComponentVisitor(Opcodes.API_VERSION) {};
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {}; protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
private String thisName; private String thisName;
@@ -91,6 +91,16 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
return visitor; return visitor;
} }
@NotNull
@Override
public RecordComponentVisitor newRecordComponent(@NotNull String name, @NotNull String desc, @Nullable String signature) {
RecordComponentVisitor visitor = getVisitor().visitRecordComponent(name, desc, signature);
if (visitor == null) {
return EMPTY_RECORD_VISITOR;
}
return visitor;
}
@Override @Override
@NotNull @NotNull
public JvmSerializationBindings getSerializationBindings() { public JvmSerializationBindings getSerializationBindings() {
@@ -19,14 +19,10 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.inline.FileMapping;
import org.jetbrains.kotlin.codegen.inline.SourceMapper; import org.jetbrains.kotlin.codegen.inline.SourceMapper;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings; import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor; import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.ClassVisitor;
import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
public interface ClassBuilder { public interface ClassBuilder {
@NotNull @NotNull
@@ -49,6 +45,12 @@ public interface ClassBuilder {
@Nullable String[] exceptions @Nullable String[] exceptions
); );
@NotNull RecordComponentVisitor newRecordComponent(
@NotNull String name,
@NotNull String desc,
@Nullable String signature
);
@NotNull @NotNull
JvmSerializationBindings getSerializationBindings(); JvmSerializationBindings getSerializationBindings();
@@ -19,14 +19,10 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.inline.FileMapping;
import org.jetbrains.kotlin.codegen.inline.SourceMapper; import org.jetbrains.kotlin.codegen.inline.SourceMapper;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings; import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor; import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.ClassVisitor;
import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
public abstract class DelegatingClassBuilder implements ClassBuilder { public abstract class DelegatingClassBuilder implements ClassBuilder {
@NotNull @NotNull
@@ -58,6 +54,14 @@ public abstract class DelegatingClassBuilder implements ClassBuilder {
return getDelegate().newMethod(origin, access, name, desc, signature, exceptions); return getDelegate().newMethod(origin, access, name, desc, signature, exceptions);
} }
@NotNull
@Override
public RecordComponentVisitor newRecordComponent(
@NotNull String name, @NotNull String desc, @Nullable String signature
) {
return getDelegate().newRecordComponent(name, desc, signature);
}
@NotNull @NotNull
@Override @Override
public JvmSerializationBindings getSerializationBindings() { public JvmSerializationBindings getSerializationBindings() {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.android.synthetic.codegen
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.android.parcel.isParcelize import org.jetbrains.kotlin.android.parcel.isParcelize
import org.jetbrains.kotlin.codegen.AbstractClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilderFactory import org.jetbrains.kotlin.codegen.ClassBuilderFactory
import org.jetbrains.kotlin.codegen.DelegatingClassBuilder import org.jetbrains.kotlin.codegen.DelegatingClassBuilder
@@ -26,8 +27,11 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.org.objectweb.asm.* 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.Opcodes.ACC_STATIC
import org.jetbrains.org.objectweb.asm.RecordComponentVisitor
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
class ParcelableClinitClassBuilderInterceptorExtension : ClassBuilderInterceptorExtension { class ParcelableClinitClassBuilderInterceptorExtension : ClassBuilderInterceptorExtension {
@@ -132,6 +136,10 @@ class ParcelableClinitClassBuilderInterceptorExtension : ClassBuilderInterceptor
return super.newMethod(origin, access, name, desc, signature, exceptions) return super.newMethod(origin, access, name, desc, signature, exceptions)
} }
override fun newRecordComponent(name: String, desc: String, signature: String?): RecordComponentVisitor {
return AbstractClassBuilder.EMPTY_RECORD_VISITOR
}
} }
private class ClinitAwareMethodVisitor(val parcelableName: String, mv: MethodVisitor) : MethodVisitor(Opcodes.API_VERSION, mv) { private class ClinitAwareMethodVisitor(val parcelableName: String, mv: MethodVisitor) : MethodVisitor(Opcodes.API_VERSION, mv) {
@@ -18,26 +18,30 @@ package org.jetbrains.kotlin.android.synthetic.codegen
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import kotlinx.android.extensions.CacheImplementation import kotlinx.android.extensions.CacheImplementation
import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension.Companion.CLEAR_CACHE_METHOD_NAME
import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension.Companion.ON_DESTROY_METHOD_NAME import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension.Companion.ON_DESTROY_METHOD_NAME
import org.jetbrains.kotlin.android.synthetic.descriptors.ContainerOptionsProxy import org.jetbrains.kotlin.android.synthetic.descriptors.ContainerOptionsProxy
import org.jetbrains.kotlin.codegen.AbstractClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilderFactory import org.jetbrains.kotlin.codegen.ClassBuilderFactory
import org.jetbrains.kotlin.codegen.DelegatingClassBuilder import org.jetbrains.kotlin.codegen.DelegatingClassBuilder
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.RecordComponentVisitor
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.android.synthetic.codegen.AbstractAndroidExtensionsExpressionCodegenExtension.Companion.CLEAR_CACHE_METHOD_NAME
import org.jetbrains.kotlin.psi.KtElement
abstract class AbstractAndroidOnDestroyClassBuilderInterceptorExtension : ClassBuilderInterceptorExtension { abstract class AbstractAndroidOnDestroyClassBuilderInterceptorExtension : ClassBuilderInterceptorExtension {
override fun interceptClassBuilderFactory( override fun interceptClassBuilderFactory(
interceptedFactory: ClassBuilderFactory, interceptedFactory: ClassBuilderFactory,
bindingContext: BindingContext, bindingContext: BindingContext,
diagnostics: DiagnosticSink diagnostics: DiagnosticSink
): ClassBuilderFactory { ): ClassBuilderFactory {
return AndroidOnDestroyClassBuilderFactory(interceptedFactory, bindingContext) return AndroidOnDestroyClassBuilderFactory(interceptedFactory, bindingContext)
} }
@@ -45,8 +49,8 @@ abstract class AbstractAndroidOnDestroyClassBuilderInterceptorExtension : ClassB
abstract fun getGlobalCacheImpl(element: KtElement): CacheImplementation abstract fun getGlobalCacheImpl(element: KtElement): CacheImplementation
private inner class AndroidOnDestroyClassBuilderFactory( private inner class AndroidOnDestroyClassBuilderFactory(
private val delegateFactory: ClassBuilderFactory, private val delegateFactory: ClassBuilderFactory,
val bindingContext: BindingContext val bindingContext: BindingContext
) : ClassBuilderFactory { ) : ClassBuilderFactory {
override fun newClassBuilder(origin: JvmDeclarationOrigin): ClassBuilder { override fun newClassBuilder(origin: JvmDeclarationOrigin): ClassBuilder {
@@ -69,8 +73,8 @@ abstract class AbstractAndroidOnDestroyClassBuilderInterceptorExtension : ClassB
} }
private inner class AndroidOnDestroyCollectorClassBuilder( private inner class AndroidOnDestroyCollectorClassBuilder(
internal val delegateClassBuilder: ClassBuilder, internal val delegateClassBuilder: ClassBuilder,
val bindingContext: BindingContext val bindingContext: BindingContext
) : DelegatingClassBuilder() { ) : DelegatingClassBuilder() {
private var currentClass: KtClass? = null private var currentClass: KtClass? = null
private var currentClassName: String? = null private var currentClassName: String? = null
@@ -78,13 +82,13 @@ abstract class AbstractAndroidOnDestroyClassBuilderInterceptorExtension : ClassB
override fun getDelegate() = delegateClassBuilder override fun getDelegate() = delegateClassBuilder
override fun defineClass( override fun defineClass(
origin: PsiElement?, origin: PsiElement?,
version: Int, version: Int,
access: Int, access: Int,
name: String, name: String,
signature: String?, signature: String?,
superName: String, superName: String,
interfaces: Array<out String> interfaces: Array<out String>
) { ) {
if (origin is KtClass) { if (origin is KtClass) {
currentClass = origin currentClass = origin
@@ -94,12 +98,12 @@ abstract class AbstractAndroidOnDestroyClassBuilderInterceptorExtension : ClassB
} }
override fun newMethod( override fun newMethod(
origin: JvmDeclarationOrigin, origin: JvmDeclarationOrigin,
access: Int, access: Int,
name: String, name: String,
desc: String, desc: String,
signature: String?, signature: String?,
exceptions: Array<out String>? exceptions: Array<out String>?
): MethodVisitor { ): MethodVisitor {
return object : MethodVisitor(Opcodes.API_VERSION, super.newMethod(origin, access, name, desc, signature, exceptions)) { return object : MethodVisitor(Opcodes.API_VERSION, super.newMethod(origin, access, name, desc, signature, exceptions)) {
override fun visitInsn(opcode: Int) { override fun visitInsn(opcode: Int) {
@@ -128,6 +132,10 @@ abstract class AbstractAndroidOnDestroyClassBuilderInterceptorExtension : ClassB
} }
} }
} }
override fun newRecordComponent(name: String, desc: String, signature: String?): RecordComponentVisitor {
return AbstractClassBuilder.EMPTY_RECORD_VISITOR
}
} }
} }
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.parcelize package org.jetbrains.kotlin.parcelize
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.AbstractClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilderFactory import org.jetbrains.kotlin.codegen.ClassBuilderFactory
import org.jetbrains.kotlin.codegen.DelegatingClassBuilder import org.jetbrains.kotlin.codegen.DelegatingClassBuilder
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
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.RecordComponentVisitor
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.InstructionAdapter
@@ -128,6 +130,10 @@ class ParcelizeClinitClassBuilderInterceptorExtension : ClassBuilderInterceptorE
return super.newMethod(origin, access, name, desc, signature, exceptions) return super.newMethod(origin, access, name, desc, signature, exceptions)
} }
override fun newRecordComponent(name: String, desc: String, signature: String?): RecordComponentVisitor {
return AbstractClassBuilder.EMPTY_RECORD_VISITOR
}
} }
private class ClinitAwareMethodVisitor(val parcelableName: String, mv: MethodVisitor) : MethodVisitor(Opcodes.API_VERSION, mv) { private class ClinitAwareMethodVisitor(val parcelableName: String, mv: MethodVisitor) : MethodVisitor(Opcodes.API_VERSION, mv) {