[JS IC] Support //RECOMPILE directive in js box tests
- change test runner to production mode when sources are being compiled into klib and then klib is being translated into js, not directly from kt to js - fix IC cache format - support IC tests
This commit is contained in:
committed by
teamcityserver
parent
6b2fee7143
commit
a2e4ebd820
@@ -38,9 +38,7 @@ import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.actualizeCacheForModule
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.buildCache
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.checkCaches
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||
@@ -76,6 +74,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun usePerFileInvalidator(configuration: CompilerConfiguration): Boolean = false
|
||||
|
||||
private fun IcCacheInfo.toICCacheMap(): Map<String, ICCache> {
|
||||
return data.map { it.key to ICCache(PersistentCacheProvider.EMPTY, PersistentCacheConsumer.EMPTY, it.value) }.toMap()
|
||||
}
|
||||
|
||||
override fun doExecute(
|
||||
arguments: K2JSCompilerArguments,
|
||||
configuration: CompilerConfiguration,
|
||||
@@ -234,7 +236,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
|
||||
// Run analysis if main module is sources
|
||||
lateinit var sourceModule: ModulesStructure
|
||||
if (arguments.includes == null) {
|
||||
val includes = arguments.includes
|
||||
if (includes == null) {
|
||||
do {
|
||||
sourceModule = prepareAnalyzedSourceModule(
|
||||
projectJs,
|
||||
@@ -245,7 +248,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
AnalyzerWithCompilerReport(config.configuration),
|
||||
icUseGlobalSignatures = icCaches.isNotEmpty(),
|
||||
icUseStdlibCache = icCaches.isNotEmpty(),
|
||||
icCache = if (icCaches.isNotEmpty()) checkCaches(libraries, icCaches, skipLib = arguments.includes).data else emptyMap()
|
||||
icCache = if (icCaches.isNotEmpty()) checkCaches(libraries, icCaches, skipLib = includes).toICCacheMap() else emptyMap()
|
||||
)
|
||||
val result = sourceModule.jsFrontEndResult.jsAnalysisResult
|
||||
if (result is JsAnalysisResult.RetryWithAdditionalRoots) {
|
||||
@@ -276,8 +279,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
|
||||
val phaseConfig = createPhaseConfig(jsPhases, arguments, messageCollector)
|
||||
|
||||
val includes = arguments.includes
|
||||
|
||||
val module = if (includes != null) {
|
||||
if (sourcesFiles.isNotEmpty()) {
|
||||
messageCollector.report(ERROR, "Source files are not supported when -Xinclude is present")
|
||||
@@ -294,7 +295,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
friendLibraries,
|
||||
icUseGlobalSignatures = icCaches.isNotEmpty(),
|
||||
icUseStdlibCache = icCaches.isNotEmpty(),
|
||||
icCache = if (icCaches.isNotEmpty()) checkCaches(libraries, icCaches, skipLib = includes).data else emptyMap()
|
||||
icCache = if (icCaches.isNotEmpty()) checkCaches(libraries, icCaches, skipLib = includes).toICCacheMap() else emptyMap()
|
||||
)
|
||||
} else {
|
||||
sourceModule
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.ic
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.AbstractAnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.MainModule
|
||||
import org.jetbrains.kotlin.ir.backend.js.toByteArray
|
||||
@@ -20,6 +19,10 @@ import kotlin.random.nextULong
|
||||
// TODO: Proper version of the compiler (should take changes to lowerings into account)
|
||||
private val compilerVersion = Random.nextULong()
|
||||
|
||||
private fun IcCacheInfo.toICCacheMap(): Map<String, ICCache> {
|
||||
return data.map { it.key to ICCache(PersistentCacheProvider.EMPTY, PersistentCacheConsumer.EMPTY, it.value) }.toMap()
|
||||
}
|
||||
|
||||
// TODO more parameters for lowerings
|
||||
// Returns true if caches were built. False if caches were up-to-date.
|
||||
fun buildCache(
|
||||
@@ -50,9 +53,9 @@ fun buildCache(
|
||||
File(icDir, "info").delete()
|
||||
icDir.mkdirs()
|
||||
|
||||
val icData = prepareSingleLibraryIcCache(project, configuration, mainModule.libPath, dependencies, friendDependencies, exportedDeclarations, icCache.data)
|
||||
val icData = prepareSingleLibraryIcCache(project, configuration, mainModule.libPath, dependencies, friendDependencies, exportedDeclarations, icCache.toICCacheMap())
|
||||
|
||||
icData.writeTo(File(cachePath))
|
||||
icData.serializedIcData.writeTo(File(cachePath))
|
||||
|
||||
CacheInfo(cachePath, mainModule.libPath, md5).save()
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.ic
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.AbstractAnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
@@ -34,8 +33,8 @@ fun prepareSingleLibraryIcCache(
|
||||
dependencies: Collection<String>,
|
||||
friendDependencies: Collection<String> = emptyList(),
|
||||
exportedDeclarations: Set<FqName> = emptySet(),
|
||||
icCache: Map<String, SerializedIcData> = emptyMap(),
|
||||
): SerializedIcData {
|
||||
icCache: Map<String, ICCache> = emptyMap(),
|
||||
): ICCache {
|
||||
val irFactory = PersistentIrFactory()
|
||||
val controller = WholeWorldStageController()
|
||||
irFactory.stageController = controller
|
||||
@@ -67,13 +66,17 @@ fun prepareSingleLibraryIcCache(
|
||||
|
||||
lowerPreservingIcData(moduleFragment, context, controller)
|
||||
|
||||
return IcSerializer(
|
||||
context.irBuiltIns,
|
||||
context.mapping,
|
||||
irFactory,
|
||||
deserializer,
|
||||
moduleFragment
|
||||
).serializeDeclarations(irFactory.allDeclarations)
|
||||
return ICCache(
|
||||
PersistentCacheProvider.EMPTY,
|
||||
PersistentCacheConsumer.EMPTY,
|
||||
IcSerializer(
|
||||
context.irBuiltIns,
|
||||
context.mapping,
|
||||
irFactory,
|
||||
deserializer,
|
||||
moduleFragment
|
||||
).serializeDeclarations(irFactory.allDeclarations)
|
||||
)
|
||||
}
|
||||
|
||||
private fun KotlinResolvedLibrary.allDependencies(): List<KotlinResolvedLibrary> {
|
||||
|
||||
@@ -265,7 +265,8 @@ private fun createCacheConsumer(path: String): PersistentCacheConsumer {
|
||||
|
||||
private fun loadCacheInfo(cachePaths: Collection<String>): MutableMap<ModulePath, String> {
|
||||
val caches = cachePaths.map { CacheInfo.load(it) ?: error("Cannot load IC cache from $it") }
|
||||
return caches.associate { it.libPath.toCanonicalPath() to it.path } as MutableMap<ModulePath, String>
|
||||
val result = mutableMapOf<ModulePath, String>()
|
||||
return caches.associateTo(result) { it.libPath.toCanonicalPath() to it.path }
|
||||
}
|
||||
|
||||
private fun loadLibraries(configuration: CompilerConfiguration, dependencies: Collection<String>): Map<ModulePath, KotlinLibrary> {
|
||||
@@ -298,7 +299,7 @@ fun actualizeCacheForModule(
|
||||
val libraries: Map<ModulePath, KotlinLibrary> = loadLibraries(compilerConfiguration, dependencies)
|
||||
|
||||
val persistentCacheProviders = icCacheMap.map { (lib, cache) ->
|
||||
libraries[lib.toCanonicalPath()]!!.let { klib -> klib to createCacheProvider(cache) }
|
||||
libraries[lib.toCanonicalPath()]!! to createCacheProvider(cache)
|
||||
}.toMap()
|
||||
|
||||
val nameToKotlinLibrary: Map<ModuleName, KotlinLibrary> = libraries.values.associateBy { it.moduleName }
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.ICCache
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.SerializedIcData
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
|
||||
@@ -396,7 +397,7 @@ fun prepareAnalyzedSourceModule(
|
||||
analyzer: AbstractAnalyzerWithCompilerReport,
|
||||
icUseGlobalSignatures: Boolean = false,
|
||||
icUseStdlibCache: Boolean = false,
|
||||
icCache: Map<String, SerializedIcData> = emptyMap(),
|
||||
icCache: Map<String, ICCache> = emptyMap(),
|
||||
errorPolicy: ErrorTolerancePolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT,
|
||||
): ModulesStructure {
|
||||
val mainModule = MainModule.SourceFiles(files)
|
||||
@@ -490,12 +491,12 @@ class ModulesStructure(
|
||||
friendDependenciesPaths: Collection<String>,
|
||||
val icUseGlobalSignatures: Boolean,
|
||||
val icUseStdlibCache: Boolean,
|
||||
val icCache: Map<String, SerializedIcData>,
|
||||
val icCache: Map<String, ICCache>,
|
||||
) {
|
||||
val loweringsCacheProvider: LoweringsCacheProvider = when {
|
||||
icUseStdlibCache -> object : LoweringsCacheProvider {
|
||||
override fun cacheByPath(path: String): SerializedIcData? {
|
||||
return icCache[path]
|
||||
return icCache[path]?.serializedIcData
|
||||
}
|
||||
}
|
||||
icUseGlobalSignatures -> EmptyLoweringsCacheProvider
|
||||
|
||||
@@ -239,6 +239,7 @@ val testDataDir = project(":js:js.translator").projectDir.resolve("testData")
|
||||
|
||||
projectTest(parallel = true) {
|
||||
setUpJsBoxTests(jsEnabled = true, jsIrEnabled = true)
|
||||
// systemProperty("kotlin.js.ir.pir", "false")
|
||||
|
||||
inputs.dir(rootDir.resolve("compiler/cli/cli-common/resources")) // compiler.xml
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.output.writeAllTo
|
||||
import org.jetbrains.kotlin.cli.js.resolve
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.*
|
||||
@@ -27,7 +26,7 @@ import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProviderImpl
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
|
||||
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.SerializedIcData
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.ICCache
|
||||
import org.jetbrains.kotlin.js.JavaScript
|
||||
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
@@ -36,7 +35,10 @@ import org.jetbrains.kotlin.js.dce.DeadCodeElimination
|
||||
import org.jetbrains.kotlin.js.dce.InputFile
|
||||
import org.jetbrains.kotlin.js.dce.InputResource
|
||||
import org.jetbrains.kotlin.js.engine.loadFiles
|
||||
import org.jetbrains.kotlin.js.facade.*
|
||||
import org.jetbrains.kotlin.js.facade.K2JSTranslator
|
||||
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||
import org.jetbrains.kotlin.js.facade.TranslationResult
|
||||
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
||||
import org.jetbrains.kotlin.js.parser.parse
|
||||
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapError
|
||||
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapLocationRemapper
|
||||
@@ -178,6 +180,8 @@ abstract class BasicBoxTest(
|
||||
return dependenciesSymbols.toSet() + dependenciesSymbols.flatMap { modules[it]!!.allTransitiveDependencies() }
|
||||
}
|
||||
|
||||
val checkIC = modules.any { it.value.hasFilesToRecompile }
|
||||
|
||||
val orderedModules = DFS.topologicalOrder(modules.values) { module -> module.dependenciesSymbols.mapNotNull { modules[it] } }
|
||||
|
||||
val testPackage = if (runPlainBoxFunction) null else testFactory.testPackage
|
||||
@@ -191,7 +195,7 @@ abstract class BasicBoxTest(
|
||||
}
|
||||
val testModuleName = if (runPlainBoxFunction) null else mainModuleName
|
||||
val mainModule = modules[mainModuleName] ?: error("No module with name \"$mainModuleName\"")
|
||||
val icCache = mutableMapOf<String, SerializedIcData>()
|
||||
val icCache = mutableMapOf<String, ICCache>()
|
||||
|
||||
val generatedJsFiles = orderedModules.asReversed().mapNotNull { module ->
|
||||
val dependencies = module.dependenciesSymbols.map { modules[it]?.outputFileName(outputDir) + ".meta.js" }
|
||||
@@ -233,6 +237,7 @@ abstract class BasicBoxTest(
|
||||
safeExternalBooleanDiagnostic,
|
||||
skipMangleVerification,
|
||||
abiVersion,
|
||||
checkIC,
|
||||
icCache
|
||||
)
|
||||
|
||||
@@ -491,7 +496,8 @@ abstract class BasicBoxTest(
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
||||
skipMangleVerification: Boolean,
|
||||
abiVersion: KotlinAbiVersion,
|
||||
icCache: MutableMap<String, SerializedIcData>
|
||||
checkIC: Boolean,
|
||||
icCache: MutableMap<String, ICCache>
|
||||
) {
|
||||
val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") }
|
||||
val testFiles = kotlinFiles.map { it.fileName }
|
||||
@@ -546,6 +552,8 @@ abstract class BasicBoxTest(
|
||||
safeExternalBooleanDiagnostic,
|
||||
skipMangleVerification,
|
||||
abiVersion,
|
||||
checkIC,
|
||||
recompile = false,
|
||||
icCache
|
||||
)
|
||||
|
||||
@@ -568,12 +576,13 @@ abstract class BasicBoxTest(
|
||||
testPackage,
|
||||
testFunction,
|
||||
needsFullIrRuntime,
|
||||
expectActualLinker
|
||||
expectActualLinker,
|
||||
icCache
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIncrementalCompilation(
|
||||
protected open fun checkIncrementalCompilation(
|
||||
sourceDirs: List<String>,
|
||||
module: TestModule,
|
||||
kotlinFiles: List<TestFile>,
|
||||
@@ -591,7 +600,8 @@ abstract class BasicBoxTest(
|
||||
testPackage: String?,
|
||||
testFunction: String,
|
||||
needsFullIrRuntime: Boolean,
|
||||
expectActualLinker: Boolean
|
||||
expectActualLinker: Boolean,
|
||||
icCaches: MutableMap<String, ICCache>
|
||||
) {
|
||||
val sourceToTranslationUnit = hashMapOf<File, TranslationUnit>()
|
||||
for (testFile in kotlinFiles) {
|
||||
@@ -645,6 +655,8 @@ abstract class BasicBoxTest(
|
||||
safeExternalBooleanDiagnostic = null,
|
||||
skipMangleVerification = false,
|
||||
abiVersion = KotlinAbiVersion.CURRENT,
|
||||
incrementalCompilation = true,
|
||||
recompile = true,
|
||||
mutableMapOf()
|
||||
)
|
||||
|
||||
@@ -729,7 +741,9 @@ abstract class BasicBoxTest(
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
||||
skipMangleVerification: Boolean,
|
||||
abiVersion: KotlinAbiVersion,
|
||||
icCache: MutableMap<String, SerializedIcData>
|
||||
incrementalCompilation: Boolean,
|
||||
recompile: Boolean,
|
||||
icCache: MutableMap<String, ICCache>
|
||||
) {
|
||||
val translator = K2JSTranslator(config, false)
|
||||
val translationResult = translator.translateUnits(ExceptionThrowingReporter, units, mainCallParameters)
|
||||
@@ -866,7 +880,7 @@ abstract class BasicBoxTest(
|
||||
|
||||
private fun createPsiFiles(fileNames: List<String>): List<KtFile> = fileNames.map(this::createPsiFile)
|
||||
|
||||
private fun createConfig(
|
||||
protected fun createConfig(
|
||||
sourceDirs: List<String>,
|
||||
module: TestModule,
|
||||
dependencies: List<String>,
|
||||
@@ -1069,13 +1083,13 @@ abstract class BasicBoxTest(
|
||||
}
|
||||
}
|
||||
|
||||
private class TestFile(val fileName: String, val module: TestModule, val recompile: Boolean, val packageName: String) {
|
||||
protected class TestFile(val fileName: String, val module: TestModule, val recompile: Boolean, val packageName: String) {
|
||||
init {
|
||||
module.files += this
|
||||
}
|
||||
}
|
||||
|
||||
private class TestModule(
|
||||
protected class TestModule(
|
||||
name: String,
|
||||
dependencies: List<String>,
|
||||
friends: List<String>,
|
||||
@@ -1147,7 +1161,7 @@ abstract class BasicBoxTest(
|
||||
protected val runTestInNashorn = getBoolean("kotlin.js.useNashorn")
|
||||
|
||||
const val TEST_MODULE = "JS_TESTS"
|
||||
private const val DEFAULT_MODULE = "main"
|
||||
const val DEFAULT_MODULE = "main"
|
||||
private const val TEST_FUNCTION = "box"
|
||||
private const val OLD_MODULE_SUFFIX = "-old"
|
||||
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.test
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.backend.common.phaser.AnyNamedPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.SerializedIcData
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.prepareSingleLibraryIcCache
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.config.JsConfig
|
||||
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
|
||||
@@ -32,7 +33,7 @@ private val defaultRuntimeKlib = System.getProperty("kotlin.js.reduced.stdlib.pa
|
||||
private val kotlinTestKLib = System.getProperty("kotlin.js.kotlin.test.path")
|
||||
|
||||
// TODO Cache on FS (requires bootstrap)
|
||||
private val predefinedKlibHasIcCache = mutableMapOf<String, SerializedIcData?>(
|
||||
private val predefinedKlibHasIcCache = mutableMapOf<String, ICCache?>(
|
||||
File(fullRuntimeKlib).absolutePath to null,
|
||||
File(kotlinTestKLib).absolutePath to null,
|
||||
File(defaultRuntimeKlib).absolutePath to null
|
||||
@@ -75,7 +76,7 @@ abstract class BasicIrBoxTest(
|
||||
val perModule: Boolean = getBoolean("kotlin.js.ir.perModule")
|
||||
|
||||
// TODO Design incremental compilation for IR and add test support
|
||||
override val incrementalCompilationChecksEnabled = false
|
||||
override val incrementalCompilationChecksEnabled = true
|
||||
|
||||
private val compilationCache = mutableMapOf<String, String>()
|
||||
|
||||
@@ -111,9 +112,11 @@ abstract class BasicIrBoxTest(
|
||||
safeExternalBooleanDiagnostic: RuntimeDiagnostic?,
|
||||
skipMangleVerification: Boolean,
|
||||
abiVersion: KotlinAbiVersion,
|
||||
icCache: MutableMap<String, SerializedIcData>
|
||||
incrementalCompilation: Boolean,
|
||||
recompile: Boolean,
|
||||
icCache: MutableMap<String, ICCache>
|
||||
) {
|
||||
val filesToCompile = units.map { (it as TranslationUnit.SourceFile).file }
|
||||
val filesToCompile = units.mapNotNull { (it as? TranslationUnit.SourceFile)?.file }
|
||||
|
||||
val runtimeKlibs = if (needsFullIrRuntime) listOf(fullRuntimeKlib, kotlinTestKLib) else listOf(defaultRuntimeKlib)
|
||||
|
||||
@@ -123,11 +126,17 @@ abstract class BasicIrBoxTest(
|
||||
compilationCache[it] ?: error("Can't find compiled module for dependency $it")
|
||||
}).map { File(it).absolutePath }.toMutableList()
|
||||
|
||||
val klibPath = outputFile.absolutePath.replace("_v5.js", "")
|
||||
val klibPath = outputFile.canonicalPath.replace("_v5.js", "")
|
||||
|
||||
prepareRuntimePirCaches(config, icCache)
|
||||
val actualOutputFile = outputFile.canonicalPath.let {
|
||||
if (!isMainModule) klibPath else it
|
||||
}
|
||||
|
||||
if (isMainModule && klibMainModule) {
|
||||
if (incrementalCompilationChecksEnabled && incrementalCompilation) {
|
||||
runtimeKlibs.forEach { createIcCache(it, runtimeKlibs, config, icCache) }
|
||||
}
|
||||
|
||||
if (!recompile) { // In case of incremental recompilation we only rebuild caches, not klib itself
|
||||
val module = prepareAnalyzedSourceModule(
|
||||
config.project,
|
||||
filesToCompile,
|
||||
@@ -143,14 +152,16 @@ abstract class BasicIrBoxTest(
|
||||
nopack = true,
|
||||
jsOutputName = null
|
||||
)
|
||||
|
||||
allKlibPaths += File(klibPath).absolutePath
|
||||
}
|
||||
|
||||
val actualOutputFile = outputFile.absolutePath.let {
|
||||
if (!isMainModule) klibPath else it
|
||||
val klibCannonPath = File(klibPath).canonicalPath
|
||||
|
||||
if (incrementalCompilation) {
|
||||
icCache[klibCannonPath] = createIcCache(klibCannonPath, allKlibPaths + klibCannonPath, config, icCache)
|
||||
}
|
||||
|
||||
compilationCache[outputFile.name.replace(".js", ".meta.js")] = actualOutputFile
|
||||
|
||||
if (isMainModule) {
|
||||
logger.logFile("Output JS", outputFile)
|
||||
|
||||
@@ -171,47 +182,27 @@ abstract class BasicIrBoxTest(
|
||||
PhaseConfig(jsPhases)
|
||||
}
|
||||
|
||||
fun prepareModule(allowIc: Boolean): ModulesStructure {
|
||||
val useIc = runIcMode && allowIc
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val icCache = if (useIc) icCache else emptyMap()
|
||||
return if (!klibMainModule) {
|
||||
prepareAnalyzedSourceModule(
|
||||
config.project,
|
||||
filesToCompile,
|
||||
config.configuration,
|
||||
allKlibPaths,
|
||||
emptyList(),
|
||||
AnalyzerWithCompilerReport(config.configuration),
|
||||
icUseGlobalSignatures = useIc,
|
||||
icUseStdlibCache = useIc,
|
||||
icCache = icCache
|
||||
)
|
||||
} else {
|
||||
ModulesStructure(
|
||||
config.project,
|
||||
MainModule.Klib(klibPath),
|
||||
config.configuration,
|
||||
allKlibPaths,
|
||||
emptyList(),
|
||||
icUseGlobalSignatures = useIc,
|
||||
icUseStdlibCache = useIc,
|
||||
icCache = icCache
|
||||
)
|
||||
}
|
||||
}
|
||||
val module = ModulesStructure(
|
||||
config.project,
|
||||
MainModule.Klib(klibPath),
|
||||
config.configuration,
|
||||
allKlibPaths + klibCannonPath,
|
||||
emptyList(),
|
||||
icUseGlobalSignatures = runIcMode,
|
||||
icUseStdlibCache = runIcMode,
|
||||
icCache = icCache
|
||||
)
|
||||
|
||||
if (!skipRegularMode) {
|
||||
val module = prepareModule(true)
|
||||
val irFactory = if (lowerPerModule) PersistentIrFactory() else IrFactoryImpl
|
||||
val compiledModule = compile(
|
||||
module,
|
||||
phaseConfig = phaseConfig,
|
||||
irFactory = irFactory,
|
||||
irFactory = IrFactoryImpl,
|
||||
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
|
||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
|
||||
generateFullJs = true,
|
||||
generateDceJs = runIrDce,
|
||||
dceDriven = false,
|
||||
es6mode = runEs6Mode,
|
||||
multiModule = splitPerModule || perModule,
|
||||
propertyLazyInitialization = propertyLazyInitialization,
|
||||
@@ -221,7 +212,10 @@ abstract class BasicIrBoxTest(
|
||||
verifySignatures = !skipMangleVerification,
|
||||
)
|
||||
|
||||
compiledModule.outputs!!.writeTo(outputFile, config)
|
||||
val jsOutputFile = if (recompile) File(outputFile.parentFile, outputFile.nameWithoutExtension + "-recompiled.js")
|
||||
else outputFile
|
||||
|
||||
compiledModule.outputs!!.writeTo(jsOutputFile, config)
|
||||
|
||||
compiledModule.outputsAfterDce?.writeTo(dceOutputFile, config)
|
||||
|
||||
@@ -232,54 +226,127 @@ abstract class BasicIrBoxTest(
|
||||
}
|
||||
}
|
||||
|
||||
if (runIrPir && !skipDceDriven) {
|
||||
val module = prepareModule(false)
|
||||
compile(
|
||||
if (runIrPir) {
|
||||
val compiledModule = compile(
|
||||
module,
|
||||
phaseConfig = phaseConfig,
|
||||
irFactory = PersistentIrFactory(),
|
||||
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null },
|
||||
exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, testFunction))),
|
||||
generateFullJs = true,
|
||||
generateDceJs = runIrDce,
|
||||
dceDriven = true,
|
||||
es6mode = runEs6Mode,
|
||||
multiModule = splitPerModule || perModule,
|
||||
propertyLazyInitialization = propertyLazyInitialization,
|
||||
lowerPerModule = lowerPerModule,
|
||||
safeExternalBoolean = safeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic,
|
||||
verifySignatures = !skipMangleVerification
|
||||
).outputs!!.writeTo(pirOutputFile, config)
|
||||
verifySignatures = !skipMangleVerification,
|
||||
)
|
||||
compiledModule.outputs!!.writeTo(pirOutputFile, config)
|
||||
}
|
||||
} else {
|
||||
val module = prepareAnalyzedSourceModule(
|
||||
config.project,
|
||||
filesToCompile,
|
||||
config.configuration,
|
||||
allKlibPaths,
|
||||
emptyList(),
|
||||
AnalyzerWithCompilerReport(config.configuration)
|
||||
)
|
||||
generateKLib(
|
||||
module,
|
||||
irFactory = IrFactoryImpl,
|
||||
outputKlibPath = actualOutputFile,
|
||||
nopack = true,
|
||||
verifySignatures = !skipMangleVerification,
|
||||
abiVersion = abiVersion,
|
||||
null
|
||||
)
|
||||
|
||||
if (runIcMode) {
|
||||
icCache[actualOutputFile] = createPirCache(actualOutputFile, allKlibPaths + actualOutputFile, config, icCache)
|
||||
}
|
||||
|
||||
logger.logFile("Output klib", File(actualOutputFile))
|
||||
|
||||
compilationCache[outputFile.name.replace(".js", ".meta.js")] = actualOutputFile
|
||||
}
|
||||
}
|
||||
|
||||
override fun checkIncrementalCompilation(
|
||||
sourceDirs: List<String>,
|
||||
module: TestModule,
|
||||
kotlinFiles: List<TestFile>,
|
||||
dependencies: List<String>,
|
||||
allDependencies: List<String>,
|
||||
friends: List<String>,
|
||||
multiModule: Boolean,
|
||||
tmpDir: File,
|
||||
remap: Boolean,
|
||||
outputFile: File,
|
||||
outputPrefixFile: File?,
|
||||
outputPostfixFile: File?,
|
||||
mainCallParameters: MainCallParameters,
|
||||
incrementalData: IncrementalData,
|
||||
testPackage: String?,
|
||||
testFunction: String,
|
||||
needsFullIrRuntime: Boolean,
|
||||
expectActualLinker: Boolean,
|
||||
icCaches: MutableMap<String, ICCache>
|
||||
) {
|
||||
val isMainModule = module.name == DEFAULT_MODULE || module.name == TEST_MODULE
|
||||
val cacheKey = outputFile.canonicalPath.replace("_v5.js", "")
|
||||
|
||||
private fun createPirCache(path: String, allKlibPaths: Collection<String>, config: JsConfig, icCache: Map<String, SerializedIcData>): SerializedIcData {
|
||||
val icCache = icCaches[cacheKey] ?: error("No IC data found for module ${module.name}")
|
||||
|
||||
val dirtyFiles = mutableListOf<String>()
|
||||
val oldBinaryAsts = mutableMapOf<String, ByteArray>()
|
||||
|
||||
for (testFile in kotlinFiles) {
|
||||
if (testFile.recompile) {
|
||||
val fileName = testFile.fileName
|
||||
oldBinaryAsts[fileName] = icCache.dataProvider.binaryAst(fileName)
|
||||
icCache.dataConsumer.invalidateForFile(fileName)
|
||||
dirtyFiles.add(fileName)
|
||||
}
|
||||
}
|
||||
|
||||
val recompiledOutputFile = File(outputFile.parentFile, outputFile.nameWithoutExtension + "-recompiled.js")
|
||||
val recompiledMinOutputFile = File(recompiledOutputFile.parentFile, recompiledOutputFile.nameWithoutExtension + "-min.js")
|
||||
val recompiledPirOutputFile = File(recompiledOutputFile.parentFile, recompiledOutputFile.nameWithoutExtension + "-pir.js")
|
||||
val recompiledConfig = createConfig(
|
||||
sourceDirs,
|
||||
module,
|
||||
dependencies,
|
||||
allDependencies,
|
||||
friends,
|
||||
multiModule,
|
||||
tmpDir,
|
||||
null,
|
||||
expectActualLinker,
|
||||
ErrorTolerancePolicy.DEFAULT
|
||||
)
|
||||
|
||||
translateFiles(
|
||||
dirtyFiles.map { TranslationUnit.SourceFile(createPsiFile(it)) },
|
||||
outputFile,
|
||||
recompiledMinOutputFile,
|
||||
recompiledPirOutputFile,
|
||||
recompiledConfig,
|
||||
outputPrefixFile,
|
||||
outputPostfixFile,
|
||||
mainCallParameters,
|
||||
incrementalData,
|
||||
remap,
|
||||
testPackage,
|
||||
testFunction,
|
||||
needsFullIrRuntime,
|
||||
isMainModule,
|
||||
skipDceDriven = true,
|
||||
splitPerModule = false, // TODO??
|
||||
propertyLazyInitialization = false, // ??
|
||||
safeExternalBoolean = false,
|
||||
safeExternalBooleanDiagnostic = null,
|
||||
skipMangleVerification = false,
|
||||
KotlinAbiVersion.CURRENT,
|
||||
incrementalCompilation = true,
|
||||
recompile = true,
|
||||
icCaches
|
||||
)
|
||||
|
||||
val newBinaryAsts = dirtyFiles.associateWith { icCache.dataProvider.binaryAst(it) }
|
||||
|
||||
for (file in dirtyFiles) {
|
||||
val oldBinaryAst = oldBinaryAsts[file]
|
||||
val newBinaryAst = newBinaryAsts[file]
|
||||
|
||||
assert(oldBinaryAst.contentEquals(newBinaryAst)) { "Binary AST changed after recompilation for file $file" }
|
||||
}
|
||||
|
||||
if (isMainModule) {
|
||||
val originalOutput = FileUtil.loadFile(outputFile)
|
||||
val recompiledOutput = FileUtil.loadFile(recompiledOutputFile)
|
||||
assertEquals("Output file changed after recompilation", originalOutput, recompiledOutput)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPirCache(path: String, allKlibPaths: Collection<String>, config: JsConfig, icCache: Map<String, ICCache>): ICCache {
|
||||
val icData = predefinedKlibHasIcCache[path] ?: prepareSingleLibraryIcCache(
|
||||
project = project,
|
||||
configuration = config.configuration,
|
||||
@@ -295,7 +362,23 @@ abstract class BasicIrBoxTest(
|
||||
return icData
|
||||
}
|
||||
|
||||
private fun prepareRuntimePirCaches(config: JsConfig, icCache: MutableMap<String, SerializedIcData>) {
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun createIcCache(path: String, allKlibPaths: Collection<String>, config: JsConfig, icCache: Map<String, ICCache>): ICCache {
|
||||
|
||||
fun prepare(): ICCache {
|
||||
return ICCache(PersistentCacheProvider.EMPTY, PersistentCacheConsumer.EMPTY, SerializedIcData(emptyList()))
|
||||
}
|
||||
|
||||
val icData = predefinedKlibHasIcCache[path] ?: prepare()
|
||||
|
||||
if (path in predefinedKlibHasIcCache) {
|
||||
predefinedKlibHasIcCache[path] = icData
|
||||
}
|
||||
|
||||
return icData
|
||||
}
|
||||
|
||||
private fun prepareRuntimePirCaches(config: JsConfig, icCache: MutableMap<String, ICCache>) {
|
||||
if (!runIcMode) return
|
||||
|
||||
val defaultRuntimePath = File(defaultRuntimeKlib).canonicalPath
|
||||
|
||||
Reference in New Issue
Block a user