Report warning (1.2) or error (1.3) on local annotations
#KT-23277 Fixed #KT-23589 Fixed
This commit is contained in:
@@ -227,6 +227,9 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_USED_AS_ANNOTATION_ARGUMENT = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<KtAnnotationEntry> ANNOTATION_USED_AS_ANNOTATION_ARGUMENT = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<KtExpression> ANNOTATION_ARGUMENT_IS_NON_CONST = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<KtExpression> ANNOTATION_ARGUMENT_IS_NON_CONST = DiagnosticFactory0.create(WARNING);
|
||||||
|
|
||||||
|
DiagnosticFactory0<KtClassOrObject> LOCAL_ANNOTATION_CLASS = DiagnosticFactory0.create(WARNING);
|
||||||
|
DiagnosticFactory0<KtClassOrObject> LOCAL_ANNOTATION_CLASS_ERROR = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory1<PsiElement, FqName> ILLEGAL_KOTLIN_VERSION_STRING_VALUE = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, FqName> ILLEGAL_KOTLIN_VERSION_STRING_VALUE = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, String> NEWER_VERSION_IN_SINCE_KOTLIN = DiagnosticFactory1.create(WARNING);
|
DiagnosticFactory1<PsiElement, String> NEWER_VERSION_IN_SINCE_KOTLIN = DiagnosticFactory1.create(WARNING);
|
||||||
|
|
||||||
|
|||||||
+3
@@ -831,6 +831,9 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(ANNOTATION_USED_AS_ANNOTATION_ARGUMENT, "An annotation can't be used as the annotations argument");
|
MAP.put(ANNOTATION_USED_AS_ANNOTATION_ARGUMENT, "An annotation can't be used as the annotations argument");
|
||||||
MAP.put(ANNOTATION_ARGUMENT_IS_NON_CONST, "An annotation argument must be a compile-time constant");
|
MAP.put(ANNOTATION_ARGUMENT_IS_NON_CONST, "An annotation argument must be a compile-time constant");
|
||||||
|
|
||||||
|
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(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level or in objects");
|
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_DELEGATE, "Const 'val' should not have a delegate");
|
||||||
MAP.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter");
|
MAP.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter");
|
||||||
|
|||||||
@@ -309,6 +309,7 @@ class DeclarationsChecker(
|
|||||||
|
|
||||||
private fun checkClass(classDescriptor: ClassDescriptorWithResolutionScopes, classOrObject: KtClassOrObject) {
|
private fun checkClass(classDescriptor: ClassDescriptorWithResolutionScopes, classOrObject: KtClassOrObject) {
|
||||||
checkSupertypesForConsistency(classDescriptor, classOrObject)
|
checkSupertypesForConsistency(classDescriptor, classOrObject)
|
||||||
|
checkLocalAnnotation(classDescriptor, classOrObject)
|
||||||
checkTypesInClassHeader(classOrObject)
|
checkTypesInClassHeader(classOrObject)
|
||||||
|
|
||||||
when (classOrObject) {
|
when (classOrObject) {
|
||||||
@@ -328,6 +329,16 @@ class DeclarationsChecker(
|
|||||||
checkPrivateExpectedDeclaration(classOrObject, classDescriptor)
|
checkPrivateExpectedDeclaration(classOrObject, classDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkLocalAnnotation(classDescriptor: ClassDescriptor, classOrObject: KtClassOrObject) {
|
||||||
|
if (classDescriptor.kind == ClassKind.ANNOTATION_CLASS && DescriptorUtils.isLocal(classDescriptor)) {
|
||||||
|
if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitLocalAnnotations)) {
|
||||||
|
trace.report(LOCAL_ANNOTATION_CLASS_ERROR.on(classOrObject))
|
||||||
|
} else {
|
||||||
|
trace.report(LOCAL_ANNOTATION_CLASS.on(classOrObject))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkTypesInClassHeader(classOrObject: KtClassOrObject) {
|
private fun checkTypesInClassHeader(classOrObject: KtClassOrObject) {
|
||||||
fun KtTypeReference.type(): KotlinType? = trace.bindingContext.get(TYPE, this)
|
fun KtTypeReference.type(): KotlinType? = trace.bindingContext.get(TYPE, this)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// !LANGUAGE: -ProhibitLocalAnnotations
|
||||||
|
|
||||||
|
fun f() {
|
||||||
|
<!LOCAL_ANNOTATION_CLASS!>annotation class Anno<!>
|
||||||
|
|
||||||
|
@Anno class Local {
|
||||||
|
<!LOCAL_ANNOTATION_CLASS!>annotation <!NESTED_CLASS_NOT_ALLOWED!>class Nested<!><!>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(): kotlin.Unit
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// !LANGUAGE: +ProhibitLocalAnnotations
|
||||||
|
|
||||||
|
fun f() {
|
||||||
|
<!LOCAL_ANNOTATION_CLASS_ERROR!>annotation class Anno<!>
|
||||||
|
|
||||||
|
@Anno class Local {
|
||||||
|
<!LOCAL_ANNOTATION_CLASS_ERROR!>annotation <!NESTED_CLASS_NOT_ALLOWED!>class Nested<!><!>
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(): kotlin.Unit
|
||||||
@@ -13692,6 +13692,27 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/localClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalClasses extends AbstractDiagnosticsTest {
|
||||||
|
public void testAllFilesPresentInLocalClasses() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/localClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localAnnotationClass.kt")
|
||||||
|
public void testLocalAnnotationClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/localClasses/localAnnotationClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localAnnotationClassError.kt")
|
||||||
|
public void testLocalAnnotationClassError() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/localClasses/localAnnotationClassError.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/modifiers")
|
@TestMetadata("compiler/testData/diagnostics/tests/modifiers")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Generated
+21
@@ -13692,6 +13692,27 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/localClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalClasses extends AbstractDiagnosticsUsingJavacTest {
|
||||||
|
public void testAllFilesPresentInLocalClasses() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/localClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localAnnotationClass.kt")
|
||||||
|
public void testLocalAnnotationClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/localClasses/localAnnotationClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localAnnotationClassError.kt")
|
||||||
|
public void testLocalAnnotationClassError() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/localClasses/localAnnotationClassError.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/modifiers")
|
@TestMetadata("compiler/testData/diagnostics/tests/modifiers")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -68,14 +68,14 @@ enum class LanguageFeature(
|
|||||||
InlineClasses(KOTLIN_1_3),
|
InlineClasses(KOTLIN_1_3),
|
||||||
ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion(KOTLIN_1_3),
|
ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion(KOTLIN_1_3),
|
||||||
ProhibitNonConstValuesAsVarargsInAnnotations(KOTLIN_1_3),
|
ProhibitNonConstValuesAsVarargsInAnnotations(KOTLIN_1_3),
|
||||||
|
|
||||||
StrictJavaNullabilityAssertions(sinceVersion = null, defaultState = State.DISABLED),
|
|
||||||
ProperIeee754Comparisons(sinceVersion = null, defaultState = State.DISABLED),
|
|
||||||
|
|
||||||
ReadDeserializedContracts(KOTLIN_1_3),
|
ReadDeserializedContracts(KOTLIN_1_3),
|
||||||
UseReturnsEffect(KOTLIN_1_3),
|
UseReturnsEffect(KOTLIN_1_3),
|
||||||
UseCallsInPlaceEffect(KOTLIN_1_3),
|
UseCallsInPlaceEffect(KOTLIN_1_3),
|
||||||
AllowContractsForCustomFunctions(KOTLIN_1_3),
|
AllowContractsForCustomFunctions(KOTLIN_1_3),
|
||||||
|
ProhibitLocalAnnotations(KOTLIN_1_3),
|
||||||
|
|
||||||
|
StrictJavaNullabilityAssertions(sinceVersion = null, defaultState = State.DISABLED),
|
||||||
|
ProperIeee754Comparisons(sinceVersion = null, defaultState = State.DISABLED),
|
||||||
|
|
||||||
// Experimental features
|
// Experimental features
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user