diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.kt b/analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.kt new file mode 100644 index 00000000000..71ebde1bc3e --- /dev/null +++ b/analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.kt @@ -0,0 +1,7 @@ +@file:[Deprecated("") Anno("anno")] +package one + +@Target(AnnotationTarget.FILE) +annotation class Anno(val s: String) + +// RESOLVE_FILE_ANNOTATIONS \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.txt b/analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.txt new file mode 100644 index 00000000000..1c8142022da --- /dev/null +++ b/analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.txt @@ -0,0 +1,209 @@ +RAW_FIR: +FILE: [ResolvedTo(RAW_FIR)] fileAnnotations.kt + @FILE:Deprecated[Unresolved](LAZY_EXPRESSION) + @FILE:Anno[Unresolved](LAZY_EXPRESSION) + [ResolvedTo(RAW_FIR)] annotations container + @Target[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(RAW_FIR)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +IMPORTS: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:Deprecated[Unresolved](LAZY_EXPRESSION) + @FILE:Anno[Unresolved](LAZY_EXPRESSION) + [ResolvedTo(RAW_FIR)] annotations container + @Target[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(RAW_FIR)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +COMPILER_REQUIRED_ANNOTATIONS: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:Deprecated[Unresolved](String()) + @FILE:Anno[Unresolved](LAZY_EXPRESSION) + [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] annotations container + @Target[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(RAW_FIR)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +COMPANION_GENERATION: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:Deprecated[Unresolved](String()) + @FILE:Anno[Unresolved](LAZY_EXPRESSION) + [ResolvedTo(COMPANION_GENERATION)] annotations container + @Target[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(RAW_FIR)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +SUPER_TYPES: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:Deprecated[Unresolved](String()) + @FILE:Anno[Unresolved](LAZY_EXPRESSION) + [ResolvedTo(SUPER_TYPES)] annotations container + @Target[Unresolved](LAZY_EXPRESSION) public? final? [ResolvedTo(RAW_FIR)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +TYPES: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](String()) + @FILE:R|one/Anno|[Types](LAZY_EXPRESSION) + [ResolvedTo(TYPES)] annotations container + @R|kotlin/annotation/Target|[CompilerRequiredAnnotations](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +STATUS: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](String()) + @FILE:R|one/Anno|[Types](LAZY_EXPRESSION) + [ResolvedTo(STATUS)] annotations container + @R|kotlin/annotation/Target|[CompilerRequiredAnnotations](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +EXPECT_ACTUAL_MATCHING: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](String()) + @FILE:R|one/Anno|[Types](LAZY_EXPRESSION) + [ResolvedTo(EXPECT_ACTUAL_MATCHING)] annotations container + @R|kotlin/annotation/Target|[CompilerRequiredAnnotations](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +ARGUMENTS_OF_ANNOTATIONS: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](String()) + @FILE:R|one/Anno|[Types](String(anno)) + [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotations container + @R|kotlin/annotation/Target|[CompilerRequiredAnnotations](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +CONTRACTS: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](String()) + @FILE:R|one/Anno|[Types](String(anno)) + [ResolvedTo(CONTRACTS)] annotations container + @R|kotlin/annotation/Target|[CompilerRequiredAnnotations](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +IMPLICIT_TYPES_BODY_RESOLVE: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](String()) + @FILE:R|one/Anno|[Types](String(anno)) + [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotations container + @R|kotlin/annotation/Target|[CompilerRequiredAnnotations](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] annotation class Anno : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] constructor([ResolvedTo(RAW_FIR)] [CorrespondingProperty=one/Anno.s] s: String): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +ANNOTATIONS_ARGUMENTS_MAPPING: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](message = String()) + @FILE:R|one/Anno|[Types](s = String(anno)) + [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] annotations container + @R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public final [ResolvedTo(STATUS)] annotation class Anno : R|kotlin/Annotation| { + public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] constructor([ResolvedTo(STATUS)] [CorrespondingProperty=one/Anno.s] s: R|kotlin/String|): R|one/Anno| { + LAZY_super + } + + public final [ResolvedTo(STATUS)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|/s| + public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] get(): R|kotlin/String| + + } + +BODY_RESOLVE: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](message = String()) + @FILE:R|one/Anno|[Types](s = String(anno)) + [ResolvedTo(BODY_RESOLVE)] annotations container + @R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|) public final [ResolvedTo(STATUS)] annotation class Anno : R|kotlin/Annotation| { + public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] constructor([ResolvedTo(STATUS)] [CorrespondingProperty=one/Anno.s] s: R|kotlin/String|): R|one/Anno| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] [IsFromPrimaryConstructor=true] val s: String = R|/s| + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Anno] get(): String + + } + +FILE RAW TO BODY: +FILE: [ResolvedTo(IMPORTS)] fileAnnotations.kt + @FILE:R|kotlin/Deprecated|[Types](message = String()) + @FILE:R|one/Anno|[Types](s = String(anno)) + [ResolvedTo(BODY_RESOLVE)] annotations container + @R|kotlin/annotation/Target|[Types](allowedTargets = vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FILE|)) public final [ResolvedTo(BODY_RESOLVE)] annotation class Anno : R|kotlin/Annotation| { + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Anno] constructor([ResolvedTo(BODY_RESOLVE)] [CorrespondingProperty=one/Anno.s] s: R|kotlin/String|): R|one/Anno| { + super() + } + + public final [ResolvedTo(BODY_RESOLVE)] [IsFromPrimaryConstructor=true] val s: R|kotlin/String| = R|/s| + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Anno] get(): R|kotlin/String| + + } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt index bd6972c9c5c..ac61d7e228d 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt @@ -5,10 +5,14 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.asResolveTarget +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirOutOfContentRootTestConfigurator import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator +import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyResolverRunner import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase @@ -50,13 +54,28 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractLowLevelApiSingle resolveWithClearCaches(ktFile) { firResolveSession -> check(firResolveSession.isSourceSession) - val ktDeclaration = testServices.expressionMarkerProvider.getElementOfTypeAtCaret(ktFile) - val declarationSymbol = ktDeclaration.resolveToFirSymbol(firResolveSession) - val declarationToResolve = chooseMemberDeclarationIfNeeded(declarationSymbol, moduleStructure) + val resolver = if (Directives.RESOLVE_FILE_ANNOTATIONS in moduleStructure.allDirectives) { + val annotationContainer = firResolveSession.getOrBuildFirFile(ktFile).annotationsContainer + val session = annotationContainer.moduleData.session as LLFirResolvableModuleSession + fun(phase: FirResolvePhase) { + session.moduleComponents.firModuleLazyDeclarationResolver.lazyResolve( + annotationContainer, + session.getScopeSession(), + phase, + ) + } + } else { + val ktDeclaration = testServices.expressionMarkerProvider.getElementOfTypeAtCaret(ktFile) + val declarationSymbol = ktDeclaration.resolveToFirSymbol(firResolveSession) + val firDeclaration = chooseMemberDeclarationIfNeeded(declarationSymbol, moduleStructure) + fun(phase: FirResolvePhase) { + firDeclaration.lazyResolveToPhase(phase) + } + } for (currentPhase in FirResolvePhase.values()) { if (currentPhase == FirResolvePhase.SEALED_CLASS_INHERITORS) continue - declarationToResolve.lazyResolveToPhase(currentPhase) + resolver(currentPhase) val firFile = firResolveSession.getOrBuildFirFile(ktFile) if (resultBuilder.isNotEmpty()) { @@ -124,6 +143,8 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractLowLevelApiSingle symbol.name() == value } } + + val RESOLVE_FILE_ANNOTATIONS by directive("Resolve file annotations instead of declaration at caret") } } 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 5800787467c..7fc16585b08 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 @@ -180,6 +180,12 @@ public class FirOutOfContentRootLazyDeclarationResolveTestGenerated extends Abst runTest("analysis/low-level-api-fir/testdata/lazyResolve/fakePrimaryConstructor.kt"); } + @Test + @TestMetadata("fileAnnotations.kt") + public void testFileAnnotations() throws Exception { + runTest("analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.kt"); + } + @Test @TestMetadata("fromLocalHierarchyToOuter.kt") public void testFromLocalHierarchyToOuter() 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 d139014d61e..0f8b69b00a5 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 @@ -180,6 +180,12 @@ public class FirSourceLazyDeclarationResolveTestGenerated extends AbstractFirSou runTest("analysis/low-level-api-fir/testdata/lazyResolve/fakePrimaryConstructor.kt"); } + @Test + @TestMetadata("fileAnnotations.kt") + public void testFileAnnotations() throws Exception { + runTest("analysis/low-level-api-fir/testdata/lazyResolve/fileAnnotations.kt"); + } + @Test @TestMetadata("fromLocalHierarchyToOuter.kt") public void testFromLocalHierarchyToOuter() throws Exception {