rra/ilgonmic/ic-to-compiler
[JS IR] Fix compilation in tests [JS IR] Fix test after migrating IC to compiler [JS IR] Fix memory leak [JS IR] Move js ic to compiler Merge-request: KT-MR-5673 Merged-by: Ilya Goncharov <Ilya.Goncharov@jetbrains.com>
This commit is contained in:
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker
|
|||||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||||
import org.jetbrains.kotlin.ir.backend.js.*
|
import org.jetbrains.kotlin.ir.backend.js.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.actualizeCacheForModule
|
import org.jetbrains.kotlin.ir.backend.js.ic.actualizeCaches
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.buildCacheForModuleFiles
|
import org.jetbrains.kotlin.ir.backend.js.ic.buildCacheForModuleFiles
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.loadModuleCaches
|
import org.jetbrains.kotlin.ir.backend.js.ic.loadModuleCaches
|
||||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||||
@@ -196,9 +196,9 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
// TODO: Handle non-empty main call arguments
|
// TODO: Handle non-empty main call arguments
|
||||||
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
|
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
|
||||||
|
|
||||||
val icCaches = configureLibraries(arguments.cacheDirectories)
|
val cacheDirectories = configureLibraries(arguments.cacheDirectories)
|
||||||
|
|
||||||
if (arguments.irBuildCache) {
|
val icCaches = if (cacheDirectories.isNotEmpty()) {
|
||||||
messageCollector.report(INFO, "")
|
messageCollector.report(INFO, "")
|
||||||
messageCollector.report(INFO, "Building cache:")
|
messageCollector.report(INFO, "Building cache:")
|
||||||
messageCollector.report(INFO, "to: ${outputFilePath}")
|
messageCollector.report(INFO, "to: ${outputFilePath}")
|
||||||
@@ -209,24 +209,22 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
|
|
||||||
val start = System.currentTimeMillis()
|
val start = System.currentTimeMillis()
|
||||||
|
|
||||||
val updateStatus = actualizeCacheForModule(
|
actualizeCaches(
|
||||||
includes,
|
includes,
|
||||||
outputFilePath,
|
|
||||||
configurationJs,
|
configurationJs,
|
||||||
libraries,
|
libraries,
|
||||||
icCaches,
|
cacheDirectories,
|
||||||
IrFactoryImplForJsIC(WholeWorldStageController()),
|
{ IrFactoryImplForJsIC(WholeWorldStageController()) },
|
||||||
mainCallArguments,
|
mainCallArguments,
|
||||||
::buildCacheForModuleFiles
|
::buildCacheForModuleFiles,
|
||||||
)
|
) { updateStatus ->
|
||||||
|
if (updateStatus.upToDate) {
|
||||||
if (updateStatus.upToDate) {
|
messageCollector.report(INFO, "IC per-file cache up-to-date check duration: ${System.currentTimeMillis() - start}ms")
|
||||||
messageCollector.report(INFO, "IC per-file cache up-to-date check duration: ${System.currentTimeMillis() - start}ms")
|
} else {
|
||||||
} else {
|
messageCollector.report(INFO, "IC per-file cache building duration: ${System.currentTimeMillis() - start}ms")
|
||||||
messageCollector.report(INFO, "IC per-file cache building duration: ${System.currentTimeMillis() - start}ms")
|
}
|
||||||
}
|
}
|
||||||
return OK
|
} else emptyList()
|
||||||
}
|
|
||||||
|
|
||||||
// Run analysis if main module is sources
|
// Run analysis if main module is sources
|
||||||
lateinit var sourceModule: ModulesStructure
|
lateinit var sourceModule: ModulesStructure
|
||||||
|
|||||||
@@ -31,5 +31,15 @@ data class CacheInfo(val path: String, val libPath: String, var flatHash: ULong,
|
|||||||
val configHashULong = configHash.toULongOrNull(16) ?: 0UL
|
val configHashULong = configHash.toULongOrNull(16) ?: 0UL
|
||||||
return CacheInfo(path, libPath, flatHash.toULong(16), transHash.toULong(16), configHashULong)
|
return CacheInfo(path, libPath, flatHash.toULong(16), transHash.toULong(16), configHashULong)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun loadOrCreate(
|
||||||
|
path: String,
|
||||||
|
moduleName: String,
|
||||||
|
flatHash: ULong = 0UL,
|
||||||
|
transHash: ULong = 0UL,
|
||||||
|
configHash: ULong = 0UL
|
||||||
|
): CacheInfo {
|
||||||
|
return load(path) ?: CacheInfo(path, moduleName, flatHash, transHash, configHash)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ import java.security.MessageDigest
|
|||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile
|
||||||
|
|
||||||
private fun KotlinLibrary.fingerprint(fileIndex: Int): Hash {
|
private fun KotlinLibrary.fingerprint(fileIndex: Int): Hash {
|
||||||
return ((((types(fileIndex).md5() * 31) + signatures(fileIndex).md5()) * 31 + strings(fileIndex).md5()) * 31 + declarations(fileIndex).md5()) * 31 + bodies(fileIndex).md5()
|
return ((((types(fileIndex).md5() * 31) + signatures(fileIndex).md5()) * 31 + strings(fileIndex).md5()) * 31 + declarations(fileIndex).md5()) * 31 + bodies(
|
||||||
|
fileIndex
|
||||||
|
).md5()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun invalidateCacheForModule(
|
private fun invalidateCacheForModule(
|
||||||
@@ -295,7 +297,7 @@ private fun createCacheConsumer(path: String): PersistentCacheConsumer {
|
|||||||
return PersistentCacheConsumerImpl(path)
|
return PersistentCacheConsumerImpl(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadCacheInfo(cachePaths: Collection<String>): MutableMap<ModulePath, CacheInfo> {
|
fun loadCacheInfo(cachePaths: Collection<String>): MutableMap<ModulePath, CacheInfo> {
|
||||||
val caches = cachePaths.map { CacheInfo.load(it) ?: error("Cannot load IC cache from $it") }
|
val caches = cachePaths.map { CacheInfo.load(it) ?: error("Cannot load IC cache from $it") }
|
||||||
val result = mutableMapOf<ModulePath, CacheInfo>()
|
val result = mutableMapOf<ModulePath, CacheInfo>()
|
||||||
return caches.associateByTo(result) { it.libPath.toCanonicalPath() }
|
return caches.associateByTo(result) { it.libPath.toCanonicalPath() }
|
||||||
@@ -311,7 +313,7 @@ private fun loadLibraries(configuration: CompilerConfiguration, dependencies: Co
|
|||||||
return allResolvedDependencies.getFullList().associateBy { it.libraryFile.path.toCanonicalPath() }
|
return allResolvedDependencies.getFullList().associateBy { it.libraryFile.path.toCanonicalPath() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.toCanonicalPath(): String = File(this).canonicalPath
|
fun String.toCanonicalPath(): String = File(this).canonicalPath
|
||||||
|
|
||||||
typealias ModuleName = String
|
typealias ModuleName = String
|
||||||
typealias ModulePath = String
|
typealias ModulePath = String
|
||||||
@@ -408,35 +410,101 @@ enum class CacheUpdateStatus(val upToDate: Boolean) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun actualizeCaches(
|
||||||
|
includes: String,
|
||||||
|
compilerConfiguration: CompilerConfiguration,
|
||||||
|
dependencies: Collection<ModulePath>,
|
||||||
|
icCachePaths: Collection<String>,
|
||||||
|
irFactory: () -> IrFactory,
|
||||||
|
mainArguments: List<String>?,
|
||||||
|
executor: CacheExecutor,
|
||||||
|
callback: (CacheUpdateStatus) -> Unit
|
||||||
|
): List<String> {
|
||||||
|
val (libraries, dependencyGraph, configMD5) = CacheConfiguration(dependencies, compilerConfiguration)
|
||||||
|
val cacheMap = libraries.values.zip(icCachePaths).toMap()
|
||||||
|
|
||||||
|
val icCacheMap: MutableMap<ModulePath, CacheInfo> = mutableMapOf<ModulePath, CacheInfo>()
|
||||||
|
val resultCaches = mutableListOf<String>()
|
||||||
|
|
||||||
|
val visitedLibraries = mutableSetOf<KotlinLibrary>()
|
||||||
|
fun visitDependency(library: KotlinLibrary) {
|
||||||
|
if (library in visitedLibraries) return
|
||||||
|
visitedLibraries.add(library)
|
||||||
|
|
||||||
|
val libraryDeps = dependencyGraph[library] ?: error("Unknown library ${library.libraryName}")
|
||||||
|
libraryDeps.forEach { visitDependency(it) }
|
||||||
|
|
||||||
|
val cachePath = cacheMap[library] ?: error("Unknown cache for library ${library.libraryName}")
|
||||||
|
resultCaches.add(cachePath)
|
||||||
|
|
||||||
|
val moduleName = library.libraryFile.path.toCanonicalPath()
|
||||||
|
val cacheInfo = CacheInfo.loadOrCreate(cachePath, moduleName, configHash = configMD5)
|
||||||
|
icCacheMap[moduleName] = cacheInfo
|
||||||
|
|
||||||
|
val updateStatus = actualizeCacheForModule(
|
||||||
|
moduleName = moduleName,
|
||||||
|
cachePath = cachePath,
|
||||||
|
compilerConfiguration = compilerConfiguration,
|
||||||
|
configMD5 = configMD5,
|
||||||
|
libraries = libraries,
|
||||||
|
dependencyGraph = dependencyGraph,
|
||||||
|
icCacheMap = icCacheMap,
|
||||||
|
irFactory = irFactory(),
|
||||||
|
mainArguments = mainArguments,
|
||||||
|
executor = executor
|
||||||
|
)
|
||||||
|
callback(updateStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
val canonicalIncludes = includes.toCanonicalPath()
|
||||||
|
val mainLibrary = libraries[canonicalIncludes] ?: error("Main library not found in libraries: $canonicalIncludes")
|
||||||
|
visitDependency(mainLibrary)
|
||||||
|
return resultCaches
|
||||||
|
}
|
||||||
|
|
||||||
|
class CacheConfiguration(
|
||||||
|
private val dependencies: Collection<ModulePath>,
|
||||||
|
val compilerConfiguration: CompilerConfiguration
|
||||||
|
) {
|
||||||
|
val libraries: Map<ModulePath, KotlinLibrary> = loadLibraries(compilerConfiguration, dependencies)
|
||||||
|
|
||||||
|
val dependencyGraph: Map<KotlinLibrary, List<KotlinLibrary>>
|
||||||
|
get() {
|
||||||
|
val nameToKotlinLibrary: Map<ModuleName, KotlinLibrary> = libraries.values.associateBy { it.moduleName }
|
||||||
|
|
||||||
|
return libraries.values.associateWith {
|
||||||
|
it.manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true).map { depName ->
|
||||||
|
nameToKotlinLibrary[depName] ?: error("No Library found for $depName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val configMD5
|
||||||
|
get() = compilerConfiguration.calcMD5()
|
||||||
|
|
||||||
|
operator fun component1() = libraries
|
||||||
|
operator fun component2() = dependencyGraph
|
||||||
|
operator fun component3() = configMD5
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if caches up-to-date
|
// Returns true if caches up-to-date
|
||||||
fun actualizeCacheForModule(
|
fun actualizeCacheForModule(
|
||||||
moduleName: String,
|
moduleName: String,
|
||||||
cachePath: String,
|
cachePath: String,
|
||||||
compilerConfiguration: CompilerConfiguration,
|
compilerConfiguration: CompilerConfiguration,
|
||||||
dependencies: Collection<ModulePath>,
|
configMD5: ULong,
|
||||||
icCachePaths: Collection<String>,
|
libraries: Map<ModulePath, KotlinLibrary>,
|
||||||
|
dependencyGraph: Map<KotlinLibrary, List<KotlinLibrary>>,
|
||||||
|
icCacheMap: Map<ModulePath, CacheInfo>,
|
||||||
irFactory: IrFactory,
|
irFactory: IrFactory,
|
||||||
mainArguments: List<String>?,
|
mainArguments: List<String>?,
|
||||||
executor: CacheExecutor
|
executor: CacheExecutor
|
||||||
): CacheUpdateStatus {
|
): CacheUpdateStatus {
|
||||||
val configMD5 = compilerConfiguration.calcMD5()
|
val cacheInfo = icCacheMap[moduleName] ?: error("Cache for $moduleName not found")
|
||||||
val modulePath = moduleName.toCanonicalPath()
|
|
||||||
val cacheInfo = CacheInfo.load(cachePath) ?: CacheInfo(cachePath, modulePath, 0UL, 0UL, configMD5)
|
|
||||||
val icCacheMap: Map<ModulePath, CacheInfo> = loadCacheInfo(icCachePaths).also {
|
|
||||||
it[modulePath] = cacheInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
val libraries: Map<ModulePath, KotlinLibrary> = loadLibraries(compilerConfiguration, dependencies)
|
|
||||||
val nameToKotlinLibrary: Map<ModuleName, KotlinLibrary> = libraries.values.associateBy { it.moduleName }
|
|
||||||
val dependencyGraph = libraries.values.associateWith {
|
|
||||||
it.manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true).map { depName ->
|
|
||||||
nameToKotlinLibrary[depName] ?: error("No Library found for $depName")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val configUpdated = configMD5 != cacheInfo.configHash
|
val configUpdated = configMD5 != cacheInfo.configHash
|
||||||
cacheInfo.configHash = configMD5
|
cacheInfo.configHash = configMD5
|
||||||
if (checkLibrariesHash(libraries, dependencyGraph, icCacheMap, modulePath) && !configUpdated) {
|
if (checkLibrariesHash(libraries, dependencyGraph, icCacheMap, moduleName) && !configUpdated) {
|
||||||
return CacheUpdateStatus.FAST_PATH // up-to-date
|
return CacheUpdateStatus.FAST_PATH // up-to-date
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +512,7 @@ fun actualizeCacheForModule(
|
|||||||
libraries[lib.toCanonicalPath()]!! to createCacheProvider(cache.path)
|
libraries[lib.toCanonicalPath()]!! to createCacheProvider(cache.path)
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
val currentModule = libraries[moduleName.toCanonicalPath()] ?: error("No loaded library found for path $moduleName")
|
val currentModule = libraries[moduleName] ?: error("No loaded library found for path $moduleName")
|
||||||
val persistentCacheConsumer = createCacheConsumer(cachePath)
|
val persistentCacheConsumer = createCacheConsumer(cachePath)
|
||||||
|
|
||||||
return actualizeCacheForModule(
|
return actualizeCacheForModule(
|
||||||
|
|||||||
@@ -17,17 +17,15 @@ import org.jetbrains.kotlin.codegen.*
|
|||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.CacheUpdateStatus
|
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.PersistentCacheConsumer
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.actualizeCacheForModule
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||||
import org.jetbrains.kotlin.ir.backend.js.prepareAnalyzedSourceModule
|
import org.jetbrains.kotlin.ir.backend.js.prepareAnalyzedSourceModule
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
|
||||||
import org.jetbrains.kotlin.test.util.JUnit4Assertions
|
import org.jetbrains.kotlin.test.util.JUnit4Assertions
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.io.path.createTempDirectory
|
import kotlin.io.path.createTempDirectory
|
||||||
@@ -58,7 +56,8 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
|||||||
cacheConsumer: PersistentCacheConsumer,
|
cacheConsumer: PersistentCacheConsumer,
|
||||||
exportedDeclarations: Set<FqName>,
|
exportedDeclarations: Set<FqName>,
|
||||||
mainArguments: List<String>?,
|
mainArguments: List<String>?,
|
||||||
) { }
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
private fun initializeStdlibCache() {
|
private fun initializeStdlibCache() {
|
||||||
if (stdlibCacheDir != null) return
|
if (stdlibCacheDir != null) return
|
||||||
@@ -67,7 +66,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
|||||||
|
|
||||||
val configuration = createConfiguration("stdlib")
|
val configuration = createConfiguration("stdlib")
|
||||||
|
|
||||||
actualizeCacheForModule(
|
actualizeCacheForModuleWithPrepare(
|
||||||
stdlibKlibPath,
|
stdlibKlibPath,
|
||||||
cacheDir.canonicalPath,
|
cacheDir.canonicalPath,
|
||||||
configuration,
|
configuration,
|
||||||
@@ -158,7 +157,17 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
|||||||
|
|
||||||
val moduleCacheDir = resolveModuleCache(module, buildDir)
|
val moduleCacheDir = resolveModuleCache(module, buildDir)
|
||||||
|
|
||||||
buildCachesAndCheck(moduleStep, configuration, moduleSourceDir, outputKlibFile, moduleCacheDir, dependencies, icCaches, dirtyFiles, deletedFiles)
|
buildCachesAndCheck(
|
||||||
|
moduleStep,
|
||||||
|
configuration,
|
||||||
|
moduleSourceDir,
|
||||||
|
outputKlibFile,
|
||||||
|
moduleCacheDir,
|
||||||
|
dependencies,
|
||||||
|
icCaches,
|
||||||
|
dirtyFiles,
|
||||||
|
deletedFiles
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,7 +221,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
|||||||
dependencies.mapTo(dependenciesPaths) { it.canonicalPath }
|
dependencies.mapTo(dependenciesPaths) { it.canonicalPath }
|
||||||
dependenciesPaths.add(moduleKlibFile.canonicalPath)
|
dependenciesPaths.add(moduleKlibFile.canonicalPath)
|
||||||
|
|
||||||
val updateStatus = actualizeCacheForModule(
|
val updateStatus = actualizeCacheForModuleWithPrepare(
|
||||||
moduleKlibFile.canonicalPath,
|
moduleKlibFile.canonicalPath,
|
||||||
moduleCacheDir.canonicalPath,
|
moduleCacheDir.canonicalPath,
|
||||||
configuration,
|
configuration,
|
||||||
@@ -235,6 +244,41 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun actualizeCacheForModuleWithPrepare(
|
||||||
|
moduleName: String,
|
||||||
|
cachePath: String,
|
||||||
|
compilerConfiguration: CompilerConfiguration,
|
||||||
|
dependencies: Collection<ModulePath>,
|
||||||
|
icCachePaths: Collection<String>,
|
||||||
|
irFactory: IrFactory,
|
||||||
|
mainArguments: List<String>?,
|
||||||
|
executor: CacheExecutor
|
||||||
|
): CacheUpdateStatus {
|
||||||
|
val (libraries, dependencyGraph, configMD5) = CacheConfiguration(dependencies, compilerConfiguration)
|
||||||
|
|
||||||
|
val modulePath = moduleName.toCanonicalPath()
|
||||||
|
val icCacheMap: Map<ModulePath, CacheInfo> = loadCacheInfo(icCachePaths).also {
|
||||||
|
it[modulePath] = CacheInfo.loadOrCreate(
|
||||||
|
cachePath,
|
||||||
|
moduleName,
|
||||||
|
configHash = configMD5
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualizeCacheForModule(
|
||||||
|
moduleName = modulePath,
|
||||||
|
cachePath = cachePath,
|
||||||
|
compilerConfiguration = compilerConfiguration,
|
||||||
|
configMD5 = configMD5,
|
||||||
|
libraries = libraries,
|
||||||
|
dependencyGraph = dependencyGraph,
|
||||||
|
icCacheMap = icCacheMap,
|
||||||
|
irFactory = irFactory,
|
||||||
|
mainArguments = mainArguments,
|
||||||
|
executor = executor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun KotlinCoreEnvironment.createPsiFile(file: File): KtFile {
|
private fun KotlinCoreEnvironment.createPsiFile(file: File): KtFile {
|
||||||
val psiManager = PsiManager.getInstance(project)
|
val psiManager = PsiManager.getInstance(project)
|
||||||
val fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) as CoreLocalFileSystem
|
val fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) as CoreLocalFileSystem
|
||||||
|
|||||||
+19
-23
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.gradle.util.normalizePath
|
|||||||
import org.junit.jupiter.api.Disabled
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.condition.DisabledIf
|
import org.junit.jupiter.api.condition.DisabledIf
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
@@ -178,7 +177,7 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
|||||||
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
||||||
|
|
||||||
build("compileDevelopmentExecutableKotlinJs") {
|
build("compileDevelopmentExecutableKotlinJs") {
|
||||||
val cacheDir = projectPath.resolve("app/build/klib/cache/lib/unspecified/")
|
val cacheDir = projectPath.resolve("app/build/klib/cache/lib/")
|
||||||
.toFile()
|
.toFile()
|
||||||
assertTrue("Lib cache size should be 2") {
|
assertTrue("Lib cache size should be 2") {
|
||||||
cacheDir
|
cacheDir
|
||||||
@@ -186,33 +185,30 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
|||||||
?.size == 2
|
?.size == 2
|
||||||
}
|
}
|
||||||
|
|
||||||
var lib: Boolean = false
|
var lib = false
|
||||||
var libOther: Boolean = false
|
var libOther = false
|
||||||
|
|
||||||
cacheDir.listFiles()!!
|
cacheDir.listFiles()!!
|
||||||
.forEach {
|
.forEach {
|
||||||
it.listFiles()!!
|
it.listFiles()!!
|
||||||
.single()
|
.filter { it.isFile }
|
||||||
.let {
|
.forEach {
|
||||||
it.listFiles()!!
|
val text = it.readText()
|
||||||
.filter { it.isFile }
|
if (text.contains("<kotlin-js-ir-ic-multiple-artifacts:lib>")) {
|
||||||
.forEach {
|
if (lib) {
|
||||||
val text = it.readText()
|
error("lib should be only once in cache")
|
||||||
if (text.contains("<kotlin-js-ir-ic-multiple-artifacts:lib>")) {
|
|
||||||
if (lib) {
|
|
||||||
error("lib should be only once in cache")
|
|
||||||
}
|
|
||||||
lib = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.contains("<kotlin-js-ir-ic-multiple-artifacts:lib_other>")) {
|
|
||||||
if (libOther) {
|
|
||||||
error("libOther should be only once in cache")
|
|
||||||
}
|
|
||||||
libOther = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
lib = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.contains("<kotlin-js-ir-ic-multiple-artifacts:lib_other>")) {
|
||||||
|
if (libOther) {
|
||||||
|
error("libOther should be only once in cache")
|
||||||
|
}
|
||||||
|
libOther = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue("lib and libOther should be once in cache") {
|
assertTrue("lib and libOther should be once in cache") {
|
||||||
|
|||||||
+38
-306
@@ -5,47 +5,27 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.targets.js.ir
|
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||||
|
|
||||||
import org.gradle.api.artifacts.Configuration
|
|
||||||
import org.gradle.api.artifacts.ResolvedArtifact
|
|
||||||
import org.gradle.api.artifacts.ResolvedDependency
|
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.DirectoryProperty
|
import org.gradle.api.file.DirectoryProperty
|
||||||
import org.gradle.api.file.FileCollection
|
|
||||||
import org.gradle.api.file.FileTree
|
import org.gradle.api.file.FileTree
|
||||||
import org.gradle.api.logging.Logger
|
|
||||||
import org.gradle.api.model.ObjectFactory
|
import org.gradle.api.model.ObjectFactory
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.work.InputChanges
|
import org.gradle.internal.hash.FileHasher
|
||||||
import org.gradle.workers.WorkerExecutor
|
import org.gradle.workers.WorkerExecutor
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||||
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
|
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
|
||||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
|
||||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
|
|
||||||
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptionsImpl
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptionsImpl
|
||||||
import org.jetbrains.kotlin.gradle.dsl.copyFreeCompilerArgsToArgs
|
|
||||||
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||||
import org.jetbrains.kotlin.gradle.report.ReportingSettings
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.DEVELOPMENT
|
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.DEVELOPMENT
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.PRODUCTION
|
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.PRODUCTION
|
||||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.SourceRoots
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.TaskOutputsBackup
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.getAllDependencies
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.getCacheDirectory
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.getDependenciesCacheDirectories
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||||
import org.jetbrains.kotlin.library.resolveSingleFileKlib
|
|
||||||
import org.jetbrains.kotlin.library.uniqueName
|
|
||||||
import org.jetbrains.kotlin.library.unresolvedDependencies
|
|
||||||
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
||||||
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -77,10 +57,18 @@ abstract class KotlinJsIrLink @Inject constructor(
|
|||||||
@get:Internal
|
@get:Internal
|
||||||
internal lateinit var compilation: KotlinCompilationData<*>
|
internal lateinit var compilation: KotlinCompilationData<*>
|
||||||
|
|
||||||
|
private val platformType by project.provider {
|
||||||
|
compilation.platformType
|
||||||
|
}
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
@get:Internal
|
@get:Internal
|
||||||
internal val propertiesProvider = PropertiesProvider(project)
|
internal val propertiesProvider = PropertiesProvider(project)
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
open val fileHasher: FileHasher
|
||||||
|
get() = throw UnsupportedOperationException()
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
internal val incrementalJsIr: Boolean = propertiesProvider.incrementalJsIr
|
internal val incrementalJsIr: Boolean = propertiesProvider.incrementalJsIr
|
||||||
|
|
||||||
@@ -117,12 +105,13 @@ abstract class KotlinJsIrLink @Inject constructor(
|
|||||||
return !entryModule.get().asFile.exists()
|
return !entryModule.get().asFile.exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun callCompilerAsync(
|
@get:Internal
|
||||||
args: K2JSCompilerArguments,
|
val rootCacheDirectory by lazy {
|
||||||
sourceRoots: SourceRoots,
|
buildDir.resolve("klib/cache")
|
||||||
inputChanges: InputChanges,
|
}
|
||||||
taskOutputsBackup: TaskOutputsBackup?
|
|
||||||
) {
|
override fun processArgs(args: K2JSCompilerArguments) {
|
||||||
|
super.processArgs(args)
|
||||||
KotlinBuildStatsService.applyIfInitialised {
|
KotlinBuildStatsService.applyIfInitialised {
|
||||||
it.report(BooleanMetrics.JS_IR_INCREMENTAL, incrementalJsIr)
|
it.report(BooleanMetrics.JS_IR_INCREMENTAL, incrementalJsIr)
|
||||||
val newArgs = K2JSCompilerArguments()
|
val newArgs = K2JSCompilerArguments()
|
||||||
@@ -136,55 +125,31 @@ abstract class KotlinJsIrLink @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (incrementalJsIr && mode == DEVELOPMENT) {
|
if (incrementalJsIr && mode == DEVELOPMENT) {
|
||||||
val visitedCompilations = mutableSetOf<KotlinCompilation<*>>()
|
args.cacheDirectories = args.libraries?.splitByPathSeparator()
|
||||||
|
?.map {
|
||||||
val cacheBuilder = CacheBuilder(
|
val file = File(it)
|
||||||
buildDir,
|
rootCacheDirectory
|
||||||
kotlinOptions,
|
.resolve(file.nameWithoutExtension)
|
||||||
libraryFilter,
|
.also {
|
||||||
compilerRunner.get(),
|
it.mkdirs()
|
||||||
{ createCompilerArgs() },
|
}
|
||||||
{ objects.fileCollection() },
|
.resolve(fileHasher.hash(file).toString())
|
||||||
defaultCompilerClasspath,
|
}
|
||||||
logger,
|
?.plus(rootCacheDirectory.resolve(entryModule.get().asFile.name))
|
||||||
reportingSettings()
|
?.let {
|
||||||
)
|
if (it.isNotEmpty())
|
||||||
val cacheArgs = visitCompilation(
|
it.joinToString(File.pathSeparator)
|
||||||
compilation as KotlinCompilation<*>,
|
else
|
||||||
cacheBuilder,
|
null
|
||||||
visitedCompilations,
|
}
|
||||||
)
|
|
||||||
|
|
||||||
args.cacheDirectories = cacheArgs.joinToString(File.pathSeparator) {
|
|
||||||
it.normalize().absolutePath
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.callCompilerAsync(args, sourceRoots, inputChanges, taskOutputsBackup)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun visitCompilation(
|
private fun String.splitByPathSeparator(): List<String> {
|
||||||
compilation: KotlinCompilation<*>,
|
return this.split(File.pathSeparator.toRegex())
|
||||||
cacheBuilder: CacheBuilder,
|
.dropLastWhile { it.isEmpty() }
|
||||||
visitedCompilations: MutableSet<KotlinCompilation<*>>,
|
.toTypedArray()
|
||||||
): List<File> {
|
.filterNot { it.isEmpty() }
|
||||||
if (compilation in visitedCompilations) return emptyList()
|
|
||||||
visitedCompilations.add(compilation)
|
|
||||||
|
|
||||||
val associatedCaches = compilation.associateWith
|
|
||||||
.flatMap {
|
|
||||||
visitCompilation(
|
|
||||||
it,
|
|
||||||
cacheBuilder,
|
|
||||||
visitedCompilations,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cacheBuilder
|
|
||||||
.buildCompilerArgs(
|
|
||||||
project.configurations.getByName(compilation.compileDependencyConfigurationName),
|
|
||||||
compilation.output.classesDirs,
|
|
||||||
associatedCaches
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupCompilerArgs(args: K2JSCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
|
override fun setupCompilerArgs(args: K2JSCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
|
||||||
@@ -204,10 +169,6 @@ abstract class KotlinJsIrLink @Inject constructor(
|
|||||||
super.setupCompilerArgs(args, defaultsOnly, ignoreClasspathResolutionErrors)
|
super.setupCompilerArgs(args, defaultsOnly, ignoreClasspathResolutionErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val platformType by project.provider {
|
|
||||||
compilation.platformType
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun KotlinJsOptions.configureOptions(vararg additionalCompilerArgs: String) {
|
private fun KotlinJsOptions.configureOptions(vararg additionalCompilerArgs: String) {
|
||||||
freeCompilerArgs += additionalCompilerArgs.toList() +
|
freeCompilerArgs += additionalCompilerArgs.toList() +
|
||||||
PRODUCE_JS +
|
PRODUCE_JS +
|
||||||
@@ -217,233 +178,4 @@ abstract class KotlinJsIrLink @Inject constructor(
|
|||||||
freeCompilerArgs += WASM_BACKEND
|
freeCompilerArgs += WASM_BACKEND
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
internal class CacheBuilder(
|
|
||||||
private val buildDir: File,
|
|
||||||
private val kotlinOptions: KotlinJsOptions,
|
|
||||||
private val libraryFilter: (File) -> Boolean,
|
|
||||||
private val compilerRunner: GradleCompilerRunner,
|
|
||||||
private val compilerArgsFactory: () -> K2JSCompilerArguments,
|
|
||||||
private val objectFilesFactory: () -> FileCollection,
|
|
||||||
private val computedCompilerClasspath: FileCollection,
|
|
||||||
private val logger: Logger,
|
|
||||||
private val reportingSettings: ReportingSettings
|
|
||||||
) {
|
|
||||||
val rootCacheDirectory by lazy {
|
|
||||||
buildDir.resolve("klib/cache")
|
|
||||||
}
|
|
||||||
|
|
||||||
private val visitedDependencies = mutableSetOf<ResolvedDependency>()
|
|
||||||
private val visitedFiles = mutableSetOf<File>()
|
|
||||||
private val visitedCacheDirectories = mutableSetOf<File>()
|
|
||||||
|
|
||||||
private val objectFiles
|
|
||||||
get() = objectFilesFactory()
|
|
||||||
|
|
||||||
fun buildCompilerArgs(
|
|
||||||
compileClasspath: Configuration,
|
|
||||||
additionalForResolve: FileCollection?,
|
|
||||||
associatedCaches: List<File>
|
|
||||||
): List<File> {
|
|
||||||
|
|
||||||
val allCacheDirectories = mutableListOf<File>()
|
|
||||||
val visitedDependenciesForCache = mutableSetOf<File>()
|
|
||||||
|
|
||||||
compileClasspath.resolvedConfiguration.firstLevelModuleDependencies
|
|
||||||
.forEach { dependency ->
|
|
||||||
ensureDependencyCached(
|
|
||||||
dependency
|
|
||||||
).forEach {
|
|
||||||
if (it !in visitedDependenciesForCache) {
|
|
||||||
visitedDependenciesForCache.add(it)
|
|
||||||
allCacheDirectories.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
additionalForResolve?.files?.forEach { file ->
|
|
||||||
val cacheDirectory = rootCacheDirectory.resolve(file.name)
|
|
||||||
cacheDirectory.mkdirs()
|
|
||||||
runCompiler(
|
|
||||||
file,
|
|
||||||
compileClasspath.files,
|
|
||||||
cacheDirectory,
|
|
||||||
(allCacheDirectories + associatedCaches).distinct()
|
|
||||||
)
|
|
||||||
allCacheDirectories.add(cacheDirectory)
|
|
||||||
}
|
|
||||||
|
|
||||||
return associatedCaches + allCacheDirectories
|
|
||||||
.filter { it !in visitedCacheDirectories }
|
|
||||||
.also { visitedCacheDirectories.addAll(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ensureDependencyCached(
|
|
||||||
dependency: ResolvedDependency
|
|
||||||
): List<File> {
|
|
||||||
if (dependency in visitedDependencies) {
|
|
||||||
return dependency.moduleArtifacts
|
|
||||||
.filter { libraryFilter(it.file) }
|
|
||||||
.map {
|
|
||||||
getCacheDirectory(rootCacheDirectory, dependency, it, { libraryFilter(it.file) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
visitedDependencies.add(dependency)
|
|
||||||
|
|
||||||
val depCacheDirs = dependency.children
|
|
||||||
.flatMap { ensureDependencyCached(it) }
|
|
||||||
.distinct()
|
|
||||||
|
|
||||||
val artifactsToAddToCache = dependency.moduleArtifacts
|
|
||||||
.filter { libraryFilter(it.file) }
|
|
||||||
|
|
||||||
if (artifactsToAddToCache.isEmpty()) return depCacheDirs
|
|
||||||
|
|
||||||
val dependenciesCacheDirectories = getDependenciesCacheDirectories(
|
|
||||||
rootCacheDirectory,
|
|
||||||
dependency,
|
|
||||||
libraryFilter = { libraryFilter(it.file) },
|
|
||||||
considerArtifact = true
|
|
||||||
) ?: return depCacheDirs
|
|
||||||
|
|
||||||
val nameMap: MutableMap<String, ResolvedArtifact> = mutableMapOf()
|
|
||||||
val depsMap: MutableMap<ResolvedArtifact, MutableList<ResolvedArtifact>> = mutableMapOf()
|
|
||||||
val cacheMap: MutableMap<ResolvedArtifact, File> = mutableMapOf()
|
|
||||||
var newOrderArtifactsToAddToCache = mutableListOf<ResolvedArtifact>()
|
|
||||||
|
|
||||||
if (artifactsToAddToCache.size > 1) {
|
|
||||||
artifactsToAddToCache.forEach {
|
|
||||||
val klib = resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File(it.file.absolutePath))
|
|
||||||
nameMap[klib.uniqueName] = it
|
|
||||||
}
|
|
||||||
artifactsToAddToCache.forEach { artifact ->
|
|
||||||
val klib = resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File(artifact.file.absolutePath))
|
|
||||||
klib.unresolvedDependencies
|
|
||||||
.forEach { depLib ->
|
|
||||||
val depName = depLib.path.substringAfterLast("/")
|
|
||||||
nameMap[depName]?.let {
|
|
||||||
val depsSet = depsMap.getOrPut(artifact) {
|
|
||||||
mutableListOf()
|
|
||||||
}
|
|
||||||
depsSet.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fun traverseDependency(library: ResolvedArtifact) {
|
|
||||||
depsMap[library]?.let {
|
|
||||||
it.forEach {
|
|
||||||
traverseDependency(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (library !in newOrderArtifactsToAddToCache) {
|
|
||||||
newOrderArtifactsToAddToCache.add(library)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
depsMap.forEach { key, deps ->
|
|
||||||
traverseDependency(key)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newOrderArtifactsToAddToCache = artifactsToAddToCache.toMutableList()
|
|
||||||
}
|
|
||||||
|
|
||||||
val additionalCacheDirs = mutableListOf<File>()
|
|
||||||
for (library in newOrderArtifactsToAddToCache) {
|
|
||||||
val cacheDirectory = getCacheDirectory(rootCacheDirectory, dependency, library, { libraryFilter(it.file) }).also {
|
|
||||||
additionalCacheDirs.add(it)
|
|
||||||
}
|
|
||||||
cacheDirectory.mkdirs()
|
|
||||||
cacheMap[library] = cacheDirectory
|
|
||||||
val additionalDependencies = depsMap[library] ?: emptyList()
|
|
||||||
val additionalCacheDirectories = if (additionalDependencies.isNotEmpty()) {
|
|
||||||
additionalDependencies.map { cacheMap.getValue(it) }
|
|
||||||
} else emptyList()
|
|
||||||
runCompiler(
|
|
||||||
library.file,
|
|
||||||
(getAllDependencies(dependency)
|
|
||||||
.flatMap { it.moduleArtifacts } + additionalDependencies)
|
|
||||||
.map { it.file },
|
|
||||||
cacheDirectory,
|
|
||||||
dependenciesCacheDirectories + additionalCacheDirectories
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return depCacheDirs + additionalCacheDirs
|
|
||||||
}
|
|
||||||
|
|
||||||
fun runCompiler(
|
|
||||||
file: File,
|
|
||||||
dependencies: Collection<File>,
|
|
||||||
cacheDirectory: File,
|
|
||||||
dependenciesCacheDirectories: Collection<File>
|
|
||||||
) {
|
|
||||||
if (file in visitedFiles) return
|
|
||||||
val compilerArgs = compilerArgsFactory()
|
|
||||||
kotlinOptions.copyFreeCompilerArgsToArgs(compilerArgs)
|
|
||||||
var prevIndex: Int? = null
|
|
||||||
compilerArgs.freeArgs = compilerArgs.freeArgs
|
|
||||||
.filterIndexed { index, arg ->
|
|
||||||
!listOf("-source-map-base-dirs", "-source-map-prefix").any {
|
|
||||||
if (prevIndex != null) {
|
|
||||||
prevIndex = null
|
|
||||||
return@any true
|
|
||||||
}
|
|
||||||
if (arg.startsWith(it)) {
|
|
||||||
prevIndex = index
|
|
||||||
return@any true
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compilerArgs.freeArgs = compilerArgs.freeArgs
|
|
||||||
.filterNot { arg ->
|
|
||||||
IGNORED_ARGS.any {
|
|
||||||
arg.startsWith(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visitedFiles.add(file)
|
|
||||||
compilerArgs.includes = file.normalize().absolutePath
|
|
||||||
compilerArgs.outputFile = cacheDirectory.normalize().absolutePath
|
|
||||||
if (dependenciesCacheDirectories.isNotEmpty()) {
|
|
||||||
compilerArgs.cacheDirectories = dependenciesCacheDirectories.joinToString(File.pathSeparator)
|
|
||||||
}
|
|
||||||
compilerArgs.irBuildCache = true
|
|
||||||
|
|
||||||
compilerArgs.libraries = dependencies
|
|
||||||
.filter { it.exists() && libraryFilter(it) }
|
|
||||||
.distinct()
|
|
||||||
.filterNot { it == file }
|
|
||||||
.joinToString(File.pathSeparator) { it.normalize().absolutePath }
|
|
||||||
|
|
||||||
val messageCollector = GradlePrintingMessageCollector(logger, false)
|
|
||||||
val outputItemCollector = OutputItemsCollectorImpl()
|
|
||||||
val environment = GradleCompilerEnvironment(
|
|
||||||
computedCompilerClasspath,
|
|
||||||
messageCollector,
|
|
||||||
outputItemCollector,
|
|
||||||
outputFiles = objectFiles.files.toList(),
|
|
||||||
reportingSettings = reportingSettings
|
|
||||||
)
|
|
||||||
|
|
||||||
compilerRunner
|
|
||||||
.runJsCompilerAsync(
|
|
||||||
emptyList(),
|
|
||||||
emptyList(),
|
|
||||||
compilerArgs,
|
|
||||||
environment,
|
|
||||||
null
|
|
||||||
)?.await()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val IGNORED_ARGS = listOf(
|
|
||||||
ENTRY_IR_MODULE,
|
|
||||||
PRODUCE_JS,
|
|
||||||
PRODUCE_UNZIPPED_KLIB,
|
|
||||||
ENABLE_DCE,
|
|
||||||
GENERATE_D_TS
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+7
@@ -1094,6 +1094,12 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
|||||||
override val incrementalProps: List<FileCollection>
|
override val incrementalProps: List<FileCollection>
|
||||||
get() = super.incrementalProps + listOf(friendDependencies)
|
get() = super.incrementalProps + listOf(friendDependencies)
|
||||||
|
|
||||||
|
open fun processArgs(
|
||||||
|
args: K2JSCompilerArguments
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun callCompilerAsync(
|
override fun callCompilerAsync(
|
||||||
args: K2JSCompilerArguments,
|
args: K2JSCompilerArguments,
|
||||||
sourceRoots: SourceRoots,
|
sourceRoots: SourceRoots,
|
||||||
@@ -1147,6 +1153,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
|||||||
reportingSettings = reportingSettings(),
|
reportingSettings = reportingSettings(),
|
||||||
incrementalCompilationEnvironment = icEnv
|
incrementalCompilationEnvironment = icEnv
|
||||||
)
|
)
|
||||||
|
processArgs(args)
|
||||||
compilerRunner.runJsCompilerAsync(
|
compilerRunner.runJsCompilerAsync(
|
||||||
sourceRoots.kotlinSourceFiles.files.toList(),
|
sourceRoots.kotlinSourceFiles.files.toList(),
|
||||||
commonSourceSet.toList(),
|
commonSourceSet.toList(),
|
||||||
|
|||||||
Reference in New Issue
Block a user