[FIR] Handle pre/postfix dec/increment of labeled expression
This commit is contained in:
committed by
Mikhail Glukhikh
parent
f55ff8eb1b
commit
8cac3f654c
+15
-6
@@ -62,20 +62,29 @@ open class BaseConverter(
|
||||
return null
|
||||
}
|
||||
|
||||
override fun LighterASTNode.getExpressionInParentheses(): LighterASTNode? {
|
||||
this.forEachChildren {
|
||||
override fun LighterASTNode.getExpressionInParentheses() = getFirstChildExpression()
|
||||
|
||||
override fun LighterASTNode.getAnnotatedExpression() = getFirstChildExpression()
|
||||
|
||||
override fun LighterASTNode.getLabeledExpression() = getLastChildExpression()
|
||||
|
||||
private fun LighterASTNode.getFirstChildExpression(): LighterASTNode? {
|
||||
forEachChildren {
|
||||
if (it.isExpression()) return it
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun LighterASTNode.getAnnotatedExpression(): LighterASTNode? {
|
||||
this.forEachChildren {
|
||||
if (it.isExpression()) return it
|
||||
private fun LighterASTNode.getLastChildExpression(): LighterASTNode? {
|
||||
var result: LighterASTNode? = null
|
||||
forEachChildren {
|
||||
if (it.isExpression()) {
|
||||
result = it
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return result
|
||||
}
|
||||
|
||||
override fun LighterASTNode.getChildNodeByType(type: IElementType): LighterASTNode? {
|
||||
|
||||
@@ -122,6 +122,10 @@ class RawFirBuilder(
|
||||
return (this as KtAnnotatedExpression).baseExpression
|
||||
}
|
||||
|
||||
override fun PsiElement.getLabeledExpression(): PsiElement? {
|
||||
return (this as KtLabeledExpression).baseExpression
|
||||
}
|
||||
|
||||
override val PsiElement?.receiverExpression: PsiElement?
|
||||
get() = (this as? KtQualifiedExpression)?.receiverExpression
|
||||
|
||||
|
||||
+22
-21
@@ -51,6 +51,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
abstract fun T.getLabelName(): String?
|
||||
abstract fun T.getExpressionInParentheses(): T?
|
||||
abstract fun T.getAnnotatedExpression(): T?
|
||||
abstract fun T.getLabeledExpression(): T?
|
||||
abstract fun T.getChildNodeByType(type: IElementType): T?
|
||||
abstract val T?.receiverExpression: T?
|
||||
abstract val T?.selectorExpression: T?
|
||||
@@ -405,29 +406,29 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
prefix: Boolean,
|
||||
convert: T.() -> FirExpression
|
||||
): FirExpression {
|
||||
if (argument == null) {
|
||||
// NOTE: By removing surrounding parentheses and labels, FirLabels will NOT be created for those labels.
|
||||
// This should be fine since the label is meaningless and unusable for a ++/-- argument.
|
||||
var unwrappedArgument = argument
|
||||
while (true) {
|
||||
unwrappedArgument = when (unwrappedArgument?.elementType) {
|
||||
PARENTHESIZED -> unwrappedArgument?.getExpressionInParentheses()
|
||||
LABELED_EXPRESSION -> unwrappedArgument?.getLabeledExpression()
|
||||
else -> break
|
||||
}
|
||||
}
|
||||
|
||||
if (unwrappedArgument == null) {
|
||||
return buildErrorExpression {
|
||||
source = argument
|
||||
source = unwrappedArgument
|
||||
diagnostic = ConeSimpleDiagnostic("Inc/dec without operand", DiagnosticKind.Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
if (argument.elementType == PARENTHESIZED) {
|
||||
return generateIncrementOrDecrementBlock(
|
||||
baseExpression,
|
||||
operationReference,
|
||||
argument.getExpressionInParentheses(),
|
||||
callName,
|
||||
prefix,
|
||||
convert
|
||||
)
|
||||
}
|
||||
|
||||
if (argument.elementType == DOT_QUALIFIED_EXPRESSION) {
|
||||
if (unwrappedArgument.elementType == DOT_QUALIFIED_EXPRESSION) {
|
||||
return generateIncrementOrDecrementBlockForQualifiedAccess(
|
||||
baseExpression,
|
||||
operationReference,
|
||||
argument,
|
||||
unwrappedArgument,
|
||||
callName,
|
||||
prefix,
|
||||
convert
|
||||
@@ -444,7 +445,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
this@BaseFirBuilder.baseSession,
|
||||
desugaredSource,
|
||||
Name.special("<unary>"),
|
||||
argument.convert()
|
||||
unwrappedArgument.convert()
|
||||
)
|
||||
|
||||
// resultInitializer is the expression for `argument.inc()`
|
||||
@@ -455,7 +456,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
name = callName
|
||||
}
|
||||
explicitReceiver = if (prefix) {
|
||||
argument.convert()
|
||||
unwrappedArgument.convert()
|
||||
} else {
|
||||
generateResolvedAccessExpression(desugaredSource, initialValueVar)
|
||||
}
|
||||
@@ -469,10 +470,10 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
resultInitializer
|
||||
)
|
||||
|
||||
val assignment = argument.generateAssignment(
|
||||
val assignment = unwrappedArgument.generateAssignment(
|
||||
desugaredSource,
|
||||
null,
|
||||
if (prefix && argument.elementType != REFERENCE_EXPRESSION)
|
||||
if (prefix && unwrappedArgument.elementType != REFERENCE_EXPRESSION)
|
||||
generateResolvedAccessExpression(source, resultVar)
|
||||
else
|
||||
resultInitializer,
|
||||
@@ -488,13 +489,13 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
if (argument.elementType != REFERENCE_EXPRESSION) {
|
||||
if (unwrappedArgument.elementType != REFERENCE_EXPRESSION) {
|
||||
statements += resultVar
|
||||
appendAssignment()
|
||||
statements += generateResolvedAccessExpression(desugaredSource, resultVar)
|
||||
} else {
|
||||
appendAssignment()
|
||||
statements += generateAccessExpression(desugaredSource, argument.getReferencedNameAsName())
|
||||
statements += generateAccessExpression(desugaredSource, unwrappedArgument.getReferencedNameAsName())
|
||||
}
|
||||
} else {
|
||||
statements += initialValueVar
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
fun box(): String {
|
||||
var x = 1
|
||||
(foo@ x)++
|
||||
|
||||
@@ -78,10 +78,10 @@ class Test() {
|
||||
(f@ <!VARIABLE_EXPECTED!>getInt()<!>) += 343
|
||||
|
||||
<!VARIABLE_EXPECTED!>1<!>++
|
||||
(<!VARIABLE_EXPECTED!>r@ 1<!>)++
|
||||
(r@ <!VARIABLE_EXPECTED!>1<!>)++
|
||||
|
||||
<!VARIABLE_EXPECTED!>getInt()<!>++
|
||||
(<!VARIABLE_EXPECTED!>m@ getInt()<!>)++
|
||||
(m@ <!VARIABLE_EXPECTED!>getInt()<!>)++
|
||||
|
||||
this<!UNRESOLVED_REFERENCE!>++<!>
|
||||
|
||||
@@ -106,7 +106,7 @@ class Test() {
|
||||
<!VARIABLE_EXPECTED!>b<!> += 34
|
||||
|
||||
a++
|
||||
(<!VARIABLE_EXPECTED!>l@ a<!>)++
|
||||
(l@ a)++
|
||||
(a)++
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user