[Test] Reproduce crash when plugin generates top-level private suspend
...function. ^KT-61993
This commit is contained in:
committed by
Space Team
parent
bba39dd4fe
commit
b2a2d32d70
+3
@@ -11,6 +11,9 @@ annotation class AllOpen
|
|||||||
annotation class AllOpen2
|
annotation class AllOpen2
|
||||||
|
|
||||||
annotation class DummyFunction
|
annotation class DummyFunction
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
|
annotation class TestTopLevelPrivateSuspendFun
|
||||||
annotation class ExternalClassWithNested
|
annotation class ExternalClassWithNested
|
||||||
annotation class NestedClassAndMaterializeMember
|
annotation class NestedClassAndMaterializeMember
|
||||||
annotation class MyInterfaceSupertype
|
annotation class MyInterfaceSupertype
|
||||||
|
|||||||
+1
@@ -30,6 +30,7 @@ class FirPluginPrototypeExtensionRegistrar : FirExtensionRegistrar() {
|
|||||||
|
|
||||||
// Declaration generators
|
// Declaration generators
|
||||||
+::TopLevelDeclarationsGenerator
|
+::TopLevelDeclarationsGenerator
|
||||||
|
+::TopLevelPrivateSuspendFunctionGenerator
|
||||||
+::ExternalClassGenerator
|
+::ExternalClassGenerator
|
||||||
+::AdditionalMembersGenerator
|
+::AdditionalMembersGenerator
|
||||||
+::CompanionGenerator
|
+::CompanionGenerator
|
||||||
|
|||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.plugin.generators
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.GeneratedDeclarationKey
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
|
||||||
|
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||||
|
import org.jetbrains.kotlin.fir.plugin.createTopLevelFunction
|
||||||
|
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generates `private suspend fun testFun_generated() {}` function
|
||||||
|
* for each package containing function annotated with `org.jetbrains.kotlin.fir.plugin.TestTopLevelPrivateSuspendFun`.
|
||||||
|
*/
|
||||||
|
internal class TopLevelPrivateSuspendFunctionGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
||||||
|
private companion object {
|
||||||
|
private val PREDICATE = LookupPredicate.create { annotated("TestTopLevelPrivateSuspendFun".fqn()) }
|
||||||
|
private val TEST_FUN_NAME = Name.identifier("testFun_generated")
|
||||||
|
}
|
||||||
|
|
||||||
|
private val predicateBasedProvider = session.predicateBasedProvider
|
||||||
|
private val matchedPackageNames by lazy {
|
||||||
|
// This could be done more elegantly if TestTopLevelPrivateSuspendFun was file-level annotation,
|
||||||
|
// but it's currently not possible to find all annotated files using FirPredicateBasedProvider (see KT-66151).
|
||||||
|
predicateBasedProvider.getSymbolsByPredicate(PREDICATE)
|
||||||
|
.filterIsInstance<FirNamedFunctionSymbol>()
|
||||||
|
.map { it.callableId.packageName }
|
||||||
|
.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generateFunctions(callableId: CallableId, context: MemberGenerationContext?): List<FirNamedFunctionSymbol> {
|
||||||
|
if (context != null) return emptyList()
|
||||||
|
if (callableId.callableName != TEST_FUN_NAME) return emptyList()
|
||||||
|
val function = createTopLevelFunction(Key, callableId, session.builtinTypes.unitType.type) {
|
||||||
|
visibility = Visibilities.Private
|
||||||
|
status { isSuspend = true }
|
||||||
|
}
|
||||||
|
return listOf(function.symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTopLevelCallableIds(): Set<CallableId> {
|
||||||
|
return matchedPackageNames.map { CallableId(it, TEST_FUN_NAME) }.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
object Key : GeneratedDeclarationKey()
|
||||||
|
|
||||||
|
override fun FirDeclarationPredicateRegistrar.registerPredicates() {
|
||||||
|
register(PREDICATE)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -17,6 +17,7 @@ class GeneratedDeclarationsIrBodyFiller : IrGenerationExtension {
|
|||||||
TransformerForCompanionGenerator(pluginContext),
|
TransformerForCompanionGenerator(pluginContext),
|
||||||
TransformerForAdditionalMembersGenerator(pluginContext),
|
TransformerForAdditionalMembersGenerator(pluginContext),
|
||||||
TransformerForTopLevelDeclarationsGenerator(pluginContext),
|
TransformerForTopLevelDeclarationsGenerator(pluginContext),
|
||||||
|
TransformerForTopLevelPrivateSuspendFunctionsGenerator(pluginContext),
|
||||||
AllPropertiesConstructorIrGenerator(pluginContext),
|
AllPropertiesConstructorIrGenerator(pluginContext),
|
||||||
TransformerForAddingAnnotations(pluginContext),
|
TransformerForAddingAnnotations(pluginContext),
|
||||||
ComposableFunctionsTransformer(pluginContext),
|
ComposableFunctionsTransformer(pluginContext),
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.plugin
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.GeneratedDeclarationKey
|
||||||
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||||
|
import org.jetbrains.kotlin.fir.plugin.generators.TopLevelPrivateSuspendFunctionGenerator
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
|
||||||
|
internal class TransformerForTopLevelPrivateSuspendFunctionsGenerator(context: IrPluginContext) : AbstractTransformerForGenerator(context, visitBodies = false) {
|
||||||
|
override fun interestedIn(key: GeneratedDeclarationKey?): Boolean {
|
||||||
|
return key == TopLevelPrivateSuspendFunctionGenerator.Key
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey?): IrBody {
|
||||||
|
return irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey?): IrBody? {
|
||||||
|
error("Should not be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
FILE: topLevelPrivateSuspendFun.kt
|
||||||
|
package foo
|
||||||
|
|
||||||
|
@R|org/jetbrains/kotlin/fir/plugin/TestTopLevelPrivateSuspendFun|() public final fun box(): R|kotlin/String| {
|
||||||
|
^box String(OK)
|
||||||
|
}
|
||||||
|
FILE: __GENERATED DECLARATIONS__.kt
|
||||||
|
package foo
|
||||||
|
|
||||||
|
private final suspend fun testFun_generated(): R|kotlin/Unit|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// This test currently fails!
|
||||||
|
package foo
|
||||||
|
|
||||||
|
@org.jetbrains.kotlin.fir.plugin.TestTopLevelPrivateSuspendFun
|
||||||
|
fun box(): String = "OK"
|
||||||
+6
@@ -143,4 +143,10 @@ public class FirLightTreePluginBlackBoxCodegenTestGenerated extends AbstractFirL
|
|||||||
public void testTopLevelCallables() {
|
public void testTopLevelCallables() {
|
||||||
runTest("plugins/fir-plugin-prototype/testData/box/topLevelCallables.kt");
|
runTest("plugins/fir-plugin-prototype/testData/box/topLevelCallables.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelPrivateSuspendFun.kt")
|
||||||
|
public void testTopLevelPrivateSuspendFun() {
|
||||||
|
runTest("plugins/fir-plugin-prototype/testData/box/topLevelPrivateSuspendFun.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user