[JS IR] initial support for KLIB incremental compilation with K2
This commit is contained in:
@@ -61,6 +61,7 @@ import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.IncrementalNextRoundException
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
@@ -481,18 +482,28 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
val mainModule = MainModule.SourceFiles(environmentForJS.getSourceFiles())
|
||||
val moduleStructure = ModulesStructure(environmentForJS.project, mainModule, configuration, libraries, friendLibraries)
|
||||
|
||||
val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING
|
||||
|
||||
val outputs = compileModuleToAnalyzedFir(
|
||||
moduleStructure = moduleStructure,
|
||||
ktFiles = environmentForJS.getSourceFiles(),
|
||||
libraries = libraries,
|
||||
friendLibraries = friendLibraries,
|
||||
messageCollector = messageCollector,
|
||||
diagnosticsReporter = diagnosticsReporter
|
||||
diagnosticsReporter = diagnosticsReporter,
|
||||
incrementalDataProvider = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER],
|
||||
lookupTracker = lookupTracker,
|
||||
) ?: return null
|
||||
|
||||
// FIR2IR
|
||||
val fir2IrActualizedResult = transformFirToIr(moduleStructure, outputs, diagnosticsReporter)
|
||||
|
||||
if (configuration.getBoolean(CommonConfigurationKeys.INCREMENTAL_COMPILATION)) {
|
||||
if (shouldGoToNextIcRound(moduleStructure, outputs, fir2IrActualizedResult, configuration)) {
|
||||
throw IncrementalNextRoundException()
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize klib
|
||||
if (arguments.irProduceKlibDir || arguments.irProduceKlibFile) {
|
||||
serializeFirKlib(
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.prepareJsSessions
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
@@ -38,10 +39,13 @@ import org.jetbrains.kotlin.fir.pipeline.*
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
|
||||
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
|
||||
import org.jetbrains.kotlin.fir.session.KlibIcData
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||
@@ -50,6 +54,7 @@ import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.utils.metadataVersion
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
fun compileModuleToAnalyzedFir(
|
||||
@@ -58,7 +63,9 @@ fun compileModuleToAnalyzedFir(
|
||||
libraries: List<String>,
|
||||
friendLibraries: List<String>,
|
||||
messageCollector: MessageCollector,
|
||||
diagnosticsReporter: BaseDiagnosticsCollector
|
||||
diagnosticsReporter: BaseDiagnosticsCollector,
|
||||
incrementalDataProvider: IncrementalDataProvider?,
|
||||
lookupTracker: LookupTracker?,
|
||||
): List<ModuleCompilerAnalyzedOutput>? {
|
||||
val renderDiagnosticNames = moduleStructure.compilerConfiguration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
|
||||
|
||||
@@ -83,7 +90,8 @@ fun compileModuleToAnalyzedFir(
|
||||
|
||||
val sessionsWithSources = prepareJsSessions(
|
||||
ktFiles, moduleStructure.compilerConfiguration, escapedMainModuleName,
|
||||
resolvedLibraries, dependencyList, extensionRegistrars, isCommonSourceForPsi, fileBelongsToModuleForPsi
|
||||
resolvedLibraries, dependencyList, extensionRegistrars, isCommonSourceForPsi, fileBelongsToModuleForPsi,
|
||||
lookupTracker, icData = incrementalDataProvider?.let { KlibIcData(it) }
|
||||
)
|
||||
|
||||
val outputs = sessionsWithSources.map {
|
||||
@@ -207,3 +215,51 @@ fun serializeFirKlib(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun shouldGoToNextIcRound(
|
||||
moduleStructure: ModulesStructure,
|
||||
firOutputs: List<ModuleCompilerAnalyzedOutput>,
|
||||
fir2IrActualizedResult: Fir2IrActualizedResult,
|
||||
config: CompilerConfiguration,
|
||||
): Boolean {
|
||||
val sourceFiles = mutableListOf<KtSourceFile>()
|
||||
val firFilesAndSessionsBySourceFile = mutableMapOf<KtSourceFile, Triple<FirFile, FirSession, ScopeSession>>()
|
||||
|
||||
for (output in firOutputs) {
|
||||
output.fir.forEach {
|
||||
sourceFiles.add(it.sourceFile!!)
|
||||
firFilesAndSessionsBySourceFile[it.sourceFile!!] = Triple(it, output.session, output.scopeSession)
|
||||
}
|
||||
}
|
||||
|
||||
val metadataVersion = moduleStructure.compilerConfiguration.metadataVersion()
|
||||
|
||||
val actualizedExpectDeclarations = fir2IrActualizedResult.irActualizedResult.extractFirDeclarations()
|
||||
|
||||
val nextRoundChecker = config.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false
|
||||
|
||||
for (ktFile in sourceFiles) {
|
||||
|
||||
val (firFile, session, scopeSession) = firFilesAndSessionsBySourceFile[ktFile]
|
||||
?: error("cannot find FIR file by source file ${ktFile.name} (${ktFile.path})")
|
||||
|
||||
val packageFragment = serializeSingleFirFile(
|
||||
firFile,
|
||||
session,
|
||||
scopeSession,
|
||||
actualizedExpectDeclarations,
|
||||
FirKLibSerializerExtension(
|
||||
session, metadataVersion,
|
||||
ConstValueProviderImpl(fir2IrActualizedResult.components),
|
||||
allowErrorTypes = false, exportKDoc = false
|
||||
),
|
||||
moduleStructure.compilerConfiguration.languageVersionSettings,
|
||||
)
|
||||
|
||||
// to minimize a number of IC rounds, we should inspect all proto for changes first,
|
||||
// then go to a next round if needed, with all new dirty files
|
||||
nextRoundChecker.checkProtoChanges(File(ktFile.path!!), packageFragment.toByteArray())
|
||||
}
|
||||
|
||||
return nextRoundChecker.shouldGoToNextRound()
|
||||
}
|
||||
Reference in New Issue
Block a user