[FIR] Handle pre/postfix dec/increment of labeled expression

This commit is contained in:
Mark Punzalan
2020-09-18 22:42:29 -07:00
committed by Mikhail Glukhikh
parent f55ff8eb1b
commit 8cac3f654c
5 changed files with 44 additions and 31 deletions
@@ -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
@@ -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)++
}