Use Klib JS serializer protocol for IC
This commit is contained in:
committed by
romanart
parent
6e9cd85b54
commit
d776e92111
@@ -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(
|
||||||
|
|||||||
+4
-2
@@ -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() }
|
||||||
}
|
}
|
||||||
+31
-22
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user