From e02c28c88a279af45958380b2c882ebb2ebbfada Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Fri, 9 Feb 2024 23:42:01 +0100 Subject: [PATCH] [LL FIR] support lazy resolve of destructuring declaration entries ^KT-62840 Fixed ^KT-65727 --- .../fir/element/builder/FirElementBuilder.kt | 5 +- .../api/fir/file/structure/FileStructure.kt | 2 +- .../fir/transformers/LLFirTargetResolver.kt | 11 +- .../level/api/fir/util/declarationUtils.kt | 7 + .../testData/fileStructure/destructuring.kts | 8 + .../destructuring.lazy.resolve.txt | 40 + .../destructuringEntryAnnotation.kts | 7 + .../destructuringEntryAnnotation.txt | 50 ++ .../destructionWithNoRValueScript.txt | 8 +- .../declarations/destructuringEntryScript.txt | 6 +- .../testData/lazyResolve/destructuring.kts | 10 + .../testData/lazyResolve/destructuring.txt | 569 +++++++++++++ .../lazyResolve/destructuringFirstEntry.kts | 10 + .../lazyResolve/destructuringFirstEntry.txt | 569 +++++++++++++ .../lazyResolve/destructuringSecondEntry.kts | 10 + .../lazyResolve/destructuringSecondEntry.txt | 569 +++++++++++++ ...tWithDestructuringDeclarationReference.kts | 14 + ...tWithDestructuringDeclarationReference.txt | 577 ++++++++++++++ .../destruct.after.txt | 57 ++ .../destruct.before.txt | 57 ++ .../destructuringDeclaration/destruct.kts | 10 + .../destruct.lazyResolve.txt | 634 +++++++++++++++ .../destructEntry.after.txt | 57 ++ .../destructEntry.before.txt | 57 ++ .../destructEntry.kts | 10 + .../destructEntry.lazyResolve.txt | 634 +++++++++++++++ .../destructEntryUsage.after.txt | 85 ++ .../destructEntryUsage.before.txt | 85 ++ .../destructEntryUsage.kts | 9 + .../destructEntryUsage.lazyResolve.txt | 674 ++++++++++++++++ .../destructEntryWithType.after.txt | 57 ++ .../destructEntryWithType.before.txt | 57 ++ .../destructEntryWithType.kts | 10 + .../destructEntryWithType.lazyResolve.txt | 634 +++++++++++++++ .../destructEntryWithTypeUsage.after.txt | 85 ++ .../destructEntryWithTypeUsage.before.txt | 85 ++ .../destructEntryWithTypeUsage.kts | 9 + ...destructEntryWithTypeUsage.lazyResolve.txt | 674 ++++++++++++++++ .../scriptLevel.after.txt | 248 ++++++ .../scriptLevel.before.txt | 248 ++++++ .../destructuringDeclaration/scriptLevel.kts | 16 + .../scriptLevel.lazyResolve.txt | 753 ++++++++++++++++++ ...ptLazyDeclarationResolveTestGenerated.java | 24 + .../fir/ScriptGetOrBuildFirTestGenerated.java | 6 + ...esolveForTypeAnnotationsTestGenerated.java | 36 + ...criptLazyTypeAnnotationsTestGenerated.java | 36 + .../ScriptContextCollectionTestGenerated.java | 6 + ...agnosticTraversalCounterTestGenerated.java | 6 + .../structure/AbstractFileStructureTest.kt | 3 + .../ScriptFileStructureTestGenerated.java | 6 + ...iptWholeFileResolvePhaseTestGenerated.java | 6 + ...tializerOfDestructuringDeclarationOnce.kts | 3 - 52 files changed, 7835 insertions(+), 14 deletions(-) create mode 100644 analysis/low-level-api-fir/testData/fileStructure/destructuring.kts create mode 100644 analysis/low-level-api-fir/testData/fileStructure/destructuring.lazy.resolve.txt create mode 100644 analysis/low-level-api-fir/testData/getOrBuildFir/annotations/destructuringEntryAnnotation.kts create mode 100644 analysis/low-level-api-fir/testData/getOrBuildFir/annotations/destructuringEntryAnnotation.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/destructuring.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/destructuring.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/destructuringFirstEntry.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/destructuringFirstEntry.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/destructuringSecondEntry.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/destructuringSecondEntry.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/lastStatementWithDestructuringDeclarationReference.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolve/lastStatementWithDestructuringDeclarationReference.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destruct.after.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destruct.before.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destruct.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destruct.lazyResolve.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntry.after.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntry.before.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntry.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntry.lazyResolve.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryUsage.after.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryUsage.before.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryUsage.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryUsage.lazyResolve.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithType.after.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithType.before.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithType.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithType.lazyResolve.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithTypeUsage.after.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithTypeUsage.before.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithTypeUsage.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/destructEntryWithTypeUsage.lazyResolve.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptLevel.after.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptLevel.before.txt create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptLevel.kts create mode 100644 analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptLevel.lazyResolve.txt 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 4925c2a3f24..0cadcf27af7 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder import com.intellij.psi.PsiElement +import com.intellij.psi.PsiErrorElement import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.ThreadSafe import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents @@ -290,7 +291,8 @@ internal fun getNonLocalContainingDeclaration( parent is KtAnonymousInitializer || parent is KtObjectLiteralExpression || parent is KtCallElement || - parent is KtCodeFragment + parent is KtCodeFragment || + parent is PsiErrorElement ) { // Candidate turned out to be local. Let's find another one. candidate = null @@ -302,6 +304,7 @@ internal fun getNonLocalContainingDeclaration( when (parent) { is KtScript -> propose(parent) is KtDestructuringDeclaration -> propose(parent) + is KtDestructuringDeclarationEntry -> propose(parent) is KtScriptInitializer -> propose(parent) is KtClassInitializer -> { val container = parent.containingDeclaration diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt index 54840fba4df..3b6096172b8 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt @@ -144,7 +144,7 @@ internal class FileStructure private constructor( structureElements += structureElement // Go down only in the case of container declaration - val canHaveInnerStructure = dcl is KtClassOrObject || dcl is KtScript + val canHaveInnerStructure = dcl is KtClassOrObject || dcl is KtScript || dcl is KtDestructuringDeclaration if (canHaveInnerStructure) { dcl.acceptChildren(this) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt index 0ba1288fc52..2b5c3273e2b 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirScript import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.destructuringDeclarationContainerVariable import org.jetbrains.kotlin.fir.declarations.utils.componentFunctionSymbol import org.jetbrains.kotlin.fir.declarations.utils.correspondingValueParameterFromPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor @@ -98,8 +99,14 @@ internal abstract class LLFirTargetResolver( // Fake or delegate declaration shared types and annotations from the original one originalDeclaration != null -> originalDeclaration.lazyResolveToPhase(resolverPhase) - // We share type references and annotations with the original parameter - target is FirProperty -> target.correspondingValueParameterFromPrimaryConstructor?.lazyResolveToPhase(resolverPhase) + target is FirProperty -> { + // We share type references and annotations with the original parameter + target.correspondingValueParameterFromPrimaryConstructor?.lazyResolveToPhase(resolverPhase) + + // Destructuring declaration entries depends on the container property + target.destructuringDeclarationContainerVariable?.lazyResolveToPhase(resolverPhase) + } + target is FirSimpleFunction && target.origin == FirDeclarationOrigin.Synthetic.DataClassMember -> { resolveDataClassMemberDependencies(target) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt index 4e514491356..bf4795cb365 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt @@ -125,6 +125,7 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider( is KtAnonymousInitializer, is KtTypeAlias, is KtDestructuringDeclaration, + is KtDestructuringDeclarationEntry, is KtScript, -> firDeclarationProvider(this) @@ -235,8 +236,14 @@ internal val FirCallableSymbol<*>.isLocalForLazyResolutionPurposes: Boolean // We should treat result$$ property as non-local explicitly as its CallableId is local // TODO: can be dropped after KT-65523 fir.origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty -> false + // Destructuring declaration container should be treated as a non-local as it is a top-level script declaration fir.origin == FirDeclarationOrigin.Synthetic.ScriptTopLevelDestructuringDeclarationContainer -> false + + // We should treat destructuring declaration entries as non-local explicitly as its CallableId is local + // TODO: can be dropped after KT-65727 + (fir as? FirProperty)?.destructuringDeclarationContainerVariable != null -> false + else -> callableId.isLocal || fir.status.visibility == Visibilities.Local } diff --git a/analysis/low-level-api-fir/testData/fileStructure/destructuring.kts b/analysis/low-level-api-fir/testData/fileStructure/destructuring.kts new file mode 100644 index 00000000000..5a16891c127 --- /dev/null +++ b/analysis/low-level-api-fir/testData/fileStructure/destructuring.kts @@ -0,0 +1,8 @@ +/* RootScriptStructureElement */var a = -1/* DeclarationStructureElement */ +var b = 0/* DeclarationStructureElement */ + +data class MyPair(val i: Int, val b: Int)/* DeclarationStructureElement *//* ClassDeclarationStructureElement */ + +val pair = MyPair(a, b)/* DeclarationStructureElement */ + +val (first/* DeclarationStructureElement */, last/* DeclarationStructureElement */) = pair/* DeclarationStructureElement */ diff --git a/analysis/low-level-api-fir/testData/fileStructure/destructuring.lazy.resolve.txt b/analysis/low-level-api-fir/testData/fileStructure/destructuring.lazy.resolve.txt new file mode 100644 index 00000000000..20ea05eb5bb --- /dev/null +++ b/analysis/low-level-api-fir/testData/fileStructure/destructuring.lazy.resolve.txt @@ -0,0 +1,40 @@ +FILE: [ResolvedTo(BODY_RESOLVE)] destructuring.kts + context(