Add diagnostics on annotations on super types. KT-23992 fixed

This commit is contained in:
Dmitriy Novozhilov
2019-02-21 17:08:25 +03:00
parent 1fc6f30c50
commit 677987c85f
10 changed files with 83 additions and 1 deletions
@@ -219,6 +219,8 @@ public interface Errors {
// Annotations
DiagnosticFactory0<KtSuperTypeList> SUPERTYPES_FOR_ANNOTATION_CLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_ON_SUPERCLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_ON_SUPERCLASS_WARNING = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<KtParameter> MISSING_VAL_ON_ANNOTATION_PARAMETER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtParameter> VAR_ANNOTATION_PARAMETER = DiagnosticFactory0.create(ERROR, VAL_OR_VAR_NODE);
DiagnosticFactory0<KtCallExpression> ANNOTATION_CLASS_CONSTRUCTOR_CALL = DiagnosticFactory0.create(ERROR);
@@ -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");
@@ -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<AnnotationUseSiteTarget> = when (this) {
is KtParameter ->
if (ownerFunction is KtPrimaryConstructor) UseSiteTargetsList.T_CONSTRUCTOR_PARAMETER else emptyList()
@@ -1,5 +1,9 @@
// !LANGUAGE: -ProhibitUseSiteTargetAnnotationsOnSuperTypes
interface Foo
annotation class Ann
class E : @field:<!DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!> @get:<!DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!> @set:<!DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!> @setparam:<!DEBUG_INFO_MISSING_UNRESOLVED!>Ann<!> Foo
class E : <!ANNOTATION_ON_SUPERCLASS_WARNING!>@field:Ann<!> <!ANNOTATION_ON_SUPERCLASS_WARNING!>@get:Ann<!> <!ANNOTATION_ON_SUPERCLASS_WARNING!>@set:Ann<!> <!ANNOTATION_ON_SUPERCLASS_WARNING!>@setparam:Ann<!> Foo
interface G : @Ann Foo
@@ -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
}
@@ -0,0 +1,9 @@
// !LANGUAGE: +ProhibitUseSiteTargetAnnotationsOnSuperTypes
interface Foo
annotation class Ann
class E : <!ANNOTATION_ON_SUPERCLASS!>@field:Ann<!> <!ANNOTATION_ON_SUPERCLASS!>@get:Ann<!> <!ANNOTATION_ON_SUPERCLASS!>@set:Ann<!> <!ANNOTATION_ON_SUPERCLASS!>@setparam:Ann<!> Foo
interface G : @Ann Foo
@@ -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
}
@@ -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");
@@ -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");
@@ -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