From c4ba32a8ccab34ff5361cfedf6b941dc812dc458 Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Wed, 29 Oct 2014 11:30:24 +0300 Subject: [PATCH] Can't use a qualified name of an annotation class in an annotation parameter #KT-6151 Fixed --- .../evaluate/ConstantExpressionEvaluator.kt | 5 ++ .../resolve/calls/CallExpressionResolver.java | 3 +- .../annotations/qualifiedCallValue.kt | 30 +++++++++ .../annotations/qualifiedCallValue.txt | 66 +++++++++++++++++++ ...JetDiagnosticsTestWithStdLibGenerated.java | 6 ++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.txt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt index 9b4bb19f6b4..0c2364b99f3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/evaluate/ConstantExpressionEvaluator.kt @@ -334,6 +334,11 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet val selectorExpression = expression.getSelectorExpression() // 1.toInt(); 1.plus(1); if (selectorExpression is JetCallExpression) { + val qualifiedCallValue = evaluate(selectorExpression, expectedType) + if (qualifiedCallValue != null) { + return qualifiedCallValue + } + val calleeExpression = selectorExpression.getCalleeExpression() if (calleeExpression !is JetSimpleNameExpression) { return null diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index 0775f641340..53c3bf60722 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -225,7 +225,8 @@ public class CallExpressionResolver { } private static boolean canInstantiateAnnotationClass(@NotNull JetCallExpression expression) { - PsiElement parent = expression.getParent(); + //noinspection unchecked + PsiElement parent = PsiTreeUtil.getParentOfType(expression, JetValueArgument.class, JetParameter.class); if (parent instanceof JetValueArgument) { return PsiTreeUtil.getParentOfType(parent, JetAnnotationEntry.class) != null; } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt new file mode 100644 index 00000000000..c2d0db1787f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt @@ -0,0 +1,30 @@ +package a.b.c + +kotlin.deprecated("aaa") +ann1(kotlin.deprecated("aaa")) + +a.b.c.ann1() +ann2(a.b.c.ann1()) + +A.IAnn() +ann3(A.IAnn()) + +a.b.c.A.IAnn() +ann3(a.b.c.A.IAnn()) + +annJavaClass(kotlin.javaClass()) + +annArray(kotlin.array("a")) +fun test() = 1 + +annotation class ann1(val p: deprecated = kotlin.deprecated("aaa")) +annotation class ann2(val p: ann1 = a.b.c.ann1()) +annotation class ann3(val p: A.IAnn = A.IAnn(), val p2: A.IAnn = a.b.c.A.IAnn()) + +annotation class annJavaClass(val p: Class<*> = kotlin.javaClass()) + +annotation class annArray(val p: Array = kotlin.array("a")) + +class A { + annotation class IAnn +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.txt new file mode 100644 index 00000000000..0557e4f77c1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.txt @@ -0,0 +1,66 @@ +package + +package a { + + package a.b { + + package a.b.c { + kotlin.deprecated(value = "aaa": kotlin.String) a.b.c.ann1(p = kotlin.deprecated(value = "aaa": kotlin.String): kotlin.deprecated) a.b.c.ann1() a.b.c.ann2(p = a.b.c.ann1(): a.b.c.ann1) a.b.c.A.IAnn() a.b.c.ann3(p = a.b.c.A.IAnn(): a.b.c.A.IAnn) a.b.c.A.IAnn() a.b.c.ann3(p = a.b.c.A.IAnn(): a.b.c.A.IAnn) a.b.c.annJavaClass(p = a.b.c.A.class: java.lang.Class) a.b.c.annArray(p = {"a"}: kotlin.Array) internal fun test(): kotlin.Int + + internal final class A { + 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 + + internal final annotation class IAnn : kotlin.Annotation { + public constructor IAnn() + 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 annotation class ann1 : kotlin.Annotation { + public constructor ann1(/*0*/ p: kotlin.deprecated = ...) + internal final val p: kotlin.deprecated + 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 annotation class ann2 : kotlin.Annotation { + public constructor ann2(/*0*/ p: a.b.c.ann1 = ...) + internal final val p: a.b.c.ann1 + 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 annotation class ann3 : kotlin.Annotation { + public constructor ann3(/*0*/ p: a.b.c.A.IAnn = ..., /*1*/ p2: a.b.c.A.IAnn = ...) + internal final val p: a.b.c.A.IAnn + internal final val p2: a.b.c.A.IAnn + 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 annotation class annArray : kotlin.Annotation { + public constructor annArray(/*0*/ p: kotlin.Array = ...) + internal final val p: 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 + } + + internal final annotation class annJavaClass : kotlin.Annotation { + public constructor annJavaClass(/*0*/ p: java.lang.Class = ...) + internal final val p: java.lang.Class + 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/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java index fc0e8a042c3..38cb63baba7 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -52,6 +52,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } + @TestMetadata("qualifiedCallValue.kt") + public void testQualifiedCallValue() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/qualifiedCallValue.kt"); + doTest(fileName); + } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)