K2: handle suspend anonymous functions properly in various compiler parts
#KT-58332 Fixed
This commit is contained in:
committed by
Space Team
parent
aec0def5ca
commit
0906258d03
+6
@@ -32222,6 +32222,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
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
|
||||
@TestMetadata("suspendConversionCompatibility.kt")
|
||||
public void testSuspendConversionCompatibility() throws Exception {
|
||||
|
||||
+6
@@ -32222,6 +32222,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
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
|
||||
@TestMetadata("suspendConversionCompatibility.kt")
|
||||
public void testSuspendConversionCompatibility() throws Exception {
|
||||
|
||||
+6
@@ -32222,6 +32222,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
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
|
||||
@TestMetadata("suspendConversionCompatibility.kt")
|
||||
public void testSuspendConversionCompatibility() throws Exception {
|
||||
|
||||
+6
@@ -32318,6 +32318,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
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
|
||||
@TestMetadata("suspendConversionCompatibility.kt")
|
||||
public void testSuspendConversionCompatibility() throws Exception {
|
||||
|
||||
+6
-3
@@ -130,9 +130,12 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
private fun findEnclosingSuspendFunction(context: CheckerContext): FirFunction? {
|
||||
return context.containingDeclarations.lastOrNull {
|
||||
when (it) {
|
||||
is FirAnonymousFunction -> it.typeRef.coneType.isSuspendOrKSuspendFunctionType(context.session)
|
||||
is FirSimpleFunction -> it.isSuspend
|
||||
else -> false
|
||||
is FirAnonymousFunction ->
|
||||
if (it.isLambda) it.typeRef.coneType.isSuspendOrKSuspendFunctionType(context.session) else it.isSuspend
|
||||
is FirSimpleFunction ->
|
||||
it.isSuspend
|
||||
else ->
|
||||
false
|
||||
}
|
||||
} as? FirFunction
|
||||
}
|
||||
|
||||
+1
-1
@@ -505,7 +505,7 @@ class FirElementSerializer private constructor(
|
||||
simpleFunction?.isInline == true,
|
||||
simpleFunction?.isTailRec == true,
|
||||
simpleFunction?.isExternal == true,
|
||||
simpleFunction?.isSuspend == true,
|
||||
function.isSuspend,
|
||||
simpleFunction?.isExpect == true,
|
||||
shouldSetStableParameterNames(function),
|
||||
)
|
||||
|
||||
+1
@@ -227,6 +227,7 @@ private fun FirFunction.copyToFreeAnonymousFunction(approximator: AbstractTypeAp
|
||||
}
|
||||
})
|
||||
typeParameters += typeParameterSet
|
||||
status = function.status
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -564,7 +564,7 @@ class Fir2IrDeclarationStorage(
|
||||
val visibility = simpleFunction?.visibility ?: Visibilities.Local
|
||||
val isSuspend =
|
||||
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 result = declareIrSimpleFunction(signature) { symbol ->
|
||||
classifierStorage.preCacheTypeParameters(function, symbol)
|
||||
|
||||
+3
@@ -1660,6 +1660,9 @@ class DeclarationsConverter(
|
||||
label = context.getLastLabel(functionDeclaration)
|
||||
val labelName = label?.name ?: context.calleeNamesForLambda.lastOrNull()?.identifier
|
||||
target = FirFunctionTarget(labelName = labelName, isLambda = false)
|
||||
if (modifiers.hasSuspend()) {
|
||||
status = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_SUSPEND_FUNCTION_EXPRESSION
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val functionName = identifier.nameAsSafeName()
|
||||
|
||||
@@ -1441,6 +1441,9 @@ open class RawFirBuilder(
|
||||
hasExplicitParameterList = true
|
||||
label = context.getLastLabel(function)
|
||||
labelName = label?.name ?: context.calleeNamesForLambda.lastOrNull()?.identifier
|
||||
if (function.hasModifier(SUSPEND_KEYWORD)) {
|
||||
status = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_SUSPEND_FUNCTION_EXPRESSION
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FirSimpleFunctionBuilder().apply {
|
||||
|
||||
+3
-7
@@ -59,6 +59,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu
|
||||
override lateinit var moduleData: FirModuleData
|
||||
override lateinit var origin: FirDeclarationOrigin
|
||||
override var attributes: FirDeclarationAttributes = FirDeclarationAttributes()
|
||||
override var status: FirDeclarationStatus = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
||||
override lateinit var returnTypeRef: FirTypeRef
|
||||
var receiverParameter: FirReceiverParameter? = null
|
||||
override var deprecationsProvider: DeprecationsProvider = UnresolvedDeprecationProvider
|
||||
@@ -86,6 +87,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu
|
||||
moduleData,
|
||||
origin,
|
||||
attributes,
|
||||
status,
|
||||
returnTypeRef,
|
||||
receiverParameter,
|
||||
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)
|
||||
@@ -136,6 +131,7 @@ inline fun buildAnonymousFunctionCopy(original: FirAnonymousFunction, init: FirA
|
||||
copyBuilder.moduleData = original.moduleData
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.attributes = original.attributes.copy()
|
||||
copyBuilder.status = original.status
|
||||
copyBuilder.returnTypeRef = original.returnTypeRef
|
||||
copyBuilder.receiverParameter = original.receiverParameter
|
||||
copyBuilder.deprecationsProvider = original.deprecationsProvider
|
||||
|
||||
+1
-3
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.InlineStatus
|
||||
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.FirBlock
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
@@ -50,6 +49,7 @@ internal class FirAnonymousFunctionImpl(
|
||||
override val moduleData: FirModuleData,
|
||||
override val origin: FirDeclarationOrigin,
|
||||
override val attributes: FirDeclarationAttributes,
|
||||
override var status: FirDeclarationStatus,
|
||||
override var returnTypeRef: FirTypeRef,
|
||||
override var receiverParameter: FirReceiverParameter?,
|
||||
override var deprecationsProvider: DeprecationsProvider,
|
||||
@@ -69,8 +69,6 @@ internal class FirAnonymousFunctionImpl(
|
||||
override val typeParameters: MutableList<FirTypeParameter>,
|
||||
override var typeRef: FirTypeRef,
|
||||
) : FirAnonymousFunction() {
|
||||
override var status: FirDeclarationStatus = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
@OptIn(ResolveStateAccess::class)
|
||||
|
||||
+5
@@ -23,6 +23,11 @@ class FirResolvedDeclarationStatusImpl(
|
||||
Modality.FINAL,
|
||||
EffectiveVisibility.Public
|
||||
)
|
||||
val DEFAULT_STATUS_FOR_SUSPEND_FUNCTION_EXPRESSION = FirResolvedDeclarationStatusImpl(
|
||||
Visibilities.Local,
|
||||
Modality.FINAL,
|
||||
EffectiveVisibility.Public
|
||||
).apply { isSuspend = true }
|
||||
}
|
||||
|
||||
internal constructor(
|
||||
|
||||
@@ -96,4 +96,10 @@ class FirAllModifierRenderer : FirModifierRenderer() {
|
||||
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(constructor: FirConstructor)
|
||||
abstract fun renderModifiers(propertyAccessor: FirPropertyAccessor)
|
||||
abstract fun renderModifiers(anonymousFunction: FirAnonymousFunction)
|
||||
open fun renderModifiers(valueParameter: FirValueParameter) {
|
||||
if (valueParameter.isCrossinline) {
|
||||
renderModifier("crossinline")
|
||||
|
||||
@@ -57,4 +57,10 @@ class FirPartialModifierRenderer : FirModifierRenderer() {
|
||||
|
||||
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) {
|
||||
annotationRenderer?.render(anonymousFunction)
|
||||
modifierRenderer?.renderModifiers(anonymousFunction)
|
||||
declarationRenderer?.render(anonymousFunction)
|
||||
print(" ")
|
||||
val receiverParameter = anonymousFunction.receiverParameter
|
||||
|
||||
+2
-1
@@ -271,8 +271,9 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
||||
defaultNull("invocationKind", "label", "body", "controlFlowGraphReference")
|
||||
default("inlineStatus", "InlineStatus.Unknown")
|
||||
default("contractDescription", "FirEmptyContractDescription")
|
||||
default("status", "FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS")
|
||||
withCopy()
|
||||
useTypes(emptyContractDescriptionType)
|
||||
useTypes(emptyContractDescriptionType, resolvedDeclarationStatusImport)
|
||||
}
|
||||
|
||||
builder(propertyAccessor) {
|
||||
|
||||
+1
-2
@@ -565,7 +565,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
impl(contractElementDeclaration)
|
||||
|
||||
val implementationsWithoutStatusAndTypeParameters = listOf(
|
||||
"FirAnonymousFunctionImpl",
|
||||
"FirValueParameterImpl",
|
||||
"FirDefaultSetterValueParameter",
|
||||
"FirErrorPropertyImpl",
|
||||
@@ -582,7 +581,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
|
||||
configureFieldInAllImplementations(
|
||||
"typeParameters",
|
||||
implementationPredicate = { it.type != "FirAnonymousFunctionImpl" && it.type in implementationsWithoutStatusAndTypeParameters }
|
||||
implementationPredicate = { it.type in implementationsWithoutStatusAndTypeParameters }
|
||||
) {
|
||||
defaultEmptyList(it)
|
||||
useTypes(resolvedDeclarationStatusImplType)
|
||||
|
||||
+2
-1
@@ -9,4 +9,5 @@ import org.jetbrains.kotlin.fir.tree.generator.model.ArbitraryImportable
|
||||
|
||||
val phaseAsResolveStateExtentionImport = ArbitraryImportable("org.jetbrains.kotlin.fir.declarations", "asResolveState")
|
||||
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")
|
||||
Vendored
+9
@@ -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| {
|
||||
}
|
||||
+12
@@ -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
|
||||
|
||||
fun foo() {
|
||||
|
||||
Generated
+6
@@ -33090,6 +33090,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
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
|
||||
@TestMetadata("suspendConversionCompatibility.kt")
|
||||
public void testSuspendConversionCompatibility() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user