From 78c394d4de8b4823adcef38ab0f2ef86d2f72089 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Tue, 13 Feb 2024 16:02:31 +0100 Subject: [PATCH] [LL FIR] FirElementBuilder: search file header elements without body resolution ^KT-65780 --- .../fir/element/builder/FirElementBuilder.kt | 33 +++++++++++++++++++ .../inImport/firstImportNamePart.txt | 2 +- .../inImport/firstImportNamePartScript.txt | 2 +- .../inImport/middleImportNamePart.txt | 2 +- .../inImport/middleImportNamePartScript.txt | 2 +- .../inImport/qualifiedImportNamePart.txt | 2 +- .../qualifiedImportNamePartScript.txt | 2 +- .../inImport/wholeImportDirective.txt | 2 +- .../inImport/wholeImportDirectiveScript.txt | 2 +- .../inImport/wholeImportName.txt | 2 +- .../inImport/wholeImportNameScript.txt | 2 +- .../inPackage/firstPackageNamePart.txt | 2 +- .../inPackage/firstPackageNamePartScript.txt | 2 +- .../inPackage/middlePackageNamePart.txt | 2 +- .../inPackage/middlePackageNamePartScript.txt | 2 +- .../inPackage/qualifiedPackageNamePart.txt | 2 +- .../qualifiedPackageNamePartScript.txt | 2 +- .../inPackage/wholePackageDirective.txt | 2 +- .../inPackage/wholePackageDirectiveScript.txt | 2 +- .../inPackage/wholePackageName.txt | 2 +- .../inPackage/wholePackageNameScript.txt | 2 +- .../wholeDeclaration/fileAnnotationList.txt | 6 ++-- .../fileAnnotationListScript.txt | 6 ++-- 23 files changed, 59 insertions(+), 26 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt index d61b804ff4b..eb166df8bb0 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt @@ -99,6 +99,7 @@ internal class FirElementBuilder( getFirForElementInsideAnnotations(element)?.let { return it } getFirForElementInsideTypes(element)?.let { return it } + getFirForElementInsideFileHeader(element)?.let { return it } val psi = getPsiAsFirElementSource(element) ?: return null val firFile = element.containingKtFile @@ -176,6 +177,38 @@ internal class FirElementBuilder( } } + private fun getFirForElementInsideFileHeader( + element: KtElement, + ): FirElement? = getFirForNonBodyElement( + element = element, + anchorElementProvider = { it.fileHeaderAnchorElement() }, + elementOwnerProvider = { it.containingKtFile }, + resolveAndFindFirForAnchor = { declaration, anchor -> + declaration.requireTypeIntersectionWith() + + when (anchor) { + is KtPackageDirective -> declaration.packageDirective + is KtFileAnnotationList -> declaration.annotationsContainer?.also { it.lazyResolveToPhase(FirResolvePhase.ANNOTATION_ARGUMENTS) } + is KtImportDirective -> { + declaration.lazyResolveToPhase(FirResolvePhase.IMPORTS) + declaration.imports.find { it.psi == anchor } + } + else -> errorWithAttachment("Unexpected element type: ${anchor::class.simpleName}") { + withPsiEntry("anchor", anchor) + } + } + }, + ) + + private fun KtElement.fileHeaderAnchorElement(): KtElement? { + /** + * File annotations already covered by [getFirForElementInsideAnnotations], but we have to cover the list itself + */ + if (this is KtFileAnnotationList) return this + + return parentsWithSelf.find { it is KtPackageDirective || it is KtImportDirective } as? KtElement + } + private fun findElementInside(firElement: FirElement, element: KtElement, stopAt: PsiElement): FirElement? { val elementToSearch = getPsiAsFirElementSource(element) ?: return null val mapping = FirElementsRecorder.recordElementsFrom(firElement, FirElementsRecorder()) diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePart.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePart.txt index 34142215649..dc309f2c7fe 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePart.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePart.txt @@ -6,4 +6,4 @@ FIR element rendered: import a.b.c FIR FILE: -FILE: [ResolvedTo(BODY_RESOLVE)] firstImportNamePart.kt +FILE: [ResolvedTo(IMPORTS)] firstImportNamePart.kt diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePartScript.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePartScript.txt index 2287ba9bf13..be88ea4e6a3 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePartScript.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/inImport/firstImportNamePartScript.txt @@ -6,7 +6,7 @@ FIR element rendered: import a.b.c FIR FILE: -FILE: [ResolvedTo(BODY_RESOLVE)] firstImportNamePartScript.kts +FILE: [ResolvedTo(IMPORTS)] firstImportNamePartScript.kts context(