[FIR IDE] Fix resolving sugared compound operators (like +=, -=)
^KTIJ-21374 Fixed
This commit is contained in:
+25
-5
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.idea.references
|
|||||||
|
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.*
|
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirPackageSymbol
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirPackageSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||||
@@ -201,7 +204,7 @@ 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 FirVariableAssignment -> getSymbolsByVariableAssignment(fir, expression, session, symbolBuilder)
|
||||||
is FirResolvedNamedReference -> getSymbolByResolvedNameReference(fir, expression, analysisSession, session, symbolBuilder)
|
is FirResolvedNamedReference -> getSymbolByResolvedNameReference(fir, expression, analysisSession, session, symbolBuilder)
|
||||||
is FirDelegatedConstructorCall ->
|
is FirDelegatedConstructorCall ->
|
||||||
getSymbolByDelegatedConstructorCall(expression, adjustedResolutionExpression, fir, session, symbolBuilder)
|
getSymbolByDelegatedConstructorCall(expression, adjustedResolutionExpression, fir, session, symbolBuilder)
|
||||||
@@ -268,12 +271,29 @@ internal object FirReferenceResolveHelper {
|
|||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalStdlibApi::class)
|
|
||||||
private fun getSymbolsByVariableAssignment(
|
private fun getSymbolsByVariableAssignment(
|
||||||
fir: FirVariableAssignment,
|
fir: FirVariableAssignment,
|
||||||
|
expression: KtSimpleNameExpression,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
symbolBuilder: KtSymbolByFirBuilder
|
symbolBuilder: KtSymbolByFirBuilder,
|
||||||
): Collection<KtSymbol> = fir.calleeReference.toTargetSymbol(session, symbolBuilder)
|
): Collection<KtSymbol> {
|
||||||
|
if (expression is KtNameReferenceExpression) {
|
||||||
|
return fir.calleeReference.toTargetSymbol(session, symbolBuilder)
|
||||||
|
}
|
||||||
|
|
||||||
|
val assignmentRValue = fir.rValue
|
||||||
|
if (expression is KtOperationReferenceExpression &&
|
||||||
|
assignmentRValue.source?.kind is KtFakeSourceElementKind.DesugaredCompoundAssignment
|
||||||
|
) {
|
||||||
|
require(assignmentRValue is FirResolvable) {
|
||||||
|
"Rvalue of desugared compound assignment should be resolvable, but it was ${assignmentRValue::class}"
|
||||||
|
}
|
||||||
|
|
||||||
|
return assignmentRValue.calleeReference.toTargetSymbol(session, symbolBuilder)
|
||||||
|
}
|
||||||
|
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun getSymbolsByNameArgumentExpression(
|
private fun getSymbolsByNameArgumentExpression(
|
||||||
expression: KtSimpleNameExpression,
|
expression: KtSimpleNameExpression,
|
||||||
|
|||||||
+18
@@ -334,6 +334,24 @@ public class FirLibrarySourceReferenceResolveTestGenerated extends AbstractRefer
|
|||||||
runTest("analysis/analysis-api/testData/referenceResolve/parameterByName.kt");
|
runTest("analysis/analysis-api/testData/referenceResolve/parameterByName.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("PlusAssignByHand.kt")
|
||||||
|
public void testPlusAssignByHand() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/referenceResolve/PlusAssignByHand.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("PlusAssignOperator.kt")
|
||||||
|
public void testPlusAssignOperator() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/referenceResolve/PlusAssignOperator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("PlusAssignViaPlusOperator.kt")
|
||||||
|
public void testPlusAssignViaPlusOperator() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/referenceResolve/PlusAssignViaPlusOperator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ReferenceInClassWhereConstraint.kt")
|
@TestMetadata("ReferenceInClassWhereConstraint.kt")
|
||||||
public void testReferenceInClassWhereConstraint() throws Exception {
|
public void testReferenceInClassWhereConstraint() throws Exception {
|
||||||
|
|||||||
+18
@@ -334,6 +334,24 @@ public class FirSourceReferenceResolveTestGenerated extends AbstractReferenceRes
|
|||||||
runTest("analysis/analysis-api/testData/referenceResolve/parameterByName.kt");
|
runTest("analysis/analysis-api/testData/referenceResolve/parameterByName.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("PlusAssignByHand.kt")
|
||||||
|
public void testPlusAssignByHand() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/referenceResolve/PlusAssignByHand.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("PlusAssignOperator.kt")
|
||||||
|
public void testPlusAssignOperator() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/referenceResolve/PlusAssignOperator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("PlusAssignViaPlusOperator.kt")
|
||||||
|
public void testPlusAssignViaPlusOperator() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/referenceResolve/PlusAssignViaPlusOperator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ReferenceInClassWhereConstraint.kt")
|
@TestMetadata("ReferenceInClassWhereConstraint.kt")
|
||||||
public void testReferenceInClassWhereConstraint() throws Exception {
|
public void testReferenceInClassWhereConstraint() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// UNRESOLVED_REFERENCE
|
||||||
|
package test
|
||||||
|
|
||||||
|
interface Foo
|
||||||
|
|
||||||
|
interface WithOperator {
|
||||||
|
operator fun plus(f: Foo): WithOperator
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(withOperator: WithOperator, foo: Foo) {
|
||||||
|
var variable = withOperator
|
||||||
|
variable <caret>= variable + foo
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
interface Foo
|
||||||
|
|
||||||
|
interface WithOperator {
|
||||||
|
operator fun plusAssign(f: Foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(withOperator: WithOperator, foo: Foo) {
|
||||||
|
withOperator <caret>+= foo
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in test.WithOperator) operator fun plusAssign(f: test.Foo)
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
interface Foo
|
||||||
|
|
||||||
|
interface WithOperator {
|
||||||
|
operator fun plus(f: Foo): WithOperator
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(withOperator: WithOperator, foo: Foo) {
|
||||||
|
var variable = withOperator
|
||||||
|
variable <caret>+= foo
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in test.WithOperator) operator fun plus(f: test.Foo): test.WithOperator
|
||||||
Reference in New Issue
Block a user