Do not store ClassDescriptor in EnumValue
Only store the ClassId of the enum class and the Name of the entry, and resolve the needed descriptor in getType() instead, which now takes the module instance where that descriptor should be resolved
This commit is contained in:
@@ -438,7 +438,7 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Set<ElementType> getJavaTargetList(ClassDescriptor descriptor) {
|
||||
private static Set<ElementType> getJavaTargetList(ClassDescriptor descriptor) {
|
||||
AnnotationDescriptor targetAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Target.class.getName()));
|
||||
if (targetAnnotation != null) {
|
||||
Collection<ConstantValue<?>> valueArguments = targetAnnotation.getAllValueArguments().values();
|
||||
@@ -449,12 +449,9 @@ public abstract class AnnotationCodegen {
|
||||
Set<ElementType> result = EnumSet.noneOf(ElementType.class);
|
||||
for (ConstantValue<?> value : values) {
|
||||
if (value instanceof EnumValue) {
|
||||
ClassDescriptor enumEntry = ((EnumValue) value).getValue();
|
||||
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
|
||||
if (classObjectType != null) {
|
||||
if ("java/lang/annotation/ElementType".equals(typeMapper.mapType(classObjectType).getInternalName())) {
|
||||
result.add(ElementType.valueOf(enumEntry.getName().asString()));
|
||||
}
|
||||
FqName enumClassFqName = ((EnumValue) value).getEnumClassId().asSingleFqName();
|
||||
if (ElementType.class.getName().equals(enumClassFqName.asString())) {
|
||||
result.add(ElementType.valueOf(((EnumValue) value).getEnumEntryName().asString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,21 +463,18 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
|
||||
private static RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
|
||||
KotlinRetention retention = DescriptorUtilsKt.getAnnotationRetention(descriptor);
|
||||
if (retention != null) {
|
||||
return annotationRetentionMap.get(retention);
|
||||
}
|
||||
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
|
||||
if (retentionAnnotation != null) {
|
||||
ConstantValue<?> compileTimeConstant = CollectionsKt.firstOrNull(retentionAnnotation.getAllValueArguments().values());
|
||||
if (compileTimeConstant instanceof EnumValue) {
|
||||
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
|
||||
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
|
||||
if (classObjectType != null) {
|
||||
if ("java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName())) {
|
||||
return RetentionPolicy.valueOf(enumEntry.getName().asString());
|
||||
}
|
||||
ConstantValue<?> value = CollectionsKt.firstOrNull(retentionAnnotation.getAllValueArguments().values());
|
||||
if (value instanceof EnumValue) {
|
||||
FqName enumClassFqName = ((EnumValue) value).getEnumClassId().asSingleFqName();
|
||||
if (RetentionPolicy.class.getName().equals(enumClassFqName.asString())) {
|
||||
return RetentionPolicy.valueOf(((EnumValue) value).getEnumEntryName().asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,16 +59,18 @@ class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable {
|
||||
throw IllegalStateException("Cannot get FQ name of error class: " + descriptor)
|
||||
}
|
||||
|
||||
// We use the following format to encode ClassId: "pkg/Outer.Inner".
|
||||
// It represents a unique name, but such names don't usually appear in the constant pool, so we're writing "Lpkg/Outer$Inner;"
|
||||
// instead and an instruction to drop the first and the last character in this string and replace all '$' with '.'.
|
||||
// This works most of the time, except in two rare cases:
|
||||
// - the name of the class or any of its outer classes contains dollars. In this case we're just storing the described
|
||||
// string literally: "pkg/Outer.Inner$with$dollars"
|
||||
// - the class is local or nested in local. In this case we're also storing the literal string, and also storing the fact that
|
||||
// this name represents a local class in a separate list
|
||||
return getClassIdIndex(descriptor.classId)
|
||||
}
|
||||
|
||||
val classId = descriptor.classId
|
||||
// We use the following format to encode ClassId: "pkg/Outer.Inner".
|
||||
// It represents a unique name, but such names don't usually appear in the constant pool, so we're writing "Lpkg/Outer$Inner;"
|
||||
// instead and an instruction to drop the first and the last character in this string and replace all '$' with '.'.
|
||||
// This works most of the time, except in two rare cases:
|
||||
// - the name of the class or any of its outer classes contains dollars. In this case we're just storing the described
|
||||
// string literally: "pkg/Outer.Inner$with$dollars"
|
||||
// - the class is local or nested in local. In this case we're also storing the literal string, and also storing the fact that
|
||||
// this name represents a local class in a separate list
|
||||
override fun getClassIdIndex(classId: ClassId): Int {
|
||||
val string = classId.asString()
|
||||
|
||||
map[string]?.let { recordedIndex ->
|
||||
|
||||
+2
-2
@@ -108,11 +108,11 @@ public class MappingClassesForWhenByEnumCodegen {
|
||||
v.putstatic(cb.getThisName(), mapping.getFieldName(), MAPPINGS_FIELD_DESCRIPTOR);
|
||||
|
||||
for (Map.Entry<EnumValue, Integer> item : mapping.enumValuesToIntMapping()) {
|
||||
EnumValue enumEntry = item.getKey();
|
||||
EnumValue enumValue = item.getKey();
|
||||
int mappedValue = item.getValue();
|
||||
|
||||
v.getstatic(cb.getThisName(), mapping.getFieldName(), MAPPINGS_FIELD_DESCRIPTOR);
|
||||
v.getstatic(enumType.getInternalName(), enumEntry.getValue().getName().asString(), enumType.getDescriptor());
|
||||
v.getstatic(enumType.getInternalName(), enumValue.getEnumEntryName().asString(), enumType.getDescriptor());
|
||||
v.invokevirtual(enumType.getInternalName(), "ordinal", Type.getMethodDescriptor(Type.INT_TYPE), false);
|
||||
v.iconst(mappedValue);
|
||||
v.astore(Type.INT_TYPE);
|
||||
|
||||
Reference in New Issue
Block a user