FIR IDE: implement assignment statement references

This commit is contained in:
Ilya Kirillov
2021-01-07 17:34:36 +01:00
parent 14d2b1be49
commit e060778528
8 changed files with 88 additions and 4 deletions
@@ -256,7 +256,6 @@ object UnusedChecker : FirControlFlowChecker() {
vararg qualifiedAccesses: FirQualifiedAccess, vararg qualifiedAccesses: FirQualifiedAccess,
): PathAwareVariableStatusInfo { ): PathAwareVariableStatusInfo {
fun retrieveSymbol(qualifiedAccess: FirQualifiedAccess): FirPropertySymbol? { fun retrieveSymbol(qualifiedAccess: FirQualifiedAccess): FirPropertySymbol? {
if (qualifiedAccess.source?.kind is FirFakeSourceElementKind) return null
val reference = qualifiedAccess.calleeReference as? FirResolvedNamedReference ?: return null val reference = qualifiedAccess.calleeReference as? FirResolvedNamedReference ?: return null
val symbol = reference.resolvedSymbol as? FirPropertySymbol ?: return null val symbol = reference.resolvedSymbol as? FirPropertySymbol ?: return null
return if (symbol !in localProperties) null else symbol return if (symbol !in localProperties) null else symbol
@@ -873,8 +873,9 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
return buildAssignmentOperatorStatement { return buildAssignmentOperatorStatement {
source = baseSource source = baseSource
this.operation = operation this.operation = operation
// TODO: take good psi leftArgument = withDefaultSourceElementKind(FirFakeSourceElementKind.DesugaredCompoundAssignment) {
leftArgument = this@generateAssignment?.convert() ?: buildErrorExpression { this@generateAssignment?.convert()
} ?: buildErrorExpression {
source = null source = null
diagnostic = ConeSimpleDiagnostic( diagnostic = ConeSimpleDiagnostic(
"Unsupported left value of assignment: ${baseSource?.psi?.text}", DiagnosticKind.ExpressionRequired "Unsupported left value of assignment: ${baseSource?.psi?.text}", DiagnosticKind.ExpressionRequired
@@ -353,7 +353,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
explicitReceiver = leftArgument explicitReceiver = leftArgument
argumentList = buildUnaryArgumentList(rightArgument) argumentList = buildUnaryArgumentList(rightArgument)
calleeReference = buildSimpleNamedReference { calleeReference = buildSimpleNamedReference {
source = assignmentOperatorStatement.source source = assignmentOperatorStatement.source?.fakeElement(FirFakeSourceElementKind.DesugaredCompoundAssignment)
this.name = name this.name = name
candidateSymbol = null candidateSymbol = null
} }
@@ -254,6 +254,16 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv
runTest("idea/testData/resolve/references/JavaReference.kt"); 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") @TestMetadata("MultiDeclarationExtension.kt")
public void testMultiDeclarationExtension() throws Exception { public void testMultiDeclarationExtension() throws Exception {
runTest("idea/testData/resolve/references/MultiDeclarationExtension.kt"); runTest("idea/testData/resolve/references/MultiDeclarationExtension.kt");
@@ -156,12 +156,20 @@ internal object FirReferenceResolveHelper {
} }
is FirReturnExpression -> getSymbolsByReturnExpression(expression, fir, symbolBuilder) is FirReturnExpression -> getSymbolsByReturnExpression(expression, fir, symbolBuilder)
is FirErrorNamedReference -> getSymbolsByErrorNamedReference(fir, symbolBuilder) is FirErrorNamedReference -> getSymbolsByErrorNamedReference(fir, symbolBuilder)
is FirVariableAssignment -> getSymbolsByVariableAssignment(fir, session, symbolBuilder)
is FirResolvable -> getSymbolsByResolvable(fir, expression, session, symbolBuilder) is FirResolvable -> getSymbolsByResolvable(fir, expression, session, symbolBuilder)
is FirNamedArgumentExpression -> getSymbolsByNameArgumentExpression(expression, analysisSession, symbolBuilder) is FirNamedArgumentExpression -> getSymbolsByNameArgumentExpression(expression, analysisSession, symbolBuilder)
else -> handleUnknownFirElement(expression, analysisSession, session, symbolBuilder) else -> handleUnknownFirElement(expression, analysisSession, session, symbolBuilder)
} }
} }
@OptIn(ExperimentalStdlibApi::class)
private fun getSymbolsByVariableAssignment(
fir: FirVariableAssignment,
session: FirSession,
symbolBuilder: KtSymbolByFirBuilder
): Collection<KtSymbol> = fir.calleeReference.toTargetSymbol(session, symbolBuilder)
private fun getSymbolsByNameArgumentExpression( private fun getSymbolsByNameArgumentExpression(
expression: KtSimpleNameExpression, expression: KtSimpleNameExpression,
analysisSession: KtFirAnalysisSession, analysisSession: KtFirAnalysisSession,
@@ -0,0 +1,27 @@
class A {
var something: Int = 10
}
fun A.foo(a: A) {
print(a.<caret>something)
a.<caret>something = 1
a.<caret>something += 1
a.<caret>something++
--a.<caret>something
<caret>something++
(<caret>something)++
(<caret>something) = 1
(a.<caret>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
@@ -0,0 +1,29 @@
class A {
var something: Int
set(value) {}
get() = 10
}
fun A.foo(a: A) {
print(a.<caret>something)
a.<caret>something = 1
a.<caret>something += 1
a.<caret>something++
--a.<caret>something
<caret>something++
(<caret>something)++
(<caret>something) = 1
(a.<caret>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
@@ -254,6 +254,16 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest
runTest("idea/testData/resolve/references/JavaReference.kt"); 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") @TestMetadata("MultiDeclarationExtension.kt")
public void testMultiDeclarationExtension() throws Exception { public void testMultiDeclarationExtension() throws Exception {
runTest("idea/testData/resolve/references/MultiDeclarationExtension.kt"); runTest("idea/testData/resolve/references/MultiDeclarationExtension.kt");