Use Klib JS serializer protocol for IC

This commit is contained in:
Alexey Tsvetkov
2019-10-28 09:55:46 +03:00
committed by romanart
parent 6e9cd85b54
commit d776e92111
4 changed files with 65 additions and 48 deletions
@@ -24,20 +24,20 @@ import org.jetbrains.kotlin.incremental.storage.*
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
import org.jetbrains.kotlin.metadata.js.JsProtoBuf
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.parentOrNull import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import java.io.DataInput import java.io.DataInput
import java.io.DataOutput import java.io.DataOutput
import java.io.File import java.io.File
open class IncrementalJsCache( open class IncrementalJsCache(
cachesDir: File, cachesDir: File,
pathConverter: FileToPathConverter pathConverter: FileToPathConverter,
serializerProtocol: SerializerExtensionProtocol
) : AbstractIncrementalCache<FqName>(cachesDir, pathConverter) { ) : AbstractIncrementalCache<FqName>(cachesDir, pathConverter) {
companion object { companion object {
private const val TRANSLATION_RESULT_MAP = "translation-result" private const val TRANSLATION_RESULT_MAP = "translation-result"
@@ -49,9 +49,11 @@ open class IncrementalJsCache(
fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists() fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists()
} }
private val protoData = ProtoDataProvider(serializerProtocol)
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile, pathConverter)) override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile, pathConverter))
override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile)) override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile, pathConverter)) private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile, pathConverter, protoData))
private val irTranslationResults = registerMap(IrTranslationResultMap(IR_TRANSLATION_RESULT_MAP.storageFile, pathConverter)) private val irTranslationResults = registerMap(IrTranslationResultMap(IR_TRANSLATION_RESULT_MAP.storageFile, pathConverter))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, pathConverter)) private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, pathConverter))
private val packageMetadata = registerMap(PackageMetadataMap(PACKAGE_META_FILE.storageFile)) private val packageMetadata = registerMap(PackageMetadataMap(PACKAGE_META_FILE.storageFile))
@@ -86,8 +88,8 @@ open class IncrementalJsCache(
dirtySources.remove(srcFile) dirtySources.remove(srcFile)
val (binaryMetadata, binaryAst, inlineData) = data val (binaryMetadata, binaryAst, inlineData) = data
val oldProtoMap = translationResults[srcFile]?.metadata?.let { getProtoData(srcFile, it) } ?: emptyMap() val oldProtoMap = translationResults[srcFile]?.metadata?.let { protoData(srcFile, it) } ?: emptyMap()
val newProtoMap = getProtoData(srcFile, binaryMetadata) val newProtoMap = protoData(srcFile, binaryMetadata)
for ((classId, protoData) in newProtoMap) { for ((classId, protoData) in newProtoMap) {
registerOutputForFile(srcFile, classId.asSingleFqName()) registerOutputForFile(srcFile, classId.asSingleFqName())
@@ -192,7 +194,8 @@ private object TranslationResultValueExternalizer : DataExternalizer<Translation
private class TranslationResultMap( private class TranslationResultMap(
storageFile: File, storageFile: File,
private val pathConverter: FileToPathConverter private val pathConverter: FileToPathConverter,
private val protoData: ProtoDataProvider
) : ) :
BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) { BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) {
override fun dumpValue(value: TranslationResultValue): String = override fun dumpValue(value: TranslationResultValue): String =
@@ -212,7 +215,7 @@ private class TranslationResultMap(
fun remove(sourceFile: File, changesCollector: ChangesCollector) { fun remove(sourceFile: File, changesCollector: ChangesCollector) {
val path = pathConverter.toPath(sourceFile) val path = pathConverter.toPath(sourceFile)
val protoBytes = storage[path]!!.metadata val protoBytes = storage[path]!!.metadata
val protoMap = getProtoData(sourceFile, protoBytes) val protoMap = protoData(sourceFile, protoBytes)
for ((_, protoData) in protoMap) { for ((_, protoData) in protoMap) {
changesCollector.collectProtoChanges(oldData = protoData, newData = null) changesCollector.collectProtoChanges(oldData = protoData, newData = null)
@@ -282,23 +285,25 @@ private class IrTranslationResultMap(
} }
} }
fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData> { private class ProtoDataProvider(private val serializerProtocol: SerializerExtensionProtocol) {
val classes = hashMapOf<ClassId, ProtoData>() operator fun invoke(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData> {
val proto = ProtoBuf.PackageFragment.parseFrom(metadata, JsSerializerProtocol.extensionRegistry) val classes = hashMapOf<ClassId, ProtoData>()
val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames) val proto = ProtoBuf.PackageFragment.parseFrom(metadata, serializerProtocol.extensionRegistry)
val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames)
proto.class_List.forEach { proto.class_List.forEach {
val classId = nameResolver.getClassId(it.fqName) val classId = nameResolver.getClassId(it.fqName)
classes[classId] = ClassProtoData(it, nameResolver) classes[classId] = ClassProtoData(it, nameResolver)
}
proto.`package`.apply {
val packageFqName = getExtensionOrNull(serializerProtocol.packageFqName)?.let(nameResolver::getPackageFqName)?.let(::FqName) ?: FqName.ROOT
val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt"))
classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName)
}
return classes
} }
proto.`package`.apply {
val packageFqName = getExtensionOrNull(JsProtoBuf.packageFqName)?.let(nameResolver::getPackageFqName)?.let(::FqName) ?: FqName.ROOT
val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt"))
classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName)
}
return classes
} }
private class InlineFunctionsMap( private class InlineFunctionsMap(
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.incremental.storage.FileToCanonicalPathConverter import org.jetbrains.kotlin.incremental.storage.FileToCanonicalPathConverter
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import java.io.File import java.io.File
private val PATH_CONVERTER = FileToCanonicalPathConverter private val PATH_CONVERTER = FileToCanonicalPathConverter
@@ -75,9 +76,10 @@ class IncrementalJvmCachesManager(
class IncrementalJsCachesManager( class IncrementalJsCachesManager(
cachesRootDir: File, cachesRootDir: File,
reporter: ICReporter reporter: ICReporter,
serializerProtocol: SerializerExtensionProtocol
) : IncrementalCachesManager<IncrementalJsCache>(cachesRootDir, reporter) { ) : IncrementalCachesManager<IncrementalJsCache>(cachesRootDir, reporter) {
private val jsCacheFile = File(cachesRootDir, "js").apply { mkdirs() } private val jsCacheFile = File(cachesRootDir, "js").apply { mkdirs() }
override val platformCache = IncrementalJsCache(jsCacheFile, PATH_CONVERTER).apply { registerCache() } override val platformCache = IncrementalJsCache(jsCacheFile, PATH_CONVERTER, serializerProtocol).apply { registerCache() }
} }
@@ -28,24 +28,27 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.* import org.jetbrains.kotlin.incremental.js.*
import org.jetbrains.kotlin.incremental.multiproject.EmptyModulesApiHistory import org.jetbrains.kotlin.incremental.multiproject.EmptyModulesApiHistory
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory
import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import java.io.File import java.io.File
fun makeJsIncrementally( fun makeJsIncrementally(
cachesDir: File, cachesDir: File,
sourceRoots: Iterable<File>, sourceRoots: Iterable<File>,
args: K2JSCompilerArguments, args: K2JSCompilerArguments,
messageCollector: MessageCollector = MessageCollector.NONE, messageCollector: MessageCollector = MessageCollector.NONE,
reporter: ICReporter = EmptyICReporter reporter: ICReporter = EmptyICReporter
) { ) {
val allKotlinFiles = sourceRoots.asSequence().flatMap { it.walk() } val allKotlinFiles = sourceRoots.asSequence().flatMap { it.walk() }
.filter { it.isFile && it.extension.equals("kt", ignoreCase = true) }.toList() .filter { it.isFile && it.extension.equals("kt", ignoreCase = true) }.toList()
val buildHistoryFile = File(cachesDir, "build-history.bin") val buildHistoryFile = File(cachesDir, "build-history.bin")
withJsIC { withJsIC {
val compiler = IncrementalJsCompilerRunner( val compiler = IncrementalJsCompilerRunner(
cachesDir, reporter, cachesDir, reporter,
buildHistoryFile = buildHistoryFile, buildHistoryFile = buildHistoryFile,
modulesApiHistory = EmptyModulesApiHistory) modulesApiHistory = EmptyModulesApiHistory
)
compiler.compile(allKotlinFiles, args, messageCollector, providedChangedFiles = null) compiler.compile(allKotlinFiles, args, messageCollector, providedChangedFiles = null)
} }
} }
@@ -64,24 +67,30 @@ inline fun <R> withJsIC(fn: () -> R): R {
class IncrementalJsCompilerRunner( class IncrementalJsCompilerRunner(
workingDir: File, workingDir: File,
reporter: ICReporter, reporter: ICReporter,
buildHistoryFile: File, buildHistoryFile: File,
private val modulesApiHistory: ModulesApiHistory private val modulesApiHistory: ModulesApiHistory
) : IncrementalCompilerRunner<K2JSCompilerArguments, IncrementalJsCachesManager>( ) : IncrementalCompilerRunner<K2JSCompilerArguments, IncrementalJsCachesManager>(
workingDir, workingDir,
"caches-js", "caches-js",
reporter, reporter,
buildHistoryFile = buildHistoryFile buildHistoryFile = buildHistoryFile
) { ) {
override fun isICEnabled(): Boolean = override fun isICEnabled(): Boolean =
IncrementalCompilation.isEnabledForJs() IncrementalCompilation.isEnabledForJs()
override fun createCacheManager(args: K2JSCompilerArguments): IncrementalJsCachesManager = override fun createCacheManager(args: K2JSCompilerArguments): IncrementalJsCachesManager {
IncrementalJsCachesManager(cacheDirectory, reporter) val serializerProtocol = if (!args.irBackend) JsSerializerProtocol else KlibMetadataSerializerProtocol
return IncrementalJsCachesManager(cacheDirectory, reporter, serializerProtocol)
}
override fun destinationDir(args: K2JSCompilerArguments): File = override fun destinationDir(args: K2JSCompilerArguments): File =
File(args.outputFile).parentFile File(args.outputFile).parentFile
override fun calculateSourcesToCompile(caches: IncrementalJsCachesManager, changedFiles: ChangedFiles.Known, args: K2JSCompilerArguments): CompilationMode { override fun calculateSourcesToCompile(
caches: IncrementalJsCachesManager,
changedFiles: ChangedFiles.Known,
args: K2JSCompilerArguments
): CompilationMode {
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) val lastBuildInfo = BuildInfo.read(lastBuildInfoFile)
?: return CompilationMode.Rebuild { "No information on previous build" } ?: return CompilationMode.Rebuild { "No information on previous build" }
@@ -130,10 +139,10 @@ class IncrementalJsCompilerRunner(
} }
override fun updateCaches( override fun updateCaches(
services: Services, services: Services,
caches: IncrementalJsCachesManager, caches: IncrementalJsCachesManager,
generatedFiles: List<GeneratedFile>, generatedFiles: List<GeneratedFile>,
changesCollector: ChangesCollector changesCollector: ChangesCollector
) { ) {
val incrementalResults = services.get(IncrementalResultsConsumer::class.java) as IncrementalResultsConsumerImpl val incrementalResults = services.get(IncrementalResultsConsumer::class.java) as IncrementalResultsConsumerImpl
@@ -145,11 +154,11 @@ class IncrementalJsCompilerRunner(
} }
override fun runCompiler( override fun runCompiler(
sourcesToCompile: Set<File>, sourcesToCompile: Set<File>,
args: K2JSCompilerArguments, args: K2JSCompilerArguments,
caches: IncrementalJsCachesManager, caches: IncrementalJsCachesManager,
services: Services, services: Services,
messageCollector: MessageCollector messageCollector: MessageCollector
): ExitCode { ): ExitCode {
val freeArgsBackup = args.freeArgs val freeArgsBackup = args.freeArgs
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.incremental.IncrementalJvmCache
import org.jetbrains.kotlin.incremental.storage.FileToPathConverter import org.jetbrains.kotlin.incremental.storage.FileToPathConverter
import org.jetbrains.kotlin.jps.build.KotlinBuilder import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import java.io.File import java.io.File
interface JpsIncrementalCache : IncrementalCacheCommon, StorageOwner { interface JpsIncrementalCache : IncrementalCacheCommon, StorageOwner {
@@ -53,7 +54,7 @@ class JpsIncrementalJsCache(
target: ModuleBuildTarget, target: ModuleBuildTarget,
paths: BuildDataPaths, paths: BuildDataPaths,
pathConverter: FileToPathConverter pathConverter: FileToPathConverter
) : IncrementalJsCache(paths.getTargetDataRoot(target), pathConverter), JpsIncrementalCache { ) : IncrementalJsCache(paths.getTargetDataRoot(target), pathConverter, JsSerializerProtocol), JpsIncrementalCache {
override fun addJpsDependentCache(cache: JpsIncrementalCache) { override fun addJpsDependentCache(cache: JpsIncrementalCache) {
if (cache is JpsIncrementalJsCache) { if (cache is JpsIncrementalJsCache) {
addDependentCache(cache) addDependentCache(cache)