diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProvider.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProvider.kt index 62f3e337f45..bf13ab184df 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProvider.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProvider.kt @@ -149,4 +149,8 @@ internal class KtFe10SymbolProvider( override fun getDestructuringDeclarationEntrySymbol(psi: KtDestructuringDeclarationEntry): KtLocalVariableSymbol { return KtFe10PsiLocalVariableSymbol(psi, analysisContext) } + + override fun getDestructuringDeclarationSymbol(psi: KtDestructuringDeclaration): KtDestructuringDeclarationSymbol { + return KtFe10PsiDestructuringDeclarationSymbol(psi, analysisSession) + } } \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/psiBased/KtFe10PsiDestructuringDeclarationSymbol.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/psiBased/KtFe10PsiDestructuringDeclarationSymbol.kt new file mode 100644 index 00000000000..b94309472cf --- /dev/null +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/psiBased/KtFe10PsiDestructuringDeclarationSymbol.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext +import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode +import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession +import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.KtFe10PsiSymbol +import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion +import org.jetbrains.kotlin.analysis.api.symbols.KtDestructuringDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtLocalVariableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.resolve.BindingContext + +internal class KtFe10PsiDestructuringDeclarationSymbol( + override val psi: KtDestructuringDeclaration, + private val analysisSession: KtFe10AnalysisSession, +) : KtDestructuringDeclarationSymbol(), KtFe10PsiSymbol { + override val descriptor: CallableDescriptor? get() = null + + override val annotationsObject: Annotations by cached { + val bindingContext = analysisContext.analyze(psi, AnalysisMode.PARTIAL) + Annotations.create( + psi.annotationEntries.mapNotNull { entry -> + bindingContext[BindingContext.ANNOTATION, entry] + } + ) + } + + override val analysisContext: Fe10AnalysisContext get() = analysisSession.analysisContext + + override val entries: List + get() = withValidityAssertion { + psi.entries.map { entry -> + with(analysisSession) { entry.getDestructuringDeclarationEntrySymbol() } + } + } + + context(KtAnalysisSession) + override fun createPointer(): KtSymbolPointer { + KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } + throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(SpecialNames.DESTRUCT.asString()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + return other is KtFe10PsiDestructuringDeclarationSymbol && other.psi == this.psi + } + + override fun hashCode(): Int = psi.hashCode() +} \ No newline at end of file diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java index 0fa25e9389f..f10fdddf563 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java @@ -323,6 +323,18 @@ public class Fe10IdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated extends KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("destructuringDeclaration.kt") + public void testDestructuringDeclaration() throws Exception { + runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.kt"); + } + + @Test + @TestMetadata("destructuringDeclarationInLambda.kt") + public void testDestructuringDeclarationInLambda() throws Exception { + runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.kt"); + } + @Test @TestMetadata("destructuringDeclarationParameterInLambda.kt") public void testDestructuringDeclarationParameterInLambda() throws Exception { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt index 47835ac504b..38338be4aa7 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt @@ -101,6 +101,13 @@ internal class KtSymbolByFirBuilder constructor( } } + + fun buildDestructuringDeclarationSymbol(firSymbol: FirVariableSymbol<*>): KtDestructuringDeclarationSymbol { + return symbolsCache.cache(firSymbol) { + KtFirDestructuringDeclarationSymbol(firSymbol, analysisSession) + } + } + fun buildEnumEntrySymbol(firSymbol: FirEnumEntrySymbol) = symbolsCache.cache(firSymbol) { KtFirEnumEntrySymbol(firSymbol, analysisSession) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt index 8e114bf8409..2b3898fa597 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt @@ -50,6 +50,7 @@ internal class KtFirSymbolContainingDeclarationProvider( is KtLocalVariableSymbol -> getParentSymbolByPsi() is KtAnonymousFunctionSymbol -> getParentSymbolByPsi() is KtAnonymousObjectSymbol -> getParentSymbolByPsi() + is KtDestructuringDeclarationSymbol -> getParentSymbolByPsi() is KtSamConstructorSymbol -> null // SAM constructors are always top-level is KtScriptSymbol -> null // Scripts are always top-level diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirDestructuringDeclarationSymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirDestructuringDeclarationSymbol.kt new file mode 100644 index 00000000000..18b10bf6f49 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirDestructuringDeclarationSymbol.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.fir.symbols + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList +import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion +import org.jetbrains.kotlin.analysis.api.symbols.KtDestructuringDeclarationSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtLocalVariableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.fir.psi +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry + +internal class KtFirDestructuringDeclarationSymbol( + override val firSymbol: FirVariableSymbol<*>, + override val analysisSession: KtFirAnalysisSession, +) : KtDestructuringDeclarationSymbol(), KtFirSymbol> { + + init { + require(firSymbol.name == SpecialNames.DESTRUCT) + } + + override val psi: KtDestructuringDeclaration + get() = withValidityAssertion { + when (val psi = firSymbol.fir.psi) { + is KtDestructuringDeclaration -> psi + is KtParameter -> psi.destructuringDeclaration + ?: errorWithAttachment("Expected to find lambda ${KtParameter::class} with ${KtDestructuringDeclaration::class}") { + withPsiEntry("psi", psi) + } + else -> errorWithAttachment("Expected to find ${KtDestructuringDeclaration::class} or ${KtParameter::class} but ${psi?.let { it::class }} found") { + withPsiEntry("psi", psi) + } + } + } + + override val annotationsList: KtAnnotationsList + get() = withValidityAssertion { KtFirAnnotationListForDeclaration.create(firSymbol, analysisSession.useSiteSession, token) } + + override val entries: List + get() = withValidityAssertion { + psi.entries.map { entry -> + with(analysisSession) { entry.getDestructuringDeclarationEntrySymbol() } + } + } + + context(KtAnalysisSession) + override fun createPointer(): KtSymbolPointer { + return KtPsiBasedSymbolPointer.createForSymbolFromSource(this) + ?: throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(SpecialNames.DESTRUCT.asString()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + return other is KtFirDestructuringDeclarationSymbol && firSymbol == other.firSymbol + } + + override fun hashCode(): Int { + return firSymbol.hashCode() + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt index d7f4e4ffe51..92ad969756b 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral -import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore internal class KtFirSymbolProvider( override val analysisSession: KtFirAnalysisSession, @@ -198,4 +197,9 @@ internal class KtFirSymbolProvider( ) } } + + override fun getDestructuringDeclarationSymbol(psi: KtDestructuringDeclaration): KtDestructuringDeclarationSymbol { + val firSymbol = psi.resolveToFirSymbolOfType>(firResolveSession) + return firSymbolBuilder.buildDestructuringDeclarationSymbol(firSymbol) + } } diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java index 0a2c45e90e1..65112b76ba2 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java @@ -323,6 +323,18 @@ public class FirIdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated extends KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("destructuringDeclaration.kt") + public void testDestructuringDeclaration() throws Exception { + runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.kt"); + } + + @Test + @TestMetadata("destructuringDeclarationInLambda.kt") + public void testDestructuringDeclarationInLambda() throws Exception { + runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.kt"); + } + @Test @TestMetadata("destructuringDeclarationParameterInLambda.kt") public void testDestructuringDeclarationParameterInLambda() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java index e5b179288ae..bdee8e0794c 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSingleSymbolByPsiGenerated.java @@ -323,6 +323,18 @@ public class FirStandaloneNormalAnalysisSourceModuleSingleSymbolByPsiGenerated e KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("destructuringDeclaration.kt") + public void testDestructuringDeclaration() throws Exception { + runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.kt"); + } + + @Test + @TestMetadata("destructuringDeclarationInLambda.kt") + public void testDestructuringDeclarationInLambda() throws Exception { + runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.kt"); + } + @Test @TestMetadata("destructuringDeclarationParameterInLambda.kt") public void testDestructuringDeclarationParameterInLambda() throws Exception { diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtDeclarationRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtDeclarationRenderer.kt index edf3b791cd2..eaee362e8a2 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtDeclarationRenderer.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/KtDeclarationRenderer.kt @@ -74,6 +74,7 @@ public class KtDeclarationRenderer private constructor( public val valueParameterRenderer: KtValueParameterSymbolRenderer, public val samConstructorRenderer: KtSamConstructorSymbolRenderer, public val propertyAccessorsRenderer: KtPropertyAccessorsRenderer, + public val destructuringDeclarationRenderer: KtDestructuringDeclarationRenderer, public val classInitializerRender: KtClassInitializerRenderer, public val classOrObjectRenderer: KtNamedClassOrObjectSymbolRenderer, @@ -108,6 +109,7 @@ public class KtDeclarationRenderer private constructor( is KtTypeParameterSymbol -> singleTypeParameterRenderer.renderSymbol(symbol, printer) is KtClassInitializerSymbol -> classInitializerRender.renderClassInitializer(symbol, printer) is KtScriptSymbol -> scriptRenderer.renderSymbol(symbol, printer) + is KtDestructuringDeclarationSymbol -> destructuringDeclarationRenderer.renderSymbol(symbol, printer) } } @@ -161,6 +163,7 @@ public class KtDeclarationRenderer private constructor( this.valueParameterRenderer = renderer.valueParameterRenderer this.samConstructorRenderer = renderer.samConstructorRenderer this.propertyAccessorsRenderer = renderer.propertyAccessorsRenderer + this.destructuringDeclarationRenderer = renderer.destructuringDeclarationRenderer this.classInitializerRender = renderer.classInitializerRender this.classOrObjectRenderer = renderer.classOrObjectRenderer @@ -229,6 +232,7 @@ public class KtDeclarationRenderer private constructor( public lateinit var valueParameterRenderer: KtValueParameterSymbolRenderer public lateinit var samConstructorRenderer: KtSamConstructorSymbolRenderer public lateinit var propertyAccessorsRenderer: KtPropertyAccessorsRenderer + public lateinit var destructuringDeclarationRenderer: KtDestructuringDeclarationRenderer public lateinit var classInitializerRender: KtClassInitializerRenderer public lateinit var classOrObjectRenderer: KtNamedClassOrObjectSymbolRenderer @@ -286,6 +290,7 @@ public class KtDeclarationRenderer private constructor( valueParameterRenderer, samConstructorRenderer, propertyAccessorsRenderer, + destructuringDeclarationRenderer, classInitializerRender, classOrObjectRenderer, diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForSource.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForSource.kt index cbe258c4007..312bb5f9cc6 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForSource.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/impl/KtDeclarationRendererForSource.kt @@ -74,6 +74,7 @@ public object KtDeclarationRendererForSource { anonymousObjectRenderer = KtAnonymousObjectSymbolRenderer.AS_SOURCE singleTypeParameterRenderer = KtSingleTypeParameterSymbolRenderer.WITHOUT_BOUNDS propertyAccessorsRenderer = KtPropertyAccessorsRenderer.NO_DEFAULT + destructuringDeclarationRenderer = KtDestructuringDeclarationRenderer.WITH_ENTRIES callableReceiverRenderer = KtCallableReceiverRenderer.AS_TYPE_WITH_IN_APPROXIMATION returnTypeRenderer = KtCallableReturnTypeRenderer.WITH_OUT_APPROXIMATION diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtDestructuringDeclarationRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtDestructuringDeclarationRenderer.kt new file mode 100644 index 00000000000..24f228f0bc4 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/renderer/declarations/renderers/callables/KtDestructuringDeclarationRenderer.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer +import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.renderers.KtRendererKeywordFilter +import org.jetbrains.kotlin.analysis.api.symbols.KtDestructuringDeclarationSymbol +import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter +import org.jetbrains.kotlin.lexer.KtTokens + +public interface KtDestructuringDeclarationRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + public fun renderSymbol(symbol: KtDestructuringDeclarationSymbol, printer: PrettyPrinter) + + public object WITH_ENTRIES : KtDestructuringDeclarationRenderer { + context(KtAnalysisSession, KtDeclarationRenderer) + override fun renderSymbol(symbol: KtDestructuringDeclarationSymbol, printer: PrettyPrinter): Unit = printer { + codeStyle.getSeparatorBetweenAnnotationAndOwner(symbol).separated( + { annotationRenderer.renderAnnotations(symbol, printer) }, + { + // do not render (val a: Int, val b: Int), render `(a: Int, b: Int)` instead + val rendererWithoutValVar = with { + keywordsRenderer = keywordsRenderer.with { + keywordFilter = keywordFilter and KtRendererKeywordFilter.without(KtTokens.VAL_KEYWORD, KtTokens.VAR_KEYWORD) + } + } + printCollection(symbol.entries, prefix = "(", postfix = ")") { + with(rendererWithoutValVar) { + localVariableRenderer.renderSymbol(it, this@printCollection) + } + } + } + ) + + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtDestructuringDeclarationSymbol.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtDestructuringDeclarationSymbol.kt new file mode 100644 index 00000000000..22f1a5fbe24 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtDestructuringDeclarationSymbol.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.symbols + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer + +/** + * A [KtSymbol] created from a [destructuring declaration][org.jetbrains.kotlin.psi.KtDestructuringDeclaration] (possibly from a lambda parameter). + * + * Examples: + * - `val (a, _) = Pair(1, 2)` leads to `KtDestructuringDeclarationSymbol(entries = [a, _])` + * - `Pair(1, _).let { (a, b) -> }` leads to `KtDestructuringDeclarationSymbol(entries = [a, _])` + */ +public abstract class KtDestructuringDeclarationSymbol : KtDeclarationSymbol, KtSymbolWithKind { + final override val symbolKind: KtSymbolKind get() = withValidityAssertion { KtSymbolKind.LOCAL } + final override val typeParameters: List get() = withValidityAssertion { emptyList() } + + /** + * A list of [KtLocalVariableSymbol]s which were created from this destructuring declaration. + * + * E.g., for the following code: + * ``` + * data class X(val y: Int, val z: String) + * fun foo() { + * val (a, _) = x // the destruction + * } + * ``` + * + * the following symbols will be created (pseudocode) + * ``` + * val a: Int + * val _: String + * ``` + */ + public abstract val entries: List + + context(KtAnalysisSession) + abstract override fun createPointer(): KtSymbolPointer +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt index c0dc5b45a97..ab97b2f22d9 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt @@ -32,6 +32,7 @@ public abstract class KtSymbolProvider : KtAnalysisSessionComponent() { is KtClassInitializer -> getClassInitializerSymbol(psi) is KtDestructuringDeclarationEntry -> getDestructuringDeclarationEntrySymbol(psi) is KtScript -> getScriptSymbol(psi) + is KtDestructuringDeclaration -> getDestructuringDeclarationSymbol(psi) else -> error("Cannot build symbol for ${psi::class}") } @@ -52,6 +53,7 @@ public abstract class KtSymbolProvider : KtAnalysisSessionComponent() { public abstract fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol public abstract fun getClassInitializerSymbol(psi: KtClassInitializer): KtClassInitializerSymbol public abstract fun getDestructuringDeclarationEntrySymbol(psi: KtDestructuringDeclarationEntry): KtLocalVariableSymbol + public abstract fun getDestructuringDeclarationSymbol(psi: KtDestructuringDeclaration): KtDestructuringDeclarationSymbol public abstract fun getPackageSymbolIfPackageExists(packageFqName: FqName): KtPackageSymbol? diff --git a/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.kt b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.kt new file mode 100644 index 00000000000..568e529081e --- /dev/null +++ b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.kt @@ -0,0 +1,15 @@ +// LOOK_UP_FOR_ELEMENT_OF_TYPE: KtDestructuringDeclaration +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE + +data class X(val a: Int, val b: Int) + +fun main(x: X) { + + + @AAA("y") + val (@BBB("aaa") a, @BBB("bbb") b) = x + +} + +annotation class AAA(val value: String) +annotation class BBB(val value: String) diff --git a/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.pretty.txt b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.pretty.txt new file mode 100644 index 00000000000..e82ad09449f --- /dev/null +++ b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.pretty.txt @@ -0,0 +1,2 @@ +@AAA(value = "y") +(@BBB(value = "aaa") a: kotlin.Int, @BBB(value = "bbb") b: kotlin.Int) \ No newline at end of file diff --git a/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.txt b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.txt new file mode 100644 index 00000000000..28a2632b479 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclaration.txt @@ -0,0 +1,14 @@ +KtDestructuringDeclarationSymbol: + annotationsList: [ + AAA(value = "y") + psi: KtAnnotationEntry + ] + entries: [ + KtLocalVariableSymbol(/a) + KtLocalVariableSymbol(/b) + ] + origin: SOURCE + symbolKind: LOCAL + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null \ No newline at end of file diff --git a/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.kt b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.kt new file mode 100644 index 00000000000..72c09f95b55 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.kt @@ -0,0 +1,12 @@ +// LOOK_UP_FOR_ELEMENT_OF_TYPE: KtDestructuringDeclaration +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE + +data class X(val a: Int, val b: Int) + +fun x(action: (X) -> Unit) {} + +fun main() { + x { (a, b) -> + + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.pretty.txt b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.pretty.txt new file mode 100644 index 00000000000..ed71595c6bd --- /dev/null +++ b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.pretty.txt @@ -0,0 +1 @@ +(a: kotlin.Int, b: kotlin.Int) \ No newline at end of file diff --git a/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.txt b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.txt new file mode 100644 index 00000000000..03342ed9b2a --- /dev/null +++ b/analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationInLambda.txt @@ -0,0 +1,11 @@ +KtDestructuringDeclarationSymbol: + annotationsList: [] + entries: [ + KtLocalVariableSymbol(/a) + KtLocalVariableSymbol(/b) + ] + origin: SOURCE + symbolKind: LOCAL + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null \ No newline at end of file