From 5bc7c9600ff3de28a32d22a6d2e589e0a1eb57b0 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 6 May 2015 14:58:40 +0300 Subject: [PATCH] Deprecate annotations in brackets --- .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../jetbrains/kotlin/psi/JetAnnotation.java | 8 +++ .../jetbrains/kotlin/psi/JetModifierList.java | 4 ++ .../kotlin/psi/JetTypeReference.java | 13 ++++- .../kotlin/resolve/AnnotationResolver.java | 15 +++++ .../kotlin/resolve/DeclarationsChecker.java | 1 + .../jetbrains/kotlin/resolve/TypeResolver.kt | 3 +- .../BasicExpressionTypingVisitor.java | 1 + .../tests/annotations/bracketsDeprecation.kt | 34 +++++++++++ .../tests/annotations/bracketsDeprecation.txt | 56 +++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 6 ++ 12 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.kt create mode 100644 compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 92751e6152a..79e15f0c502 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -130,6 +130,7 @@ public interface Errors { DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_CLASS_LITERAL = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_KCLASS_LITERAL = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_ENUM_CONST = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 DEPRECATED_ANNOTATION_SYNTAX = DiagnosticFactory0.create(WARNING); // Classes and traits 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 8dfc810cd07..5c6649b122a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -566,6 +566,7 @@ public class DefaultErrorMessages { MAP.put(ANNOTATION_PARAMETER_MUST_BE_ENUM_CONST, "An enum annotation parameter must be a enum constant"); MAP.put(ANNOTATION_PARAMETER_MUST_BE_CLASS_LITERAL, "An annotation parameter must be a `javaClass()` call"); MAP.put(ANNOTATION_PARAMETER_MUST_BE_KCLASS_LITERAL, "An annotation parameter must be a class literal (T::class)"); + MAP.put(DEPRECATED_ANNOTATION_SYNTAX, "This syntax for annotations is deprecated. Use '@' before annotation identifier instead"); MAP.put(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE, "An overriding function is not allowed to specify default values for its parameters"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java index 676abdbebad..88c9d77a27e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetAnnotation.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.psi; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub; import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes; @@ -38,6 +39,13 @@ public class JetAnnotation extends JetElementImplStub getEntries() { return getStubOrPsiChildrenAsList(JetStubElementTypes.ANNOTATION_ENTRY); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetModifierList.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetModifierList.java index c73753acd4b..6710c3e7036 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetModifierList.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetModifierList.java @@ -76,4 +76,8 @@ public abstract class JetModifierList extends JetElementImplStub> implements JetAnnotationsContainer { +public class JetTypeReference extends JetElementImplStub> implements JetAnnotated, JetAnnotationsContainer { public JetTypeReference(@NotNull ASTNode node) { super(node); @@ -54,7 +55,15 @@ public class JetTypeReference extends JetElementImplStub getAnnotations() { + @NotNull + @Override + public List getAnnotations() { + return getStubOrPsiChildrenAsList(JetStubElementTypes.ANNOTATION); + } + + @NotNull + @Override + public List getAnnotationEntries() { return PsiUtilPackage.collectAnnotationEntriesFromStubOrPsi(this); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java index c3f3aeac128..0e745c4bdb8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java @@ -61,6 +61,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static org.jetbrains.kotlin.diagnostics.Errors.DEPRECATED_ANNOTATION_SYNTAX; import static org.jetbrains.kotlin.diagnostics.Errors.NOT_AN_ANNOTATION_CLASS; import static org.jetbrains.kotlin.resolve.BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT; import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE; @@ -122,6 +123,8 @@ public class AnnotationResolver { if (modifierList == null) { return Annotations.EMPTY; } + reportDeprecatedAnnotationSyntax(modifierList.getAnnotations(), trace); + List annotationEntryElements = modifierList.getAnnotationEntries(); return resolveAnnotationEntries(scope, annotationEntryElements, trace, shouldResolveArguments); @@ -388,4 +391,16 @@ public class AnnotationResolver { trace.report(Errors.UNSUPPORTED.on(annotationEntry, "Annotations for type parameters are not supported yet")); } } + + public static void reportDeprecatedAnnotationSyntax(@NotNull List annotations, @NotNull BindingTrace trace) { + for (JetAnnotation annotation : annotations) { + reportDeprecatedAnnotationSyntax(annotation, trace); + } + } + + public static void reportDeprecatedAnnotationSyntax(@NotNull JetAnnotation annotation, @NotNull BindingTrace trace) { + if (annotation.isDeprecated()) { + trace.report(DEPRECATED_ANNOTATION_SYNTAX.on(annotation)); + } + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java index 393937ff7dc..2ea239937fe 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java @@ -237,6 +237,7 @@ public class DeclarationsChecker { } private void checkClass(BodiesResolveContext c, JetClass aClass, ClassDescriptorWithResolutionScopes classDescriptor) { + AnnotationResolver.reportDeprecatedAnnotationSyntax(aClass.getAnnotations(), trace); checkOpenMembers(classDescriptor); checkPrimaryConstructor(aClass, classDescriptor); checkTypeParameters(aClass); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index faeb550f1e5..2b75d9a8e9a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -103,7 +103,8 @@ public class TypeResolver( } private fun doResolvePossiblyBareType(c: TypeResolutionContext, typeReference: JetTypeReference): PossiblyBareType { - val annotations = annotationResolver.resolveAnnotationsWithArguments(c.scope, typeReference.getAnnotations(), c.trace) + AnnotationResolver.reportDeprecatedAnnotationSyntax(typeReference.getAnnotations(), c.trace); + val annotations = annotationResolver.resolveAnnotationsWithArguments(c.scope, typeReference.getAnnotationEntries(), c.trace) val typeElement = typeReference.getTypeElement() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index ae99ad5c94c..0a0b732381c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -1497,6 +1497,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } public JetTypeInfo visitAnnotatedExpression(JetAnnotatedExpression expression, ExpressionTypingContext context, boolean isStatement) { + AnnotationResolver.reportDeprecatedAnnotationSyntax(expression.getAnnotations(), context.trace); components.annotationResolver.resolveAnnotationsWithArguments( context.scope, expression.getAnnotationEntries(), context.trace); diff --git a/compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.kt b/compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.kt new file mode 100644 index 00000000000..488f8e505c0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.kt @@ -0,0 +1,34 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE +[file: Ann] +annotation class Ann(val arg: Int = 1) + +fun bar(block: () -> Int) = block() + +data class Q(val x: Int, val y: Int) + +fun bar2(): Array = null!! + +[Ann Ann] class A [Ann] ([Ann] val prop: Int) { + [Ann] val x = 1 + [Ann] fun foo([Ann] x: Int) { + [Ann] class B + + [Ann] fun local() {} + + 2 + [Ann Ann] 2 + + for ([Ann] (a, [Ann] b) in bar2()) {} + } + + fun x(): [Ann] String { + [Ann] val x: [Ann] String = "" + return "" + } +} + +val y: Array<[Ann] String?> = arrayOfNulls(1) +val block: ([Ann] x: [Ann] String) -> [Ann] String = { "" } +trait B +trait D : [Ann] B + +Ann([Ann] 1) class MyClass diff --git a/compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.txt b/compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.txt new file mode 100644 index 00000000000..cc0eebc5d4c --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.txt @@ -0,0 +1,56 @@ +package + +internal val block: ([Ann()] kotlin.String) -> [Ann()] kotlin.String +internal val y: kotlin.Array +internal fun bar(/*0*/ block: () -> kotlin.Int): kotlin.Int +internal fun bar2(): kotlin.Array + +Ann() Ann() internal final class A { + Ann() public constructor A(/*0*/ Ann() prop: kotlin.Int) + Ann() internal final val prop: kotlin.Int + Ann() internal final val x: kotlin.Int = 1 + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + Ann() internal final fun foo(/*0*/ Ann() x: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + internal final fun x(): [Ann()] kotlin.String +} + +internal final annotation class Ann : kotlin.Annotation { + public constructor Ann(/*0*/ arg: kotlin.Int = ...) + internal final val arg: kotlin.Int + 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 +} + +internal trait B { + 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 +} + +internal trait D : B { + 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 +} + +Ann() internal final class MyClass { + public constructor MyClass() + 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 +} + +kotlin.data() internal final class Q { + public constructor Q(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int) + internal final val x: kotlin.Int + internal final val y: kotlin.Int + internal final /*synthesized*/ fun component1(): kotlin.Int + internal final /*synthesized*/ fun component2(): kotlin.Int + public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.Int = ...): Q + 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/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index e548b33cfd4..af14e463083 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -657,6 +657,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("bracketsDeprecation.kt") + public void testBracketsDeprecation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/bracketsDeprecation.kt"); + doTest(fileName); + } + @TestMetadata("ConstructorCall.kt") public void testConstructorCall() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/ConstructorCall.kt");