diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt index 7e50f6c1b52..be49ba13eaf 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firCheckResolvedUtils.kt @@ -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 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) + } + } + } } } diff --git a/analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.kt b/analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.kt new file mode 100644 index 00000000000..439307e5ae9 --- /dev/null +++ b/analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.kt @@ -0,0 +1,5 @@ +annotation class Foo(val s: String) + +@Foo("") +fun foo() { +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.txt b/analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.txt new file mode 100644 index 00000000000..8bd14b69665 --- /dev/null +++ b/analysis/low-level-api-fir/testData/lazyResolve/functions/typeArgumentInAnnotation.txt @@ -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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @Foo[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @Foo[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @Foo[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @Foo[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @Foo[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @R|Foo|[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @R|Foo|[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @R|Foo|[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @R|Foo|[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @R|Foo|[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| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Foo] get(): String + + } + @R|Foo|[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| { + LAZY_super + } + + public final [ResolvedTo(STATUS)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|/s| + public [ResolvedTo(STATUS)] [ContainingClassKey=Foo] get(): R|kotlin/String| + + } + @R|Foo|[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| { + LAZY_super + } + + public final [ResolvedTo(STATUS)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|/s| + public [ResolvedTo(STATUS)] [ContainingClassKey=Foo] get(): R|kotlin/String| + + } + @R|Foo|[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| { + super() + } + + public final [ResolvedTo(BODY_RESOLVE)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|/s| + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Foo] get(): R|kotlin/String| + + } + @R|Foo|[Types](s = String()) public final [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit| { + } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java index fc6b5b68e2b..08cdbfe4d3f 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java @@ -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 { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java index c37d23d2a08..0804a2d4bd5 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java @@ -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 { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index ef605afe2bf..7039293938e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -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) }