Use findAnnotation() instead of iterating through all annotations

This commit is contained in:
Andrey Breslav
2014-01-22 17:52:39 +04:00
parent ca7d5a2988
commit 04b47439bd
9 changed files with 59 additions and 96 deletions
@@ -34,9 +34,11 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
@@ -288,23 +290,19 @@ public abstract class AnnotationCodegen {
@NotNull
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) {
String internalName = typeMapper.mapType(annotationDescriptor.getType()).getInternalName();
if ("java/lang/annotation/Retention".equals(internalName)) {
Collection<CompileTimeConstant<?>> valueArguments = annotationDescriptor.getAllValueArguments().values();
assert valueArguments.size() == 1 : "Retention should have an argument: " + annotationDescriptor;
CompileTimeConstant<?> compileTimeConstant = valueArguments.iterator().next();
assert compileTimeConstant instanceof EnumValue : "Retention argument should be enum value: " + compileTimeConstant;
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
JetType classObjectType = enumEntry.getClassObjectType();
assert classObjectType != null : "Enum entry should have a class object: " + enumEntry;
assert "java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName()) :
"Retention argument should be of type RetentionPolicy: " + enumEntry;
return RetentionPolicy.valueOf(enumEntry.getName().asString());
}
}
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
if (retentionAnnotation == null) return RetentionPolicy.CLASS;
return RetentionPolicy.CLASS;
Collection<CompileTimeConstant<?>> valueArguments = retentionAnnotation.getAllValueArguments().values();
assert valueArguments.size() == 1 : "Retention should have an argument: " + retentionAnnotation + " on " + descriptor;
CompileTimeConstant<?> compileTimeConstant = valueArguments.iterator().next();
assert compileTimeConstant instanceof EnumValue : "Retention argument should be enum value: " + compileTimeConstant;
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
JetType classObjectType = enumEntry.getClassObjectType();
assert classObjectType != null : "Enum entry should have a class object: " + enumEntry;
assert "java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName()) :
"Retention argument should be of type RetentionPolicy: " + enumEntry;
return RetentionPolicy.valueOf(enumEntry.getName().asString());
}
@NotNull
@@ -21,9 +21,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.RangeCodegenUtil;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.AnnotationUtils;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
@@ -228,16 +227,9 @@ public class IntrinsicMethods {
}
}
for (AnnotationDescriptor annotation : descriptor.getAnnotations()) {
ClassifierDescriptor classifierDescriptor = annotation.getType().getConstructor().getDeclarationDescriptor();
assert classifierDescriptor != null;
if ("Intrinsic".equals(classifierDescriptor.getName().asString())) {
String value = (String) annotation.getAllValueArguments().values().iterator().next().getValue();
IntrinsicMethod result = namedMethods.get(value);
if (result != null) return result;
}
}
String value = AnnotationUtils.getIntrinsicAnnotationArgument(descriptor);
if (value == null) return null;
return null;
return namedMethods.get(value);
}
}
@@ -16,20 +16,25 @@
package org.jetbrains.jet.lang.resolve;
import jet.runtime.Intrinsic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.jet.lang.diagnostics.Errors.INVALID_TYPE_OF_ANNOTATION_MEMBER;
@@ -91,26 +96,24 @@ public class AnnotationUtils {
return false;
}
@Nullable
public static String getIntrinsicAnnotationArgument(@NotNull Annotated annotatedDescriptor) {
AnnotationDescriptor intrinsicAnnotation = annotatedDescriptor.getAnnotations().findAnnotation(new FqName(Intrinsic.class.getName()));
if (intrinsicAnnotation == null) return null;
Collection<CompileTimeConstant<?>> values = intrinsicAnnotation.getAllValueArguments().values();
if (values.isEmpty()) return null;
Object value = values.iterator().next().getValue();
return value instanceof String ? (String) value : null;
}
public static boolean isArrayMethodCall(@NotNull ResolvedCall resolvedCall) {
Annotations annotations = resolvedCall.getResultingDescriptor().getOriginal().getAnnotations();
for (AnnotationDescriptor annotation : annotations) {
//noinspection ConstantConditions
if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().asString())) {
return "kotlin.arrays.array".equals(annotation.getAllValueArguments().values().iterator().next().getValue());
}
}
return false;
return "kotlin.arrays.array".equals(getIntrinsicAnnotationArgument(resolvedCall.getResultingDescriptor().getOriginal()));
}
public static boolean isJavaClassMethodCall(@NotNull ResolvedCall resolvedCall) {
Annotations annotations = resolvedCall.getResultingDescriptor().getOriginal().getAnnotations();
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;
return "kotlin.javaClass.function".equals(getIntrinsicAnnotationArgument(resolvedCall.getResultingDescriptor().getOriginal()));
}
public static boolean isPropertyCompileTimeConstant(@NotNull PropertyDescriptor descriptor) {
@@ -618,14 +618,13 @@ public class OverrideResolver {
@NotNull
private JetAnnotationEntry findDataAnnotationForDataClass(@NotNull DeclarationDescriptor dataClass) {
ClassDescriptor stdDataClassAnnotation = KotlinBuiltIns.getInstance().getDataClassAnnotation();
for (AnnotationDescriptor annotation : dataClass.getAnnotations()) {
if (stdDataClassAnnotation.equals(annotation.getType().getConstructor().getDeclarationDescriptor())) {
return BindingContextUtils.getNotNull(trace.getBindingContext(),
BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT,
annotation);
}
AnnotationDescriptor annotation = dataClass.getAnnotations().findAnnotation(DescriptorUtils.getFqNameSafe(stdDataClassAnnotation));
if (annotation == null) {
throw new IllegalStateException("No data annotation is found for data class " + dataClass);
}
throw new IllegalStateException("No data annotation is found for data class");
return BindingContextUtils.getNotNull(trace.getBindingContext(),
BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT,
annotation);
}
private CallableMemberDescriptor findInvisibleOverriddenDescriptor(CallableMemberDescriptor declared, ClassDescriptor declaringClass) {
@@ -39,6 +39,7 @@ public class NullabilityAnnotationsTest extends KotlinAsJavaTestBase {
@Override
protected void extraConfiguration(@NotNull CompilerConfiguration configuration) {
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, JetTestUtils.getAnnotationsJar());
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, JetTestUtils.findMockJdkRtJar());
}
public void test_DefaultPackage() throws Exception {
@@ -23,9 +23,9 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -81,21 +81,16 @@ public class ExpectedLoadErrorsUtil {
}
private Void visitDeclaration(@NotNull DeclarationDescriptor descriptor) {
for (AnnotationDescriptor annotation : descriptor.getAnnotations()) {
ClassDescriptor annotationClass = (ClassDescriptor) annotation.getType().getConstructor().getDeclarationDescriptor();
assert annotationClass != null;
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(new FqName(ANNOTATION_CLASS_NAME));
if (annotation == null) return null;
if (DescriptorUtils.getFqName(annotationClass).asString().equals(ANNOTATION_CLASS_NAME)) {
// we expect exactly one annotation argument
CompileTimeConstant<?> argument = annotation.getAllValueArguments().values().iterator().next();
// we expect exactly one annotation argument
CompileTimeConstant<?> argument = annotation.getAllValueArguments().values().iterator().next();
String error = (String) argument.getValue();
List<String> errors = Arrays.asList(error.split("\\|"));
String error = (String) argument.getValue();
List<String> errors = Arrays.asList(error.split("\\|"));
map.put(descriptor, errors);
}
}
map.put(descriptor, errors);
return null;
}
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
@@ -932,13 +931,8 @@ public class KotlinBuiltIns {
}
static boolean containsAnnotation(DeclarationDescriptor descriptor, ClassDescriptor annotationClass) {
Annotations annotations = descriptor.getOriginal().getAnnotations();
for (AnnotationDescriptor annotation : annotations) {
if (annotationClass.equals(annotation.getType().getConstructor().getDeclarationDescriptor())) {
return true;
}
}
return false;
FqName fqName = DescriptorUtils.getFqName(annotationClass).toSafe();
return descriptor.getOriginal().getAnnotations().findAnnotation(fqName) != null;
}
public boolean isVolatile(@NotNull PropertyDescriptor descriptor) {
@@ -220,14 +220,8 @@ public class DeprecatedAnnotationVisitor extends AfterAnalysisHighlightingVisito
@Nullable
private static AnnotationDescriptor getDeprecated(DeclarationDescriptor descriptor) {
for (AnnotationDescriptor annotation : descriptor.getAnnotations()) {
ClassDescriptor jetDeprecated = KotlinBuiltIns.getInstance().getDeprecatedAnnotation();
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(annotation.getType());
if (jetDeprecated.equals(classDescriptor)) {
return annotation;
}
}
return null;
ClassDescriptor jetDeprecated = KotlinBuiltIns.getInstance().getDeprecatedAnnotation();
return descriptor.getAnnotations().findAnnotation(DescriptorUtils.getFqNameSafe(jetDeprecated));
}
private static String composeTooltipString(@NotNull DeclarationDescriptor declarationDescriptor, @NotNull AnnotationDescriptor descriptor) {
@@ -21,8 +21,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.name.FqName;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getContainingClass;
@@ -85,20 +85,7 @@ public final class AnnotationsUtils {
@Nullable
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor, @NotNull String fqn) {
for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) {
if (getAnnotationClassFQName(annotationDescriptor).equals(fqn)) {
return annotationDescriptor;
}
}
return null;
}
@NotNull
private static String getAnnotationClassFQName(@NotNull AnnotationDescriptor annotationDescriptor) {
DeclarationDescriptor annotationDeclaration =
annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
assert annotationDeclaration != null : "Annotation supposed to have a declaration";
return DescriptorUtils.getFqName(annotationDeclaration).asString();
return descriptor.getAnnotations().findAnnotation(new FqName(fqn));
}
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {