From e060778528996a5cda295ebc2e011fce2ecd670e Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 7 Jan 2021 17:34:36 +0100 Subject: [PATCH] FIR IDE: implement assignment statement references --- .../checkers/extended/UnusedChecker.kt | 1 - .../kotlin/fir/builder/BaseFirBuilder.kt | 5 ++-- .../FirExpressionsResolveTransformer.kt | 2 +- .../FirReferenceResolveTestGenerated.java | 10 +++++++ .../references/FirReferenceResolveHelper.kt | 8 +++++ .../references/KotlinPropertyAssignment.kt | 27 +++++++++++++++++ ...inPropertyWithGetterAndSetterAssignment.kt | 29 +++++++++++++++++++ .../ReferenceResolveTestGenerated.java | 10 +++++++ 8 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 idea/testData/resolve/references/KotlinPropertyAssignment.kt create mode 100644 idea/testData/resolve/references/KotlinPropertyWithGetterAndSetterAssignment.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt index 2b54d48eb3f..75c004f1f87 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UnusedChecker.kt @@ -256,7 +256,6 @@ object UnusedChecker : FirControlFlowChecker() { vararg qualifiedAccesses: FirQualifiedAccess, ): PathAwareVariableStatusInfo { fun retrieveSymbol(qualifiedAccess: FirQualifiedAccess): FirPropertySymbol? { - if (qualifiedAccess.source?.kind is FirFakeSourceElementKind) return null val reference = qualifiedAccess.calleeReference as? FirResolvedNamedReference ?: return null val symbol = reference.resolvedSymbol as? FirPropertySymbol ?: return null return if (symbol !in localProperties) null else symbol diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 0608e5c70c6..00499bafcf2 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -873,8 +873,9 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte return buildAssignmentOperatorStatement { source = baseSource this.operation = operation - // TODO: take good psi - leftArgument = this@generateAssignment?.convert() ?: buildErrorExpression { + leftArgument = withDefaultSourceElementKind(FirFakeSourceElementKind.DesugaredCompoundAssignment) { + this@generateAssignment?.convert() + } ?: buildErrorExpression { source = null diagnostic = ConeSimpleDiagnostic( "Unsupported left value of assignment: ${baseSource?.psi?.text}", DiagnosticKind.ExpressionRequired diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index a73e495a382..1c186683cf5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -353,7 +353,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform explicitReceiver = leftArgument argumentList = buildUnaryArgumentList(rightArgument) calleeReference = buildSimpleNamedReference { - source = assignmentOperatorStatement.source + source = assignmentOperatorStatement.source?.fakeElement(FirFakeSourceElementKind.DesugaredCompoundAssignment) this.name = name candidateSymbol = null } diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java index 1e5df1e9ac4..41ae5fa3fbd 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java @@ -254,6 +254,16 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv runTest("idea/testData/resolve/references/JavaReference.kt"); } + @TestMetadata("KotlinPropertyAssignment.kt") + public void testKotlinPropertyAssignment() throws Exception { + runTest("idea/testData/resolve/references/KotlinPropertyAssignment.kt"); + } + + @TestMetadata("KotlinPropertyWithGetterAndSetterAssignment.kt") + public void testKotlinPropertyWithGetterAndSetterAssignment() throws Exception { + runTest("idea/testData/resolve/references/KotlinPropertyWithGetterAndSetterAssignment.kt"); + } + @TestMetadata("MultiDeclarationExtension.kt") public void testMultiDeclarationExtension() throws Exception { runTest("idea/testData/resolve/references/MultiDeclarationExtension.kt"); diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt index 8c7fcd13ab3..98d3e6d3456 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt @@ -156,12 +156,20 @@ internal object FirReferenceResolveHelper { } is FirReturnExpression -> getSymbolsByReturnExpression(expression, fir, symbolBuilder) is FirErrorNamedReference -> getSymbolsByErrorNamedReference(fir, symbolBuilder) + is FirVariableAssignment -> getSymbolsByVariableAssignment(fir, session, symbolBuilder) is FirResolvable -> getSymbolsByResolvable(fir, expression, session, symbolBuilder) is FirNamedArgumentExpression -> getSymbolsByNameArgumentExpression(expression, analysisSession, symbolBuilder) else -> handleUnknownFirElement(expression, analysisSession, session, symbolBuilder) } } + @OptIn(ExperimentalStdlibApi::class) + private fun getSymbolsByVariableAssignment( + fir: FirVariableAssignment, + session: FirSession, + symbolBuilder: KtSymbolByFirBuilder + ): Collection = fir.calleeReference.toTargetSymbol(session, symbolBuilder) + private fun getSymbolsByNameArgumentExpression( expression: KtSimpleNameExpression, analysisSession: KtFirAnalysisSession, diff --git a/idea/testData/resolve/references/KotlinPropertyAssignment.kt b/idea/testData/resolve/references/KotlinPropertyAssignment.kt new file mode 100644 index 00000000000..935eff84e49 --- /dev/null +++ b/idea/testData/resolve/references/KotlinPropertyAssignment.kt @@ -0,0 +1,27 @@ +class A { + var something: Int = 10 +} + +fun A.foo(a: A) { + print(a.something) + a.something = 1 + a.something += 1 + a.something++ + --a.something + + something++ + (something)++ + (something) = 1 + (a.something) = 1 +} + +// MULTIRESOLVE +// REF1: (in A).something +// REF2: (in A).something +// REF3: (in A).something +// REF4: (in A).something +// REF5: (in A).something +// REF6: (in A).something +// REF7: (in A).something +// REF8: (in A).something +// REF9: (in A).something diff --git a/idea/testData/resolve/references/KotlinPropertyWithGetterAndSetterAssignment.kt b/idea/testData/resolve/references/KotlinPropertyWithGetterAndSetterAssignment.kt new file mode 100644 index 00000000000..43f8ad26871 --- /dev/null +++ b/idea/testData/resolve/references/KotlinPropertyWithGetterAndSetterAssignment.kt @@ -0,0 +1,29 @@ +class A { + var something: Int + set(value) {} + get() = 10 +} + +fun A.foo(a: A) { + print(a.something) + a.something = 1 + a.something += 1 + a.something++ + --a.something + + something++ + (something)++ + (something) = 1 + (a.something) = 1 +} + +// MULTIRESOLVE +// REF1: (in A).something +// REF2: (in A).something +// REF3: (in A).something +// REF4: (in A).something +// REF5: (in A).something +// REF6: (in A).something +// REF7: (in A).something +// REF8: (in A).something +// REF9: (in A).something diff --git a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java index ef2b824fbad..0ad7563c22b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java @@ -254,6 +254,16 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest runTest("idea/testData/resolve/references/JavaReference.kt"); } + @TestMetadata("KotlinPropertyAssignment.kt") + public void testKotlinPropertyAssignment() throws Exception { + runTest("idea/testData/resolve/references/KotlinPropertyAssignment.kt"); + } + + @TestMetadata("KotlinPropertyWithGetterAndSetterAssignment.kt") + public void testKotlinPropertyWithGetterAndSetterAssignment() throws Exception { + runTest("idea/testData/resolve/references/KotlinPropertyWithGetterAndSetterAssignment.kt"); + } + @TestMetadata("MultiDeclarationExtension.kt") public void testMultiDeclarationExtension() throws Exception { runTest("idea/testData/resolve/references/MultiDeclarationExtension.kt");