Set correct IR origins for inc/dec operations

NB: in order to produce correct IR origins, the source element kinds for
some FIR elements has been changed. As a side effect, mapping PSI to FIR
slightly changed: namely, for `a[b]++`, `a[b]` used to be mapped on
`set` call or callable reference, but now it is mapped on `get` call.

^KT-61891: Fixed
^KT-64387: Fixed
This commit is contained in:
vladislav.grechko
2023-12-28 17:12:17 +01:00
committed by Space Team
parent 8b1d87848d
commit 9aa8fb80e7
65 changed files with 463 additions and 972 deletions
@@ -14,6 +14,8 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.tree.IElementType
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.getElementTextWithContext
sealed class KtSourceElementKind {
@@ -146,16 +148,16 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor
// x++ -> x = x.inc()
// x = x++ -> x = { val <unary> = x; x = <unary>.inc(); <unary> }
object DesugaredIncrementOrDecrement : KtFakeSourceElementKind()
sealed class DesugaredIncrementOrDecrement : KtFakeSourceElementKind()
object DesugaredPrefixInc : DesugaredIncrementOrDecrement()
object DesugaredPrefixDec : DesugaredIncrementOrDecrement()
object DesugaredPostfixInc : DesugaredIncrementOrDecrement()
object DesugaredPostfixDec : DesugaredIncrementOrDecrement()
// In ++a[1], a.get(1) will be called twice. This kind is used for the second call reference.
object DesugaredPrefixSecondGetReference : KtFakeSourceElementKind()
// ++x --> `inc` calleeReference
object DesugaredPrefixNameReference : KtFakeSourceElementKind()
// x++ --> `inc` calleeReference
object DesugaredPostfixNameReference : KtFakeSourceElementKind()
sealed class DesugaredPrefixSecondGetReference : KtFakeSourceElementKind()
object DesugaredPrefixIncSecondGetReference : DesugaredPrefixSecondGetReference()
object DesugaredPrefixDecSecondGetReference : DesugaredPrefixSecondGetReference()
// x !in list --> !(x in list) where ! and !(x in list) will have a fake source
object DesugaredInvertedContains : KtFakeSourceElementKind()
@@ -608,5 +610,19 @@ inline fun LighterASTNode.toKtLightSourceElement(
tree: FlyweightCapableTreeStructure<LighterASTNode>,
kind: KtSourceElementKind = KtRealSourceElementKind,
startOffset: Int = this.startOffset,
endOffset: Int = this.endOffset
endOffset: Int = this.endOffset,
): KtLightSourceElement = KtLightSourceElement(this, startOffset, endOffset, tree, kind)
fun sourceKindForIncOrDec(operation: Name, isPrefix: Boolean) = when (operation) {
OperatorNameConventions.INC -> if (isPrefix) {
KtFakeSourceElementKind.DesugaredPrefixInc
} else {
KtFakeSourceElementKind.DesugaredPostfixInc
}
OperatorNameConventions.DEC -> if (isPrefix) {
KtFakeSourceElementKind.DesugaredPrefixDec
} else {
KtFakeSourceElementKind.DesugaredPostfixDec
}
else -> error("Unexpected operator: ${operation.identifier}")
}