[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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun LighterASTNode.getExpressionInParentheses(): LighterASTNode? {
|
override fun LighterASTNode.getExpressionInParentheses() = getFirstChildExpression()
|
||||||
this.forEachChildren {
|
|
||||||
|
override fun LighterASTNode.getAnnotatedExpression() = getFirstChildExpression()
|
||||||
|
|
||||||
|
override fun LighterASTNode.getLabeledExpression() = getLastChildExpression()
|
||||||
|
|
||||||
|
private fun LighterASTNode.getFirstChildExpression(): LighterASTNode? {
|
||||||
|
forEachChildren {
|
||||||
if (it.isExpression()) return it
|
if (it.isExpression()) return it
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun LighterASTNode.getAnnotatedExpression(): LighterASTNode? {
|
private fun LighterASTNode.getLastChildExpression(): LighterASTNode? {
|
||||||
this.forEachChildren {
|
var result: LighterASTNode? = null
|
||||||
if (it.isExpression()) return it
|
forEachChildren {
|
||||||
|
if (it.isExpression()) {
|
||||||
|
result = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun LighterASTNode.getChildNodeByType(type: IElementType): LighterASTNode? {
|
override fun LighterASTNode.getChildNodeByType(type: IElementType): LighterASTNode? {
|
||||||
|
|||||||
@@ -122,6 +122,10 @@ class RawFirBuilder(
|
|||||||
return (this as KtAnnotatedExpression).baseExpression
|
return (this as KtAnnotatedExpression).baseExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun PsiElement.getLabeledExpression(): PsiElement? {
|
||||||
|
return (this as KtLabeledExpression).baseExpression
|
||||||
|
}
|
||||||
|
|
||||||
override val PsiElement?.receiverExpression: PsiElement?
|
override val PsiElement?.receiverExpression: PsiElement?
|
||||||
get() = (this as? KtQualifiedExpression)?.receiverExpression
|
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.getLabelName(): String?
|
||||||
abstract fun T.getExpressionInParentheses(): T?
|
abstract fun T.getExpressionInParentheses(): T?
|
||||||
abstract fun T.getAnnotatedExpression(): T?
|
abstract fun T.getAnnotatedExpression(): T?
|
||||||
|
abstract fun T.getLabeledExpression(): T?
|
||||||
abstract fun T.getChildNodeByType(type: IElementType): T?
|
abstract fun T.getChildNodeByType(type: IElementType): T?
|
||||||
abstract val T?.receiverExpression: T?
|
abstract val T?.receiverExpression: T?
|
||||||
abstract val T?.selectorExpression: T?
|
abstract val T?.selectorExpression: T?
|
||||||
@@ -405,29 +406,29 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
prefix: Boolean,
|
prefix: Boolean,
|
||||||
convert: T.() -> FirExpression
|
convert: T.() -> FirExpression
|
||||||
): 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 {
|
return buildErrorExpression {
|
||||||
source = argument
|
source = unwrappedArgument
|
||||||
diagnostic = ConeSimpleDiagnostic("Inc/dec without operand", DiagnosticKind.Syntax)
|
diagnostic = ConeSimpleDiagnostic("Inc/dec without operand", DiagnosticKind.Syntax)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argument.elementType == PARENTHESIZED) {
|
if (unwrappedArgument.elementType == DOT_QUALIFIED_EXPRESSION) {
|
||||||
return generateIncrementOrDecrementBlock(
|
|
||||||
baseExpression,
|
|
||||||
operationReference,
|
|
||||||
argument.getExpressionInParentheses(),
|
|
||||||
callName,
|
|
||||||
prefix,
|
|
||||||
convert
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argument.elementType == DOT_QUALIFIED_EXPRESSION) {
|
|
||||||
return generateIncrementOrDecrementBlockForQualifiedAccess(
|
return generateIncrementOrDecrementBlockForQualifiedAccess(
|
||||||
baseExpression,
|
baseExpression,
|
||||||
operationReference,
|
operationReference,
|
||||||
argument,
|
unwrappedArgument,
|
||||||
callName,
|
callName,
|
||||||
prefix,
|
prefix,
|
||||||
convert
|
convert
|
||||||
@@ -444,7 +445,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
this@BaseFirBuilder.baseSession,
|
this@BaseFirBuilder.baseSession,
|
||||||
desugaredSource,
|
desugaredSource,
|
||||||
Name.special("<unary>"),
|
Name.special("<unary>"),
|
||||||
argument.convert()
|
unwrappedArgument.convert()
|
||||||
)
|
)
|
||||||
|
|
||||||
// resultInitializer is the expression for `argument.inc()`
|
// resultInitializer is the expression for `argument.inc()`
|
||||||
@@ -455,7 +456,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
name = callName
|
name = callName
|
||||||
}
|
}
|
||||||
explicitReceiver = if (prefix) {
|
explicitReceiver = if (prefix) {
|
||||||
argument.convert()
|
unwrappedArgument.convert()
|
||||||
} else {
|
} else {
|
||||||
generateResolvedAccessExpression(desugaredSource, initialValueVar)
|
generateResolvedAccessExpression(desugaredSource, initialValueVar)
|
||||||
}
|
}
|
||||||
@@ -469,10 +470,10 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
resultInitializer
|
resultInitializer
|
||||||
)
|
)
|
||||||
|
|
||||||
val assignment = argument.generateAssignment(
|
val assignment = unwrappedArgument.generateAssignment(
|
||||||
desugaredSource,
|
desugaredSource,
|
||||||
null,
|
null,
|
||||||
if (prefix && argument.elementType != REFERENCE_EXPRESSION)
|
if (prefix && unwrappedArgument.elementType != REFERENCE_EXPRESSION)
|
||||||
generateResolvedAccessExpression(source, resultVar)
|
generateResolvedAccessExpression(source, resultVar)
|
||||||
else
|
else
|
||||||
resultInitializer,
|
resultInitializer,
|
||||||
@@ -488,13 +489,13 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (prefix) {
|
if (prefix) {
|
||||||
if (argument.elementType != REFERENCE_EXPRESSION) {
|
if (unwrappedArgument.elementType != REFERENCE_EXPRESSION) {
|
||||||
statements += resultVar
|
statements += resultVar
|
||||||
appendAssignment()
|
appendAssignment()
|
||||||
statements += generateResolvedAccessExpression(desugaredSource, resultVar)
|
statements += generateResolvedAccessExpression(desugaredSource, resultVar)
|
||||||
} else {
|
} else {
|
||||||
appendAssignment()
|
appendAssignment()
|
||||||
statements += generateAccessExpression(desugaredSource, argument.getReferencedNameAsName())
|
statements += generateAccessExpression(desugaredSource, unwrappedArgument.getReferencedNameAsName())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
statements += initialValueVar
|
statements += initialValueVar
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var x = 1
|
var x = 1
|
||||||
(foo@ x)++
|
(foo@ x)++
|
||||||
|
|||||||
@@ -78,10 +78,10 @@ class Test() {
|
|||||||
(f@ <!VARIABLE_EXPECTED!>getInt()<!>) += 343
|
(f@ <!VARIABLE_EXPECTED!>getInt()<!>) += 343
|
||||||
|
|
||||||
<!VARIABLE_EXPECTED!>1<!>++
|
<!VARIABLE_EXPECTED!>1<!>++
|
||||||
(<!VARIABLE_EXPECTED!>r@ 1<!>)++
|
(r@ <!VARIABLE_EXPECTED!>1<!>)++
|
||||||
|
|
||||||
<!VARIABLE_EXPECTED!>getInt()<!>++
|
<!VARIABLE_EXPECTED!>getInt()<!>++
|
||||||
(<!VARIABLE_EXPECTED!>m@ getInt()<!>)++
|
(m@ <!VARIABLE_EXPECTED!>getInt()<!>)++
|
||||||
|
|
||||||
this<!UNRESOLVED_REFERENCE!>++<!>
|
this<!UNRESOLVED_REFERENCE!>++<!>
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ class Test() {
|
|||||||
<!VARIABLE_EXPECTED!>b<!> += 34
|
<!VARIABLE_EXPECTED!>b<!> += 34
|
||||||
|
|
||||||
a++
|
a++
|
||||||
(<!VARIABLE_EXPECTED!>l@ a<!>)++
|
(l@ a)++
|
||||||
(a)++
|
(a)++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user