[FIR] Fix computing labels of anonymous functions (not lambdas)

This commit is contained in:
Dmitriy Novozhilov
2021-03-31 13:40:03 +03:00
committed by TeamCityServer
parent 8a549cafec
commit 22cbb8720a
6 changed files with 15 additions and 7 deletions
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.lexer.KtToken import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.stubs.elements.KtFunctionElementType
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
abstract class BaseConverter( abstract class BaseConverter(
@@ -54,6 +55,9 @@ abstract class BaseConverter(
} }
override fun LighterASTNode.getLabelName(): String? { override fun LighterASTNode.getLabelName(): String? {
if (tokenType == KtNodeTypes.FUN) {
return getParent()?.getLabelName()
}
this.forEachChildren { this.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
KtNodeTypes.LABEL_QUALIFIER -> return it.asText.replaceFirst("@", "") KtNodeTypes.LABEL_QUALIFIER -> return it.asText.replaceFirst("@", "")
@@ -1327,7 +1327,8 @@ class DeclarationsConverter(
val isLocal = !(parentNode?.tokenType == KT_FILE || parentNode?.tokenType == CLASS_BODY) val isLocal = !(parentNode?.tokenType == KT_FILE || parentNode?.tokenType == CLASS_BODY)
val target: FirFunctionTarget val target: FirFunctionTarget
val functionBuilder = if (identifier == null && isLocal) { val functionBuilder = if (identifier == null && isLocal) {
target = FirFunctionTarget(labelName = functionDeclaration.getLabelName(), isLambda = false) val labelName = functionDeclaration.getLabelName() ?: context.calleeNamesForLambda.lastOrNull()?.identifier
target = FirFunctionTarget(labelName = labelName, isLambda = false)
FirAnonymousFunctionBuilder().apply { FirAnonymousFunctionBuilder().apply {
source = functionDeclaration.toFirSourceElement() source = functionDeclaration.toFirSourceElement()
receiverTypeRef = receiverType receiverTypeRef = receiverType
@@ -99,7 +99,11 @@ open class RawFirBuilder(
} }
override fun PsiElement.getLabelName(): String? { override fun PsiElement.getLabelName(): String? {
return (this as? KtExpressionWithLabel)?.getLabelName() return when (this) {
is KtExpressionWithLabel -> getLabelName()
is KtNamedFunction -> parent.getLabelName()
else -> null
}
} }
override fun PsiElement.getExpressionInParentheses(): PsiElement? { override fun PsiElement.getExpressionInParentheses(): PsiElement? {
@@ -967,7 +971,7 @@ open class RawFirBuilder(
receiverTypeRef = receiverType receiverTypeRef = receiverType
symbol = FirAnonymousFunctionSymbol() symbol = FirAnonymousFunctionSymbol()
isLambda = false isLambda = false
labelName = function.getLabelName() labelName = function.getLabelName() ?: context.calleeNamesForLambda.lastOrNull()?.identifier
} }
} else { } else {
FirSimpleFunctionBuilder().apply { FirSimpleFunctionBuilder().apply {
@@ -14,7 +14,7 @@ FILE: lambdaAndAnonymousFunction.kt
} }
public? final? fun test_2(): R|kotlin/Unit| { public? final? fun test_2(): R|kotlin/Unit| {
run#(fun <anonymous>(): Int <inline=Unknown> { run#(fun <anonymous>(): Int <inline=Unknown> {
^ IntegerLiteral(1) ^@run IntegerLiteral(1)
} }
) )
} }
@@ -31,7 +31,7 @@ FILE: locals.kt
} }
.foo#() .foo#()
^withLocals sum#(code#, Local#(IntegerLiteral(1)).diff#(), fun <anonymous>(x: Int, y: Int): <implicit> <inline=Unknown> { ^withLocals sum#(code#, Local#(IntegerLiteral(1)).diff#(), fun <anonymous>(x: Int, y: Int): <implicit> <inline=Unknown> {
^ x#.plus#(y#) ^@sum x#.plus#(y#)
} }
) )
} }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun simple() = fun (): Boolean { return true } fun simple() = fun (): Boolean { return true }
fun withLabel() = l@ fun (): Boolean { return@l true } fun withLabel() = l@ fun (): Boolean { return@l true }
@@ -8,4 +7,4 @@ fun box(): String {
if (!withLabel()()) return "Test withLabel failed" if (!withLabel()()) return "Test withLabel failed"
return "OK" return "OK"
} }