[FIR] add missing transformation of annotation type arguments

^KT-62679
This commit is contained in:
Dmitrii Gridin
2023-10-18 15:48:53 +02:00
committed by Space Team
parent 27c5a0b60d
commit 32ed81440c
6 changed files with 214 additions and 0 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
@@ -78,6 +79,14 @@ internal fun <T> checkAnnotationTypeIsResolved(annotationContainer: T) where T :
checkTypeRefIsResolved(annotation.annotationTypeRef, "annotation type", owner = annotationContainer) {
withFirEntry("firAnnotation", annotation)
}
annotation.typeArguments.forEach {
if (it is FirTypeProjectionWithVariance) {
checkTypeRefIsResolved(it.typeRef, "annotation type argument", owner = annotationContainer) {
withFirEntry("typeProjection", it)
}
}
}
}
}
@@ -0,0 +1,5 @@
annotation class Foo<T>(val s: String)
@Foo<Int>("")
fun <caret>foo() {
}
@@ -0,0 +1,186 @@
RAW_FIR:
FILE: [ResolvedTo(RAW_FIR)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@Foo<Int>[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
IMPORTS:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@Foo<Int>[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(RAW_FIR)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
COMPILER_REQUIRED_ANNOTATIONS:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@Foo<Int>[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
COMPANION_GENERATION:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@Foo<Int>[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(COMPANION_GENERATION)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
SUPER_TYPES:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@Foo<Int>[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(SUPER_TYPES)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
TYPES:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@R|Foo<kotlin/Int>|[Types](LAZY_EXPRESSION) public? final? [ResolvedTo(TYPES)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
STATUS:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@R|Foo<kotlin/Int>|[Types](LAZY_EXPRESSION) public final [ResolvedTo(STATUS)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
EXPECT_ACTUAL_MATCHING:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@R|Foo<kotlin/Int>|[Types](LAZY_EXPRESSION) public final [ResolvedTo(EXPECT_ACTUAL_MATCHING)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
ARGUMENTS_OF_ANNOTATIONS:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@R|Foo<kotlin/Int>|[Types](String()) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
CONTRACTS:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@R|Foo<kotlin/Int>|[Types](String()) public final [ResolvedTo(CONTRACTS)] fun foo(): R|kotlin/Unit| {
}
IMPLICIT_TYPES_BODY_RESOLVE:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public? final? [ResolvedTo(RAW_FIR)] annotation class Foo<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| {
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] constructor<[ResolvedTo(RAW_FIR)] T>([ResolvedTo(RAW_FIR)] [CorrespondingProperty=/Foo.s] s: String): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|<local>/s|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String
}
@R|Foo<kotlin/Int>|[Types](String()) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun foo(): R|kotlin/Unit| {
}
ANNOTATIONS_ARGUMENTS_MAPPING:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public final [ResolvedTo(STATUS)] annotation class Foo<[ResolvedTo(STATUS)] T> : R|kotlin/Annotation| {
public [ResolvedTo(STATUS)] [ContainingClassKey=Foo] constructor<[ResolvedTo(STATUS)] T>([ResolvedTo(STATUS)] [CorrespondingProperty=/Foo.s] s: R|kotlin/String|): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public final [ResolvedTo(STATUS)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|<local>/s|
public [ResolvedTo(STATUS)] [ContainingClassKey=Foo] get(): R|kotlin/String|
}
@R|Foo<kotlin/Int>|[Types](s = String()) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] fun foo(): R|kotlin/Unit| {
}
BODY_RESOLVE:
FILE: [ResolvedTo(IMPORTS)] typeArgumentInAnnotation.kt
public final [ResolvedTo(STATUS)] annotation class Foo<[ResolvedTo(STATUS)] T> : R|kotlin/Annotation| {
public [ResolvedTo(STATUS)] [ContainingClassKey=Foo] constructor<[ResolvedTo(STATUS)] T>([ResolvedTo(STATUS)] [CorrespondingProperty=/Foo.s] s: R|kotlin/String|): R|Foo<T>| {
LAZY_super<R|kotlin/Any|>
}
public final [ResolvedTo(STATUS)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|<local>/s|
public [ResolvedTo(STATUS)] [ContainingClassKey=Foo] get(): R|kotlin/String|
}
@R|Foo<kotlin/Int>|[Types](s = String()) public final [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit| {
}
FILE RAW TO BODY:
FILE: [ResolvedTo(BODY_RESOLVE)] typeArgumentInAnnotation.kt
public final [ResolvedTo(BODY_RESOLVE)] annotation class Foo<[ResolvedTo(BODY_RESOLVE)] T> : R|kotlin/Annotation| {
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Foo] constructor<[ResolvedTo(BODY_RESOLVE)] T>([ResolvedTo(BODY_RESOLVE)] [CorrespondingProperty=/Foo.s] s: R|kotlin/String|): R|Foo<T>| {
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|<local>/s|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Foo] get(): R|kotlin/String|
}
@R|Foo<kotlin/Int>|[Types](s = String()) public final [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit| {
}
@@ -821,6 +821,12 @@ public class FirOutOfContentRootLazyDeclarationResolveTestGenerated extends Abst
runTest("analysis/low-level-api-fir/testData/lazyResolve/functions/simpleLoopInOverride2.kt");
}
@Test
@TestMetadata("typeArgumentInAnnotation.kt")
public void testTypeArgumentInAnnotation() throws Exception {
runTest("analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.kt");
}
@Test
@TestMetadata("unresolvedAnnotationOnFunctionType.kt")
public void testUnresolvedAnnotationOnFunctionType() throws Exception {
@@ -821,6 +821,12 @@ public class FirSourceLazyDeclarationResolveTestGenerated extends AbstractFirSou
runTest("analysis/low-level-api-fir/testData/lazyResolve/functions/simpleLoopInOverride2.kt");
}
@Test
@TestMetadata("typeArgumentInAnnotation.kt")
public void testTypeArgumentInAnnotation() throws Exception {
runTest("analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.kt");
}
@Test
@TestMetadata("unresolvedAnnotationOnFunctionType.kt")
public void testUnresolvedAnnotationOnFunctionType() throws Exception {
@@ -355,6 +355,7 @@ open class FirTypeResolveTransformer(
else -> shouldNotBeCalled()
}
FirAnnotationResolvePhase.CompilerRequiredAnnotations -> {
annotationCall.transformTypeArguments(this, data)
annotationCall.replaceAnnotationResolvePhase(FirAnnotationResolvePhase.Types)
val alternativeResolvedTypeRef =
originalTypeRef.delegatedTypeRef?.transformSingle(this, data) ?: return annotationCall
@@ -378,6 +379,7 @@ open class FirTypeResolveTransformer(
}
else -> {
val transformedTypeRef = originalTypeRef.transformSingle(this, data)
annotationCall.transformTypeArguments(this, data)
annotationCall.replaceAnnotationResolvePhase(FirAnnotationResolvePhase.Types)
annotationCall.replaceAnnotationTypeRef(transformedTypeRef)
}