Introduce & use FirJvmSerializerExtension & FirBasedClassCodegen

#KT-38156 In Process
This commit is contained in:
Mikhail Glukhikh
2020-04-15 12:48:19 +03:00
parent 7ae98485b8
commit c6c848f929
147 changed files with 663 additions and 174 deletions
@@ -8,6 +8,8 @@ dependencies {
compile(project(":compiler:fir:cones"))
compile(project(":compiler:fir:tree"))
compile(project(":compiler:fir:resolve"))
compileOnly(project(":compiler:ir.tree"))
compileOnly(project(":compiler:fir:fir2ir"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) }
}
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
@@ -51,7 +53,8 @@ class FirElementSerializer private constructor(
) {
private val contractSerializer = FirContractSerializer()
fun classProto(klass: FirClass<*>): ProtoBuf.Class.Builder {
fun classProto(irClass: IrClass): ProtoBuf.Class.Builder {
val klass = (irClass.metadata as FirMetadataSource.Class).klass
val builder = ProtoBuf.Class.newBuilder()
val regularClass = klass as? FirRegularClass
@@ -143,7 +146,7 @@ class FirElementSerializer private constructor(
builder.addAllVersionRequirement(versionRequirementTable.serializeVersionRequirements(klass))
extension.serializeClass(klass, builder, versionRequirementTable, this)
extension.serializeClass(irClass, builder, versionRequirementTable, this)
writeVersionRequirementForInlineClasses(klass, builder, versionRequirementTable)
@@ -545,11 +548,11 @@ class FirElementSerializer private constructor(
fillFromPossiblyInnerType(builder, type)
}
is ConeTypeParameterType -> {
// TODO: type parameter containing declaration?
if (false /*descriptor.containingDeclaration === containingDeclaration*/) {
//builder.typeParameterName = getSimpleNameIndex(descriptor.name)
val typeParameter = type.lookupTag.typeParameterSymbol.fir
if (typeParameter in (containingDeclaration as? FirMemberDeclaration)?.typeParameters ?: emptyList()) {
builder.typeParameterName = getSimpleNameIndex(typeParameter.name)
} else {
builder.typeParameter = getTypeParameterId(type.lookupTag.typeParameterSymbol.fir)
builder.typeParameter = getTypeParameterId(typeParameter)
}
}
}
@@ -636,7 +639,7 @@ class FirElementSerializer private constructor(
typeTable, versionRequirementTable, serializeTypeTableToFunction = false
)
private val stringTable: FirElementAwareStringTable
val stringTable: FirElementAwareStringTable
get() = extension.stringTable
private fun useTypeTable(): Boolean = extension.shouldUseTypeTable()
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
@@ -35,7 +36,7 @@ abstract class FirSerializerExtension {
}
open fun serializeClass(
klass: FirClass<*>,
klass: IrClass,
proto: ProtoBuf.Class.Builder,
versionRequirementTable: MutableVersionRequirementTable,
childSerializer: FirElementSerializer
-1
View File
@@ -7,7 +7,6 @@ dependencies {
compileOnly(project(":core:descriptors"))
compileOnly(project(":compiler:fir:cones"))
compileOnly(project(":compiler:fir:resolve"))
compileOnly(project(":compiler:fir:fir-serialization"))
compileOnly(project(":compiler:fir:tree"))
compileOnly(project(":compiler:ir.tree"))
compileOnly(project(":compiler:ir.psi2ir"))
@@ -9,6 +9,7 @@ dependencies {
compileOnly(project(":compiler:fir:resolve"))
compileOnly(project(":compiler:fir:tree"))
compileOnly(project(":compiler:fir:fir2ir"))
compileOnly(project(":compiler:fir:fir-serialization"))
compileOnly(project(":compiler:ir.tree"))
compileOnly(project(":compiler:backend"))
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.backend.jvm
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.serialization.FirElementAwareStringTable
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
class FirJvmElementAwareStringTable(
private val typeMapper: KotlinTypeMapperBase,
nameResolver: JvmNameResolver? = null
) : JvmStringTable(nameResolver), FirElementAwareStringTable {
override fun getLocalClassIdReplacement(classLikeDeclaration: FirClassLikeDeclaration<*>): ClassId {
return when (classLikeDeclaration.symbol.classId.outerClassId) {
// TODO: how to determine parent declaration for FIR local class properly?
//is ClassifierDescriptorWithTypeParameters -> getLocalClassIdReplacement(container).createNestedClassId(descriptor.name)
// null -> {
// throw IllegalStateException(
// "getLocalClassIdReplacement should only be called for local classes: ${classLikeDeclaration.render()}"
// )
// }
else -> {
classLikeDeclaration.symbol.classId
// TODO: typeMapper.mapClass
//val fqName = FqName(typeMapper.mapClass(descriptor).internalName.replace('/', '.'))
//ClassId(fqName.parent(), FqName.topLevel(fqName.shortName()), true)
}
}
}
}
@@ -0,0 +1,404 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.backend.jvm
import org.jetbrains.kotlin.codegen.ClassBuilderMode
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirEffectiveVisibility
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.serialization.FirElementSerializer
import org.jetbrains.kotlin.fir.serialization.FirSerializerExtension
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
import org.jetbrains.kotlin.metadata.jvm.deserialization.ClassMapperLite
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmFlags
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_FQ_NAME
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method
class FirJvmSerializerExtension @JvmOverloads constructor(
override val session: FirSession,
private val bindings: JvmSerializationBindings,
state: GenerationState,
private val typeMapper: KotlinTypeMapperBase = state.typeMapper
) : FirSerializerExtension() {
private val globalBindings = state.globalSerializationBindings
override val stringTable = FirJvmElementAwareStringTable(typeMapper)
private val useTypeTable = state.useTypeTableInSerializer
private val moduleName = state.moduleName
private val classBuilderMode = state.classBuilderMode
private val isParamAssertionsDisabled = state.isParamAssertionsDisabled
private val unifiedNullChecks = state.unifiedNullChecks
override val metadataVersion = state.metadataVersion
private val jvmDefaultMode = state.jvmDefaultMode
override fun shouldUseTypeTable(): Boolean = useTypeTable
override fun shouldSerializeFunction(function: FirFunction<*>): Boolean {
return classBuilderMode != ClassBuilderMode.ABI ||
function !is FirSimpleFunction || function.visibility != Visibilities.PRIVATE
}
override fun shouldSerializeProperty(property: FirProperty): Boolean {
return classBuilderMode != ClassBuilderMode.ABI || property.visibility != Visibilities.PRIVATE
}
override fun shouldSerializeTypeAlias(typeAlias: FirTypeAlias): Boolean {
return classBuilderMode != ClassBuilderMode.ABI || typeAlias.visibility != Visibilities.PRIVATE
}
override fun shouldSerializeNestedClass(nestedClass: FirRegularClass): Boolean {
return classBuilderMode != ClassBuilderMode.ABI || nestedClass.effectiveVisibility != FirEffectiveVisibility.Private
}
override fun serializeClass(
klass: IrClass,
proto: ProtoBuf.Class.Builder,
versionRequirementTable: MutableVersionRequirementTable,
childSerializer: FirElementSerializer
) {
if (moduleName != JvmProtoBufUtil.DEFAULT_MODULE_NAME) {
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName))
}
//TODO: support local delegated properties in new defaults scheme
val containerAsmType =
if (klass is FirRegularClass && klass.classKind == ClassKind.INTERFACE) typeMapper.mapDefaultImpls(klass.descriptor)
else typeMapper.mapClass(klass.descriptor)
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable)
val firClass = (klass.metadata as FirMetadataSource.Class).klass
writeVersionRequirementForJvmDefaultIfNeeded(firClass, proto, versionRequirementTable)
if (jvmDefaultMode.forAllMethodsWithBody && klass is FirRegularClass && klass.classKind == ClassKind.INTERFACE) {
proto.setExtension(JvmProtoBuf.jvmClassFlags, JvmFlags.getClassFlags(true))
}
}
// Interfaces which have @JvmDefault members somewhere in the hierarchy need the compiler 1.2.40+
// so that the generated bridges in subclasses would call the super members correctly
private fun writeVersionRequirementForJvmDefaultIfNeeded(
klass: FirClass<*>,
builder: ProtoBuf.Class.Builder,
versionRequirementTable: MutableVersionRequirementTable
) {
if (klass is FirRegularClass && klass.classKind == ClassKind.INTERFACE) {
if (jvmDefaultMode == JvmDefaultMode.ENABLE && klass.declarations.any {
it is FirCallableMemberDeclaration<*> && it.annotations.any { annotationCall ->
val classId = annotationCall.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.classId
classId?.asSingleFqName() == JVM_DEFAULT_FQ_NAME
}
}) {
builder.addVersionRequirement(
DescriptorSerializer.writeVersionRequirement(
1,
2,
40,
ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION,
versionRequirementTable
)
)
}
if (jvmDefaultMode == JvmDefaultMode.ALL_INCOMPATIBLE) {
builder.addVersionRequirement(
DescriptorSerializer.writeVersionRequirement(
1,
4,
0,
ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION,
versionRequirementTable
)
)
}
}
}
override fun serializePackage(packageFqName: FqName, proto: ProtoBuf.Package.Builder) {
if (moduleName != JvmProtoBufUtil.DEFAULT_MODULE_NAME) {
proto.setExtension(JvmProtoBuf.packageModuleName, stringTable.getStringIndex(moduleName))
}
}
fun serializeJvmPackage(proto: ProtoBuf.Package.Builder, partAsmType: Type) {
writeLocalProperties(proto, partAsmType, JvmProtoBuf.packageLocalVariable)
}
private fun <MessageType : GeneratedMessageLite.ExtendableMessage<MessageType>, BuilderType : GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>> writeLocalProperties(
proto: BuilderType,
classAsmType: Type,
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Property>>
) {
// TODO
// val localVariables = CodegenBinding.getLocalDelegatedProperties(codegenBinding, classAsmType) ?: return
//
// for (localVariable in localVariables) {
// val propertyDescriptor = createFreeFakeLocalPropertyDescriptor(localVariable)
// val serializer = FirElementSerializer.createForLambda(this)
// proto.addExtension(extension, serializer.propertyProto(propertyDescriptor)?.build() ?: continue)
// }
}
override fun serializeFlexibleType(
type: ConeFlexibleType,
lowerProto: ProtoBuf.Type.Builder,
upperProto: ProtoBuf.Type.Builder
) {
lowerProto.flexibleTypeCapabilitiesId = stringTable.getStringIndex(JvmProtoBufUtil.PLATFORM_TYPE_ID)
if (type is ConeRawType) {
lowerProto.setExtension(JvmProtoBuf.isRaw, true)
// we write this Extension for compatibility with old compiler
upperProto.setExtension(JvmProtoBuf.isRaw, true)
}
}
override fun serializeType(type: ConeKotlinType, proto: ProtoBuf.Type.Builder) {
// TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead
// TODO: (FIR) ConeKotlinType does not store annotations, see KT-30066
// for (annotation in type.annotations) {
// proto.addExtension(JvmProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation))
// }
}
override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) {
for (annotation in typeParameter.annotations) {
proto.addExtension(JvmProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotation))
}
}
override fun serializeConstructor(
constructor: FirConstructor, proto: ProtoBuf.Constructor.Builder, childSerializer: FirElementSerializer
) {
val method = getBinding(METHOD_FOR_FIR_FUNCTION, constructor)
if (method != null) {
val signature = SignatureSerializer().methodSignature(constructor, method)
if (signature != null) {
proto.setExtension(JvmProtoBuf.constructorSignature, signature)
}
}
}
override fun serializeFunction(
function: FirFunction<*>,
proto: ProtoBuf.Function.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: FirElementSerializer
) {
val method = getBinding(METHOD_FOR_FIR_FUNCTION, function)
if (method != null) {
val signature = SignatureSerializer().methodSignature(function, method)
if (signature != null) {
proto.setExtension(JvmProtoBuf.methodSignature, signature)
}
}
if (function.needsInlineParameterNullCheckRequirement()) {
versionRequirementTable?.writeInlineParameterNullCheckRequirement(proto::addVersionRequirement)
}
}
private fun MutableVersionRequirementTable.writeInlineParameterNullCheckRequirement(add: (Int) -> Unit) {
if (unifiedNullChecks) {
// Since Kotlin 1.4, we generate a call to Intrinsics.checkNotNullParameter in inline functions which causes older compilers
// (earlier than 1.3.50) to crash because a functional parameter in this position can't be inlined
add(DescriptorSerializer.writeVersionRequirement(1, 3, 50, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, this))
}
}
private fun FirFunction<*>.needsInlineParameterNullCheckRequirement(): Boolean =
this is FirSimpleFunction && isInline && !isSuspend && !isParamAssertionsDisabled &&
!Visibilities.isPrivate(visibility) &&
(valueParameters.any { it.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.isBuiltinFunctionalType(session) == true } ||
receiverTypeRef?.coneTypeSafe<ConeKotlinType>()?.isBuiltinFunctionalType(session) == true)
override fun serializeProperty(
property: FirProperty,
proto: ProtoBuf.Property.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: FirElementSerializer
) {
val signatureSerializer = SignatureSerializer()
val getter = property.getter
val setter = property.setter
val getterMethod = if (getter == null) null else getBinding(METHOD_FOR_FIR_FUNCTION, getter)
val setterMethod = if (setter == null) null else getBinding(METHOD_FOR_FIR_FUNCTION, setter)
// TODO: FIR field metadata
//val field = getBinding(JvmSerializationBindings.FIELD_FOR_PROPERTY, property)
val syntheticMethod = getBinding(SYNTHETIC_METHOD_FOR_FIR_VARIABLE, property)
val signature = signatureSerializer.propertySignature(
property,
null, //field?.second,
null, //field?.first?.descriptor,
if (syntheticMethod != null) signatureSerializer.methodSignature(null, syntheticMethod) else null,
if (getterMethod != null) signatureSerializer.methodSignature(null, getterMethod) else null,
if (setterMethod != null) signatureSerializer.methodSignature(null, setterMethod) else null
)
if (signature != null) {
proto.setExtension(JvmProtoBuf.propertySignature, signature)
}
// TODO
// if (property.isJvmFieldPropertyInInterfaceCompanion() && versionRequirementTable != null) {
// proto.setExtension(JvmProtoBuf.flags, JvmFlags.getPropertyFlags(true))
//
// proto.addVersionRequirement(
// DescriptorSerializer.writeVersionRequirement(
// 1,
// 2,
// 70,
// ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION,
// versionRequirementTable
// )
// )
// }
if (getter?.needsInlineParameterNullCheckRequirement() == true || setter?.needsInlineParameterNullCheckRequirement() == true) {
versionRequirementTable?.writeInlineParameterNullCheckRequirement(proto::addVersionRequirement)
}
}
private fun PropertyDescriptor.isJvmFieldPropertyInInterfaceCompanion(): Boolean {
if (!JvmAbi.hasJvmFieldAnnotation(this)) return false
val container = containingDeclaration
if (!DescriptorUtils.isCompanionObject(container)) return false
val grandParent = (container as ClassDescriptor).containingDeclaration
return DescriptorUtils.isInterface(grandParent) || DescriptorUtils.isAnnotationClass(grandParent)
}
override fun serializeErrorType(type: ConeKotlinErrorType, builder: ProtoBuf.Type.Builder) {
if (classBuilderMode === ClassBuilderMode.KAPT3) {
builder.className = stringTable.getStringIndex(NON_EXISTENT_CLASS_NAME)
return
}
super.serializeErrorType(type, builder)
}
private fun <K, V> getBinding(slice: JvmSerializationBindings.SerializationMappingSlice<K, V>, key: K): V? =
bindings.get(slice, key) ?: globalBindings.get(slice, key)
private inner class SignatureSerializer {
fun methodSignature(function: FirFunction<*>?, method: Method): JvmProtoBuf.JvmMethodSignature? {
val builder = JvmProtoBuf.JvmMethodSignature.newBuilder()
if (function == null || (function as? FirSimpleFunction)?.name?.asString() != method.name) {
builder.name = stringTable.getStringIndex(method.name)
}
if (function == null || requiresSignature(function, method.descriptor)) {
builder.desc = stringTable.getStringIndex(method.descriptor)
}
return if (builder.hasName() || builder.hasDesc()) builder.build() else null
}
// We don't write those signatures which can be trivially reconstructed from already serialized data
// TODO: make JvmStringTable implement NameResolver and use JvmProtoBufUtil#getJvmMethodSignature instead
private fun requiresSignature(function: FirFunction<*>, desc: String): Boolean {
val sb = StringBuilder()
sb.append("(")
val receiverTypeRef = function.receiverTypeRef
if (receiverTypeRef != null) {
val receiverDesc = mapTypeDefault(receiverTypeRef) ?: return true
sb.append(receiverDesc)
}
for (valueParameter in function.valueParameters) {
val paramDesc = mapTypeDefault(valueParameter.returnTypeRef) ?: return true
sb.append(paramDesc)
}
sb.append(")")
val returnTypeRef = function.returnTypeRef
val returnTypeDesc = (mapTypeDefault(returnTypeRef)) ?: return true
sb.append(returnTypeDesc)
return sb.toString() != desc
}
private fun requiresSignature(property: FirProperty, desc: String): Boolean {
return desc != mapTypeDefault(property.returnTypeRef)
}
private fun mapTypeDefault(typeRef: FirTypeRef): String? {
val classId = typeRef.coneTypeSafe<ConeClassLikeType>()?.classId
return if (classId == null) null else ClassMapperLite.mapClass(classId.asString())
}
fun propertySignature(
property: FirProperty,
fieldName: String?,
fieldDesc: String?,
syntheticMethod: JvmProtoBuf.JvmMethodSignature?,
getter: JvmProtoBuf.JvmMethodSignature?,
setter: JvmProtoBuf.JvmMethodSignature?
): JvmProtoBuf.JvmPropertySignature? {
val signature = JvmProtoBuf.JvmPropertySignature.newBuilder()
if (fieldDesc != null) {
assert(fieldName != null) { "Field name shouldn't be null when there's a field type: $fieldDesc" }
signature.field = fieldSignature(property, fieldName!!, fieldDesc)
}
if (syntheticMethod != null) {
signature.syntheticMethod = syntheticMethod
}
if (getter != null) {
signature.getter = getter
}
if (setter != null) {
signature.setter = setter
}
return signature.build().takeIf { it.serializedSize > 0 }
}
fun fieldSignature(
property: FirProperty,
name: String,
desc: String
): JvmProtoBuf.JvmFieldSignature {
val builder = JvmProtoBuf.JvmFieldSignature.newBuilder()
if (property.name.asString() != name) {
builder.name = stringTable.getStringIndex(name)
}
if (requiresSignature(property, desc)) {
builder.desc = stringTable.getStringIndex(desc)
}
return builder.build()
}
}
companion object {
val METHOD_FOR_FIR_FUNCTION = JvmSerializationBindings.SerializationMappingSlice.create<FirFunction<*>, Method>()
val SYNTHETIC_METHOD_FOR_FIR_VARIABLE = JvmSerializationBindings.SerializationMappingSlice.create<FirVariable<*>, Method>()
}
}
@@ -7,21 +7,34 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
interface FirMetadataSource : MetadataSource {
val session: FirSession
class Class(
val klass: FirClass<*>, descriptor: WrappedClassDescriptor
) : MetadataSource.Class(descriptor), FirMetadataSource
) : MetadataSource.Class(descriptor), FirMetadataSource {
override val session: FirSession
get() = klass.session
}
class Function(
val function: FirFunction<*>, descriptor: FunctionDescriptor
) : MetadataSource.Function(descriptor), FirMetadataSource
) : MetadataSource.Function(descriptor), FirMetadataSource {
override val session: FirSession
get() = function.session
}
class Variable(
val variable: FirVariable<*>,
descriptor: PropertyDescriptor
) : MetadataSource.Property(descriptor), FirMetadataSource
) : MetadataSource.Property(descriptor), FirMetadataSource {
override val session: FirSession
get() = variable.session
}
}
+3
View File
@@ -5,6 +5,9 @@ plugins {
dependencies {
compile(project(":kotlin-annotations-jvm"))
compile(project(":compiler:fir:fir-serialization"))
compile(project(":compiler:fir:fir2ir"))
compile(project(":compiler:fir:fir2ir:jvm-backend"))
compile(project(":compiler:backend"))
compile(project(":compiler:ir.tree"))
compile(project(":compiler:ir.psi2ir"))
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
@@ -204,7 +205,11 @@ abstract class ClassCodegen protected constructor(
companion object {
fun getOrCreate(irClass: IrClass, context: JvmBackendContext, parentFunction: IrFunction? = null): ClassCodegen =
context.classCodegens.getOrPut(irClass) {
DescriptorBasedClassCodegen(irClass, context, parentFunction)
if (irClass.metadata is FirMetadataSource) {
FirBasedClassCodegen(irClass, context, parentFunction)
} else {
DescriptorBasedClassCodegen(irClass, context, parentFunction)
}
}.also {
assert(parentFunction == null || it.parentFunction == parentFunction) {
"inconsistent parent function for ${irClass.render()}:\n" +
@@ -217,6 +222,8 @@ abstract class ClassCodegen protected constructor(
name.splitToSequence('/').any { identifier -> identifier.any { it in JvmSimpleNameBacktickChecker.INVALID_CHARS } }
}
protected abstract fun bindFieldMetadata(field: IrField, fieldType: Type, fieldName: String)
private fun generateField(field: IrField) {
if (field.isFakeOverride) return
@@ -244,10 +251,7 @@ abstract class ClassCodegen protected constructor(
}.genAnnotations(field, fieldType, field.type)
}
val descriptor = field.metadata?.descriptor
if (descriptor != null) {
state.globalSerializationBindings.put(JvmSerializationBindings.FIELD_FOR_PROPERTY, descriptor, fieldType to fieldName)
}
bindFieldMetadata(field, fieldType, fieldName)
}
private val generatedInlineMethods = mutableMapOf<IrFunction, SMAPAndMethodNode>()
@@ -266,6 +270,8 @@ abstract class ClassCodegen protected constructor(
return SMAPAndMethodNode(copy, smap)
}
protected abstract fun bindMethodMetadata(method: IrFunction, signature: Method)
private fun generateMethod(method: IrFunction, classSMAP: DefaultSourceMapper) {
if (method.isFakeOverride) {
jvmSignatureClashDetector.trackFakeOverrideMethod(method)
@@ -299,24 +305,7 @@ abstract class ClassCodegen protected constructor(
jvmSignatureClashDetector.trackMethod(method, RawSignature(node.name, node.desc, MemberKind.METHOD))
val signature = Method(node.name, node.desc)
when (val metadata = method.metadata) {
is MetadataSource.Property -> {
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
// moved to DefaultImpls, origin is changed to DEFAULT_IMPLS
// TODO: fix origin somehow, because otherwise $annotations methods in interfaces also don't have ACC_SYNTHETIC
assert(method.name.asString().endsWith(JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX)) { method.dump() }
state.globalSerializationBindings.put(
JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY, metadata.descriptor, signature
)
}
is MetadataSource.Function -> {
visitor.serializationBindings.put(JvmSerializationBindings.METHOD_FOR_FUNCTION, metadata.descriptor, signature)
}
null -> {
}
else -> error("Incorrect metadata source $metadata for:\n${method.dump()}")
}
bindMethodMetadata(method, signature)
}
private fun generateInnerAndOuterClasses() {
@@ -9,17 +9,19 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.getPackageFragment
import org.jetbrains.kotlin.ir.util.isFileClass
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method
class DescriptorBasedClassCodegen internal constructor(
irClass: IrClass,
@@ -110,4 +112,31 @@ class DescriptorBasedClassCodegen internal constructor(
}
}
override fun bindMethodMetadata(method: IrFunction, signature: Method) {
when (val metadata = method.metadata) {
is MetadataSource.Property -> {
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
// moved to DefaultImpls, origin is changed to DEFAULT_IMPLS
// TODO: fix origin somehow, because otherwise $annotations methods in interfaces also don't have ACC_SYNTHETIC
assert(method.name.asString().endsWith(JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX)) { method.dump() }
state.globalSerializationBindings.put(
JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY, metadata.descriptor, signature
)
}
is MetadataSource.Function -> {
visitor.serializationBindings.put(JvmSerializationBindings.METHOD_FOR_FUNCTION, metadata.descriptor, signature)
}
null -> {
}
else -> error("Incorrect metadata source $metadata for:\n${method.dump()}")
}
}
override fun bindFieldMetadata(field: IrField, fieldType: Type, fieldName: String) {
val descriptor = field.metadata?.descriptor
if (descriptor != null) {
state.globalSerializationBindings.put(JvmSerializationBindings.FIELD_FOR_PROPERTY, descriptor, fieldType to fieldName)
}
}
}
@@ -0,0 +1,142 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmSerializerExtension
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
import org.jetbrains.kotlin.fir.serialization.FirElementSerializer
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isFileClass
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method
class FirBasedClassCodegen internal constructor(
irClass: IrClass,
context: JvmBackendContext,
parentFunction: IrFunction? = null
) : ClassCodegen(irClass, context, parentFunction) {
private val session = (irClass.metadata as FirMetadataSource).session
private val serializerExtension = FirJvmSerializerExtension(session, visitor.serializationBindings, state, typeMapper)
private val serializer: FirElementSerializer? =
when (val metadata = irClass.metadata) {
is FirMetadataSource.Class -> FirElementSerializer.create(
metadata.klass, serializerExtension, (parentClassCodegen as? FirBasedClassCodegen)?.serializer
)
is FirMetadataSource.Function -> FirElementSerializer.createForLambda(session, serializerExtension)
else -> null
}
private fun FirFunction<*>.copyToFreeAnonymousFunction(): FirAnonymousFunction {
val function = this
return buildAnonymousFunction {
session = function.session
symbol = FirAnonymousFunctionSymbol()
returnTypeRef = function.returnTypeRef
receiverTypeRef = function.receiverTypeRef
isLambda = false
valueParameters.addAll(function.valueParameters)
typeParameters.addAll(function.typeParameters.filterIsInstance<FirTypeParameter>())
}
}
override fun generateKotlinMetadataAnnotation() {
val localDelegatedProperties = (irClass.attributeOwnerId as? IrClass)?.let(context.localDelegatedProperties::get)
if (localDelegatedProperties != null && localDelegatedProperties.isNotEmpty()) {
state.bindingTrace.record(
CodegenBinding.DELEGATED_PROPERTIES_WITH_METADATA, type, localDelegatedProperties.map { it.descriptor }
)
}
// TODO: if `-Xmultifile-parts-inherit` is enabled, write the corresponding flag for parts and facades to [Metadata.extraInt].
var extraFlags = JvmAnnotationNames.METADATA_JVM_IR_FLAG
if (state.isIrWithStableAbi) {
extraFlags += JvmAnnotationNames.METADATA_JVM_IR_STABLE_ABI_FLAG
}
when (val metadata = irClass.metadata) {
is FirMetadataSource.Class -> {
val classProto = serializer!!.classProto(irClass).build()
writeKotlinMetadata(visitor, state, KotlinClassHeader.Kind.CLASS, extraFlags) {
AsmUtil.writeAnnotationData(it, classProto, serializer.stringTable as JvmStringTable)
}
assert(irClass !in context.classNameOverride) {
"JvmPackageName is not supported for classes: ${irClass.render()}"
}
}
is FirMetadataSource.Function -> {
val fakeAnonymousFunction = metadata.function.copyToFreeAnonymousFunction()
val functionProto = serializer!!.functionProto(fakeAnonymousFunction)?.build()
writeKotlinMetadata(visitor, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, extraFlags) {
if (functionProto != null) {
AsmUtil.writeAnnotationData(it, functionProto, serializer.stringTable as JvmStringTable)
}
}
}
else -> {
val entry = irClass.fileParent.fileEntry
if (entry is MultifileFacadeFileEntry) {
val partInternalNames = entry.partFiles.mapNotNull { partFile ->
val fileClass = partFile.declarations.singleOrNull { it.isFileClass } as IrClass?
if (fileClass != null) typeMapper.mapClass(fileClass).internalName else null
}
MultifileClassCodegenImpl.writeMetadata(
visitor, state, extraFlags, partInternalNames, type, irClass.fqNameWhenAvailable!!.parent()
)
} else {
writeSyntheticClassMetadata(visitor, state)
}
}
}
}
override fun bindMethodMetadata(method: IrFunction, signature: Method) {
when (val metadata = method.metadata) {
is FirMetadataSource.Variable -> {
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
// moved to DefaultImpls, origin is changed to DEFAULT_IMPLS
// TODO: fix origin somehow, because otherwise $annotations methods in interfaces also don't have ACC_SYNTHETIC
assert(method.name.asString().endsWith(JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX)) { method.dump() }
state.globalSerializationBindings.put(
FirJvmSerializerExtension.SYNTHETIC_METHOD_FOR_FIR_VARIABLE, metadata.variable, signature
)
}
is FirMetadataSource.Function -> {
visitor.serializationBindings.put(FirJvmSerializerExtension.METHOD_FOR_FIR_FUNCTION, metadata.function, signature)
}
null -> {
}
else -> error("Incorrect metadata source $metadata for:\n${method.dump()}")
}
}
override fun bindFieldMetadata(field: IrField, fieldType: Type, fieldName: String) {
// TODO
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_COROUTINES
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FULL_JDK
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,5 +1,4 @@
// !LANGUAGE: +FunctionTypesWithBigArity
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS, NATIVE
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_REFLECT
// SKIP_JDK6
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
import kotlin.reflect.full.primaryConstructor
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_REFLECT
// TARGET_BACKEND: JVM
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// "IOOBE: Invalid index 4, size is 4" for java.lang.reflect.ParameterizedType on Android
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
package test
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE

Some files were not shown because too many files have changed in this diff Show More