From b6bdcb303d34b052076f1dbabbc947ac83834b44 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Thu, 4 Jul 2013 17:39:15 +0400 Subject: [PATCH] Resolve java.lang.Class as annotation argument --- .../AnnotationArgumentVisitor.java | 2 + .../jet/lang/resolve/AnnotationResolver.java | 9 ++-- .../jet/lang/resolve/AnnotationUtils.java | 13 +++++ .../resolve/constants/JavaClassValue.java | 52 +++++++++++++++++++ .../testData/resolveAnnotations/testFile.kt | 1 + .../AnnotationDescriptorResolveTest.java | 6 +++ 6 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java index 06229b57f33..ef2fe79ae12 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java @@ -48,4 +48,6 @@ public interface AnnotationArgumentVisitor { R visitArrayValue(ArrayValue value, D data); R visitAnnotationValue(AnnotationValue value, D data); + + R visitJavaClassValue(JavaClassValue value, D data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index 00b575063f6..62a759df815 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -30,10 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.constants.AnnotationValue; -import org.jetbrains.jet.lang.resolve.constants.ArrayValue; -import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; -import org.jetbrains.jet.lang.resolve.constants.EnumValue; +import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.ErrorUtils; @@ -312,6 +309,10 @@ public class AnnotationResolver { return new AnnotationValue(descriptor); } } + + if (AnnotationUtils.isJavaClassMethodCall(call)) { + return new JavaClassValue(resultingDescriptor.getReturnType()); + } } return null; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java index 339c19c43ed..947f0a498f2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java @@ -102,6 +102,19 @@ public class AnnotationUtils { return false; } + public static boolean isJavaClassMethodCall(@NotNull ResolvedCall resolvedCall) { + List annotations = resolvedCall.getResultingDescriptor().getOriginal().getAnnotations(); + if (annotations != null) { + for (AnnotationDescriptor annotation : annotations) { + //noinspection ConstantConditions + if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().asString())) { + return "kotlin.javaClass.function".equals(annotation.getAllValueArguments().values().iterator().next().getValue()); + } + } + } + return false; + } + private static boolean isJavaLangClass(ClassDescriptor descriptor) { return "java.lang.Class".equals(DescriptorUtils.getFQName(descriptor).asString()); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.java new file mode 100644 index 00000000000..5b93e540bd8 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.java @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.constants; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; + +public class JavaClassValue implements CompileTimeConstant { + + private final JetType value; + + public JavaClassValue(JetType value) { + this.value = value; + } + + @Override + public JetType getValue() { + return value.getArguments().iterator().next().getType(); + } + + @NotNull + @Override + public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) { + return value; + } + + @Override + public R accept(AnnotationArgumentVisitor visitor, D data) { + return visitor.visitJavaClassValue(this, data); + } + + @Override + public String toString() { + return getValue() + ".class"; + } +} diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index ca0d49d67be..498c7d6d49c 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -46,6 +46,7 @@ annotation class AnnStringVararg(vararg a: String) annotation class AnnStringArray(a: Array) annotation class AnnArrayOfEnum(a: Array) annotation class AnnAnn(a: AnnInt) +annotation class AnnClass(a: Class<*>) enum class MyEnum { A diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 6129e4c616d..e689c63f531 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -119,6 +119,12 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testJavaClassAnnotation() throws Exception { + String content = getContent("AnnClass(javaClass())"); + String expectedAnnotation = "AnnClass[a = MyClass.class: java.lang.Class]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass");