Store .kotlin_module files in MetadataSerializer
Compilation of top level functions/properties/typealiases results in a bunch of different .kotlin_metadata files, so we need to store names of these files to avoid scanning the file system in the compiler when loading code compiled by K2MetadataCompiler. For this, we reuse the PackageTable protobuf message, which is already used for exactly the same purpose in the JVM back-end
This commit is contained in:
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.collections.MapsKt;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
@@ -31,7 +29,6 @@ import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
@@ -40,9 +37,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
|
||||
@@ -100,47 +95,28 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
final JvmPackageTable.PackageTable.Builder builder = JvmPackageTable.PackageTable.newBuilder();
|
||||
String outputFilePath = getMappingFileName(state.getModuleName());
|
||||
|
||||
List<PackageParts> parts = new SmartList<PackageParts>(partsGroupedByPackage.values());
|
||||
|
||||
for (PackageParts part : ClassFileUtilsKt.addCompiledPartsAndSort(parts, state)) {
|
||||
PackageParts.Companion.serialize(part, builder);
|
||||
for (PackageParts part : ClassFileUtilsKt.addCompiledPartsAndSort(partsGroupedByPackage.values(), state)) {
|
||||
part.addTo(builder);
|
||||
}
|
||||
|
||||
if (builder.getPackagePartsCount() != 0) {
|
||||
generators.put(outputFilePath, new OutAndSourceFileList(CollectionsKt.toList(packagePartSourceFiles)) {
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
try {
|
||||
ByteArrayOutputStream moduleMapping = new ByteArrayOutputStream(4096);
|
||||
DataOutputStream dataOutStream = new DataOutputStream(moduleMapping);
|
||||
int[] version = JvmMetadataVersion.INSTANCE.toArray();
|
||||
dataOutStream.writeInt(version.length);
|
||||
for (int number : version) {
|
||||
dataOutStream.writeInt(number);
|
||||
}
|
||||
builder.build().writeTo(dataOutStream);
|
||||
dataOutStream.flush();
|
||||
return moduleMapping.toByteArray();
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (builder.getPackagePartsCount() == 0) return;
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilderFactory factory) {
|
||||
try {
|
||||
return new String(asBytes(factory), "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
generators.put(outputFilePath, new OutAndSourceFileList(CollectionsKt.toList(packagePartSourceFiles)) {
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
return ClassFileUtilsKt.serializeToByteArray(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilderFactory factory) {
|
||||
try {
|
||||
return new String(asBytes(factory), "UTF-8");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import com.intellij.util.io.DataOutputStream
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
fun ClassFileFactory.getClassFiles(): Iterable<OutputFile> {
|
||||
return asList().filterClassFiles()
|
||||
@@ -29,12 +33,12 @@ fun List<OutputFile>.filterClassFiles(): Iterable<OutputFile> {
|
||||
return filter { it.relativePath.endsWith(".class") }
|
||||
}
|
||||
|
||||
fun List<PackageParts>.addCompiledPartsAndSort(state: GenerationState): List<PackageParts> =
|
||||
fun Iterable<PackageParts>.addCompiledPartsAndSort(state: GenerationState): List<PackageParts> =
|
||||
addCompiledParts(state).sortedBy { it.packageFqName }
|
||||
|
||||
private fun List<PackageParts>.addCompiledParts(state: GenerationState): List<PackageParts> {
|
||||
val incrementalCache = state.incrementalCacheForThisTarget ?: return this
|
||||
val moduleMappingData = incrementalCache.getModuleMappingData() ?: return this
|
||||
private fun Iterable<PackageParts>.addCompiledParts(state: GenerationState): List<PackageParts> {
|
||||
val incrementalCache = state.incrementalCacheForThisTarget ?: return this.toList()
|
||||
val moduleMappingData = incrementalCache.getModuleMappingData() ?: return this.toList()
|
||||
|
||||
val mapping = ModuleMapping.create(moduleMappingData, "<incremental>")
|
||||
|
||||
@@ -54,3 +58,16 @@ private fun List<PackageParts>.addCompiledParts(state: GenerationState): List<Pa
|
||||
newPackageParts
|
||||
}
|
||||
}
|
||||
|
||||
fun JvmPackageTable.PackageTable.Builder.serializeToByteArray(): ByteArray {
|
||||
val moduleMapping = ByteArrayOutputStream(4096)
|
||||
val out = DataOutputStream(moduleMapping)
|
||||
val version = JvmMetadataVersion.INSTANCE.toArray()
|
||||
out.writeInt(version.size)
|
||||
for (number in version) {
|
||||
out.writeInt(number)
|
||||
}
|
||||
build().writeTo(out)
|
||||
out.flush()
|
||||
return moduleMapping.toByteArray()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user