[Gradle, JS] Add libraries filter caching in compile task
Previously any compile task was honestly reading dependency metadata from filesystem to check whether it's K/JS module even if another compile task already tested this dependency. Now the result of check is cached in build service that is cleared after build finish. It can save many rebuild time on incremental compilation of complex projects. #KT-47154 Fixed
This commit is contained in:
+28
-2
@@ -16,6 +16,8 @@ import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.services.BuildService
|
||||
import org.gradle.api.services.BuildServiceParameters
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
@@ -57,6 +59,7 @@ import org.jetbrains.kotlin.incremental.ChangedFiles
|
||||
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
|
||||
import org.jetbrains.kotlin.utils.JsLibraryUtils
|
||||
import java.io.File
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.inject.Inject
|
||||
|
||||
const val KOTLIN_BUILD_DIR_NAME = "kotlin"
|
||||
@@ -616,6 +619,21 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
||||
}
|
||||
}
|
||||
).disallowChanges()
|
||||
val libraryCacheService = task.project.rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
"${LibraryFilterCachingService::class.java.canonicalName}_${LibraryFilterCachingService::class.java.classLoader.hashCode()}",
|
||||
LibraryFilterCachingService::class.java
|
||||
) {}
|
||||
task.libraryCache.set(libraryCacheService).also { task.libraryCache.disallowChanges() }
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class LibraryFilterCachingService : BuildService<BuildServiceParameters.None>, AutoCloseable {
|
||||
private val cache = ConcurrentHashMap<File, Boolean>()
|
||||
|
||||
fun getOrCompute(key: File, compute: (File) -> Boolean) = cache.computeIfAbsent(key, compute)
|
||||
|
||||
override fun close() {
|
||||
cache.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,8 +729,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
||||
// 1) purely pre-IR backend
|
||||
// 2) purely IR backend
|
||||
// 3) hybrid pre-IR and IR backend. Can only accept libraries with both JS and IR parts.
|
||||
@get:Internal
|
||||
protected val libraryFilter: (File) -> Boolean
|
||||
private val libraryFilterBody: (File) -> Boolean
|
||||
get() = if (kotlinOptions.isIrBackendEnabled()) {
|
||||
if (kotlinOptions.isPreIrBackendDisabled()) {
|
||||
::isKotlinLibrary
|
||||
@@ -723,6 +740,15 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
||||
JsLibraryUtils::isKotlinJavascriptLibrary
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal abstract val libraryCache: Property<LibraryFilterCachingService>
|
||||
|
||||
@get:Internal
|
||||
protected val libraryFilter: (File) -> Boolean
|
||||
get() = { file ->
|
||||
libraryCache.get().getOrCompute(file, libraryFilterBody)
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal val absolutePathProvider = project.projectDir.absolutePath
|
||||
|
||||
|
||||
Reference in New Issue
Block a user