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 31e7102f8d2..68000decfb4 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 @@ -126,4 +126,8 @@ internal class KtFe10SymbolProvider( .filter { it.name == name } .mapNotNull { it.toKtSymbol(analysisContext) as? KtCallableSymbol } } + + override fun getDestructuringDeclarationEntrySymbol(psi: KtDestructuringDeclarationEntry): KtLocalVariableSymbol { + return KtFe10PsiLocalVariableSymbol(psi, analysisContext) + } } \ 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/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java index 6cdd24d1b22..47a3af995f1 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/symbols/Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java @@ -112,6 +112,12 @@ public class Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends A runTest("analysis/analysis-api/testData/symbols/symbolByPsi/deprecated.kt"); } + @Test + @TestMetadata("destructuringDeclaration.kt") + public void testDestructuringDeclaration() throws Exception { + runTest("analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.kt"); + } + @Test @TestMetadata("dynamic.kt") public void testDynamic() throws Exception { 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 95fde0cdd37..03a822a93c1 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 @@ -122,14 +122,14 @@ internal class KtFirSymbolProvider( // A KtClassOrObject may also map to an FirEnumEntry. Hence, we need to return null in this case. if (psi is KtEnumEntry) return null return firSymbolBuilder.classifierBuilder.buildNamedClassOrObjectSymbol( - psi.resolveToFirSymbolOfType(firResolveSession) - ) + psi.resolveToFirSymbolOfType(firResolveSession)) + } override fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol { return firSymbolBuilder.callableBuilder.buildPropertyAccessorSymbol( - psi.resolveToFirSymbolOfType(firResolveSession) - ) + psi.resolveToFirSymbolOfType(firResolveSession)) + } override fun getClassInitializerSymbol(psi: KtClassInitializer): KtClassInitializerSymbol { @@ -149,4 +149,12 @@ internal class KtFirSymbolProvider( } override val ROOT_PACKAGE_SYMBOL: KtPackageSymbol = KtFirPackageSymbol(FqName.ROOT, firResolveSession.project, token) + + override fun getDestructuringDeclarationEntrySymbol(psi: KtDestructuringDeclarationEntry): KtLocalVariableSymbol { + return firSymbolBuilder.variableLikeBuilder.buildLocalVariableSymbol( + psi.resolveToFirSymbolOfType( + firResolveSession + ) + ) + } } diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java index 73c1023226a..1beea35c3e4 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/symbols/FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java @@ -112,6 +112,12 @@ public class FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends Ab runTest("analysis/analysis-api/testData/symbols/symbolByPsi/deprecated.kt"); } + @Test + @TestMetadata("destructuringDeclaration.kt") + public void testDestructuringDeclaration() throws Exception { + runTest("analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.kt"); + } + @Test @TestMetadata("dynamic.kt") public void testDynamic() throws Exception { diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByPsiTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByPsiTest.kt index 00472af10dd..022f2586f41 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByPsiTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolByPsiTest.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.psi.KtBackingField import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType @@ -30,6 +31,7 @@ abstract class AbstractSymbolByPsiTest : AbstractSymbolTest() { get() = when (this) { is KtBackingField -> false + is KtDestructuringDeclaration -> false is KtParameter -> !this.isFunctionTypeParameter else -> true } diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java index 2051211901b..e59154d7563 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/symbols/FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated.java @@ -112,6 +112,12 @@ public class FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated ext runTest("analysis/analysis-api/testData/symbols/symbolByPsi/deprecated.kt"); } + @Test + @TestMetadata("destructuringDeclaration.kt") + public void testDestructuringDeclaration() throws Exception { + runTest("analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.kt"); + } + @Test @TestMetadata("dynamic.kt") public void testDynamic() throws Exception { 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 7405df72342..16f8e0eb08b 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 @@ -30,6 +30,7 @@ public abstract class KtSymbolProvider : KtAnalysisSessionComponent() { } is KtPropertyAccessor -> getPropertyAccessorSymbol(psi) is KtClassInitializer -> getClassInitializerSymbol(psi) + is KtDestructuringDeclarationEntry -> getDestructuringDeclarationEntrySymbol(psi) else -> error("Cannot build symbol for ${psi::class}") } @@ -48,6 +49,7 @@ public abstract class KtSymbolProvider : KtAnalysisSessionComponent() { public abstract fun getNamedClassOrObjectSymbol(psi: KtClassOrObject): KtNamedClassOrObjectSymbol? public abstract fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol public abstract fun getClassInitializerSymbol(psi: KtClassInitializer): KtClassInitializerSymbol + public abstract fun getDestructuringDeclarationEntrySymbol(psi: KtDestructuringDeclarationEntry): KtLocalVariableSymbol public abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol? @@ -133,6 +135,13 @@ public interface KtSymbolProviderMixIn : KtAnalysisSessionMixIn { public fun FqName.getContainingCallableSymbolsWithName(name: Name): Sequence = withValidityAssertion { analysisSession.symbolProvider.getTopLevelCallableSymbols(this, name) } + /** + * @return symbol corresponding to the local variable introduced by individual destructuring declaration entries. + * E.g. `val (x, y) = p` has two declaration entries, one corresponding to `x`, one to `y`. + */ + public fun KtDestructuringDeclarationEntry.getDestructuringDeclarationEntrySymbol(): KtLocalVariableSymbol = + analysisSession.symbolProvider.getDestructuringDeclarationEntrySymbol(this) + @Suppress("PropertyName") public val ROOT_PACKAGE_SYMBOL: KtPackageSymbol get() = withValidityAssertion { analysisSession.symbolProvider.ROOT_PACKAGE_SYMBOL } diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.descriptors.pretty.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.descriptors.pretty.txt new file mode 100644 index 00000000000..edb93c58b07 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.descriptors.pretty.txt @@ -0,0 +1,9 @@ +fun destruct(): kotlin.Int + +data class P { + constructor(x: kotlin.Int, y: kotlin.Int) + + val x: kotlin.Int + + val y: kotlin.Int +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.kt b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.kt new file mode 100644 index 00000000000..22f601b4bc0 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.kt @@ -0,0 +1,6 @@ +data class P(val x: Int, val y: Int) + +fun destruct(): Int { + val (l, r) = P(1, 2) + return l + r +} diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.pretty.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.pretty.txt new file mode 100644 index 00000000000..3ecaf04abe4 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.pretty.txt @@ -0,0 +1,15 @@ +fun destruct(): kotlin.Int + +class P { + constructor(x: kotlin.Int, y: kotlin.Int) + + val x: kotlin.Int + + val y: kotlin.Int + + operator fun component1(): kotlin.Int + + operator fun component2(): kotlin.Int + + fun copy(x: kotlin.Int = ..., y: kotlin.Int = ...): P +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.txt new file mode 100644 index 00000000000..5b3eee6e05b --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/destructuringDeclaration.txt @@ -0,0 +1,128 @@ +KtValueParameterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + generatedPrimaryConstructorProperty: KtKotlinPropertySymbol(/P.x) + hasDefaultValue: false + isExtension: false + isImplicitLambdaParameter: false + isVararg: false + name: x + origin: SOURCE + receiverType: null + returnType: kotlin/Int + symbolKind: LOCAL + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtValueParameterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + generatedPrimaryConstructorProperty: KtKotlinPropertySymbol(/P.y) + hasDefaultValue: false + isExtension: false + isImplicitLambdaParameter: false + isVararg: false + name: y + origin: SOURCE + receiverType: null + returnType: kotlin/Int + symbolKind: LOCAL + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtConstructorSymbol: + annotationsList: [] + callableIdIfNonLocal: null + containingClassIdIfNonLocal: P + hasStableParameterNames: true + isExtension: false + isPrimary: true + origin: SOURCE + receiverType: null + returnType: P + symbolKind: CLASS_MEMBER + typeParameters: [] + valueParameters: [ + KtValueParameterSymbol(x) + KtValueParameterSymbol(y) + ] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: P + classKind: CLASS + companionObject: null + isData: true + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: P + origin: SOURCE + superTypes: [ + kotlin/Any + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtLocalVariableSymbol: + annotationsList: [] + callableIdIfNonLocal: null + isExtension: false + isVal: true + name: l + origin: SOURCE + receiverType: null + returnType: kotlin/Int + symbolKind: LOCAL + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtLocalVariableSymbol: + annotationsList: [] + callableIdIfNonLocal: null + isExtension: false + isVal: true + name: r + origin: SOURCE + receiverType: null + returnType: kotlin/Int + symbolKind: LOCAL + typeParameters: [] + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: /destruct + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: destruct + origin: SOURCE + receiverType: null + returnType: kotlin/Int + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null \ No newline at end of file