From 677987c85f78d337f29b89f1263079971475f8df Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 21 Feb 2019 17:08:25 +0300 Subject: [PATCH] Add diagnostics on annotations on super types. KT-23992 fixed --- .../jetbrains/kotlin/diagnostics/Errors.java | 2 ++ .../rendering/DefaultErrorMessages.java | 3 +++ .../kotlin/resolve/AnnotationChecker.kt | 20 ++++++++++++++ .../annotations/withUseSiteTarget/kt23992.kt | 6 ++++- .../annotations/withUseSiteTarget/kt23992.txt | 6 +++++ .../withUseSiteTarget/kt23992_after.kt | 9 +++++++ .../withUseSiteTarget/kt23992_after.txt | 27 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 5 ++++ .../DiagnosticsUsingJavacTestGenerated.java | 5 ++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + 10 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.kt create mode 100644 compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 52fb2b16aeb..bb69bde693b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -219,6 +219,8 @@ public interface Errors { // Annotations DiagnosticFactory0 SUPERTYPES_FOR_ANNOTATION_CLASS = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 ANNOTATION_ON_SUPERCLASS = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 ANNOTATION_ON_SUPERCLASS_WARNING = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 MISSING_VAL_ON_ANNOTATION_PARAMETER = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 VAR_ANNOTATION_PARAMETER = DiagnosticFactory0.create(ERROR, VAL_OR_VAR_NODE); DiagnosticFactory0 ANNOTATION_CLASS_CONSTRUCTOR_CALL = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index cf6de2b4264..6857226c859 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -883,6 +883,9 @@ public class DefaultErrorMessages { MAP.put(LOCAL_ANNOTATION_CLASS, "Local annotation classes are deprecated and will be unsupported in a future release"); MAP.put(LOCAL_ANNOTATION_CLASS_ERROR, "Annotation class cannot be local"); + MAP.put(ANNOTATION_ON_SUPERCLASS, "Annotations on superclass are meaningless"); + MAP.put(ANNOTATION_ON_SUPERCLASS_WARNING, "Annotations on superclass are meaningless and deprecated"); + MAP.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level or in objects"); MAP.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate"); MAP.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt index 1bdf4387b12..05dc034bcf7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt @@ -41,6 +41,9 @@ class AnnotationChecker( if (annotated is KtProperty) { checkPropertyUseSiteTargetAnnotations(annotated, trace) } + if (annotated is KtClass) { + checkSuperTypeAnnotations(annotated, trace) + } if (annotated is KtCallableDeclaration) { annotated.typeReference?.let { check(it, trace) } annotated.receiverTypeReference?.let { check(it, trace) } @@ -104,6 +107,23 @@ class AnnotationChecker( } } + private fun checkSuperTypeAnnotations(annotated: KtClass, trace: BindingTrace) { + val reportError = languageVersionSettings.supportsFeature(LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes) + + for (superType in annotated.superTypeListEntries.mapNotNull { it.typeReference }) { + for (entry in superType.annotationEntries) { + if (entry.useSiteTarget != null) { + val diagnostic = if (reportError) { + Errors.ANNOTATION_ON_SUPERCLASS.on(entry) + } else { + Errors.ANNOTATION_ON_SUPERCLASS_WARNING.on(entry) + } + trace.report(diagnostic) + } + } + } + } + private fun KtAnnotated?.getImplicitUseSiteTargetList(): List = when (this) { is KtParameter -> if (ownerFunction is KtPrimaryConstructor) UseSiteTargetsList.T_CONSTRUCTOR_PARAMETER else emptyList() diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.kt index 2a2a4ceb90a..b14cc4a6a2a 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.kt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.kt @@ -1,5 +1,9 @@ +// !LANGUAGE: -ProhibitUseSiteTargetAnnotationsOnSuperTypes + interface Foo annotation class Ann -class E : @field:Ann @get:Ann @set:Ann @setparam:Ann Foo \ No newline at end of file +class E : @field:Ann @get:Ann @set:Ann @setparam:Ann Foo + +interface G : @Ann Foo \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.txt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.txt index 8f433672169..f8066dc6177 100644 --- a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.txt +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.txt @@ -19,3 +19,9 @@ public interface Foo { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + +public interface G : @Ann Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.kt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.kt new file mode 100644 index 00000000000..35d9da9d040 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.kt @@ -0,0 +1,9 @@ +// !LANGUAGE: +ProhibitUseSiteTargetAnnotationsOnSuperTypes + +interface Foo + +annotation class Ann + +class E : @field:Ann @get:Ann @set:Ann @setparam:Ann Foo + +interface G : @Ann Foo \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.txt b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.txt new file mode 100644 index 00000000000..f8066dc6177 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.txt @@ -0,0 +1,27 @@ +package + +public final annotation class Ann : kotlin.Annotation { + public constructor Ann() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class E : Foo { + public constructor E() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface G : @Ann Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index db461d9cdf1..54a27f3d161 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -1449,6 +1449,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.kt"); } + @TestMetadata("kt23992_after.kt") + public void testKt23992_after() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.kt"); + } + @TestMetadata("kt26638.kt") public void testKt26638() throws Exception { runTest("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt26638.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index deeb0305993..efd4ac29b82 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -1444,6 +1444,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992.kt"); } + @TestMetadata("kt23992_after.kt") + public void testKt23992_after() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt23992_after.kt"); + } + @TestMetadata("kt26638.kt") public void testKt26638() throws Exception { runTest("compiler/testData/diagnostics/tests/annotations/withUseSiteTarget/kt26638.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index ee9b0e662fd..c9e67df5d5a 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -99,6 +99,7 @@ enum class LanguageFeature( ProhibitTypeParametersInAnonymousObjects(KOTLIN_1_4, kind = BUG_FIX), ProperInlineFromHigherPlatformDiagnostic(KOTLIN_1_4, kind = BUG_FIX), ProhibitRepeatedUseSiteTargetAnnotations(KOTLIN_1_4, kind = BUG_FIX), + ProhibitUseSiteTargetAnnotationsOnSuperTypes(KOTLIN_1_4, kind = BUG_FIX), ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX), // Temporarily disabled, see KT-27084/KT-22379