diff --git a/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/annotations.kt b/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/annotations.kt index 574c08d6496..bfa233804e5 100644 --- a/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/annotations.kt +++ b/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/annotations.kt @@ -34,8 +34,7 @@ annotation class SupertypeWithTypeArgument(val kClass: KClass<*>) annotation class MetaSupertype -@Target(AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.EXPRESSION) -@Retention(AnnotationRetention.SOURCE) +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.TYPE) annotation class MyComposable annotation class AllPropertiesConstructor diff --git a/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/functionsForFunctionalKindsTest.kt b/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/functionsForFunctionalKindsTest.kt new file mode 100644 index 00000000000..8b55ef81d84 --- /dev/null +++ b/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/functionsForFunctionalKindsTest.kt @@ -0,0 +1,13 @@ +/* + * 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 + +class Box(val value: T) + +fun produceComposableFunction(): @MyComposable () -> Unit = null!! +fun consumeComposableFunction(@Suppress("UNUSED_PARAMETER") block: @MyComposable () -> Unit) {} + +fun produceBoxedComposableFunction(): Box<@MyComposable () -> Unit> = Box(produceComposableFunction()) diff --git a/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/functionsForTypeAttributesTest.kt b/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/functionsForTypeAttributesTest.kt new file mode 100644 index 00000000000..ccf51fff0ff --- /dev/null +++ b/plugins/fir-plugin-prototype/plugin-annotations/src/org/jetbrains/kotlin/fir/plugin/functionsForTypeAttributesTest.kt @@ -0,0 +1,11 @@ +/* + * 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 + +fun producePositiveInt(): @Positive Int = 1 +fun consumePositiveInt(@Suppress("UNUSED_PARAMETER") x: @Positive Int) {} + +fun produceBoxedPositiveInt(): Box<@Positive Int> = Box(1) diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.fir.txt b/plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.fir.txt new file mode 100644 index 00000000000..a9d482f644b --- /dev/null +++ b/plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.fir.txt @@ -0,0 +1,24 @@ +FILE: dependencyWithoutAttributePlugin.kt + public final fun takePositive(x: R|@Positive kotlin/Number|): R|kotlin/Unit| { + } + public final fun takeNegative(x: R|@Negative kotlin/Number|): R|kotlin/Unit| { + } + public final fun takeAny(x: R|kotlin/Number|): R|kotlin/Unit| { + } + public final fun test_1(positiveInt: R|@Positive kotlin/Int|, negativeInt: R|@Negative kotlin/Int|, someInt: R|kotlin/Int|): R|kotlin/Unit| { + R|org/jetbrains/kotlin/fir/plugin/consumePositiveInt|(R|/positiveInt|) + R|org/jetbrains/kotlin/fir/plugin/consumePositiveInt|(R|/negativeInt|) + R|org/jetbrains/kotlin/fir/plugin/consumePositiveInt|(R|/someInt|) + } + public final fun test_2(): R|kotlin/Unit| { + lval x: R|@R|org/jetbrains/kotlin/fir/plugin/Positive|() kotlin/Int| = R|org/jetbrains/kotlin/fir/plugin/producePositiveInt|() + R|/takePositive|(R|/x|) + R|/takeNegative|(R|/x|) + R|/takeAny|(R|/x|) + } + public final fun test_3(): R|kotlin/Unit| { + lval x: R|@R|org/jetbrains/kotlin/fir/plugin/Positive|() kotlin/Int| = R|org/jetbrains/kotlin/fir/plugin/produceBoxedPositiveInt|().R|SubstitutionOverride| + R|/takePositive|(R|/x|) + R|/takeNegative|(R|/x|) + R|/takeAny|(R|/x|) + } diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.kt b/plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.kt new file mode 100644 index 00000000000..e29f2ca3314 --- /dev/null +++ b/plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.kt @@ -0,0 +1,29 @@ +import org.jetbrains.kotlin.fir.plugin.* + +fun takePositive(x: @Positive Number) {} +fun takeNegative(x: @Negative Number) {} +fun takeAny(x: Number) {} + +fun test_1( + positiveInt: @Positive Int, + negativeInt: @Negative Int, + someInt: Int +) { + consumePositiveInt(positiveInt) + consumePositiveInt(negativeInt) // should be error + consumePositiveInt(someInt) // should be error +} + +fun test_2() { + val x = producePositiveInt() + takePositive(x) + takeNegative(x) // should be error + takeAny(x) +} + +fun test_3() { + val x = produceBoxedPositiveInt().value + takePositive(x) + takeNegative(x) // should be error + takeAny(x) +} diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/dependencyWithoutFunctionalKindPlugin.fir.txt b/plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/dependencyWithoutFunctionalKindPlugin.fir.txt new file mode 100644 index 00000000000..6a3d873c02b --- /dev/null +++ b/plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/dependencyWithoutFunctionalKindPlugin.fir.txt @@ -0,0 +1,26 @@ +FILE: dependencyWithoutFunctionalKindPlugin.kt + public final fun consumeRegularFunction(block: R|() -> kotlin/Unit|): R|kotlin/Unit| { + } + public final fun consumeSuspendFunction(block: R|suspend () -> kotlin/Unit|): R|kotlin/Unit| { + } + public final fun consumeOurComposableFunction(block: R|@R|org/jetbrains/kotlin/fir/plugin/MyComposable|() some/MyComposableFunction0|): R|kotlin/Unit| { + } + public final fun test_1(block: R|() -> kotlin/Unit|, composableBlock: R|@R|org/jetbrains/kotlin/fir/plugin/MyComposable|() some/MyComposableFunction0|, suspendBlock: R|suspend () -> kotlin/Unit|): R|kotlin/Unit| { + R|org/jetbrains/kotlin/fir/plugin/consumeComposableFunction|(R|/block|) + R|org/jetbrains/kotlin/fir/plugin/consumeComposableFunction#|(R|/composableBlock|) + R|org/jetbrains/kotlin/fir/plugin/consumeComposableFunction#|(R|/suspendBlock|) + } + public final fun test_2(): R|kotlin/Unit| { + lval block: R|() -> kotlin/Unit| = R|org/jetbrains/kotlin/fir/plugin/produceComposableFunction|() + R|/consumeRegularFunction|(R|/block|) + R|/consumeSuspendFunction|(R|/block|) + R|/consumeOurComposableFunction|(R|/block|) + R|org/jetbrains/kotlin/fir/plugin/consumeComposableFunction|(R|/block|) + } + public final fun test_3(): R|kotlin/Unit| { + lval block: R|() -> kotlin/Unit| = R|org/jetbrains/kotlin/fir/plugin/produceBoxedComposableFunction|().R|SubstitutionOverride kotlin/Unit|>| + R|/consumeRegularFunction|(R|/block|) + R|/consumeSuspendFunction|(R|/block|) + R|/consumeOurComposableFunction|(R|/block|) + R|org/jetbrains/kotlin/fir/plugin/consumeComposableFunction|(R|/block|) + } diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/dependencyWithoutFunctionalKindPlugin.kt b/plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/dependencyWithoutFunctionalKindPlugin.kt new file mode 100644 index 00000000000..6823d46d392 --- /dev/null +++ b/plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/dependencyWithoutFunctionalKindPlugin.kt @@ -0,0 +1,31 @@ +import org.jetbrains.kotlin.fir.plugin.* + +fun consumeRegularFunction(block: () -> Unit) {} +fun consumeSuspendFunction(block: suspend () -> Unit) {} +fun consumeOurComposableFunction(block: @MyComposable () -> Unit) {} + +fun test_1( + block: () -> Unit, + composableBlock: @MyComposable () -> Unit, + suspendBlock: suspend () -> Unit, +) { + consumeComposableFunction(block) + consumeComposableFunction(composableBlock) + consumeComposableFunction(suspendBlock) // should be error +} + +fun test_2() { + val block = produceComposableFunction() + consumeRegularFunction(block) // should be error + consumeSuspendFunction(block) // should be error + consumeOurComposableFunction(block) + consumeComposableFunction(block) +} + +fun test_3() { + val block = produceBoxedComposableFunction().value + consumeRegularFunction(block) // should be error + consumeSuspendFunction(block) // should be error + consumeOurComposableFunction(block) + consumeComposableFunction(block) +} diff --git a/plugins/fir-plugin-prototype/tests-gen/org/jetbrains/kotlin/fir/plugin/runners/FirPsiPluginDiagnosticTestGenerated.java b/plugins/fir-plugin-prototype/tests-gen/org/jetbrains/kotlin/fir/plugin/runners/FirPsiPluginDiagnosticTestGenerated.java index 8999f69bda2..e7548901c38 100644 --- a/plugins/fir-plugin-prototype/tests-gen/org/jetbrains/kotlin/fir/plugin/runners/FirPsiPluginDiagnosticTestGenerated.java +++ b/plugins/fir-plugin-prototype/tests-gen/org/jetbrains/kotlin/fir/plugin/runners/FirPsiPluginDiagnosticTestGenerated.java @@ -33,6 +33,12 @@ public class FirPsiPluginDiagnosticTestGenerated extends AbstractFirPsiPluginDia KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/fir-plugin-prototype/testData/diagnostics/checkers"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("dependencyWithoutAttributePlugin.kt") + public void testDependencyWithoutAttributePlugin() throws Exception { + runTest("plugins/fir-plugin-prototype/testData/diagnostics/checkers/dependencyWithoutAttributePlugin.kt"); + } + @Test @TestMetadata("signedNumbersCheckers.kt") public void testSignedNumbersCheckers() throws Exception { @@ -61,6 +67,12 @@ public class FirPsiPluginDiagnosticTestGenerated extends AbstractFirPsiPluginDia runTest("plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/ambigousKinds.kt"); } + @Test + @TestMetadata("dependencyWithoutFunctionalKindPlugin.kt") + public void testDependencyWithoutFunctionalKindPlugin() throws Exception { + runTest("plugins/fir-plugin-prototype/testData/diagnostics/functionalTypes/dependencyWithoutFunctionalKindPlugin.kt"); + } + @Test @TestMetadata("inference.kt") public void testInference() throws Exception {