diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index d46ec991bce..4a199d24deb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -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, AutoCloseable { + private val cache = ConcurrentHashMap() + + 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 + + @get:Internal + protected val libraryFilter: (File) -> Boolean + get() = { file -> + libraryCache.get().getOrCompute(file, libraryFilterBody) + } + @get:Internal internal val absolutePathProvider = project.projectDir.absolutePath