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
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter;
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
@@ -144,7 +145,7 @@ public final class AnalyzerWithCompilerReport {
Integer abiVersion = bindingContext.get(TraceBasedErrorReporter.ABI_VERSION_ERRORS, kotlinClass);
String path = toSystemDependentName(kotlinClass.getFile().getPath());
messageCollectorWrapper.report(CompilerMessageSeverity.ERROR,
"Class '" + kotlinClass.getClassName() +
"Class '" + JvmClassName.byClassId(kotlinClass.getClassId()) +
"' was compiled with an incompatible version of Kotlin. " +
"Its ABI version is " + abiVersion + ", expected ABI version is " + JvmAbi.VERSION,
CompilerMessageLocation.create(path, 0, 0));
@@ -21,7 +21,7 @@ import kotlin.Function3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
import org.jetbrains.jet.lang.resolve.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -38,16 +38,16 @@ import static org.jetbrains.org.objectweb.asm.ClassReader.*;
import static org.jetbrains.org.objectweb.asm.Opcodes.ASM5;
public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
private final JvmClassName className;
private final ClassId classId;
private final KotlinClassHeader classHeader;
private final InnerClassesInfo innerClasses;
protected FileBasedKotlinClass(
@NotNull JvmClassName className,
@NotNull ClassId classId,
@NotNull KotlinClassHeader classHeader,
@NotNull InnerClassesInfo innerClasses
) {
this.className = className;
this.classId = classId;
this.classHeader = classHeader;
this.innerClasses = innerClasses;
}
@@ -84,7 +84,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
@Nullable
protected static <T extends FileBasedKotlinClass> T create(
@NotNull byte[] fileContents,
@NotNull Function3<JvmClassName, KotlinClassHeader, InnerClassesInfo, T> factory
@NotNull Function3<ClassId, KotlinClassHeader, InnerClassesInfo, T> factory
) {
final ReadKotlinClassHeaderAnnotationVisitor readHeaderVisitor = new ReadKotlinClassHeaderAnnotationVisitor();
final Ref<String> classNameRef = Ref.create();
@@ -120,13 +120,13 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
if (header == null) return null;
ClassId id = resolveNameByInternalName(className, innerClasses);
return factory.invoke(JvmClassName.byClassId(id), header, innerClasses);
return factory.invoke(id, header, innerClasses);
}
@NotNull
@Override
public JvmClassName getClassName() {
return className;
public ClassId getClassId() {
return classId;
}
@NotNull
@@ -154,7 +154,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
private static org.jetbrains.org.objectweb.asm.AnnotationVisitor convertAnnotationVisitor(
@NotNull AnnotationVisitor visitor, @NotNull String desc, @NotNull InnerClassesInfo innerClasses
) {
AnnotationArgumentVisitor v = visitor.visitAnnotation(JvmClassName.byClassId(resolveNameByDesc(desc, innerClasses)));
AnnotationArgumentVisitor v = visitor.visitAnnotation(resolveNameByDesc(desc, innerClasses));
return v == null ? null : convertAnnotationVisitor(v, innerClasses);
}
@@ -179,7 +179,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
@Override
public void visitEnum(String name, @NotNull String desc, @NotNull String value) {
arv.visitEnum(JvmClassName.byClassId(resolveNameByDesc(desc, innerClasses)), Name.identifier(value));
arv.visitEnum(resolveNameByDesc(desc, innerClasses), Name.identifier(value));
}
@Override
@@ -191,7 +191,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
@Override
public void visitEnum(String name, @NotNull String desc, @NotNull String value) {
v.visitEnum(Name.identifier(name), JvmClassName.byClassId(resolveNameByDesc(desc, innerClasses)), Name.identifier(value));
v.visitEnum(Name.identifier(name), resolveNameByDesc(desc, innerClasses), Name.identifier(value));
}
@Override
@@ -235,7 +235,7 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
@Override
public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int parameter, @NotNull String desc, boolean visible) {
AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, JvmClassName.byClassId(resolveNameByDesc(desc, innerClasses)));
AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, resolveNameByDesc(desc, innerClasses));
return av == null ? null : convertAnnotationVisitor(av, innerClasses);
}
@@ -257,6 +257,15 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
@NotNull
private static ClassId resolveNameByInternalName(@NotNull String name, @NotNull InnerClassesInfo innerClasses) {
if (!name.contains("$")) {
return ClassId.topLevel(new FqName(name.replace('/', '.')));
}
if (name.equals(JvmAnnotationNames.KotlinSyntheticClass.KIND_INTERNAL_NAME)) {
// TODO: this is a hack which can be dropped once JVM back-end begins to write InnerClasses attribute for all referenced classes
return JvmAnnotationNames.KotlinSyntheticClass.KIND_CLASS_ID;
}
List<String> classes = new ArrayList<String>(1);
while (true) {
@@ -22,7 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import kotlin.Function3;
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.utils.UtilsPackage;
@@ -35,7 +35,7 @@ public final class VirtualFileKotlinClass extends FileBasedKotlinClass {
private VirtualFileKotlinClass(
@NotNull VirtualFile file,
@NotNull JvmClassName className,
@NotNull ClassId className,
@NotNull KotlinClassHeader classHeader,
@NotNull InnerClassesInfo innerClasses
) {
@@ -48,10 +48,10 @@ public final class VirtualFileKotlinClass extends FileBasedKotlinClass {
assert file.getFileType() == JavaClassFileType.INSTANCE : "Trying to read binary data from a non-class file " + file;
try {
return create(file.contentsToByteArray(),
new Function3<JvmClassName, KotlinClassHeader, InnerClassesInfo, VirtualFileKotlinClass>() {
new Function3<ClassId, KotlinClassHeader, InnerClassesInfo, VirtualFileKotlinClass>() {
@Override
public VirtualFileKotlinClass invoke(
JvmClassName name, KotlinClassHeader header, InnerClassesInfo innerClasses
ClassId name, KotlinClassHeader header, InnerClassesInfo innerClasses
) {
return new VirtualFileKotlinClass(file, name, header, innerClasses);
}
@@ -1,6 +1,7 @@
package test
//this test relies on particular heuristic implemntation, can become irrelevant should implementation change
annotation class `$$$$$$`
annotation class `Anno$tation`
`$$$$$$`class A
`$$$$$$` class A
`Anno$tation` class `Cla$s`
@@ -6,4 +6,12 @@ internal final annotation class $$$$$$ : kotlin.Annotation {
test.$$$$$$() internal final class A {
/*primary*/ public constructor A()
}
}
internal final annotation class Anno$tation : kotlin.Annotation {
/*primary*/ public constructor Anno$tation()
}
test.Anno$tation() internal final class Cla$s {
/*primary*/ public constructor Cla$s()
}
@@ -48,7 +48,6 @@ public class KotlinClassFinderTest : KotlinTestWithEnvironmentManagement() {
val binaryClass = VirtualFileFinder.SERVICE.getInstance(project).findKotlinClass(JavaClassImpl(psiClass!!))
assertNotNull(binaryClass, "No binary class for $className")
assertEquals("test/A\$B\$C", binaryClass?.getClassName()?.getInternalName())
assertEquals("test/A.B.C", binaryClass?.getClassId()?.toString())
}
}
@@ -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);
}
}
@@ -37,15 +37,15 @@ public fun buildDecompiledText(
): DecompiledText {
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
val classFqName = kotlinClass!!.getClassName().getFqNameForClassNameWithoutDollars()
val classId = kotlinClass!!.getClassId()
val kind = kotlinClass.getClassHeader().kind
val packageFqName = classFqName.parent()
val packageFqName = classId.getPackageFqName()
return if (kind == KotlinClassHeader.Kind.PACKAGE_FACADE) {
buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInPackage(packageFqName)))
}
else if (kind == KotlinClassHeader.Kind.CLASS) {
buildDecompiledText(packageFqName, listOf(resolver.resolveTopLevelClass(classFqName)).filterNotNull())
buildDecompiledText(packageFqName, listOf(resolver.resolveTopLevelClass(classId)).filterNotNull())
}
else {
throw UnsupportedOperationException("Unknown header kind: " + kind)
@@ -48,8 +48,7 @@ import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
val classFqName = kotlinClass!!.getClassName().getFqNameForClassNameWithoutDollars()
val packageFqName = classFqName.parent()
val packageFqName = kotlinClass!!.getClassId().getPackageFqName()
return DeserializerForDecompiler(classFile.getParent()!!, packageFqName)
}
@@ -60,14 +59,14 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
private fun createDummyModule(name: String) = ModuleDescriptorImpl(Name.special("<$name>"), listOf(), PlatformToKotlinClassMap.EMPTY)
override fun resolveTopLevelClass(classFqName: FqName) = deserializationContext.classDeserializer.deserializeClass(classFqName.toClassId())
override fun resolveTopLevelClass(classId: ClassId) = deserializationContext.classDeserializer.deserializeClass(classId)
override fun resolveDeclarationsInPackage(packageFqName: FqName): Collection<DeclarationDescriptor> {
assert(packageFqName == directoryPackageFqName, "Was called for $packageFqName but only $directoryPackageFqName is expected.")
val binaryClassForPackageClass = localClassFinder.findKotlinClass(PackageClassUtils.getPackageClassId(packageFqName))
val annotationData = binaryClassForPackageClass?.getClassHeader()?.annotationData
if (annotationData == null) {
LOG.error("Could not read annotation data for $packageFqName from ${binaryClassForPackageClass?.getClassName()}")
LOG.error("Could not read annotation data for $packageFqName from ${binaryClassForPackageClass?.getClassId()}")
return Collections.emptyList()
}
val membersScope = DeserializedPackageMemberScope(
@@ -122,7 +121,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
val binaryClass = localClassFinder.findKotlinClass(classId) ?: return null
val data = binaryClass.getClassHeader().annotationData
if (data == null) {
LOG.error("Annotation data missing for ${binaryClass.getClassName()}")
LOG.error("Annotation data missing for ${binaryClass.getClassId()}")
return null
}
return JavaProtoBufUtil.readClassDataFrom(data)
@@ -186,7 +185,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
LOG.error("Could not infer visibility for $descriptor")
}
override fun reportIncompatibleAbiVersion(kotlinClass: KotlinJvmBinaryClass, actualVersion: Int) {
LOG.error("Incompatible ABI version for class ${kotlinClass.getClassName()}, actual version: $actualVersion")
LOG.error("Incompatible ABI version for class ${kotlinClass.getClassId()}, actual version: $actualVersion")
}
}
}
@@ -19,8 +19,10 @@ package org.jetbrains.jet.plugin.libraries
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.descriptors.serialization.ClassId
public trait ResolverForDecompiler {
public fun resolveTopLevelClass(classFqName: FqName): ClassDescriptor?
public fun resolveTopLevelClass(classId: ClassId): ClassDescriptor?
public fun resolveDeclarationsInPackage(packageFqName: FqName): Collection<DeclarationDescriptor>
}
}
@@ -74,7 +74,7 @@ public final class KotlinClassFileIndex extends ScalarIndexExtension<FqName> {
try {
KotlinJvmBinaryClass kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(inputData.getFile());
if (kotlinClass != null && kotlinClass.getClassHeader().getKind() != KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION) {
return Collections.singletonMap(kotlinClass.getClassName().getFqNameForClassNameWithoutDollars(), null);
return Collections.singletonMap(kotlinClass.getClassId().asSingleFqName().toSafe(), null);
}
}
catch (Throwable e) {
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.resolve.java.TopDownAnalyzerFacadeForJVM
import org.jetbrains.jet.lang.resolve.BindingTraceContext
import org.jetbrains.jet.descriptors.serialization.ClassId
public class DecompiledTextConsistencyTest : JetLightCodeInsightFixtureTestCase() {
@@ -66,8 +67,9 @@ class ProjectBasedResolverForDecompiler(project: Project) : ResolverForDecompile
module, null, null
).getModuleDescriptor()
}
override fun resolveTopLevelClass(classFqName: FqName): ClassDescriptor? {
return module.resolveTopLevelClass(classFqName)
override fun resolveTopLevelClass(classId: ClassId): ClassDescriptor? {
return module.resolveTopLevelClass(classId.asSingleFqName().toSafe())
}
override fun resolveDeclarationsInPackage(packageFqName: FqName): Collection<DeclarationDescriptor> {
+1 -1
View File
@@ -18,7 +18,7 @@
<orderEntry type="module" module-name="descriptors" />
<orderEntry type="module" module-name="frontend.java" />
<orderEntry type="module" module-name="serialization.java" />
<orderEntry type="module" module-name="serialization" scope="TEST" />
<orderEntry type="module" module-name="serialization" />
<orderEntry type="module" module-name="compiler-tests" scope="TEST" />
<orderEntry type="library" name="asm" level="project" />
</component>
@@ -63,7 +63,7 @@ public class IncrementalCacheImpl(val baseDir: File): StorageOwner, IncrementalC
if (kotlinClass == null) return DO_NOTHING
val fileBytes = kotlinClass.getFileContents()
val className = kotlinClass.getClassName()
val className = JvmClassName.byClassId(kotlinClass.getClassId())
val header = kotlinClass.getClassHeader()
val annotationDataEncoded = header.annotationData
@@ -17,14 +17,14 @@
package org.jetbrains.jet.jps.incremental
import org.jetbrains.jet.lang.resolve.kotlin.FileBasedKotlinClass
import org.jetbrains.jet.lang.resolve.java.JvmClassName
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader
import org.jetbrains.jet.descriptors.serialization.ClassId
import java.io.File
class LocalFileKotlinClass private(
private val file: File,
private val fileContents: ByteArray,
className: JvmClassName,
className: ClassId,
classHeader: KotlinClassHeader,
innerClasses: FileBasedKotlinClass.InnerClassesInfo
) : FileBasedKotlinClass(className, classHeader, innerClasses) {