From a5d6d6719c82b4aa0b65b2be4577e21cffac103d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 13 Nov 2013 20:45:08 +0400 Subject: [PATCH] EnumValue now has a ClassDescriptor for its enum entry --- .../jet/codegen/AnnotationCodegen.java | 27 +++++++++++-------- .../jet/lang/resolve/AnnotationResolver.java | 17 +++++++----- .../JavaAnnotationArgumentResolver.java | 12 +++------ .../AnnotationDescriptorDeserializer.java | 15 +++-------- .../jet/lang/resolve/constants/EnumValue.java | 21 +++++++-------- .../jet/lang/types/lang/InlineUtil.java | 3 +-- 6 files changed, 45 insertions(+), 50 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index c51ab301cf1..1cf1039e048 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -143,9 +143,10 @@ public abstract class AnnotationCodegen { } @Nullable - private String genAnnotation(AnnotationDescriptor annotationDescriptor) { + private String genAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) { ClassifierDescriptor classifierDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); - RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper); + assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor; + RetentionPolicy rp = getRetentionPolicy(classifierDescriptor); if (rp == RetentionPolicy.SOURCE) { return null; } @@ -273,17 +274,21 @@ public abstract class AnnotationCodegen { value.accept(argumentVisitor, null); } - private static RetentionPolicy getRetentionPolicy(ClassifierDescriptor descriptor, JetTypeMapper typeMapper) { + @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)) { - CompileTimeConstant compileTimeConstant = annotationDescriptor.getAllValueArguments().values().iterator().next(); - assert compileTimeConstant instanceof EnumValue : "Retention argument should be Enum value " + compileTimeConstant; - PropertyDescriptor propertyDescriptor = ((EnumValue) compileTimeConstant).getValue(); - assert "java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(propertyDescriptor.getType()).getInternalName()) : - "Retention argument should be of type RetentionPolicy"; - String propertyDescriptorName = propertyDescriptor.getName().asString(); - return RetentionPolicy.valueOf(propertyDescriptorName); + if ("java/lang/annotation/Retention".equals(internalName)) { + Collection> 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()); } } 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 b6cc6d49059..ccd2c335d15 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -47,6 +47,7 @@ import java.util.Map; import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT; import static org.jetbrains.jet.lang.resolve.BindingContext.COMPILE_TIME_INITIALIZER; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; public class AnnotationResolver { @@ -286,22 +287,24 @@ public class AnnotationResolver { } @Override - public CompileTimeConstant visitStringTemplateExpression( - @NotNull JetStringTemplateExpression expression, - Void nothing) { + public CompileTimeConstant visitStringTemplateExpression(@NotNull JetStringTemplateExpression expression, Void nothing) { return trace.get(BindingContext.COMPILE_TIME_VALUE, expression); } @Override public CompileTimeConstant visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, Void data) { - ResolvedCall resolvedCall = - trace.getBindingContext().get(BindingContext.RESOLVED_CALL, expression); + DeclarationDescriptor descriptor = trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, expression); + if (descriptor != null && isEnumEntry(descriptor)) { + return new EnumValue((ClassDescriptor) descriptor); + } + + ResolvedCall resolvedCall = trace.getBindingContext().get(BindingContext.RESOLVED_CALL, expression); if (resolvedCall != null) { CallableDescriptor callableDescriptor = resolvedCall.getResultingDescriptor(); if (callableDescriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) callableDescriptor; if (isEnumProperty(propertyDescriptor)) { - return new EnumValue(propertyDescriptor); + return new EnumValue(((VariableDescriptorForObject) propertyDescriptor).getObjectClass()); } if (AnnotationUtils.isPropertyAcceptableAsAnnotationParameter(propertyDescriptor)) { return trace.getBindingContext().get(COMPILE_TIME_INITIALIZER, propertyDescriptor); @@ -364,7 +367,7 @@ public class AnnotationResolver { } private static boolean isEnumProperty(@NotNull PropertyDescriptor descriptor) { - // TODO: doesn't return true anymore + // TODO: this is true only for enum entries loaded from Java, refactor JDR to use classes with class objects instead ClassifierDescriptor classifier = descriptor.getType().getConstructor().getDeclarationDescriptor(); return classifier != null && DescriptorUtils.isEnumClass(classifier) && diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationArgumentResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationArgumentResolver.java index 2d9086bd830..48150ce27e7 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationArgumentResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationArgumentResolver.java @@ -19,9 +19,8 @@ package org.jetbrains.jet.lang.resolve.java.resolver; 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.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; -import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.StringValue; @@ -141,13 +140,10 @@ public final class JavaAnnotationArgumentResolver { ClassDescriptor enumClass = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES, taskList); if (enumClass == null) return null; - for (VariableDescriptor variableDescriptor : getEnumEntriesScope(enumClass).getProperties(field.getName())) { - if (variableDescriptor.getReceiverParameter() == null) { - return new EnumValue((PropertyDescriptor) variableDescriptor); - } - } + ClassifierDescriptor classifier = getEnumEntriesScope(enumClass).getClassifier(field.getName()); + if (!(classifier instanceof ClassDescriptor)) return null; - return null; + return new EnumValue((ClassDescriptor) classifier); } @Nullable diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java index 217aced4649..488fd6ac93a 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java @@ -44,8 +44,7 @@ import javax.inject.Inject; import java.io.IOException; import java.util.*; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES; import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName; import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName; @@ -185,15 +184,9 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer private CompileTimeConstant enumEntryValue(@NotNull JvmClassName enumClassName, @NotNull Name name) { ClassDescriptor enumClass = resolveClass(enumClassName); if (enumClass.getKind() == ClassKind.ENUM_CLASS) { - ClassDescriptor classObject = enumClass.getClassObjectDescriptor(); - if (classObject != null) { - Collection properties = classObject.getDefaultType().getMemberScope().getProperties(name); - if (properties.size() == 1) { - VariableDescriptor property = properties.iterator().next(); - if (property instanceof PropertyDescriptor) { - return new EnumValue((PropertyDescriptor) property); - } - } + ClassifierDescriptor classifier = getEnumEntriesScope(enumClass).getClassifier(name); + if (classifier instanceof ClassDescriptor) { + return new EnumValue((ClassDescriptor) classifier); } } return ErrorValue.create("Unresolved enum entry: " + enumClassName.getInternalName() + "." + name); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/EnumValue.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/EnumValue.java index 4813fade533..f135c876372 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/EnumValue.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/constants/EnumValue.java @@ -17,29 +17,30 @@ package org.jetbrains.jet.lang.resolve.constants; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; 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 EnumValue implements CompileTimeConstant { - - private final PropertyDescriptor value; +public class EnumValue implements CompileTimeConstant { + private final ClassDescriptor value; - public EnumValue(@NotNull PropertyDescriptor value) { + public EnumValue(@NotNull ClassDescriptor value) { this.value = value; } @Override @NotNull - public PropertyDescriptor getValue() { + public ClassDescriptor getValue() { return value; } @NotNull @Override public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) { - return value.getType(); + JetType type = value.getClassObjectType(); + assert type != null : "Enum entry should have a class object: " + value; + return type; } @Override @@ -49,7 +50,7 @@ public class EnumValue implements CompileTimeConstant { @Override public String toString() { - return value.getType() + "." + value.getName(); + return getType(KotlinBuiltIns.getInstance()) + "." + value.getName(); } @Override @@ -57,9 +58,7 @@ public class EnumValue implements CompileTimeConstant { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - EnumValue enumValue = (EnumValue) o; - - return value.equals(enumValue.value); + return value.equals(((EnumValue) o).value); } @Override diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/lang/InlineUtil.java b/core/descriptors/src/org/jetbrains/jet/lang/types/lang/InlineUtil.java index 49c23e0209d..44a365df03d 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/lang/InlineUtil.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/lang/InlineUtil.java @@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -63,7 +62,7 @@ public class InlineUtil { } else { assert argument instanceof EnumValue : "Inline annotation parameter should be inline entry but was: " + argument + "!"; - PropertyDescriptor value = ((EnumValue)argument).getValue(); + ClassDescriptor value = ((EnumValue) argument).getValue(); String name = value.getName().asString(); return name.equals(InlineStrategy.IN_PLACE.name()) ? InlineStrategy.IN_PLACE : InlineStrategy.AS_FUNCTION; }