[FIR plugin prototype] Implement Composable-like extension
This commit is contained in:
committed by
Space Team
parent
1c8587f82d
commit
f268ab8858
+4
@@ -33,3 +33,7 @@ enum class Visibility {
|
||||
annotation class SupertypeWithTypeArgument(val kClass: KClass<*>)
|
||||
|
||||
annotation class MetaSupertype
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class MyComposable
|
||||
|
||||
+2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
|
||||
import org.jetbrains.kotlin.fir.plugin.generators.*
|
||||
import org.jetbrains.kotlin.fir.plugin.types.FirNumberSignAttributeExtension
|
||||
import org.jetbrains.kotlin.fir.plugin.types.ComposableLikeFunctionalTypeKindExtension
|
||||
import org.jetbrains.kotlin.ir.plugin.GeneratedDeclarationsIrBodyFiller
|
||||
|
||||
class FirPluginPrototypeExtensionRegistrar : FirExtensionRegistrar() {
|
||||
@@ -23,6 +24,7 @@ class FirPluginPrototypeExtensionRegistrar : FirExtensionRegistrar() {
|
||||
+::PluginAdditionalCheckers
|
||||
+::FirNumberSignAttributeExtension
|
||||
+::AlgebraReceiverInjector
|
||||
+::ComposableLikeFunctionalTypeKindExtension
|
||||
|
||||
// Declaration generators
|
||||
+::TopLevelDeclarationsGenerator
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.extensions.FirFunctionalTypeKindExtension
|
||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class ComposableLikeFunctionalTypeKindExtension(session: FirSession) : FirFunctionalTypeKindExtension(session) {
|
||||
override fun FunctionalTypeKindRegistrar.registerKinds() {
|
||||
registerKind(ComposableFunction, KComposableFunction)
|
||||
}
|
||||
}
|
||||
|
||||
private val COMPOSABLE_PACKAGE_FQN = FqName.topLevel(Name.identifier("some"))
|
||||
private val MY_COMPOSABLE_ANNOTATION_CLASS_ID = ClassId.topLevel("MyComposable".fqn())
|
||||
|
||||
object ComposableFunction : FunctionalTypeKind(
|
||||
COMPOSABLE_PACKAGE_FQN,
|
||||
"MyComposableFunction",
|
||||
MY_COMPOSABLE_ANNOTATION_CLASS_ID,
|
||||
isReflectType = false
|
||||
) {
|
||||
override val prefixForTypeRender: String
|
||||
get() = "@MyComposable"
|
||||
|
||||
override fun reflectKind(): FunctionalTypeKind = KComposableFunction
|
||||
}
|
||||
|
||||
object KComposableFunction : FunctionalTypeKind(
|
||||
COMPOSABLE_PACKAGE_FQN,
|
||||
"KMyComposableFunction",
|
||||
MY_COMPOSABLE_ANNOTATION_CLASS_ID,
|
||||
isReflectType = true
|
||||
) {
|
||||
override fun nonReflectKind(): FunctionalTypeKind = ComposableFunction
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
FILE: ambigousKinds.kt
|
||||
public final fun incorrect(block: <ERROR TYPE REF: There are multiple functional kinds for functional type ref>): R|kotlin/Unit| {
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import org.jetbrains.kotlin.fir.plugin.MyComposable
|
||||
|
||||
fun incorrect(block: <!AMBIGUOUS_FUNCTIONAL_TYPE_KIND!>@MyComposable suspend () -> Unit<!>) {}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
FILE: simple.kt
|
||||
public final fun runUsual(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun runComposable(block: R|@R|org/jetbrains/kotlin/fir/plugin/MyComposable|() some/MyComposableFunction0<kotlin/Unit>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval l0: R|() -> kotlin/Unit| = fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
^ Unit
|
||||
}
|
||||
|
||||
lval l1: R|some/MyComposableFunction0<kotlin/Unit>| = fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
^ Unit
|
||||
}
|
||||
|
||||
lval l2: R|@R|org/jetbrains/kotlin/fir/plugin/MyComposable|() some/MyComposableFunction0<kotlin/Unit>| = fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
^ Unit
|
||||
}
|
||||
|
||||
lval l3: R|some/MyComposableFunction0<kotlin/Unit>| = @R|org/jetbrains/kotlin/fir/plugin/MyComposable|() fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
^ Unit
|
||||
}
|
||||
|
||||
R|/runUsual|(R|<local>/l0|)
|
||||
R|/runUsual<Inapplicable(INAPPLICABLE): /runUsual>#|(R|<local>/l1|)
|
||||
R|/runUsual<Inapplicable(INAPPLICABLE): /runUsual>#|(R|<local>/l2|)
|
||||
R|/runUsual<Inapplicable(INAPPLICABLE): /runUsual>#|(R|<local>/l3|)
|
||||
R|/runUsual|(<L> = runUsual@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
|
||||
^@runUsual Unit
|
||||
}
|
||||
)
|
||||
R|/runUsual<Inapplicable(INAPPLICABLE): /runUsual>#|(<L> = @R|org/jetbrains/kotlin/fir/plugin/MyComposable|() runUsual@fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
^@runUsual Unit
|
||||
}
|
||||
)
|
||||
R|/runComposable|(R|<local>/l0|)
|
||||
R|/runComposable|(R|<local>/l1|)
|
||||
R|/runComposable|(R|<local>/l2|)
|
||||
R|/runComposable|(R|<local>/l3|)
|
||||
R|/runComposable|(<L> = runComposable@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
|
||||
^@runComposable Unit
|
||||
}
|
||||
)
|
||||
R|/runComposable|(<L> = @R|org/jetbrains/kotlin/fir/plugin/MyComposable|() runComposable@fun <anonymous>(): R|kotlin/Unit| <inline=NoInline> {
|
||||
^@runComposable Unit
|
||||
}
|
||||
)
|
||||
}
|
||||
public final fun runComposable2(block: R|some/MyComposableFunction1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
R|/runComposable2|(<L> = runComposable2@fun <anonymous>(it: R|kotlin/String|): R|kotlin/Int| <inline=NoInline> {
|
||||
^ R|<local>/it|.R|kotlin/String.length|
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import org.jetbrains.kotlin.fir.plugin.MyComposable
|
||||
|
||||
fun runUsual(block: () -> Unit) {}
|
||||
fun runComposable(block: @MyComposable () -> Unit) {}
|
||||
|
||||
fun test_1() {
|
||||
val l0 = {}
|
||||
val l1: some.MyComposableFunction0<Unit> = {}
|
||||
val l2: @MyComposable (() -> Unit) = {}
|
||||
val l3 = @MyComposable {}
|
||||
|
||||
runUsual(l0) // ok
|
||||
runUsual(<!ARGUMENT_TYPE_MISMATCH!>l1<!>) // error
|
||||
runUsual(<!ARGUMENT_TYPE_MISMATCH!>l2<!>) // error
|
||||
runUsual(<!ARGUMENT_TYPE_MISMATCH!>l3<!>) // error
|
||||
runUsual {} // ok
|
||||
runUsual @MyComposable <!ARGUMENT_TYPE_MISMATCH!>{}<!> // error
|
||||
|
||||
runComposable(l0) // ok
|
||||
runComposable(l1) // ok
|
||||
runComposable(l2) // ok
|
||||
runComposable(l3) // ok
|
||||
runComposable {} // ok
|
||||
runComposable @MyComposable {} // ok
|
||||
}
|
||||
|
||||
fun runComposable2(block: some.MyComposableFunction1<String, Int>) {}
|
||||
|
||||
fun test_2() {
|
||||
runComposable2 { it.length }
|
||||
}
|
||||
+22
@@ -46,6 +46,28 @@ public class FirPluginDiagnosticTestGenerated extends AbstractFirPluginDiagnosti
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FunctionalTypes {
|
||||
@Test
|
||||
public void testAllFilesPresentInFunctionalTypes() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ambigousKinds.kt")
|
||||
public void testAmbigousKinds() throws Exception {
|
||||
runTest("plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/ambigousKinds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("plugins/fir-plugin-prototype/testData/diagnostics/memberGen")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
Reference in New Issue
Block a user