From db42941586c2698ac45e995a5f7c73a1736dd4e7 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 25 Nov 2015 13:43:01 +0300 Subject: [PATCH] Allow annotation constructor calls in default parameter value expressions of anonymous classes (if it is not a compile-time constant, it will be reported separately). #KT-10136 Fixed --- .../resolve/calls/CallExpressionResolver.java | 23 +++++++++++----- .../boxWithStdlib/annotations/kt10136.kt | 19 ++++++++++++++ .../annotationParameters/kt10136.kt | 8 ++++++ .../annotationParameters/kt10136.txt | 26 +++++++++++++++++++ .../DiagnosticsTestWithStdLibGenerated.java | 6 +++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 6 +++++ 6 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/annotations/kt10136.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java index 0230bdb82bd..f942b365de6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java @@ -284,14 +284,25 @@ public class CallExpressionResolver { //noinspection unchecked PsiElement parent = PsiTreeUtil.getParentOfType(expression, KtValueArgument.class, KtParameter.class); if (parent instanceof KtValueArgument) { - return PsiTreeUtil.getParentOfType(parent, KtAnnotationEntry.class) != null; + if (PsiTreeUtil.getParentOfType(parent, KtAnnotationEntry.class) != null) { + return true; + } + parent = PsiTreeUtil.getParentOfType(parent, KtParameter.class); + if (parent != null) { + return isUnderAnnotationClassDeclaration(trace, parent); + } } else if (parent instanceof KtParameter) { - KtClass ktClass = PsiTreeUtil.getParentOfType(parent, KtClass.class); - if (ktClass != null) { - DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, ktClass); - return DescriptorUtils.isAnnotationClass(descriptor); - } + return isUnderAnnotationClassDeclaration(trace, parent); + } + return false; + } + + private static boolean isUnderAnnotationClassDeclaration(@NotNull BindingTrace trace, PsiElement parent) { + KtClass ktClass = PsiTreeUtil.getParentOfType(parent, KtClass.class); + if (ktClass != null) { + DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, ktClass); + return DescriptorUtils.isAnnotationClass(descriptor); } return false; } diff --git a/compiler/testData/codegen/boxWithStdlib/annotations/kt10136.kt b/compiler/testData/codegen/boxWithStdlib/annotations/kt10136.kt new file mode 100644 index 00000000000..69f88544ff7 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/annotations/kt10136.kt @@ -0,0 +1,19 @@ +annotation class A + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +annotation class B(val items: Array = arrayOf(A())) + +@B +class C + +fun box(): String { + val bClass = B::class.java + val cClass = C::class.java + + val items = cClass.getAnnotation(bClass).items + assert(items.size == 1) { "Expected: [A()], got ${items.asList()}" } + assert(items[0] is A) { "Expected: [A()], got ${items.asList()}" } + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.kt new file mode 100644 index 00000000000..f7bd9cb2ba5 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.kt @@ -0,0 +1,8 @@ +annotation class A +annotation class A1(val x: Int) + +annotation class B( + val a: A = A(), + val x: Int = A1(42).x, + val aa: Array = arrayOf(A()) +) \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.txt new file mode 100644 index 00000000000..3b893af999d --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.txt @@ -0,0 +1,26 @@ +package + +public final annotation class A : kotlin.Annotation { + public constructor A() + 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 final annotation class A1 : kotlin.Annotation { + public constructor A1(/*0*/ x: kotlin.Int) + public final val x: 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 +} + +public final annotation class B : kotlin.Annotation { + public constructor B(/*0*/ a: A = ..., /*1*/ x: kotlin.Int = ..., /*2*/ aa: kotlin.Array = ...) + public final val a: A + public final val aa: kotlin.Array + public final val x: 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index eb3fcf23118..153054f9fd1 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -207,6 +207,12 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("kt10136.kt") + public void testKt10136() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/kt10136.kt"); + doTest(fileName); + } + @TestMetadata("orderWithValue.kt") public void testOrderWithValue() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/orderWithValue.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 256b83e846d..97bdc777c0e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -100,6 +100,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("kt10136.kt") + public void testKt10136() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/annotations/kt10136.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("nestedClassPropertyAsParameter.kt") public void testNestedClassPropertyAsParameter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/annotations/nestedClassPropertyAsParameter.kt");