Use ClassId instead of JvmClassName in KotlinJvmBinaryClass

ClassId contains exact information about origin of the class (e.g. if '$' in
the class name denotes nested classes separator or just a character in the
name)
This commit is contained in:
Alexander Udalov
2014-09-15 13:49:55 +04:00
parent 1f8b2cef52
commit 7595e32bb6
21 changed files with 108 additions and 110 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Arrays;
@@ -44,7 +45,9 @@ public final class JvmAnnotationNames {
public static class KotlinSyntheticClass {
public static final JvmClassName CLASS_NAME = JvmClassName.byInternalName("kotlin/jvm/internal/KotlinSyntheticClass");
public static final String KIND_INTERNAL_NAME = "kotlin/jvm/internal/KotlinSyntheticClass$Kind";
public static final ClassId KIND_CLASS_ID =
new ClassId(new FqName("kotlin.jvm.internal"), new FqNameUnsafe("KotlinSyntheticClass.Kind"));
public static final String KIND_INTERNAL_NAME = JvmClassName.byClassId(KIND_CLASS_ID).getInternalName();
public static final Name KIND_FIELD_NAME = Name.identifier("kind");
@@ -104,11 +107,8 @@ public final class JvmAnnotationNames {
}
public static boolean isSpecialAnnotation(@NotNull ClassId classId) {
return isSpecialAnnotation(JvmClassName.byClassId(classId));
}
public static boolean isSpecialAnnotation(@NotNull JvmClassName name) {
return SPECIAL_ANNOTATIONS.contains(name) || name.getInternalName().startsWith("jet/runtime/typeinfo/");
JvmClassName className = JvmClassName.byClassId(classId);
return SPECIAL_ANNOTATIONS.contains(className) || className.getInternalName().startsWith("jet/runtime/typeinfo/");
}
private JvmAnnotationNames() {
@@ -20,8 +20,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.Arrays;
public class JvmClassName {
@NotNull
public static JvmClassName byInternalName(@NotNull String internalName) {
@@ -88,28 +86,6 @@ public class JvmClassName {
return internalName;
}
@NotNull
public FqName getPackageFqName() {
int packageNameEnd = internalName.lastIndexOf("/");
if (packageNameEnd == -1) {
return FqName.ROOT;
}
return FqName.fromSegments(Arrays.asList(internalName.substring(0, packageNameEnd).split("/")));
}
@NotNull
public FqName getHeuristicClassFqName() {
String name = internalName.substring(internalName.lastIndexOf("/") + 1);
char[] chars = name.toCharArray();
//treat all 'stand-alone' dollars as dots, except for last and first char of class name
for (int i = 1; i < chars.length - 1; ++i) {
if (name.charAt(i) == '$' && name.charAt(i - 1) != '$' && name.charAt(i + 1) != '$') {
chars[i] = '.';
}
}
return new FqName(new String(chars));
}
@Override
public String toString() {
return internalName;
@@ -28,12 +28,9 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.ErrorUtils;
@@ -45,7 +42,7 @@ import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorLoadersStorage.MemberSignature;
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.javaFqNameToKotlinFqName;
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.javaClassIdToKotlinClassId;
public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements AnnotationLoader {
@@ -100,8 +97,8 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
kotlinClass.loadClassAnnotations(new KotlinJvmBinaryClass.AnnotationVisitor() {
@Nullable
@Override
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) {
return resolveAnnotation(className, result, module);
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) {
return resolveAnnotation(classId, result, module);
}
@Override
@@ -114,13 +111,13 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
@Nullable
public static KotlinJvmBinaryClass.AnnotationArgumentVisitor resolveAnnotation(
@NotNull JvmClassName className,
@NotNull ClassId classId,
@NotNull final List<AnnotationDescriptor> result,
@NotNull final ModuleDescriptor moduleDescriptor
) {
if (JvmAnnotationNames.isSpecialAnnotation(className)) return null;
if (JvmAnnotationNames.isSpecialAnnotation(classId)) return null;
final ClassDescriptor annotationClass = resolveClass(className, moduleDescriptor);
final ClassDescriptor annotationClass = resolveClass(classId, moduleDescriptor);
return new KotlinJvmBinaryClass.AnnotationArgumentVisitor() {
private final Map<ValueParameterDescriptor, CompileTimeConstant<?>> arguments = new HashMap<ValueParameterDescriptor, CompileTimeConstant<?>>();
@@ -133,8 +130,8 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
}
@Override
public void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
setArgumentValueByName(name, enumEntryValue(enumClassName, enumEntryName));
public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
setArgumentValueByName(name, enumEntryValue(enumClassId, enumEntryName));
}
@Nullable
@@ -149,8 +146,8 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
}
@Override
public void visitEnum(@NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
elements.add(enumEntryValue(enumClassName, enumEntryName));
public void visitEnum(@NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
elements.add(enumEntryValue(enumClassId, enumEntryName));
}
@Override
@@ -165,15 +162,15 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
}
@NotNull
private CompileTimeConstant<?> enumEntryValue(@NotNull JvmClassName enumClassName, @NotNull Name name) {
ClassDescriptor enumClass = resolveClass(enumClassName, moduleDescriptor);
private CompileTimeConstant<?> enumEntryValue(@NotNull ClassId enumClassId, @NotNull Name name) {
ClassDescriptor enumClass = resolveClass(enumClassId, moduleDescriptor);
if (enumClass.getKind() == ClassKind.ENUM_CLASS) {
ClassifierDescriptor classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name);
if (classifier instanceof ClassDescriptor) {
return new EnumValue((ClassDescriptor) classifier, false);
}
}
return ErrorValue.create("Unresolved enum entry: " + enumClassName.getInternalName() + "." + name);
return ErrorValue.create("Unresolved enum entry: " + enumClassId + "." + name);
}
@Override
@@ -200,12 +197,10 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
}
@NotNull
private static ClassDescriptor resolveClass(@NotNull JvmClassName className, @NotNull ModuleDescriptor moduleDescriptor) {
FqName packageFqName = className.getPackageFqName();
FqNameUnsafe relativeClassName = javaFqNameToKotlinFqName(className.getHeuristicClassFqName());
ClassId classId = new ClassId(packageFqName, relativeClassName);
ClassDescriptor annotationClass = SerializationPackage.findClassAcrossModuleDependencies(moduleDescriptor, classId);
return annotationClass != null ? annotationClass : ErrorUtils.createErrorClass(className.getInternalName());
private static ClassDescriptor resolveClass(@NotNull ClassId javaClassId, @NotNull ModuleDescriptor moduleDescriptor) {
ClassId classId = javaClassIdToKotlinClassId(javaClassId);
ClassDescriptor classDescriptor = SerializationPackage.findClassAcrossModuleDependencies(moduleDescriptor, classId);
return classDescriptor != null ? classDescriptor : ErrorUtils.createErrorClass(classId.asSingleFqName().asString());
}
@NotNull
@@ -19,11 +19,11 @@ package org.jetbrains.jet.lang.resolve.kotlin;
import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.ConstantsPackage;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull;
@@ -130,14 +130,14 @@ public class DescriptorLoadersStorage {
@Nullable
@Override
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull JvmClassName className) {
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull ClassId classId) {
MemberSignature paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index);
List<AnnotationDescriptor> result = memberAnnotations.get(paramSignature);
if (result == null) {
result = new ArrayList<AnnotationDescriptor>();
memberAnnotations.put(paramSignature, result);
}
return AnnotationDescriptorLoader.resolveAnnotation(className, result, module);
return AnnotationDescriptorLoader.resolveAnnotation(classId, result, module);
}
}
@@ -151,8 +151,8 @@ public class DescriptorLoadersStorage {
@Nullable
@Override
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) {
return AnnotationDescriptorLoader.resolveAnnotation(className, result, module);
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) {
return AnnotationDescriptorLoader.resolveAnnotation(classId, result, module);
}
@Override
@@ -68,6 +68,11 @@ public class DeserializedResolverUtils {
return FqNameUnsafe.fromSegments(correctedSegments);
}
@NotNull
public static ClassId javaClassIdToKotlinClassId(@NotNull ClassId javaClassId) {
return new ClassId(javaClassId.getPackageFqName(), javaFqNameToKotlinFqName(javaClassId.getRelativeClassName().toSafe()));
}
@NotNull
public static ClassId getClassId(@NotNull ClassDescriptor descriptor) {
DeclarationDescriptor owner = descriptor.getContainingDeclaration();
@@ -18,13 +18,13 @@ package org.jetbrains.jet.lang.resolve.kotlin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
import org.jetbrains.jet.lang.resolve.name.Name;
public interface KotlinJvmBinaryClass {
@NotNull
JvmClassName getClassName();
ClassId getClassId();
void loadClassAnnotations(@NotNull AnnotationVisitor visitor);
@@ -45,21 +45,21 @@ public interface KotlinJvmBinaryClass {
interface AnnotationVisitor {
@Nullable
AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className);
AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId);
void visitEnd();
}
interface MethodAnnotationVisitor extends AnnotationVisitor {
@Nullable
AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull JvmClassName className);
AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull ClassId classId);
}
interface AnnotationArgumentVisitor {
// TODO: annotations, java.lang.Class
void visit(@Nullable Name name, @Nullable Object value);
void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName);
void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName);
@Nullable
AnnotationArrayArgumentVisitor visitArray(@NotNull Name name);
@@ -70,7 +70,7 @@ public interface KotlinJvmBinaryClass {
interface AnnotationArrayArgumentVisitor {
void visit(@Nullable Object value);
void visitEnum(@NotNull JvmClassName enumClassName, @NotNull Name enumEntryName);
void visitEnum(@NotNull ClassId enumClassId, @NotNull Name enumEntryName);
void visitEnd();
}
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.kotlin.header;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -72,7 +73,8 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Nullable
@Override
public AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName annotation) {
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) {
JvmClassName annotation = JvmClassName.byClassId(classId);
KotlinClassHeader.Kind newKind = HEADER_KINDS.get(annotation);
if (newKind == null) return null;
@@ -106,7 +108,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
@Override
public void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
unexpectedArgument(name, annotationClassName);
}
@@ -137,7 +139,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
@Override
public void visitEnum(@NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
public void visitEnum(@NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
unexpectedArgument(null, annotationClassName);
}
@@ -163,9 +165,8 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
@Override
public void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
if (enumClassName.getInternalName().equals(KotlinSyntheticClass.KIND_INTERNAL_NAME) &&
name.equals(KotlinSyntheticClass.KIND_FIELD_NAME)) {
public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
if (enumClassId.equals(KotlinSyntheticClass.KIND_CLASS_ID) && name.equals(KotlinSyntheticClass.KIND_FIELD_NAME)) {
// Don't call KotlinSyntheticClass.Kind.valueOf() here, because it will throw an exception if there's no such value,
// but we don't want to fail if we're loading the header with an _incompatible_ ABI version
syntheticClassKind = KotlinSyntheticClass.Kind.valueOfOrNull(enumEntryName.asString());
@@ -173,7 +174,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
if (isAbiVersionCompatible(version)) {
throw new IllegalStateException("Unexpected enum entry for synthetic class annotation: " +
name + "=" + enumClassName + "." + enumEntryName);
name + "=" + enumClassId + "." + enumEntryName);
}
}