[FIR] KT-56769: Ensure @receiver: is only allowed on receivers
Note that there's no code that checks that FirReceiverParameter's annotation's use-site target is indeed `@receiver:`, because otherwise the annotation wouldn't have made it into the FirReceiverParameter. In contrast, in K1 all such annotations are treated as annotations on a KtTypeReference. ^KT-56769 Fixed
This commit is contained in:
committed by
Space Team
parent
174f39aa46
commit
93ba0c3e70
+6
@@ -519,6 +519,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt56769.kt")
|
||||||
|
public void testKt56769() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/kt56769.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("LValueAssignment.kt")
|
@TestMetadata("LValueAssignment.kt")
|
||||||
public void testLValueAssignment() throws Exception {
|
public void testLValueAssignment() throws Exception {
|
||||||
|
|||||||
+6
@@ -519,6 +519,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt56769.kt")
|
||||||
|
public void testKt56769() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/kt56769.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("LValueAssignment.kt")
|
@TestMetadata("LValueAssignment.kt")
|
||||||
public void testLValueAssignment() throws Exception {
|
public void testLValueAssignment() throws Exception {
|
||||||
|
|||||||
+6
@@ -519,6 +519,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt56769.kt")
|
||||||
|
public void testKt56769() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/kt56769.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("LValueAssignment.kt")
|
@TestMetadata("LValueAssignment.kt")
|
||||||
public void testLValueAssignment() throws Exception {
|
public void testLValueAssignment() throws Exception {
|
||||||
|
|||||||
+11
-1
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.checkers.type
|
package org.jetbrains.kotlin.fir.analysis.checkers.type
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
@@ -24,10 +25,19 @@ object FirTypeAnnotationChecker : FirTypeRefChecker() {
|
|||||||
|
|
||||||
for (annotation in typeRef.annotations) {
|
for (annotation in typeRef.annotations) {
|
||||||
if (annotation.source == null) continue
|
if (annotation.source == null) continue
|
||||||
|
val useSiteTarget = annotation.useSiteTarget
|
||||||
|
|
||||||
|
// Annotations with `@receiver:` go
|
||||||
|
// into FirReceiverParameter, not FirTypeRef
|
||||||
|
if (useSiteTarget == AnnotationUseSiteTarget.RECEIVER) {
|
||||||
|
reporter.reportOn(
|
||||||
|
annotation.source, FirErrors.WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET,
|
||||||
|
"type usage", useSiteTarget.renderName, context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val annotationTargets = annotation.getAllowedAnnotationTargets(context.session)
|
val annotationTargets = annotation.getAllowedAnnotationTargets(context.session)
|
||||||
if (KotlinTarget.TYPE !in annotationTargets) {
|
if (KotlinTarget.TYPE !in annotationTargets) {
|
||||||
val useSiteTarget = annotation.useSiteTarget
|
|
||||||
if (useSiteTarget == null || KotlinTarget.USE_SITE_MAPPING[useSiteTarget] !in annotationTargets) {
|
if (useSiteTarget == null || KotlinTarget.USE_SITE_MAPPING[useSiteTarget] !in annotationTargets) {
|
||||||
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "type usage", context)
|
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "type usage", context)
|
||||||
}
|
}
|
||||||
|
|||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
// !LANGUAGE: +RestrictionOfWrongAnnotationsWithUseSiteTargetsOnTypes
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.VALUE_PARAMETER)
|
|
||||||
annotation class Fancy
|
|
||||||
|
|
||||||
fun @receiver:Fancy String.myExtension() { }
|
|
||||||
val @receiver:Fancy Int.asVal get() = 0
|
|
||||||
|
|
||||||
fun ((@receiver:Fancy Int) -> Unit).complexReceiver1() {}
|
|
||||||
fun ((Int) -> @receiver:Fancy Unit).complexReceiver2() {}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +RestrictionOfWrongAnnotationsWithUseSiteTargetsOnTypes
|
// !LANGUAGE: +RestrictionOfWrongAnnotationsWithUseSiteTargetsOnTypes
|
||||||
|
|
||||||
@Target(AnnotationTarget.VALUE_PARAMETER)
|
@Target(AnnotationTarget.VALUE_PARAMETER)
|
||||||
|
|||||||
+2
-2
@@ -6,5 +6,5 @@ annotation class Fancy
|
|||||||
fun @receiver:Fancy String.myExtension() { }
|
fun @receiver:Fancy String.myExtension() { }
|
||||||
val @receiver:Fancy Int.asVal get() = 0
|
val @receiver:Fancy Int.asVal get() = 0
|
||||||
|
|
||||||
fun ((@receiver:Fancy Int) -> Unit).complexReceiver1() {}
|
fun ((<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Fancy<!> Int) -> Unit).complexReceiver1() {}
|
||||||
fun ((Int) -> @receiver:Fancy Unit).complexReceiver2() {}
|
fun ((Int) -> <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Fancy<!> Unit).complexReceiver2() {}
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
fun test1(i: @setparam:Suppress Int) {}
|
fun test1(i: @setparam:Suppress Int) {}
|
||||||
fun test2(i: @param:Suppress Int) {}
|
fun test2(i: @param:Suppress Int) {}
|
||||||
fun test3(i: @receiver:Suppress Int) {}
|
fun test3(i: <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Suppress<!> Int) {}
|
||||||
|
|
||||||
fun test4(): @setparam:Suppress Int = TODO()
|
fun test4(): @setparam:Suppress Int = TODO()
|
||||||
fun test5(i: (@setparam:Suppress Int) -> Unit) {}
|
fun test5(i: (@setparam:Suppress Int) -> Unit) {}
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
fun test1(i: @setparam:Suppress Int) {}
|
fun test1(i: @setparam:Suppress Int) {}
|
||||||
fun test2(i: @param:Suppress Int) {}
|
fun test2(i: @param:Suppress Int) {}
|
||||||
fun test3(i: @receiver:Suppress Int) {}
|
fun test3(i: <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Suppress<!> Int) {}
|
||||||
|
|
||||||
fun test4(): @setparam:Suppress Int = TODO()
|
fun test4(): @setparam:Suppress Int = TODO()
|
||||||
fun test5(i: (@setparam:Suppress Int) -> Unit) {}
|
fun test5(i: (@setparam:Suppress Int) -> Unit) {}
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
fun test1(i: @setparam:Suppress Int) {}
|
fun test1(i: @setparam:Suppress Int) {}
|
||||||
fun test2(i: @param:Suppress Int) {}
|
fun test2(i: @param:Suppress Int) {}
|
||||||
fun test3(i: @receiver:Suppress Int) {}
|
fun test3(i: <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Suppress<!> Int) {}
|
||||||
|
|
||||||
fun test4(): @setparam:Suppress Int = TODO()
|
fun test4(): @setparam:Suppress Int = TODO()
|
||||||
fun test5(i: (@setparam:Suppress Int) -> Unit) {}
|
fun test5(i: (@setparam:Suppress Int) -> Unit) {}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
fun main(args: Array<<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Anno<!> String>) {}
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
fun Int.train(args: Array<<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Anno<!> String>) {}
|
||||||
|
|
||||||
|
fun Int.plane(<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Anno<!> args: Array<String>) {}
|
||||||
|
|
||||||
|
fun vein(args: Array<<!WRONG_ANNOTATION_TARGET!>@file:Anno<!> String>) {}
|
||||||
|
|
||||||
|
fun rain(args: Array<<!WRONG_ANNOTATION_TARGET!>@Anno<!> String>) {}
|
||||||
|
|
||||||
|
fun <!WRONG_ANNOTATION_TARGET!>@Anno<!> Int.strain() {}
|
||||||
|
|
||||||
|
fun @receiver:Anno Int.drain() {}
|
||||||
|
|
||||||
|
fun <!WRONG_ANNOTATION_TARGET!>@file:Anno<!> Int.brain() {}
|
||||||
|
|
||||||
|
fun (<!WRONG_ANNOTATION_TARGET!>@Anno<!> Int).crane() {}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
fun main(args: Array<<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Anno<!> String>) {}
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
fun Int.train(args: Array<<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Anno<!> String>) {}
|
||||||
|
|
||||||
|
fun Int.plane(<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@receiver:Anno<!> args: Array<String>) {}
|
||||||
|
|
||||||
|
fun vein(args: Array<<!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@file:Anno<!> String>) {}
|
||||||
|
|
||||||
|
fun rain(args: Array<<!WRONG_ANNOTATION_TARGET!>@Anno<!> String>) {}
|
||||||
|
|
||||||
|
fun <!WRONG_ANNOTATION_TARGET!>@Anno<!> Int.strain() {}
|
||||||
|
|
||||||
|
fun @receiver:Anno Int.drain() {}
|
||||||
|
|
||||||
|
fun <!WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET!>@file:Anno<!> Int.brain() {}
|
||||||
|
|
||||||
|
fun (<!WRONG_ANNOTATION_TARGET!>@Anno<!> Int).crane() {}
|
||||||
Generated
+6
@@ -519,6 +519,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
runTest("compiler/testData/diagnostics/tests/kt56723.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt56769.kt")
|
||||||
|
public void testKt56769() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/kt56769.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("LValueAssignment.kt")
|
@TestMetadata("LValueAssignment.kt")
|
||||||
public void testLValueAssignment() throws Exception {
|
public void testLValueAssignment() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user