[FIR] Fix FindReferencePositioningStrategy for light tree

There was a problem which causes to lookup for assign token inside
  functions from arguments of call
This commit is contained in:
Dmitriy Novozhilov
2022-03-11 11:38:04 +03:00
committed by teamcity
parent ade2307345
commit 6f64aedaf0
3 changed files with 14 additions and 4 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET
import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtStringTemplateExpressionElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
object LightTreePositioningStrategies {
val DEFAULT = object : LightTreePositioningStrategy() {
@@ -654,7 +655,7 @@ object LightTreePositioningStrategies {
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
when {
node.tokenType == KtNodeTypes.BINARY_EXPRESSION && tree.findDescendantByType(node, KtTokens.EQ) != null -> {
node.tokenType == KtNodeTypes.BINARY_EXPRESSION && tree.findDescendantByType(node, KtTokens.EQ, followFunctions = false) != null -> {
// Look for reference in LHS of variable assignment.
tree.findExpressionDeep(node)?.let {
return markElement(it, startOffset, endOffset, tree, node)
@@ -1396,11 +1397,19 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.findLastChildByType(node: Ligh
return childrenRef.get()?.lastOrNull { it?.tokenType == type }
}
fun FlyweightCapableTreeStructure<LighterASTNode>.findDescendantByType(node: LighterASTNode, type: IElementType): LighterASTNode? {
fun FlyweightCapableTreeStructure<LighterASTNode>.findDescendantByType(
node: LighterASTNode,
type: IElementType,
followFunctions: Boolean = true
): LighterASTNode? {
val childrenRef = Ref<Array<LighterASTNode?>>()
getChildren(node, childrenRef)
return childrenRef.get()?.firstOrNull { it?.tokenType == type } ?: childrenRef.get()
?.firstNotNullOfOrNull { child -> child?.let { findDescendantByType(it, type) } }
?.firstNotNullOfOrNull { child ->
runUnless(!followFunctions && child?.tokenType == KtNodeTypes.FUN) {
child?.let { findDescendantByType(it, type, followFunctions) }
}
}
}
fun FlyweightCapableTreeStructure<LighterASTNode>.findDescendantByTypes(node: LighterASTNode, types: TokenSet): LighterASTNode? {
@@ -14,7 +14,7 @@ fun <T> id(x: T) = x
fun main() {
var newValue = A()
newValue <!ASSIGN_OPERATOR_AMBIGUITY!>+=<!> id { total -> A() }
<!ASSIGN_OPERATOR_AMBIGUITY!>newValue<!> += id(fun(total) = A())
newValue <!ASSIGN_OPERATOR_AMBIGUITY!>+=<!> id(fun(total) = A())
newValue <!ASSIGN_OPERATOR_AMBIGUITY!>+=<!> id(fun(total): A { return A() })
newValue <!ASSIGN_OPERATOR_AMBIGUITY!>+=<!> id(::foo)
}
@@ -178,6 +178,7 @@ inline fun <T, R> Iterable<T>.same(extractor: (T) -> R): Boolean {
}
inline fun <R> runIf(condition: Boolean, block: () -> R): R? = if (condition) block() else null
inline fun <R> runUnless(condition: Boolean, block: () -> R): R? = if (condition) null else block()
inline fun <T, R> Collection<T>.foldMap(transform: (T) -> R, operation: (R, R) -> R): R {
val iterator = iterator()