K2: handle suspend anonymous functions properly in various compiler parts

#KT-58332 Fixed
This commit is contained in:
Mikhail Glukhikh
2023-05-05 11:56:37 +02:00
committed by Space Team
parent aec0def5ca
commit 0906258d03
24 changed files with 95 additions and 19 deletions
@@ -32222,6 +32222,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt"); runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt");
} }
@Test
@TestMetadata("suspendCallFromAnonymousSuspend.kt")
public void testSuspendCallFromAnonymousSuspend() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendCallFromAnonymousSuspend.kt");
}
@Test @Test
@TestMetadata("suspendConversionCompatibility.kt") @TestMetadata("suspendConversionCompatibility.kt")
public void testSuspendConversionCompatibility() throws Exception { public void testSuspendConversionCompatibility() throws Exception {
@@ -32222,6 +32222,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt"); runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt");
} }
@Test
@TestMetadata("suspendCallFromAnonymousSuspend.kt")
public void testSuspendCallFromAnonymousSuspend() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendCallFromAnonymousSuspend.kt");
}
@Test @Test
@TestMetadata("suspendConversionCompatibility.kt") @TestMetadata("suspendConversionCompatibility.kt")
public void testSuspendConversionCompatibility() throws Exception { public void testSuspendConversionCompatibility() throws Exception {
@@ -32222,6 +32222,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt"); runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt");
} }
@Test
@TestMetadata("suspendCallFromAnonymousSuspend.kt")
public void testSuspendCallFromAnonymousSuspend() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendCallFromAnonymousSuspend.kt");
}
@Test @Test
@TestMetadata("suspendConversionCompatibility.kt") @TestMetadata("suspendConversionCompatibility.kt")
public void testSuspendConversionCompatibility() throws Exception { public void testSuspendConversionCompatibility() throws Exception {
@@ -32318,6 +32318,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt"); runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt");
} }
@Test
@TestMetadata("suspendCallFromAnonymousSuspend.kt")
public void testSuspendCallFromAnonymousSuspend() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendCallFromAnonymousSuspend.kt");
}
@Test @Test
@TestMetadata("suspendConversionCompatibility.kt") @TestMetadata("suspendConversionCompatibility.kt")
public void testSuspendConversionCompatibility() throws Exception { public void testSuspendConversionCompatibility() throws Exception {
@@ -130,9 +130,12 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
private fun findEnclosingSuspendFunction(context: CheckerContext): FirFunction? { private fun findEnclosingSuspendFunction(context: CheckerContext): FirFunction? {
return context.containingDeclarations.lastOrNull { return context.containingDeclarations.lastOrNull {
when (it) { when (it) {
is FirAnonymousFunction -> it.typeRef.coneType.isSuspendOrKSuspendFunctionType(context.session) is FirAnonymousFunction ->
is FirSimpleFunction -> it.isSuspend if (it.isLambda) it.typeRef.coneType.isSuspendOrKSuspendFunctionType(context.session) else it.isSuspend
else -> false is FirSimpleFunction ->
it.isSuspend
else ->
false
} }
} as? FirFunction } as? FirFunction
} }
@@ -505,7 +505,7 @@ class FirElementSerializer private constructor(
simpleFunction?.isInline == true, simpleFunction?.isInline == true,
simpleFunction?.isTailRec == true, simpleFunction?.isTailRec == true,
simpleFunction?.isExternal == true, simpleFunction?.isExternal == true,
simpleFunction?.isSuspend == true, function.isSuspend,
simpleFunction?.isExpect == true, simpleFunction?.isExpect == true,
shouldSetStableParameterNames(function), shouldSetStableParameterNames(function),
) )
@@ -227,6 +227,7 @@ private fun FirFunction.copyToFreeAnonymousFunction(approximator: AbstractTypeAp
} }
}) })
typeParameters += typeParameterSet typeParameters += typeParameterSet
status = function.status
} }
} }
@@ -564,7 +564,7 @@ class Fir2IrDeclarationStorage(
val visibility = simpleFunction?.visibility ?: Visibilities.Local val visibility = simpleFunction?.visibility ?: Visibilities.Local
val isSuspend = val isSuspend =
if (isLambda) ((function as FirAnonymousFunction).typeRef as? FirResolvedTypeRef)?.type?.isSuspendOrKSuspendFunctionType(session) == true if (isLambda) ((function as FirAnonymousFunction).typeRef as? FirResolvedTypeRef)?.type?.isSuspendOrKSuspendFunctionType(session) == true
else simpleFunction?.isSuspend == true else function.isSuspend
val created = function.convertWithOffsets { startOffset, endOffset -> val created = function.convertWithOffsets { startOffset, endOffset ->
val result = declareIrSimpleFunction(signature) { symbol -> val result = declareIrSimpleFunction(signature) { symbol ->
classifierStorage.preCacheTypeParameters(function, symbol) classifierStorage.preCacheTypeParameters(function, symbol)
@@ -1660,6 +1660,9 @@ class DeclarationsConverter(
label = context.getLastLabel(functionDeclaration) label = context.getLastLabel(functionDeclaration)
val labelName = label?.name ?: context.calleeNamesForLambda.lastOrNull()?.identifier val labelName = label?.name ?: context.calleeNamesForLambda.lastOrNull()?.identifier
target = FirFunctionTarget(labelName = labelName, isLambda = false) target = FirFunctionTarget(labelName = labelName, isLambda = false)
if (modifiers.hasSuspend()) {
status = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_SUSPEND_FUNCTION_EXPRESSION
}
} }
} else { } else {
val functionName = identifier.nameAsSafeName() val functionName = identifier.nameAsSafeName()
@@ -1441,6 +1441,9 @@ open class RawFirBuilder(
hasExplicitParameterList = true hasExplicitParameterList = true
label = context.getLastLabel(function) label = context.getLastLabel(function)
labelName = label?.name ?: context.calleeNamesForLambda.lastOrNull()?.identifier labelName = label?.name ?: context.calleeNamesForLambda.lastOrNull()?.identifier
if (function.hasModifier(SUSPEND_KEYWORD)) {
status = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_SUSPEND_FUNCTION_EXPRESSION
}
} }
} else { } else {
FirSimpleFunctionBuilder().apply { FirSimpleFunctionBuilder().apply {
@@ -59,6 +59,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu
override lateinit var moduleData: FirModuleData override lateinit var moduleData: FirModuleData
override lateinit var origin: FirDeclarationOrigin override lateinit var origin: FirDeclarationOrigin
override var attributes: FirDeclarationAttributes = FirDeclarationAttributes() override var attributes: FirDeclarationAttributes = FirDeclarationAttributes()
override var status: FirDeclarationStatus = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
override lateinit var returnTypeRef: FirTypeRef override lateinit var returnTypeRef: FirTypeRef
var receiverParameter: FirReceiverParameter? = null var receiverParameter: FirReceiverParameter? = null
override var deprecationsProvider: DeprecationsProvider = UnresolvedDeprecationProvider override var deprecationsProvider: DeprecationsProvider = UnresolvedDeprecationProvider
@@ -86,6 +87,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu
moduleData, moduleData,
origin, origin,
attributes, attributes,
status,
returnTypeRef, returnTypeRef,
receiverParameter, receiverParameter,
deprecationsProvider, deprecationsProvider,
@@ -107,13 +109,6 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu
) )
} }
@Deprecated("Modification of 'status' has no impact for FirAnonymousFunctionBuilder", level = DeprecationLevel.HIDDEN)
override var status: FirDeclarationStatus
get() = throw IllegalStateException()
set(_) {
throw IllegalStateException()
}
} }
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
@@ -136,6 +131,7 @@ inline fun buildAnonymousFunctionCopy(original: FirAnonymousFunction, init: FirA
copyBuilder.moduleData = original.moduleData copyBuilder.moduleData = original.moduleData
copyBuilder.origin = original.origin copyBuilder.origin = original.origin
copyBuilder.attributes = original.attributes.copy() copyBuilder.attributes = original.attributes.copy()
copyBuilder.status = original.status
copyBuilder.returnTypeRef = original.returnTypeRef copyBuilder.returnTypeRef = original.returnTypeRef
copyBuilder.receiverParameter = original.receiverParameter copyBuilder.receiverParameter = original.receiverParameter
copyBuilder.deprecationsProvider = original.deprecationsProvider copyBuilder.deprecationsProvider = original.deprecationsProvider
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.InlineStatus import org.jetbrains.kotlin.fir.declarations.InlineStatus
import org.jetbrains.kotlin.fir.declarations.asResolveState import org.jetbrains.kotlin.fir.declarations.asResolveState
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
@@ -50,6 +49,7 @@ internal class FirAnonymousFunctionImpl(
override val moduleData: FirModuleData, override val moduleData: FirModuleData,
override val origin: FirDeclarationOrigin, override val origin: FirDeclarationOrigin,
override val attributes: FirDeclarationAttributes, override val attributes: FirDeclarationAttributes,
override var status: FirDeclarationStatus,
override var returnTypeRef: FirTypeRef, override var returnTypeRef: FirTypeRef,
override var receiverParameter: FirReceiverParameter?, override var receiverParameter: FirReceiverParameter?,
override var deprecationsProvider: DeprecationsProvider, override var deprecationsProvider: DeprecationsProvider,
@@ -69,8 +69,6 @@ internal class FirAnonymousFunctionImpl(
override val typeParameters: MutableList<FirTypeParameter>, override val typeParameters: MutableList<FirTypeParameter>,
override var typeRef: FirTypeRef, override var typeRef: FirTypeRef,
) : FirAnonymousFunction() { ) : FirAnonymousFunction() {
override var status: FirDeclarationStatus = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
init { init {
symbol.bind(this) symbol.bind(this)
@OptIn(ResolveStateAccess::class) @OptIn(ResolveStateAccess::class)
@@ -23,6 +23,11 @@ class FirResolvedDeclarationStatusImpl(
Modality.FINAL, Modality.FINAL,
EffectiveVisibility.Public EffectiveVisibility.Public
) )
val DEFAULT_STATUS_FOR_SUSPEND_FUNCTION_EXPRESSION = FirResolvedDeclarationStatusImpl(
Visibilities.Local,
Modality.FINAL,
EffectiveVisibility.Public
).apply { isSuspend = true }
} }
internal constructor( internal constructor(
@@ -96,4 +96,10 @@ class FirAllModifierRenderer : FirModifierRenderer() {
renderModifier("external") renderModifier("external")
} }
} }
override fun renderModifiers(anonymousFunction: FirAnonymousFunction) {
if (anonymousFunction.isSuspend) {
renderModifier("suspend")
}
}
} }
@@ -22,6 +22,7 @@ abstract class FirModifierRenderer {
abstract fun renderModifiers(backingField: FirBackingField) abstract fun renderModifiers(backingField: FirBackingField)
abstract fun renderModifiers(constructor: FirConstructor) abstract fun renderModifiers(constructor: FirConstructor)
abstract fun renderModifiers(propertyAccessor: FirPropertyAccessor) abstract fun renderModifiers(propertyAccessor: FirPropertyAccessor)
abstract fun renderModifiers(anonymousFunction: FirAnonymousFunction)
open fun renderModifiers(valueParameter: FirValueParameter) { open fun renderModifiers(valueParameter: FirValueParameter) {
if (valueParameter.isCrossinline) { if (valueParameter.isCrossinline) {
renderModifier("crossinline") renderModifier("crossinline")
@@ -57,4 +57,10 @@ class FirPartialModifierRenderer : FirModifierRenderer() {
override fun renderModifiers(propertyAccessor: FirPropertyAccessor) { override fun renderModifiers(propertyAccessor: FirPropertyAccessor) {
} }
override fun renderModifiers(anonymousFunction: FirAnonymousFunction) {
if (anonymousFunction.isSuspend) {
renderModifier("suspend")
}
}
} }
@@ -388,6 +388,7 @@ class FirRenderer(
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction) { override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
annotationRenderer?.render(anonymousFunction) annotationRenderer?.render(anonymousFunction)
modifierRenderer?.renderModifiers(anonymousFunction)
declarationRenderer?.render(anonymousFunction) declarationRenderer?.render(anonymousFunction)
print(" ") print(" ")
val receiverParameter = anonymousFunction.receiverParameter val receiverParameter = anonymousFunction.receiverParameter
@@ -271,8 +271,9 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
defaultNull("invocationKind", "label", "body", "controlFlowGraphReference") defaultNull("invocationKind", "label", "body", "controlFlowGraphReference")
default("inlineStatus", "InlineStatus.Unknown") default("inlineStatus", "InlineStatus.Unknown")
default("contractDescription", "FirEmptyContractDescription") default("contractDescription", "FirEmptyContractDescription")
default("status", "FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS")
withCopy() withCopy()
useTypes(emptyContractDescriptionType) useTypes(emptyContractDescriptionType, resolvedDeclarationStatusImport)
} }
builder(propertyAccessor) { builder(propertyAccessor) {
@@ -565,7 +565,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
impl(contractElementDeclaration) impl(contractElementDeclaration)
val implementationsWithoutStatusAndTypeParameters = listOf( val implementationsWithoutStatusAndTypeParameters = listOf(
"FirAnonymousFunctionImpl",
"FirValueParameterImpl", "FirValueParameterImpl",
"FirDefaultSetterValueParameter", "FirDefaultSetterValueParameter",
"FirErrorPropertyImpl", "FirErrorPropertyImpl",
@@ -582,7 +581,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
configureFieldInAllImplementations( configureFieldInAllImplementations(
"typeParameters", "typeParameters",
implementationPredicate = { it.type != "FirAnonymousFunctionImpl" && it.type in implementationsWithoutStatusAndTypeParameters } implementationPredicate = { it.type in implementationsWithoutStatusAndTypeParameters }
) { ) {
defaultEmptyList(it) defaultEmptyList(it)
useTypes(resolvedDeclarationStatusImplType) useTypes(resolvedDeclarationStatusImplType)
@@ -10,3 +10,4 @@ import org.jetbrains.kotlin.fir.tree.generator.model.ArbitraryImportable
val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState") val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState")
val resolvePhaseExtensionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "resolvePhase") val resolvePhaseExtensionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "resolvePhase")
val resolveStateAccessImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "ResolveStateAccess") val resolveStateAccessImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "ResolveStateAccess")
val resolvedDeclarationStatusImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations.impl", "FirResolvedDeclarationStatusImpl")
@@ -0,0 +1,9 @@
FILE: suspendCallFromAnonymousSuspend.kt
public final fun foo(): R|kotlin/Unit| {
suspend fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
R|/bar|()
}
}
public final suspend fun bar(): R|kotlin/Unit| {
}
@@ -0,0 +1,12 @@
// FIR_IDENTICAL
// FIR_DUMP
fun foo() {
suspend fun() {
bar()
}
}
suspend fun bar() {
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ISSUE: KT-58332 // ISSUE: KT-58332
fun foo() { fun foo() {
@@ -33090,6 +33090,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt"); runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendAndFunConversionInDisabledMode.kt");
} }
@Test
@TestMetadata("suspendCallFromAnonymousSuspend.kt")
public void testSuspendCallFromAnonymousSuspend() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendCallFromAnonymousSuspend.kt");
}
@Test @Test
@TestMetadata("suspendConversionCompatibility.kt") @TestMetadata("suspendConversionCompatibility.kt")
public void testSuspendConversionCompatibility() throws Exception { public void testSuspendConversionCompatibility() throws Exception {