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:
+2
-1
@@ -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
-12
@@ -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) {
|
||||
|
||||
+4
-4
@@ -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);
|
||||
}
|
||||
|
||||
+3
-2
@@ -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`
|
||||
|
||||
+9
-1
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -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;
|
||||
|
||||
+17
-22
@@ -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
|
||||
|
||||
+5
-5
@@ -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
|
||||
|
||||
+5
@@ -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();
|
||||
|
||||
+6
-6
@@ -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();
|
||||
}
|
||||
|
||||
+8
-7
@@ -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)
|
||||
|
||||
+5
-6
@@ -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>
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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> {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user