Fix performance problem in KotlinTargetsIndex creation

Creation of KotlinTargetsIndex takes too long,
even if Java project doesn't have any Kotlin files.
Remove function hasJsStdLib, as it takes too much time
because of recursively checking all dependencies (migrate to facets)
Also fix tests: Add Kotlin JS facet, where its needed

#KT-34351 Fixed
This commit is contained in:
Aleksei.Cherepanov
2021-01-18 15:15:13 +03:00
committed by TeamCityServer
parent bfc7eb7bab
commit c74f471a82
4 changed files with 28 additions and 41 deletions
@@ -195,7 +195,7 @@ open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() {
}
fun testKotlinJavaScriptProjectWithCustomOutputPaths() {
initProject(JS_STDLIB)
initProject(JS_STDLIB_WITHOUT_FACET)
buildAllModules().assertSuccessful()
checkOutputFilesList(File(workDir, "target"))
@@ -246,6 +246,7 @@ open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() {
fun testKotlinJavaScriptProjectWithDirectoryAsStdlib() {
initProject()
setupKotlinJSFacet()
val jslibJar = PathUtil.kotlinPathsForDistDirectory.jsStdLibJarPath
val jslibDir = File(workDir, "KotlinJavaScript")
try {
@@ -195,7 +195,7 @@ open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() {
}
fun testKotlinJavaScriptProjectWithCustomOutputPaths() {
initProject(JS_STDLIB)
initProject(JS_STDLIB_WITHOUT_FACET)
buildAllModules().assertSuccessful()
checkOutputFilesList(File(workDir, "target"))
@@ -246,6 +246,7 @@ open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() {
fun testKotlinJavaScriptProjectWithDirectoryAsStdlib() {
initProject()
setupKotlinJSFacet()
val jslibJar = PathUtil.kotlinPathsForDistDirectory.jsStdLibJarPath
val jslibDir = File(workDir, "KotlinJavaScript")
try {
@@ -9,6 +9,10 @@ import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.config.KotlinFacetSettings
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
import org.jetbrains.kotlin.platform.js.JsPlatforms
import java.io.File
import java.nio.file.Paths
@@ -51,6 +55,7 @@ abstract class KotlinJpsBuildTestBase : AbstractKotlinJpsBuildTestCase() {
NONE,
JVM_MOCK_RUNTIME,
JVM_FULL_RUNTIME,
JS_STDLIB_WITHOUT_FACET,
JS_STDLIB,
}
@@ -62,7 +67,24 @@ abstract class KotlinJpsBuildTestBase : AbstractKotlinJpsBuildTestCase() {
LibraryDependency.NONE -> {}
LibraryDependency.JVM_MOCK_RUNTIME -> addKotlinMockRuntimeDependency()
LibraryDependency.JVM_FULL_RUNTIME -> addKotlinStdlibDependency()
LibraryDependency.JS_STDLIB -> addKotlinJavaScriptStdlibDependency()
LibraryDependency.JS_STDLIB_WITHOUT_FACET -> addKotlinJavaScriptStdlibDependency()
LibraryDependency.JS_STDLIB -> {
addKotlinJavaScriptStdlibDependency()
setupKotlinJSFacet()
}
}
}
protected fun setupKotlinJSFacet() {
myProject.modules.forEach {
val facet = KotlinFacetSettings()
facet.compilerArguments = K2JSCompilerArguments()
facet.targetPlatform = JsPlatforms.defaultJsPlatform
it.container.setChild(
JpsKotlinFacetModuleExtension.KIND,
JpsKotlinFacetModuleExtension(facet)
)
}
}
@@ -8,18 +8,14 @@ package org.jetbrains.kotlin.jps.targets
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.library.JpsOrderRootType
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.build.KotlinChunk
import org.jetbrains.kotlin.jps.build.KotlinCompileContext
import org.jetbrains.kotlin.jps.build.ModuleBuildTarget
import org.jetbrains.kotlin.jps.model.platform
import org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider
import org.jetbrains.kotlin.platform.IdePlatformKind
import org.jetbrains.kotlin.platform.idePlatformKind
import org.jetbrains.kotlin.platform.impl.*
import org.jetbrains.kotlin.utils.LibraryUtils
import kotlin.system.measureTimeMillis
class KotlinTargetsIndex(
@@ -32,7 +28,6 @@ internal class KotlinTargetsIndexBuilder internal constructor(
private val uninitializedContext: KotlinCompileContext
) {
private val byJpsModuleBuildTarget = mutableMapOf<ModuleBuildTarget, KotlinModuleBuildTarget<*>>()
private val isKotlinJsStdlibJar = mutableMapOf<String, Boolean>()
private val chunks = mutableListOf<KotlinChunk>()
fun build(): KotlinTargetsIndex {
@@ -132,10 +127,9 @@ internal class KotlinTargetsIndexBuilder internal constructor(
return dependencies
}
private fun ensureLoaded(target: ModuleBuildTarget): KotlinModuleBuildTarget<*> {
return byJpsModuleBuildTarget.computeIfAbsent(target) {
val platform = target.module.platform?.idePlatformKind ?: detectTargetPlatform(target)
val platform = target.module.platform?.idePlatformKind ?: DefaultIdeTargetPlatformKindProvider.defaultPlatform.idePlatformKind
when {
platform.isCommon -> KotlinCommonModuleBuildTarget(uninitializedContext, target)
@@ -145,35 +139,4 @@ internal class KotlinTargetsIndexBuilder internal constructor(
}
}
}
/**
* Compatibility for KT-14082
* todo: remove when all projects migrated to facets
*/
private fun detectTargetPlatform(target: ModuleBuildTarget): IdePlatformKind<*> {
if (hasJsStdLib(target)) return JsIdePlatformKind
return DefaultIdeTargetPlatformKindProvider.defaultPlatform.idePlatformKind
}
private fun hasJsStdLib(target: ModuleBuildTarget): Boolean {
JpsJavaExtensionService.dependencies(target.module)
.recursively()
.exportedOnly()
.includedIn(JpsJavaClasspathKind.compile(target.isTests))
.libraries
.forEach { library ->
for (root in library.getRoots(JpsOrderRootType.COMPILED)) {
val url = root.url
val isKotlinJsLib = isKotlinJsStdlibJar.computeIfAbsent(url) {
LibraryUtils.isKotlinJavascriptStdLibrary(JpsPathUtil.urlToFile(url))
}
if (isKotlinJsLib) return true
}
}
return false
}
}