diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/JavaAnnotationCallChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/JavaAnnotationCallChecker.kt index 63ffc596c59..085b10421f3 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/JavaAnnotationCallChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/JavaAnnotationCallChecker.kt @@ -23,8 +23,13 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0 import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.load.java.components.JavaAnnotationMapper import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.FqNameUnsafe +import org.jetbrains.kotlin.psi.JetAnnotationEntry import org.jetbrains.kotlin.psi.JetExpression +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext @@ -33,6 +38,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.types.JetType +import org.jetbrains.kotlin.types.TypeUtils +import java.lang.annotation.Target public class JavaAnnotationCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall, context: BasicCallResolutionContext) { @@ -41,6 +48,15 @@ public class JavaAnnotationCallChecker : CallChecker { resultingDescriptor.getContainingDeclaration().getKind() != ClassKind.ANNOTATION_CLASS) return reportErrorsOnPositionedArguments(resolvedCall, context) + reportDeprecatedJavaAnnotation(resolvedCall, context) + } + + private fun reportDeprecatedJavaAnnotation(resolvedCall: ResolvedCall<*>, context: BasicCallResolutionContext) { + val annotationEntry = resolvedCall.call.callElement as? JetAnnotationEntry ?: return + val type = context.trace.get(BindingContext.TYPE, annotationEntry.typeReference) ?: return + JavaAnnotationMapper.javaToKotlinNameMap[type.constructor.declarationDescriptor?.let { DescriptorUtils.getFqNameSafe(it) }]?.let { + context.trace.report(ErrorsJvm.DEPRECATED_JAVA_ANNOTATION.on(annotationEntry, it)) + } } private fun reportErrorsOnPositionedArguments( diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java index c5c2d84881e..9fed88dfbcb 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java @@ -58,6 +58,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION, "Only named arguments are available for Java annotations"); MAP.put(ErrorsJvm.DEPRECATED_ANNOTATION_METHOD_CALL, "Annotation methods are deprecated. Use property instead"); + MAP.put(ErrorsJvm.DEPRECATED_JAVA_ANNOTATION, "This annotation is deprecated in Kotlin. Use ''{0}'' instead", Renderers.TO_STRING); MAP.put(ErrorsJvm.NO_REFLECTION_IN_CLASS_PATH, "Call uses reflection API which is not found in compilation classpath. " + "Make sure you have kotlin-reflect.jar in the classpath"); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java index 1c59989e593..4510b03c513 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java @@ -18,11 +18,14 @@ package org.jetbrains.kotlin.resolve.jvm.diagnostics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0; import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1; import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2; import org.jetbrains.kotlin.diagnostics.Errors; +import org.jetbrains.kotlin.name.FqName; +import org.jetbrains.kotlin.psi.JetAnnotationEntry; import org.jetbrains.kotlin.psi.JetDeclaration; import org.jetbrains.kotlin.psi.JetElement; import org.jetbrains.kotlin.psi.JetExpression; @@ -51,8 +54,9 @@ public interface ErrorsJvm { DiagnosticFactory0 NATIVE_DECLARATION_IN_TRAIT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 NATIVE_DECLARATION_CANNOT_BE_INLINED = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); - DiagnosticFactory0 POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION = DiagnosticFactory0.create(ERROR); - DiagnosticFactory0 DEPRECATED_ANNOTATION_METHOD_CALL = DiagnosticFactory0.create(WARNING); + DiagnosticFactory0 POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 DEPRECATED_ANNOTATION_METHOD_CALL = DiagnosticFactory0.create(WARNING); + DiagnosticFactory1 DEPRECATED_JAVA_ANNOTATION = DiagnosticFactory1.create(WARNING); DiagnosticFactory0 TRAIT_CANT_CALL_DEFAULT_METHOD_VIA_SUPER = DiagnosticFactory0.create(ERROR); diff --git a/compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt b/compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt index 65552282a72..460d3c5adf9 100644 --- a/compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt +++ b/compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.kt @@ -4,5 +4,5 @@ import java.lang.annotation.* annotation class my Retention(RetentionPolicy.RUNTIME) -Target(ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR) +Target(ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR) annotation class my1 \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt index 1f45611e0c5..d643771bee1 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt @@ -54,6 +54,8 @@ public object JavaAnnotationMapper { public val kotlinToJavaNameMap: Map = mapOf(KotlinBuiltIns.FQ_NAMES.target to FqName(javaClass().getCanonicalName())) + + public val javaToKotlinNameMap: Map = kotlinToJavaNameMap.map { it.value to it.key }.toMap() } class JavaTargetAnnotationDescriptor(