From f53baebf899b9a03f2bddbc205a764f3002911eb Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 17 Apr 2015 17:34:44 +0300 Subject: [PATCH] Show warning on usages of javaClass() in annotations loaded from Java --- .../load/kotlin/JavaAnnotationCallChecker.kt | 62 +++++++++++++++++-- .../diagnostics/DefaultErrorMessagesJvm.java | 1 + .../resolve/jvm/diagnostics/ErrorsJvm.java | 1 + .../kotlin/resolve/AnnotationResolver.java | 2 +- .../resolve/CompileTimeConstantUtils.java | 8 +-- .../javaClassArgumentError.kt | 17 +++++ .../javaClassArgumentError.txt | 26 ++++++++ .../javaClassArrayInAnnotations.kt | 26 ++++++++ .../javaClassArrayInAnnotations.txt | 53 ++++++++++++++++ .../javaClassInAnnotations.kt | 14 +++++ .../javaClassInAnnotations.txt | 53 ++++++++++++++++ ...JetDiagnosticsTestWithStdLibGenerated.java | 18 ++++++ .../kotlin/resolve/DescriptorUtils.java | 4 ++ 13 files changed, 272 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.txt 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 ec41dae95ec..07f917fcf74 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 @@ -16,15 +16,23 @@ package org.jetbrains.kotlin.load.kotlin +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor 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.descriptors.JavaConstructorDescriptor +import org.jetbrains.kotlin.psi.JetExpression +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument 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 public class JavaAnnotationCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall, context: BasicCallResolutionContext) { @@ -32,14 +40,56 @@ public class JavaAnnotationCallChecker : CallChecker { if (resultingDescriptor !is JavaConstructorDescriptor || resultingDescriptor.getContainingDeclaration().getKind() != ClassKind.ANNOTATION_CLASS) return + reportErrorsOnPositionedArguments(resolvedCall, context) + reportWarningOnJavaClassUsages(resolvedCall, context) + } + + private fun reportWarningOnJavaClassUsages( + resolvedCall: ResolvedCall<*>, + context: BasicCallResolutionContext + ) { + resolvedCall.getValueArguments().filter { it.getKey().getType().isJavaLangClassOrArray() }.forEach { + reportOnValueArgument(context, it, ErrorsJvm.JAVA_LANG_CLASS_ARGUMENT_IN_ANNOTATION) + } + } + + private fun JetType.isJavaLangClassOrArray() = isJavaLangClass() || + (KotlinBuiltIns.isArray(this) && getArguments().first().getType().isJavaLangClass()) + + private fun JetType.isJavaLangClass(): Boolean { + val classifier = getConstructor().getDeclarationDescriptor() + + if (classifier !is ClassDescriptor) return false + return DescriptorUtils.isJavaLangClass(classifier) + } + + private fun reportErrorsOnPositionedArguments( + resolvedCall: ResolvedCall<*>, + context: BasicCallResolutionContext + ) { resolvedCall.getValueArguments().filter { - p -> p.key.getName() != JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME && - p.value is ExpressionValueArgument && - !((p.value as ExpressionValueArgument).getValueArgument()?.isNamed() ?: true) + p -> + p.key.getName() != JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME && + p.value is ExpressionValueArgument && + !((p.value as ExpressionValueArgument).getValueArgument()?.isNamed() ?: true) }.forEach { - context.trace.report( - ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION.on( - it.getValue().getArguments().first().getArgumentExpression())) + reportOnValueArgument(context, it, ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION) + } + } + + private fun reportOnValueArgument( + context: BasicCallResolutionContext, + argument: Map.Entry, + diagnostic: DiagnosticFactory0 + ) { + argument.getValue().getArguments().forEach { + if (it.getArgumentExpression() != null) { + context.trace.report( + diagnostic.on( + it.getArgumentExpression() + ) + ) + } } } } 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 92550e0b3e7..4d72b7482cc 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 @@ -57,6 +57,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ErrorsJvm.NATIVE_DECLARATION_CANNOT_BE_INLINED, "Members of traits can not be inlined"); MAP.put(ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION, "Only named arguments are available for Java annotations"); + MAP.put(ErrorsJvm.JAVA_LANG_CLASS_ARGUMENT_IN_ANNOTATION, "Usage of `javaClass()` in annotations is deprecated. Use T::class instead"); MAP.put(ErrorsJvm.NO_REFLECTION_IN_CLASS_PATH, "Expression ''{0}'' uses reflection which is not found in compilation classpath. Make sure you have kotlin-reflect.jar in the classpath", Renderers.ELEMENT_TEXT); 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 d28078e6e6b..c0b5ec2f51d 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 @@ -52,6 +52,7 @@ public interface ErrorsJvm { DiagnosticFactory0 NATIVE_DECLARATION_CANNOT_BE_INLINED = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 JAVA_LANG_CLASS_ARGUMENT_IN_ANNOTATION = DiagnosticFactory0.create(WARNING); // TODO: make this a warning DiagnosticFactory1 NO_REFLECTION_IN_CLASS_PATH = DiagnosticFactory1.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java index f5b310d1a9f..4792eeee081 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java @@ -306,7 +306,7 @@ public class AnnotationResolver { if (descriptor != null && DescriptorUtils.isEnumClass(descriptor)) { trace.report(Errors.ANNOTATION_PARAMETER_MUST_BE_ENUM_CONST.on(argumentExpression)); } - else if (descriptor instanceof ClassDescriptor && CompileTimeConstantUtils.isJavaLangClass((ClassDescriptor) descriptor)) { + else if (descriptor instanceof ClassDescriptor && DescriptorUtils.isJavaLangClass((ClassDescriptor) descriptor)) { trace.report(Errors.ANNOTATION_PARAMETER_MUST_BE_CLASS_LITERAL.on(argumentExpression)); } else if (descriptor instanceof ClassDescriptor && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor)) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java index 2187d6d074b..aae2f988c6c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java @@ -78,7 +78,7 @@ public class CompileTimeConstantUtils { KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); if (isEnumClass(typeDescriptor) || isAnnotationClass(typeDescriptor) || - isJavaLangClass(typeDescriptor) || + DescriptorUtils.isJavaLangClass(typeDescriptor) || KotlinBuiltIns.isKClass(typeDescriptor) || KotlinBuiltIns.isPrimitiveArray(parameterType) || KotlinBuiltIns.isPrimitiveType(parameterType) || @@ -97,7 +97,7 @@ public class CompileTimeConstantUtils { if (arrayTypeDescriptor != null) { return isEnumClass(arrayTypeDescriptor) || isAnnotationClass(arrayTypeDescriptor) || - isJavaLangClass(arrayTypeDescriptor) || + DescriptorUtils.isJavaLangClass(arrayTypeDescriptor) || KotlinBuiltIns.isKClass(arrayTypeDescriptor) || builtIns.getStringType().equals(arrayType); } @@ -127,10 +127,6 @@ public class CompileTimeConstantUtils { return "kotlin.javaClass.function".equals(getIntrinsicAnnotationArgument(resolvedCall.getResultingDescriptor().getOriginal())); } - public static boolean isJavaLangClass(ClassDescriptor descriptor) { - return "java.lang.Class".equals(DescriptorUtils.getFqName(descriptor).asString()); - } - public static boolean canBeReducedToBooleanConstant( @Nullable JetExpression expression, @NotNull BindingTrace trace, diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.kt new file mode 100644 index 00000000000..f1e76b1d440 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.kt @@ -0,0 +1,17 @@ +// FILE: A.java +public @interface A { + Class[] value(); +} + +// FILE: b.kt +val jClass = javaClass() +A( + jClass, + javaClass() +) +class MyClass1 + +A( + javaClass<Err>(), + javaClass() +) class MyClass2 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.txt new file mode 100644 index 00000000000..3fb2f0ce6ac --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.txt @@ -0,0 +1,26 @@ +package + +internal val jClass: java.lang.Class + +public final annotation class A : kotlin.Annotation { + public /*synthesized*/ constructor A(/*0*/ vararg value: java.lang.Class<*> /*kotlin.Array>*/) + public constructor A(/*0*/ vararg value: kotlin.reflect.KClass<*> /*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 + public abstract fun value(): kotlin.Array> +} + +A(value = {javaClass()}: kotlin.Array>) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +A(value = {javaClass<[ERROR : Err]>(), javaClass()}: kotlin.Array>) internal final class MyClass2 { + public constructor MyClass2() + 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/annotationParameters/javaClassArrayInAnnotations.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.kt new file mode 100644 index 00000000000..ab3eab07cbc --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.kt @@ -0,0 +1,26 @@ +// FILE: A.java +public @interface A { + Class[] value() default {Integer.class}; + Class[] arg() default {String.class}; +} + +// FILE: b.kt +A(javaClass(), +javaClass(), +arg = array(javaClass(), javaClass())) +class MyClass1 + +A(javaClass(), javaClass()) +class MyClass2 + +A(arg = array(javaClass(), javaClass())) +class MyClass3 + +A class MyClass4 + +A(value = *array(javaClass(), javaClass()), +arg = array(javaClass(), javaClass())) +class MyClass5 + +A(value = *array(javaClass(), javaClass())) +class MyClass6 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.txt new file mode 100644 index 00000000000..5f97cf407f0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.txt @@ -0,0 +1,53 @@ +package + +public final annotation class A : kotlin.Annotation { + public /*synthesized*/ constructor A(/*0*/ vararg value: java.lang.Class<*> /*kotlin.Array>*/ = ..., /*1*/ arg: kotlin.Array> = ...) + public constructor A(/*0*/ vararg value: kotlin.reflect.KClass<*> /*kotlin.Array>*/ = ..., /*1*/ arg: kotlin.Array> = ...) + public abstract fun arg(): 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 + public abstract fun value(): kotlin.Array> +} + +A(arg = {javaClass(), javaClass()}: kotlin.Array>>, value = {javaClass(), javaClass()}: kotlin.Array>) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +A(value = {javaClass(), javaClass()}: kotlin.Array>) internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +A(arg = {javaClass(), javaClass()}: kotlin.Array>>) internal final class MyClass3 { + public constructor MyClass3() + 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 +} + +A() internal final class MyClass4 { + public constructor MyClass4() + 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 +} + +A(arg = {javaClass(), javaClass()}: kotlin.Array>>, value = {javaClass(), javaClass()}: kotlin.Array>) internal final class MyClass5 { + public constructor MyClass5() + 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 +} + +A(value = {javaClass(), javaClass()}: kotlin.Array>) internal final class MyClass6 { + public constructor MyClass6() + 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/annotationParameters/javaClassInAnnotations.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.kt new file mode 100644 index 00000000000..4a7adf7db80 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.kt @@ -0,0 +1,14 @@ +// FILE: A.java +public @interface A { + Class value() default Integer.class; + Class arg() default String.class; +} + +// FILE: b.kt +A(javaClass(), arg = javaClass()) class MyClass1 +A(javaClass()) class MyClass2 +A(arg = javaClass()) class MyClass3 +A class MyClass4 + +A(value = javaClass(), arg = javaClass()) class MyClass5 +A(value = javaClass()) class MyClass6 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.txt new file mode 100644 index 00000000000..5318be6a8f6 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.txt @@ -0,0 +1,53 @@ +package + +public final annotation class A : kotlin.Annotation { + public /*synthesized*/ constructor A(/*0*/ value: java.lang.Class<*> = ..., /*1*/ arg: java.lang.Class<*> = ...) + public constructor A(/*0*/ value: kotlin.reflect.KClass<*> = ..., /*1*/ arg: kotlin.reflect.KClass<*> = ...) + public abstract fun arg(): 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 + public abstract fun value(): kotlin.reflect.KClass<*> +} + +A(arg = javaClass(): java.lang.Class, value = javaClass(): java.lang.Class) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +A(value = javaClass(): java.lang.Class) internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +A(arg = javaClass(): java.lang.Class) internal final class MyClass3 { + public constructor MyClass3() + 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 +} + +A() internal final class MyClass4 { + public constructor MyClass4() + 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 +} + +A(arg = javaClass(): java.lang.Class, value = javaClass(): java.lang.Class) internal final class MyClass5 { + public constructor MyClass5() + 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 +} + +A(value = javaClass(): java.lang.Class) internal final class MyClass6 { + public constructor MyClass6() + 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/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 16ff8282609..72ad06d7a15 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -117,6 +117,24 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("javaClassArgumentError.kt") + public void testJavaClassArgumentError() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArgumentError.kt"); + doTest(fileName); + } + + @TestMetadata("javaClassArrayInAnnotations.kt") + public void testJavaClassArrayInAnnotations() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassArrayInAnnotations.kt"); + doTest(fileName); + } + + @TestMetadata("javaClassInAnnotations.kt") + public void testJavaClassInAnnotations() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/javaClassInAnnotations.kt"); + doTest(fileName); + } + @TestMetadata("orderWithValue.kt") public void testOrderWithValue() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/orderWithValue.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index 275c7047a0a..2b2a107fef7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -532,4 +532,8 @@ public class DescriptorUtils { } } } + + public static boolean isJavaLangClass(ClassDescriptor descriptor) { + return "java.lang.Class".equals(getFqName(descriptor).asString()); + } }