From 42b587b0d519896125b64dfe797f9e402ac42e86 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 19 Nov 2015 10:38:45 +0300 Subject: [PATCH] Prohibit callable references to annotation class constructors. See KT-4391. --- .../org/jetbrains/kotlin/diagnostics/Errors.java | 1 + .../diagnostics/rendering/DefaultErrorMessages.java | 1 + .../expressions/BasicExpressionTypingVisitor.java | 6 +++++- .../function/abstractClassConstructors.kt | 2 +- .../function/annotationClassConstructor.kt | 5 +++++ .../function/annotationClassConstructor.txt | 13 +++++++++++++ .../kotlin/checkers/DiagnosticsTestGenerated.java | 6 ++++++ 7 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 202b665ed55..6679d5afb04 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -503,6 +503,7 @@ public interface Errors { DiagnosticFactory0 CALLABLE_REFERENCE_LHS_NOT_A_CLASS = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 CALLABLE_REFERENCE_TO_MEMBER_OR_EXTENSION_WITH_EMPTY_LHS = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 CALLABLE_REFERENCE_TO_OBJECT_MEMBER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 CLASS_LITERAL_LHS_NOT_A_CLASS = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT = 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 e6cc21742a4..25246fa5566 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -674,6 +674,7 @@ public class DefaultErrorMessages { "Left-hand side of a callable reference with a receiver parameter cannot be empty. " + "Please specify the type of the receiver before '::' explicitly"); MAP.put(CALLABLE_REFERENCE_TO_OBJECT_MEMBER, "Callable references to object members are not supported"); + MAP.put(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, "Annotation class cannot be instantiated"); MAP.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left hand side of a class literal"); MAP.put(ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT, "kotlin.Array class literal requires a type argument, please specify one in angle brackets"); 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 6d97fad1356..aa75ddbd704 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -719,9 +719,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { context.trace.report(CALLABLE_REFERENCE_TO_MEMBER_OR_EXTENSION_WITH_EMPTY_LHS.on(reference)); } - if (DescriptorUtils.isObject(descriptor.getContainingDeclaration())) { + DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); + if (DescriptorUtils.isObject(containingDeclaration)) { context.trace.report(CALLABLE_REFERENCE_TO_OBJECT_MEMBER.on(reference)); } + if (descriptor instanceof ConstructorDescriptor && DescriptorUtils.isAnnotationClass(containingDeclaration)) { + context.trace.report(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR.on(reference)); + } return CallableReferencesResolutionUtilsKt.createReflectionTypeForResolvedCallableReference( expression, lhsType, descriptor, context, components.reflectionTypes diff --git a/compiler/testData/diagnostics/tests/callableReference/function/abstractClassConstructors.kt b/compiler/testData/diagnostics/tests/callableReference/function/abstractClassConstructors.kt index 9afebc524cc..39ad4d37600 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/abstractClassConstructors.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/abstractClassConstructors.kt @@ -7,6 +7,6 @@ enum class D fun main() { ::A ::B - ::C // KT-3465 + ::C // KT-3465 ::D } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.kt b/compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.kt new file mode 100644 index 00000000000..249ee1a7094 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.kt @@ -0,0 +1,5 @@ +annotation class Ann(val prop: String) + +val annCtorRef = ::Ann +val annClassRef = Ann::class +val annPropRef = Ann::prop diff --git a/compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.txt b/compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.txt new file mode 100644 index 00000000000..4dfffcc7cae --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.txt @@ -0,0 +1,13 @@ +package + +public val annClassRef: kotlin.reflect.KClass +public val annCtorRef: kotlin.reflect.KFunction1 +public val annPropRef: kotlin.reflect.KProperty1 + +public final annotation class Ann : kotlin.Annotation { + public constructor Ann(/*0*/ prop: kotlin.String) + public final val prop: kotlin.String + 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/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index cd890dd1ebe..a7fe7c0b554 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -1619,6 +1619,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("annotationClassConstructor.kt") + public void testAnnotationClassConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/annotationClassConstructor.kt"); + doTest(fileName); + } + @TestMetadata("callableRefrenceOnNestedObject.kt") public void testCallableRefrenceOnNestedObject() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/callableRefrenceOnNestedObject.kt");