Calculate empty array literal types in FIR2IR instead of deserializer
This commit handles situations when some annotation in deserialized code has an empty array literal argument [] or even non-empty [something]. Before this commit, we tried to guess a type of this array by "resolving" the relevant annotation class and looking into the corresponding parameter. Sometimes it can work, but also it can provoke recursive resolve e.g. when the annotation class is a nested class in the same scope. In this commit we changed the behavior in the following way: - first, for non-empty array literals in deserialized code we just take the array type from the corresponding array literal element - second, for empty array literals we no more try to "guess" anything. Instead we approximate array type as Array<Any>, and later at FIR2IR stage we use the corresponding parameter type instead. At FIR2IR stage, everything is already resolved and problems with recursions are no more possible. #KT-62598 Fixed
This commit is contained in:
committed by
Space Team
parent
19a95f2fb4
commit
290adda8fc
+12
@@ -533,6 +533,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
@@ -19574,6 +19580,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
|
||||
runTest("compiler/testData/codegen/box/fir/selectingLambdas.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("StackOverflowInAnnotationLoader.kt")
|
||||
public void testStackOverflowInAnnotationLoader() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("staticImportFromEnum.kt")
|
||||
public void testStaticImportFromEnum() throws Exception {
|
||||
|
||||
+12
@@ -533,6 +533,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
@@ -19574,6 +19580,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
|
||||
runTest("compiler/testData/codegen/box/fir/selectingLambdas.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("StackOverflowInAnnotationLoader.kt")
|
||||
public void testStackOverflowInAnnotationLoader() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/StackOverflowInAnnotationLoader.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("staticImportFromEnum.kt")
|
||||
public void testStaticImportFromEnum() throws Exception {
|
||||
|
||||
@@ -774,12 +774,10 @@ fun IrActualizedResult?.extractFirDeclarations(): Set<FirDeclaration>? {
|
||||
|
||||
// This method is intended to be used for default values of annotation parameters (compile-time strings, numbers, enum values, KClasses)
|
||||
// where they are needed and may produce incorrect results for values that may be encountered outside annotations.
|
||||
fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents): IrExpressionBody? {
|
||||
return when (val elem = this.accept(Fir2IrVisitor(components, Fir2IrConversionScope(components.configuration)), null)) {
|
||||
is IrExpressionBody -> elem
|
||||
is IrExpression -> components.irFactory.createExpressionBody(elem)
|
||||
else -> null
|
||||
}
|
||||
fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents, expectedType: ConeKotlinType? = null): IrExpressionBody {
|
||||
val visitor = Fir2IrVisitor(components, Fir2IrConversionScope(components.configuration))
|
||||
val expression = visitor.convertToIrExpression(this, expectedType = expectedType)
|
||||
return components.irFactory.createExpressionBody(expression)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -894,7 +894,12 @@ class Fir2IrVisitor(
|
||||
|
||||
internal fun convertToIrExpression(
|
||||
expression: FirExpression,
|
||||
isDelegate: Boolean = false
|
||||
isDelegate: Boolean = false,
|
||||
// This argument is used for a corner case with deserialized empty array literals
|
||||
// These array literals normally have a type of Array<Any>,
|
||||
// so FIR2IR should instead use a type of corresponding property
|
||||
// See also KT-62598
|
||||
expectedType: ConeKotlinType? = null,
|
||||
): IrExpression {
|
||||
return when (expression) {
|
||||
is FirBlock -> expression.convertToIrExpressionOrBlock(
|
||||
@@ -908,6 +913,7 @@ class Fir2IrVisitor(
|
||||
else -> {
|
||||
when (val unwrappedExpression = expression.unwrapArgument()) {
|
||||
is FirCallableReferenceAccess -> convertCallableReferenceAccess(unwrappedExpression, isDelegate)
|
||||
is FirArrayLiteral -> convertToArrayLiteral(unwrappedExpression, expectedType)
|
||||
else -> expression.accept(this, null) as IrExpression
|
||||
}
|
||||
}
|
||||
@@ -1577,9 +1583,13 @@ class Fir2IrVisitor(
|
||||
classifierStorage.getOrCreateIrClass(it).symbol
|
||||
}
|
||||
|
||||
private fun convertToArrayLiteral(arrayLiteral: FirArrayLiteral): IrVararg {
|
||||
private fun convertToArrayLiteral(
|
||||
arrayLiteral: FirArrayLiteral,
|
||||
// See comment to convertToIrExpression
|
||||
expectedType: ConeKotlinType?,
|
||||
): IrVararg {
|
||||
return arrayLiteral.convertWithOffsets { startOffset, endOffset ->
|
||||
val arrayType = arrayLiteral.resolvedType.toIrType()
|
||||
val arrayType = (expectedType ?: arrayLiteral.resolvedType).toIrType()
|
||||
val elementType = arrayType.getArrayElementType(irBuiltIns)
|
||||
IrVarargImpl(
|
||||
startOffset, endOffset,
|
||||
@@ -1590,10 +1600,6 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitArrayLiteral(arrayLiteral: FirArrayLiteral, data: Any?): IrElement = whileAnalysing(session, arrayLiteral) {
|
||||
return convertToArrayLiteral(arrayLiteral)
|
||||
}
|
||||
|
||||
override fun visitAugmentedArraySetCall(
|
||||
augmentedArraySetCall: FirAugmentedArraySetCall,
|
||||
data: Any?
|
||||
|
||||
+10
-3
@@ -1032,10 +1032,17 @@ class CallAndReferenceGenerator(
|
||||
parameter: FirValueParameter?,
|
||||
substitutor: ConeSubstitutor,
|
||||
): IrExpression {
|
||||
var irArgument = visitor.convertToIrExpression(argument)
|
||||
if (parameter != null) {
|
||||
val parameterConeType = parameter?.returnTypeRef?.coneType
|
||||
// Normally argument type should be correct itself.
|
||||
// However, for deserialized annotations it's possible to have imprecise Array<Any> type
|
||||
// for empty integer literal arguments.
|
||||
// In this case we have to use parameter type itself which is more precise, like Array<String> or IntArray.
|
||||
// See KT-62598 and its fix for details.
|
||||
val expectedType = parameterConeType.takeIf { visitor.annotationMode && parameterConeType?.isArrayType == true }
|
||||
var irArgument = visitor.convertToIrExpression(argument, expectedType = expectedType)
|
||||
if (parameterConeType != null) {
|
||||
with(visitor.implicitCastInserter) {
|
||||
irArgument = irArgument.cast(argument, argument.resolvedType, parameter.returnTypeRef.coneType)
|
||||
irArgument = irArgument.cast(argument, argument.resolvedType, parameterConeType)
|
||||
}
|
||||
}
|
||||
with(adapterGenerator) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.resolvedType
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -95,7 +96,9 @@ class Fir2IrLazyProperty(
|
||||
private fun toIrInitializer(initializer: FirExpression?): IrExpressionBody? {
|
||||
// Annotations need full initializer information to instantiate them correctly
|
||||
return when {
|
||||
containingClass?.classKind?.isAnnotationClass == true -> initializer?.asCompileTimeIrInitializer(components)
|
||||
containingClass?.classKind?.isAnnotationClass == true -> initializer?.asCompileTimeIrInitializer(
|
||||
components, fir.returnTypeRef.coneType
|
||||
)
|
||||
// Setting initializers to every other class causes some cryptic errors in lowerings
|
||||
initializer is FirConstExpression<*> -> {
|
||||
val constType = with(typeConverter) { initializer.resolvedType.toIrType() }
|
||||
|
||||
+6
@@ -534,6 +534,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
|
||||
+6
@@ -534,6 +534,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
|
||||
+6
@@ -534,6 +534,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
|
||||
+15
-23
@@ -7,18 +7,11 @@ package org.jetbrains.kotlin.fir.java.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.SpecialJvmAnnotations
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
|
||||
import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||
import org.jetbrains.kotlin.fir.java.createConstantOrError
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getRegularClassSymbolByClassId
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.getProperties
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
@@ -99,10 +92,22 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
|
||||
override fun visitEnd() {
|
||||
visitExpression(name, buildArrayLiteral {
|
||||
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||
// 1. Calculate array literal type using its element, if any
|
||||
// 2. If array literal is empty, try to "guess" type (works only for default values)
|
||||
// 3. If both ways don't work, use Array<Any> as an approximation; later FIR2IR will calculate more precise type
|
||||
// See KT-62598
|
||||
// Note: we suppose that (1) can be dropped without real semantic changes;
|
||||
// in this case array literal argument types will be always Array<Any> at FIR level (even for non-empty literals),
|
||||
// but at IR level we will still have a real array type, like Array<String> or IntArray
|
||||
// Maybe we can drop also (2), see KT-62929, with the same consequences
|
||||
// Anyway, FIR provides no guarantees on having exact type of deserialized array literals in annotations,
|
||||
// including non-empty ones.
|
||||
elements.firstOrNull()?.coneTypeOrNull?.createOutArrayType()?.let {
|
||||
coneTypeOrNull = it
|
||||
} ?: guessArrayTypeIfNeeded(name, elements)?.let {
|
||||
coneTypeOrNull = it.coneTypeOrNull
|
||||
} ?: run {
|
||||
coneTypeOrNull = StandardClassIds.Any.constructClassLikeType().createOutArrayType()
|
||||
}
|
||||
argumentList = buildArgumentList {
|
||||
arguments += elements
|
||||
@@ -136,7 +141,6 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
|
||||
|
||||
return object : AnnotationsLoaderVisitorImpl(enumEntryReferenceCreator) {
|
||||
private val argumentMap = mutableMapOf<Name, FirExpression>()
|
||||
private val scopeSession: ScopeSession = ScopeSession()
|
||||
|
||||
override fun visitExpression(name: Name?, expr: FirExpression) {
|
||||
if (name != null) argumentMap[name] = expr
|
||||
@@ -145,21 +149,9 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
|
||||
override val visitNullNames: Boolean = false
|
||||
|
||||
override fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List<FirExpression>): FirTypeRef? {
|
||||
// Needed if we load a default value which is another annotation that has array value in it. e.g.:
|
||||
// To instantiate Deprecated() we need a default value for ReplaceWith() that has imports: Array<String> with default value [].
|
||||
if (name == null) return null
|
||||
// Note: generally we are not allowed to resolve anything, as this is might lead to recursive resolve problems
|
||||
// However, K1 deserializer did exactly the same and no issues were reported.
|
||||
val classSymbol = session.symbolProvider.getRegularClassSymbolByClassId(annotationClassId) ?: return null
|
||||
// We need to enhance java classes, but we can't call unsubstitutedScope unconditionally because
|
||||
// for Kotlin types, it will resolve the class to the SUPER_TYPES phase which can lead to a contract violation.
|
||||
val scope = if (classSymbol.isJavaOrEnhancement) {
|
||||
classSymbol.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false, memberRequiredPhase = null)
|
||||
} else {
|
||||
classSymbol.declaredMemberScope(session, memberRequiredPhase = null)
|
||||
}
|
||||
val propS = scope.getProperties(name).firstOrNull()
|
||||
return propS?.resolvedReturnTypeRef
|
||||
// Array<Any> will be created, later FIR2IR will use more precise type
|
||||
// See KT-62598
|
||||
return null
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
|
||||
Vendored
+110
@@ -0,0 +1,110 @@
|
||||
Module: lib
|
||||
FILE fqName:a fileName:/AnnotationInstantiationWithArrayLib.kt
|
||||
CLASS ANNOTATION_CLASS name:Outer modality:OPEN visibility:public superTypes:[kotlin.Annotation]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:a.Outer
|
||||
CONSTRUCTOR visibility:public <> (array:kotlin.Array<a.Outer.Inner>) returnType:a.Outer [primary]
|
||||
VALUE_PARAMETER name:array index:0 type:kotlin.Array<a.Outer.Inner>
|
||||
EXPRESSION_BODY
|
||||
VARARG type=kotlin.Array<a.Outer.Inner> varargElementType=a.Outer.Inner
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (v: kotlin.IntArray) declared in a.Outer.Inner' type=a.Outer.Inner origin=null
|
||||
v: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
CONST Int type=kotlin.Int value=1
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (v: kotlin.IntArray) declared in a.Outer.Inner' type=a.Outer.Inner origin=null
|
||||
v: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
CONST Int type=kotlin.Int value=2
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (v: kotlin.IntArray) declared in a.Outer.Inner' type=a.Outer.Inner origin=null
|
||||
v: VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:Outer modality:OPEN visibility:public superTypes:[kotlin.Annotation]'
|
||||
PROPERTY name:array visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:array type:kotlin.Array<a.Outer.Inner> visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'array: kotlin.Array<a.Outer.Inner> declared in a.Outer.<init>' type=kotlin.Array<a.Outer.Inner> origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-array> visibility:public modality:FINAL <> ($this:a.Outer) returnType:kotlin.Array<a.Outer.Inner>
|
||||
correspondingProperty: PROPERTY name:array visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:a.Outer
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-array> (): kotlin.Array<a.Outer.Inner> declared in a.Outer'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:array type:kotlin.Array<a.Outer.Inner> visibility:private [final]' type=kotlin.Array<a.Outer.Inner> origin=null
|
||||
receiver: GET_VAR '<this>: a.Outer declared in a.Outer.<get-array>' type=a.Outer origin=null
|
||||
CLASS ANNOTATION_CLASS name:Inner modality:OPEN visibility:public superTypes:[kotlin.Annotation]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:a.Outer.Inner
|
||||
CONSTRUCTOR visibility:public <> (v:kotlin.IntArray) returnType:a.Outer.Inner [primary]
|
||||
VALUE_PARAMETER name:v index:0 type:kotlin.IntArray
|
||||
EXPRESSION_BODY
|
||||
VARARG type=kotlin.IntArray varargElementType=kotlin.Int
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:Inner modality:OPEN visibility:public superTypes:[kotlin.Annotation]'
|
||||
PROPERTY name:v visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:v type:kotlin.IntArray visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'v: kotlin.IntArray declared in a.Outer.Inner.<init>' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-v> visibility:public modality:FINAL <> ($this:a.Outer.Inner) returnType:kotlin.IntArray
|
||||
correspondingProperty: PROPERTY name:v visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:a.Outer.Inner
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-v> (): kotlin.IntArray declared in a.Outer.Inner'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:v type:kotlin.IntArray visibility:private [final]' type=kotlin.IntArray origin=null
|
||||
receiver: GET_VAR '<this>: a.Outer.Inner declared in a.Outer.Inner.<get-v>' type=a.Outer.Inner origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||
overridden:
|
||||
public open fun hashCode (): kotlin.Int declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||
overridden:
|
||||
public open fun hashCode (): kotlin.Int declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Annotation
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
Module: app
|
||||
FILE fqName:test fileName:/AnnotationInstantiationWithArrayApp.kt
|
||||
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:test.C
|
||||
CONSTRUCTOR visibility:public <> () returnType:test.C [primary]
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]'
|
||||
FUN name:six visibility:public modality:FINAL <> ($this:test.C) returnType:a.Outer
|
||||
$this: VALUE_PARAMETER name:<this> type:test.C
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun six (): a.Outer declared in test.C'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (array: kotlin.Array<a.Outer.Inner>) declared in a.Outer' type=a.Outer origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||
overridden:
|
||||
public open fun hashCode (): kotlin.Int declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
CALL 'public open fun toString (): kotlin.String declared in a.Outer' type=kotlin.String origin=null
|
||||
$this: CALL 'public final fun six (): a.Outer declared in test.C' type=a.Outer origin=null
|
||||
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in test.C' type=test.C origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in test'
|
||||
CONST String type=kotlin.String value="OK"
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// FIR_IDENTICAL
|
||||
// DUMP_IR
|
||||
// WITH_STDLIB
|
||||
// ISSUE: KT-62598
|
||||
// This test is a simplified version of annotations/instances/multimoduleCreation.kt with potential deserialized annotation resolve problems
|
||||
|
||||
// MODULE: lib
|
||||
// FILE: AnnotationInstantiationWithArrayLib.kt
|
||||
|
||||
package a
|
||||
|
||||
annotation class Outer(
|
||||
val array: Array<Inner> = [Inner([1]), Inner([2]), Inner([])]
|
||||
) {
|
||||
annotation class Inner(val v: IntArray = [])
|
||||
}
|
||||
|
||||
// MODULE: app(lib)
|
||||
// FILE: AnnotationInstantiationWithArrayApp.kt
|
||||
|
||||
package test
|
||||
|
||||
import a.*
|
||||
|
||||
class C {
|
||||
fun six(): Outer = Outer()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
C().six().toString()
|
||||
return "OK"
|
||||
}
|
||||
@@ -52,7 +52,6 @@ interface HolderWithEmpty {
|
||||
import Holder
|
||||
import ByteHolder
|
||||
import HolderWithDefault
|
||||
// This line still provokes SOE in K2
|
||||
//import HolderWithEmpty
|
||||
import HolderWithEmpty
|
||||
|
||||
fun box() = "OK"
|
||||
|
||||
+6
@@ -534,6 +534,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
|
||||
+6
@@ -534,6 +534,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
|
||||
+5
@@ -483,6 +483,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationInstantiationWithArray.kt")
|
||||
public void testAnnotationInstantiationWithArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/AnnotationInstantiationWithArray.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationJvmHashCode.kt")
|
||||
public void testAnnotationJvmHashCode() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationJvmHashCode.kt");
|
||||
|
||||
Reference in New Issue
Block a user