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 6655bc9b592..7f67b743121 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 @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.typeUtil.isArrayOfJavaLangClass import org.jetbrains.kotlin.types.typeUtil.isJavaLangClass +import org.jetbrains.kotlin.types.typeUtil.isJavaLangClassOrArray public class JavaAnnotationCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall, context: BasicCallResolutionContext) { @@ -55,8 +56,6 @@ public class JavaAnnotationCallChecker : CallChecker { } } - private fun JetType.isJavaLangClassOrArray() = isJavaLangClass() || isArrayOfJavaLangClass() - private fun reportErrorsOnPositionedArguments( resolvedCall: ResolvedCall<*>, context: BasicCallResolutionContext diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 4db93e4dbc2..f71410e69dd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -123,6 +123,7 @@ public interface Errors { DiagnosticFactory0 ANNOTATION_CLASS_WITH_BODY = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INVALID_TYPE_OF_ANNOTATION_MEMBER = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 NULLABLE_TYPE_OF_ANNOTATION_MEMBER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 ILLEGAL_ANNOTATION_KEYWORD = DiagnosticFactory0 .create(ERROR, modifierSetPosition(JetTokens.ANNOTATION_KEYWORD)); DiagnosticFactory0 ANNOTATION_PARAMETER_MUST_BE_CONST = 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 845f94cb8b5..7566d209cee 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -565,6 +565,7 @@ public class DefaultErrorMessages { MAP.put(ANNOTATION_CLASS_WITH_BODY, "Body is not allowed for annotation class"); MAP.put(INVALID_TYPE_OF_ANNOTATION_MEMBER, "Invalid type of annotation member"); MAP.put(NULLABLE_TYPE_OF_ANNOTATION_MEMBER, "An annotation parameter cannot be nullable"); + MAP.put(JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION, "java.lang.Class as annotation parameter is deprecated. Use KClass instead"); MAP.put(ILLEGAL_ANNOTATION_KEYWORD, "''annotation'' keyword is only applicable for class"); MAP.put(ANNOTATION_PARAMETER_MUST_BE_CONST, "An annotation parameter must be a compile-time constant"); MAP.put(ANNOTATION_PARAMETER_MUST_BE_ENUM_CONST, "An enum annotation parameter must be a enum constant"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java index 73f938103ca..118e9bf50f1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java @@ -35,12 +35,14 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.TypeProjection; import org.jetbrains.kotlin.types.TypeUtils; +import org.jetbrains.kotlin.types.typeUtil.TypeUtilPackage; import java.util.Collection; import java.util.List; import java.util.Set; import static org.jetbrains.kotlin.diagnostics.Errors.INVALID_TYPE_OF_ANNOTATION_MEMBER; +import static org.jetbrains.kotlin.diagnostics.Errors.JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION; import static org.jetbrains.kotlin.diagnostics.Errors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER; import static org.jetbrains.kotlin.resolve.BindingContext.VALUE_PARAMETER; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isAnnotationClass; @@ -68,6 +70,9 @@ public class CompileTimeConstantUtils { else if (!isAcceptableTypeForAnnotationParameter(parameterType)) { trace.report(INVALID_TYPE_OF_ANNOTATION_MEMBER.on(typeReference)); } + else if (TypeUtilPackage.isJavaLangClassOrArray(parameterType)) { + trace.report(JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION.on(typeReference)); + } } } } diff --git a/compiler/testData/diagnostics/tests/annotations/deprecatedJavaLangClass.kt b/compiler/testData/diagnostics/tests/annotations/deprecatedJavaLangClass.kt new file mode 100644 index 00000000000..fce18badca4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/deprecatedJavaLangClass.kt @@ -0,0 +1,10 @@ +annotation class Ann( + val x1: Class<*>, + val x2: Class, + val x3: Class, + val x4: java.lang.Class<*>, + val x5: Array>, + val x6: Array>, + val x7: Array>, + vararg val x8: Class<*> +) diff --git a/compiler/testData/diagnostics/tests/annotations/deprecatedJavaLangClass.txt b/compiler/testData/diagnostics/tests/annotations/deprecatedJavaLangClass.txt new file mode 100644 index 00000000000..944f110ca7e --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/deprecatedJavaLangClass.txt @@ -0,0 +1,16 @@ +package + +internal final annotation class Ann : kotlin.Annotation { + public constructor Ann(/*0*/ x1: java.lang.Class<*>, /*1*/ x2: java.lang.Class, /*2*/ x3: java.lang.Class, /*3*/ x4: java.lang.Class<*>, /*4*/ x5: kotlin.Array>, /*5*/ x6: kotlin.Array>, /*6*/ x7: kotlin.Array>, /*7*/ vararg x8: java.lang.Class<*> /*kotlin.Array>*/) + internal final val x1: java.lang.Class<*> + internal final val x2: java.lang.Class + internal final val x3: java.lang.Class + internal final val x4: java.lang.Class<*> + internal final val x5: kotlin.Array> + internal final val x6: kotlin.Array> + internal final val x7: kotlin.Array> + internal final val x8: kotlin.Array> + 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/invalidTypesInAnnotationConstructor.kt b/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt index 2abd3811cac..95681866dc0 100644 --- a/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt +++ b/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION package test import java.lang.annotation.RetentionPolicy diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsClass.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsClass.kt index 825b4120b83..e387e68edb2 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsClass.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsClass.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION package test annotation class AnnClass(val a: Class<*>) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsKClass.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsKClass.kt new file mode 100644 index 00000000000..8d190a5e007 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsKClass.kt @@ -0,0 +1,11 @@ +package test +import kotlin.reflect.KClass + +annotation class AnnClass(val a: KClass<*>) + +class MyClass { + + AnnClass(MyClass::class) companion object { + } + +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsKClass.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsKClass.txt new file mode 100644 index 00000000000..582d8098cf0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsKClass.txt @@ -0,0 +1,26 @@ +package + +package test { + + internal final annotation class AnnClass : kotlin.Annotation { + public constructor AnnClass(/*0*/ a: kotlin.reflect.KClass<*>) + internal final val a: kotlin.reflect.KClass<*> + 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 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 + + test.AnnClass(a = test.MyClass::class: kotlin.reflect.KClass) internal companion object Companion { + private constructor Companion() + 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/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt index 230be569b65..454ed468906 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/array.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION annotation class Ann(val i: IntArray) Ann(intArrayOf(i)) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/classLiteral.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/classLiteral.kt index 6f5610ee40c..cd566466355 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/classLiteral.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/classLiteral.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION annotation class AnnC(val c: Class<*>) AnnC(c) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt index 26f8646b57b..3b7d37d724f 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/vararg.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION annotation class Ann(vararg val i: Int) Ann(i) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt index 0ada662ebd6..fe873501e6f 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -JAVA_LANG_CLASS_PARAMETER_IN_ANNOTATION package a.b.c kotlin.deprecated("aaa") diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index c535aa81ae0..c6b1b58581b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -681,6 +681,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("deprecatedJavaLangClass.kt") + public void testDeprecatedJavaLangClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/deprecatedJavaLangClass.kt"); + doTest(fileName); + } + @TestMetadata("invalidTypesInAnnotationConstructor.kt") public void testInvalidTypesInAnnotationConstructor() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index be7c3b48405..4f15c68981a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -55,6 +55,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } + @TestMetadata("ClassObjectAnnotatedWithItsKClass.kt") + public void testClassObjectAnnotatedWithItsKClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/ClassObjectAnnotatedWithItsKClass.kt"); + doTest(fileName); + } + @TestMetadata("qualifiedCallValue.kt") public void testQualifiedCallValue() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index b5d6f05db06..bd3242c5271 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -95,3 +95,5 @@ public fun JetType.isJavaLangClass(): Boolean { public fun JetType.isArrayOfJavaLangClass(): Boolean = KotlinBuiltIns.isArray(this) && getArguments().firstOrNull()?.getType()?.isJavaLangClass() ?: false + +public fun JetType.isJavaLangClassOrArray(): Boolean = isJavaLangClass() || isArrayOfJavaLangClass()