Introduce infrastructure to separate string table from metadata on JVM

Nothing especially helpful happens here, this is only a big refactoring
introducing a separate string array for the string table, which is currently
always empty, but will contain actual strings soon
This commit is contained in:
Alexander Udalov
2015-09-21 18:22:14 +03:00
parent 5fe958f034
commit 6a8d0fbd75
32 changed files with 177 additions and 113 deletions
@@ -48,6 +48,7 @@ public final class JvmAnnotationNames {
public static final String FILE_PART_CLASS_NAMES_FIELD_NAME = "filePartClassNames";
public static final String MULTIFILE_CLASS_NAME_FIELD_NAME = "multifileClassName";
public static final String DATA_FIELD_NAME = "data";
public static final String STRINGS_FIELD_NAME = "strings";
public static final Name DEFAULT_ANNOTATION_MEMBER_NAME = Name.identifier("value");
public static final Name TARGET_ANNOTATION_MEMBER_NAME = Name.identifier("allowedTargets");
@@ -61,7 +61,9 @@ public final class DeserializedDescriptorResolver {
public ClassDescriptor resolveClass(@NotNull KotlinJvmBinaryClass kotlinClass) {
String[] data = readData(kotlinClass, KOTLIN_CLASS);
if (data != null) {
ClassData classData = JvmProtoBufUtil.readClassDataFrom(data);
String[] strings = kotlinClass.getClassHeader().getStrings();
assert strings != null : "String table not found in " + kotlinClass;
ClassData classData = JvmProtoBufUtil.readClassDataFrom(data, strings);
KotlinJvmBinarySourceElement sourceElement = new KotlinJvmBinarySourceElement(kotlinClass);
return components.getClassDeserializer().deserializeClass(
kotlinClass.getClassId(),
@@ -75,13 +77,15 @@ public final class DeserializedDescriptorResolver {
public JetScope createKotlinPackagePartScope(@NotNull PackageFragmentDescriptor descriptor, @NotNull KotlinJvmBinaryClass kotlinClass) {
String[] data = readData(kotlinClass, KOTLIN_FILE_FACADE_OR_MULTIFILE_CLASS_PART);
if (data != null) {
//all classes are included in java scope
PackageData packageData = JvmProtoBufUtil.readPackageDataFrom(data);
String[] strings = kotlinClass.getClassHeader().getStrings();
assert strings != null : "String table not found in " + kotlinClass;
PackageData packageData = JvmProtoBufUtil.readPackageDataFrom(data, strings);
return new DeserializedPackageMemberScope(
descriptor, packageData.getPackageProto(), packageData.getNameResolver(), components,
new Function0<Collection<Name>>() {
@Override
public Collection<Name> invoke() {
// All classes are included into Java scope
return Collections.emptyList();
}
}
@@ -27,11 +27,12 @@ public class JavaClassDataFinder(
) : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassDataWithSource? {
val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) ?: return null
assert(kotlinJvmBinaryClass.getClassId() == classId) {
"Class with incorrect id found: expected $classId, actual ${kotlinJvmBinaryClass.getClassId()}"
assert(kotlinJvmBinaryClass.classId == classId) {
"Class with incorrect id found: expected $classId, actual ${kotlinJvmBinaryClass.classId}"
}
val data = deserializedDescriptorResolver.readData(kotlinJvmBinaryClass, DeserializedDescriptorResolver.KOTLIN_CLASS) ?: return null
val classData = JvmProtoBufUtil.readClassDataFrom(data)
val strings = kotlinJvmBinaryClass.classHeader.strings ?: error("String table not found in $kotlinJvmBinaryClass")
val classData = JvmProtoBufUtil.readClassDataFrom(data, strings)
return ClassDataWithSource(classData, KotlinJvmBinarySourceElement(kotlinJvmBinaryClass))
}
}
@@ -25,6 +25,7 @@ public class KotlinClassHeader(
public val kind: KotlinClassHeader.Kind,
public val version: BinaryVersion,
public val annotationData: Array<String>?,
public val strings: Array<String>?,
public val classKind: KotlinClass.Kind?,
public val syntheticClassKind: KotlinSyntheticClass.Kind?,
public val filePartClassNames: Array<String>?,
@@ -64,6 +64,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
private String multifileClassName = null;
private String[] filePartClassNames = null;
private String[] annotationData = null;
private String[] strings = null;
private KotlinClassHeader.Kind headerKind = null;
private KotlinClass.Kind classKind = null;
private KotlinSyntheticClass.Kind syntheticClassKind = null;
@@ -80,7 +81,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
if (!AbiVersionUtil.isAbiVersionCompatible(version)) {
return new KotlinClassHeader(headerKind, version, null, classKind, syntheticClassKind, null, null);
return new KotlinClassHeader(headerKind, version, null, strings, classKind, syntheticClassKind, null, null);
}
if (shouldHaveData() && annotationData == null) {
@@ -89,7 +90,9 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
return null;
}
return new KotlinClassHeader(headerKind, version, annotationData, classKind, syntheticClassKind, filePartClassNames, multifileClassName);
return new KotlinClassHeader(
headerKind, version, annotationData, strings, classKind, syntheticClassKind, filePartClassNames, multifileClassName
);
}
private boolean shouldHaveData() {
@@ -171,10 +174,14 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Override
@Nullable
public AnnotationArrayArgumentVisitor visitArray(@NotNull Name name) {
if (name.asString().equals(DATA_FIELD_NAME)) {
String string = name.asString();
if (DATA_FIELD_NAME.equals(string)) {
return dataArrayVisitor();
}
else if (name.asString().equals(FILE_PART_CLASS_NAMES_FIELD_NAME)) {
else if (STRINGS_FIELD_NAME.equals(string)) {
return stringsArrayVisitor();
}
else if (FILE_PART_CLASS_NAMES_FIELD_NAME.equals(string)) {
return filePartClassNamesVisitor();
}
else {
@@ -186,12 +193,32 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
private AnnotationArrayArgumentVisitor filePartClassNamesVisitor() {
return new CollectStringArrayAnnotationVisitor() {
@Override
protected void visitEnd(String[] data) {
protected void visitEnd(@NotNull String[] data) {
filePartClassNames = data;
}
};
}
@NotNull
private AnnotationArrayArgumentVisitor dataArrayVisitor() {
return new CollectStringArrayAnnotationVisitor() {
@Override
protected void visitEnd(@NotNull String[] data) {
annotationData = data;
}
};
}
@NotNull
private AnnotationArrayArgumentVisitor stringsArrayVisitor() {
return new CollectStringArrayAnnotationVisitor() {
@Override
protected void visitEnd(@NotNull String[] data) {
strings = data;
}
};
}
@Override
public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
}
@@ -202,16 +229,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
return null;
}
@NotNull
private AnnotationArrayArgumentVisitor dataArrayVisitor() {
return new CollectStringArrayAnnotationVisitor() {
@Override
protected void visitEnd(String[] data) {
annotationData = data;
}
};
}
@Override
public void visitEnd() {
}
@@ -240,7 +257,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
visitEnd(strings.toArray(new String[strings.size()]));
}
protected abstract void visitEnd(String[] data);
protected abstract void visitEnd(@NotNull String[] data);
}
}
@@ -31,11 +31,11 @@ public object JvmProtoBufUtil {
}
@JvmStatic
public fun readClassDataFrom(data: Array<String>): ClassData =
readClassDataFrom(BitEncoding.decodeBytes(data))
public fun readClassDataFrom(data: Array<String>, strings: Array<String>): ClassData =
readClassDataFrom(BitEncoding.decodeBytes(data), strings)
@JvmStatic
public fun readClassDataFrom(bytes: ByteArray): ClassData {
public fun readClassDataFrom(bytes: ByteArray, strings: Array<String>): ClassData {
val input = ByteArrayInputStream(bytes)
val nameResolver = NameResolverImpl.read(input)
val classProto = ProtoBuf.Class.parseFrom(input, EXTENSION_REGISTRY)
@@ -43,11 +43,11 @@ public object JvmProtoBufUtil {
}
@JvmStatic
public fun readPackageDataFrom(data: Array<String>): PackageData =
readPackageDataFrom(BitEncoding.decodeBytes(data))
public fun readPackageDataFrom(data: Array<String>, strings: Array<String>): PackageData =
readPackageDataFrom(BitEncoding.decodeBytes(data), strings)
@JvmStatic
public fun readPackageDataFrom(bytes: ByteArray): PackageData {
public fun readPackageDataFrom(bytes: ByteArray, strings: Array<String>): PackageData {
val input = ByteArrayInputStream(bytes)
val nameResolver = NameResolverImpl.read(input)
val packageProto = ProtoBuf.Package.parseFrom(input, EXTENSION_REGISTRY)