[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 DummyFunction
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class TestTopLevelPrivateSuspendFun
|
||||
annotation class ExternalClassWithNested
|
||||
annotation class NestedClassAndMaterializeMember
|
||||
annotation class MyInterfaceSupertype
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ class FirPluginPrototypeExtensionRegistrar : FirExtensionRegistrar() {
|
||||
|
||||
// Declaration generators
|
||||
+::TopLevelDeclarationsGenerator
|
||||
+::TopLevelPrivateSuspendFunctionGenerator
|
||||
+::ExternalClassGenerator
|
||||
+::AdditionalMembersGenerator
|
||||
+::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),
|
||||
TransformerForAdditionalMembersGenerator(pluginContext),
|
||||
TransformerForTopLevelDeclarationsGenerator(pluginContext),
|
||||
TransformerForTopLevelPrivateSuspendFunctionsGenerator(pluginContext),
|
||||
AllPropertiesConstructorIrGenerator(pluginContext),
|
||||
TransformerForAddingAnnotations(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() {
|
||||
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