jps (refactor): reimplement KotlinModuleBuildTarget data binding using CompileContext
This commit is contained in:
@@ -40,6 +40,7 @@ import org.jetbrains.jps.cmdline.ProjectDescriptor
|
||||
import org.jetbrains.jps.incremental.*
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
||||
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
|
||||
@@ -17,23 +17,19 @@
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.JpsBuildTestCase
|
||||
import org.jetbrains.kotlin.jps.platforms.clearKotlinModuleBuildTargetDataBindings
|
||||
|
||||
abstract class BaseKotlinJpsBuildTestCase : JpsBuildTestCase() {
|
||||
@Throws(Exception::class)
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
JpsUtils.resetCaches()
|
||||
System.setProperty("kotlin.jps.tests", "true")
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun tearDown() {
|
||||
JpsUtils.resetCaches()
|
||||
System.clearProperty("kotlin.jps.tests")
|
||||
super.tearDown()
|
||||
myModel = null
|
||||
myBuildParams.clear()
|
||||
clearKotlinModuleBuildTargetDataBindings()
|
||||
}
|
||||
}
|
||||
@@ -64,9 +64,6 @@ import org.jetbrains.kotlin.jps.model.JpsKotlinCompilerSettings
|
||||
import org.jetbrains.kotlin.jps.build.KotlinJpsBuildTest.LibraryDependency.*
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.platforms.KotlinJsModuleBuildTarget
|
||||
import org.jetbrains.kotlin.jps.platforms.clearKotlinModuleBuildTargetDataBindings
|
||||
import org.jetbrains.kotlin.jps.platforms.kotlinData
|
||||
import org.jetbrains.kotlin.jps.platforms.productionBuildTarget
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -181,8 +178,6 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
originalProjectDir = projDirPath.toFile()
|
||||
workDir = AbstractKotlinJpsBuildTestCase.copyTestDataToTmpDir(originalProjectDir)
|
||||
orCreateProjectDir
|
||||
|
||||
JpsUtils.resetCaches()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
@@ -250,7 +245,7 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
buildAllModules().assertSuccessful()
|
||||
|
||||
checkOutputFilesList()
|
||||
checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME))
|
||||
checkWhen(touch("src/test1.kt"), null, pathsToDelete = k2jsOutput(PROJECT_NAME))
|
||||
}
|
||||
|
||||
private fun k2jsOutput(vararg moduleNames: String): Array<String> {
|
||||
@@ -259,11 +254,11 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
|
||||
myProject.modules.forEach {
|
||||
if (it.name in moduleNamesSet) {
|
||||
val productionTarget = it.productionBuildTarget.kotlinData as KotlinJsModuleBuildTarget
|
||||
list.add(toSystemIndependentName(productionTarget.outputFile.relativeTo(workDir).path))
|
||||
list.add(toSystemIndependentName(productionTarget.outputMetaFile.relativeTo(workDir).path))
|
||||
val outputDir = it.productionBuildTarget.outputDir!!
|
||||
list.add(toSystemIndependentName(File("$outputDir/${it.name}.js").relativeTo(workDir).path))
|
||||
list.add(toSystemIndependentName(File("$outputDir/${it.name}.meta.js").relativeTo(workDir).path))
|
||||
|
||||
val kjsmFiles = productionTarget.outputDir.walk()
|
||||
val kjsmFiles = outputDir.walk()
|
||||
.filter { it.isFile && it.extension.equals("kjsm", ignoreCase = true) }
|
||||
|
||||
list.addAll(kjsmFiles.map { toSystemIndependentName(it.relativeTo(workDir).path) })
|
||||
@@ -1068,8 +1063,6 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
}
|
||||
|
||||
protected fun checkWhen(actions: Array<Action>, pathsToCompile: Array<String>?, pathsToDelete: Array<String>?) {
|
||||
clearKotlinModuleBuildTargetDataBindings()
|
||||
|
||||
for (action in actions) {
|
||||
action.apply()
|
||||
}
|
||||
|
||||
+20
-14
@@ -62,8 +62,11 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion.TEST_IS_PRE_RELEASE_SYS
|
||||
import org.jetbrains.kotlin.incremental.CacheVersion
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.withIC
|
||||
import org.jetbrains.kotlin.jps.JpsKotlinCompilerSettings
|
||||
import org.jetbrains.kotlin.jps.model.JpsKotlinCompilerSettings
|
||||
import org.jetbrains.kotlin.jps.build.KotlinJpsBuildTest.LibraryDependency.*
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.platforms.productionBuildTarget
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
@@ -174,8 +177,6 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
originalProjectDir = projDirPath.toFile()
|
||||
workDir = AbstractKotlinJpsBuildTestCase.copyTestDataToTmpDir(originalProjectDir)
|
||||
orCreateProjectDir
|
||||
|
||||
JpsUtils.resetCaches()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
@@ -243,21 +244,26 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
buildAllModules().assertSuccessful()
|
||||
|
||||
checkOutputFilesList()
|
||||
checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME))
|
||||
checkWhen(touch("src/test1.kt"), null, pathsToDelete = k2jsOutput(PROJECT_NAME))
|
||||
}
|
||||
|
||||
private fun k2jsOutput(vararg moduleNames: String): Array<String> {
|
||||
val list = arrayListOf<String>()
|
||||
for (moduleName in moduleNames) {
|
||||
val outputDir = File("out/production/$moduleName")
|
||||
list.add(toSystemIndependentName(JpsJsModuleUtils.getOutputFile(outputDir, moduleName, false).path))
|
||||
list.add(toSystemIndependentName(JpsJsModuleUtils.getOutputMetaFile(outputDir, moduleName, false).path))
|
||||
val moduleNamesSet = moduleNames.toSet()
|
||||
val list = mutableListOf<String>()
|
||||
|
||||
val kjsmFiles = File(workDir, outputDir.path).walk()
|
||||
.filter { it.isFile && it.extension.equals("kjsm", ignoreCase = true) }
|
||||
list.addAll(kjsmFiles.map { toSystemIndependentName(it.relativeTo(workDir).path) })
|
||||
myProject.modules.forEach {
|
||||
if (it.name in moduleNamesSet) {
|
||||
val outputDir = it.productionBuildTarget.outputDir!!
|
||||
list.add(toSystemIndependentName(File("$outputDir/${it.name}.js").relativeTo(workDir).path))
|
||||
list.add(toSystemIndependentName(File("$outputDir/${it.name}.meta.js").relativeTo(workDir).path))
|
||||
|
||||
val kjsmFiles = outputDir.walk()
|
||||
.filter { it.isFile && it.extension.equals("kjsm", ignoreCase = true) }
|
||||
|
||||
list.addAll(kjsmFiles.map { toSystemIndependentName(it.relativeTo(workDir).path) })
|
||||
}
|
||||
}
|
||||
|
||||
return list.toTypedArray()
|
||||
}
|
||||
|
||||
@@ -515,9 +521,9 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
|
||||
assertEquals(1, myProject.modules.size)
|
||||
val module = myProject.modules.first()
|
||||
val args = JpsKotlinCompilerSettings.getCommonCompilerArguments(module)
|
||||
val args = module.kotlinCompilerArguments
|
||||
args.apiVersion = "1.2"
|
||||
JpsKotlinCompilerSettings.setCommonCompilerArguments(myProject, args)
|
||||
myProject.kotlinCommonCompilerArguments = args
|
||||
|
||||
buildAllModules().assertSuccessful()
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget;
|
||||
import org.jetbrains.jps.model.java.JpsJavaClasspathKind;
|
||||
import org.jetbrains.jps.model.java.JpsJavaDependenciesEnumerator;
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
|
||||
import org.jetbrains.jps.model.library.JpsLibrary;
|
||||
import org.jetbrains.jps.model.library.JpsLibraryRoot;
|
||||
import org.jetbrains.jps.model.library.JpsOrderRootType;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
import org.jetbrains.kotlin.config.TargetPlatformKind;
|
||||
import org.jetbrains.kotlin.jps.model.ModuleSettingsKt;
|
||||
import org.jetbrains.kotlin.utils.LibraryUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
class JpsUtils {
|
||||
private static final Map<ModuleBuildTarget, Boolean> IS_KOTLIN_JS_MODULE_CACHE = new ConcurrentHashMap<ModuleBuildTarget, Boolean>();
|
||||
private static final Map<String, Boolean> IS_KOTLIN_JS_STDLIB_JAR_CACHE = new ConcurrentHashMap<String, Boolean>();
|
||||
|
||||
private JpsUtils() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static JpsJavaDependenciesEnumerator getAllDependencies(@NotNull ModuleBuildTarget target) {
|
||||
return JpsJavaExtensionService.dependencies(target.getModule()).recursively().exportedOnly()
|
||||
.includedIn(JpsJavaClasspathKind.compile(target.isTests()));
|
||||
}
|
||||
|
||||
static boolean isJsKotlinModule(@NotNull ModuleBuildTarget target) {
|
||||
Boolean cachedValue = IS_KOTLIN_JS_MODULE_CACHE.get(target);
|
||||
if (cachedValue != null) return cachedValue;
|
||||
|
||||
boolean isKotlinJsModule = isJsKotlinModuleImpl(target);
|
||||
IS_KOTLIN_JS_MODULE_CACHE.put(target, isKotlinJsModule);
|
||||
|
||||
return isKotlinJsModule;
|
||||
}
|
||||
|
||||
private static boolean isJsKotlinModuleImpl(@NotNull ModuleBuildTarget target) {
|
||||
TargetPlatformKind<?> targetPlatform = ModuleSettingsKt.getTargetPlatform(target.getModule());
|
||||
if (targetPlatform != null) return targetPlatform == TargetPlatformKind.JavaScript.INSTANCE;
|
||||
|
||||
Set<JpsLibrary> libraries = getAllDependencies(target).getLibraries();
|
||||
for (JpsLibrary library : libraries) {
|
||||
for (JpsLibraryRoot root : library.getRoots(JpsOrderRootType.COMPILED)) {
|
||||
String url = root.getUrl();
|
||||
|
||||
Boolean cachedValue = IS_KOTLIN_JS_STDLIB_JAR_CACHE.get(url);
|
||||
if (cachedValue != null) {
|
||||
if (cachedValue.booleanValue()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isKotlinJavascriptStdLibrary = LibraryUtils.isKotlinJavascriptStdLibrary(JpsPathUtil.urlToFile(url));
|
||||
IS_KOTLIN_JS_STDLIB_JAR_CACHE.put(url, isKotlinJavascriptStdLibrary);
|
||||
if (isKotlinJavascriptStdLibrary) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
static void resetCaches() {
|
||||
IS_KOTLIN_JS_MODULE_CACHE.clear();
|
||||
IS_KOTLIN_JS_STDLIB_JAR_CACHE.clear();
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.incremental.*
|
||||
import org.jetbrains.kotlin.jps.platforms.KotlinJsModuleBuildTarget
|
||||
import org.jetbrains.kotlin.jps.platforms.kotlinData
|
||||
import org.jetbrains.kotlin.jps.platforms.kotlinBuildTargets
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -213,7 +213,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
val allVersions = cacheVersionsProvider.allVersions(targets)
|
||||
val actions = allVersions.map { it.checkVersion() }.toMutableSet()
|
||||
|
||||
if (chunk.representativeTarget().kotlinData !is KotlinJsModuleBuildTarget) {
|
||||
val kotlinModuleBuilderTarget = context.kotlinBuildTargets[chunk.representativeTarget()]
|
||||
if (kotlinModuleBuilderTarget !is KotlinJsModuleBuildTarget) {
|
||||
val args = compilerArgumentsForChunk(chunk)
|
||||
val currentBuildMetaInfo = JvmBuildMetaInfo(args)
|
||||
|
||||
@@ -309,7 +310,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
fsOperations: FSOperationsHelper
|
||||
): ModuleLevelBuilder.ExitCode {
|
||||
// Workaround for Android Studio
|
||||
if (!JavaBuilder.IS_ENABLED[context, true] && !JpsUtils.isJsKotlinModule(chunk.representativeTarget())) {
|
||||
val isJsModule = context.kotlinBuildTargets[chunk.representativeTarget()] is KotlinJsModuleBuildTarget
|
||||
if (!JavaBuilder.IS_ENABLED[context, true] && !isJsModule) {
|
||||
messageCollector.report(INFO, "Kotlin JPS plugin is disabled")
|
||||
return NOTHING_DONE
|
||||
}
|
||||
@@ -377,7 +379,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
LOG.info("Compiled successfully")
|
||||
}
|
||||
|
||||
val generatedFiles = getGeneratedFiles(chunk, environment.outputItemsCollector)
|
||||
val generatedFiles = getGeneratedFiles(context, chunk, environment.outputItemsCollector)
|
||||
|
||||
registerOutputItems(outputConsumer, generatedFiles)
|
||||
saveVersions(context, chunk, commonArguments)
|
||||
@@ -391,7 +393,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
rebuildAfterCacheVersionChanged.clean(target)
|
||||
}
|
||||
|
||||
chunk.representativeTarget().kotlinData?.doAfterBuild()
|
||||
chunk.targets.forEach {
|
||||
context.kotlinBuildTargets[it]?.doAfterBuild()
|
||||
}
|
||||
|
||||
updateJavaMappings(chunk, context, dirtyFilesHolder, filesToCompile, generatedFiles, incrementalCaches)
|
||||
|
||||
@@ -497,7 +501,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
val cacheVersionsProvider = CacheVersionProvider(dataManager.dataPaths)
|
||||
cacheVersionsProvider.allVersions(targets).forEach { it.saveIfNeeded() }
|
||||
|
||||
if (!JpsUtils.isJsKotlinModule(chunk.representativeTarget())) {
|
||||
val isJsModule = context.kotlinBuildTargets[chunk.representativeTarget()] is KotlinJsModuleBuildTarget
|
||||
if (!isJsModule) {
|
||||
val jvmBuildMetaInfo = JvmBuildMetaInfo(commonArguments)
|
||||
val serializedMetaInfo = JvmBuildMetaInfo.serializeToString(jvmBuildMetaInfo)
|
||||
|
||||
@@ -549,9 +554,10 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
}
|
||||
}
|
||||
|
||||
val isDoneSomething = representativeTarget.kotlinData?.compileModuleChunk(
|
||||
allCompiledFiles, chunk, commonArguments, context,
|
||||
dirtyFilesHolder, environment, filesToCompile, fsOperations
|
||||
val kotlinModuleBuilderTarget = context.kotlinBuildTargets[representativeTarget]
|
||||
val isDoneSomething = kotlinModuleBuilderTarget?.compileModuleChunk(
|
||||
allCompiledFiles, chunk, commonArguments, dirtyFilesHolder,
|
||||
environment, filesToCompile, fsOperations
|
||||
) ?: false
|
||||
|
||||
return if (isDoneSomething) environment.outputItemsCollector else null
|
||||
@@ -567,7 +573,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
register(LookupTracker::class.java, lookupTracker)
|
||||
register(
|
||||
IncrementalCompilationComponents::class.java,
|
||||
IncrementalCompilationComponentsImpl(incrementalCaches.mapKeys { it.key.kotlinData!!.targetId })
|
||||
IncrementalCompilationComponentsImpl(incrementalCaches.mapKeys { context.kotlinBuildTargets[it.key]!!.targetId })
|
||||
)
|
||||
register(CompilationCanceledStatus::class.java, object : CompilationCanceledStatus {
|
||||
override fun checkCanceled() {
|
||||
@@ -617,6 +623,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
}
|
||||
|
||||
private fun getGeneratedFiles(
|
||||
context: CompileContext,
|
||||
chunk: ModuleChunk,
|
||||
outputItemCollector: OutputItemsCollectorImpl
|
||||
): Map<ModuleBuildTarget, List<GeneratedFile>> {
|
||||
@@ -624,7 +631,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
val sourceToTarget = HashMap<File, ModuleBuildTarget>()
|
||||
if (chunk.targets.size > 1) {
|
||||
for (target in chunk.targets) {
|
||||
target.kotlinData?.sources?.forEach {
|
||||
context.kotlinBuildTargets[target]?.sources?.forEach {
|
||||
sourceToTarget[it] = target
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.builders.DirtyFilesHolder
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||
import com.intellij.openapi.compiler.CompileContext as JpsCompileContext
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.FSOperations
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
@@ -21,14 +22,13 @@ import org.jetbrains.kotlin.jps.model.k2MetadataCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
|
||||
import java.io.File
|
||||
|
||||
class KotlinCommonModuleBuildTarget(jpsModuleBuildTarget: ModuleBuildTarget) :
|
||||
KotlinModuleBuilderTarget(jpsModuleBuildTarget) {
|
||||
class KotlinCommonModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
|
||||
KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) {
|
||||
|
||||
override fun compileModuleChunk(
|
||||
allCompiledFiles: MutableSet<File>,
|
||||
chunk: ModuleChunk,
|
||||
commonArguments: CommonCompilerArguments,
|
||||
context: CompileContext,
|
||||
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
||||
environment: JpsCompilerEnvironment,
|
||||
filesToCompile: MultiMap<ModuleBuildTarget, File>,
|
||||
|
||||
@@ -28,12 +28,13 @@ import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.META_JS_SUFFIX
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
|
||||
class KotlinJsModuleBuildTarget(jpsModuleBuildTarget: ModuleBuildTarget) : KotlinModuleBuilderTarget(jpsModuleBuildTarget) {
|
||||
class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
|
||||
KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) {
|
||||
|
||||
override fun compileModuleChunk(
|
||||
allCompiledFiles: MutableSet<File>,
|
||||
chunk: ModuleChunk,
|
||||
commonArguments: CommonCompilerArguments,
|
||||
context: CompileContext,
|
||||
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
||||
environment: JpsCompilerEnvironment,
|
||||
filesToCompile: MultiMap<ModuleBuildTarget, File>,
|
||||
@@ -139,7 +140,7 @@ class KotlinJsModuleBuildTarget(jpsModuleBuildTarget: ModuleBuildTarget) : Kotli
|
||||
result: MutableList<String>,
|
||||
isTests: Boolean
|
||||
) {
|
||||
val dependencyBuildTarget = ModuleBuildTarget(module, isTests).kotlinData
|
||||
val dependencyBuildTarget = context.kotlinBuildTargets[ModuleBuildTarget(module, isTests)]
|
||||
|
||||
if (dependencyBuildTarget != this@KotlinJsModuleBuildTarget &&
|
||||
dependencyBuildTarget is KotlinJsModuleBuildTarget &&
|
||||
|
||||
@@ -34,12 +34,13 @@ import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
class KotlinJvmModuleBuildTarget(jpsModuleBuildTarget: ModuleBuildTarget) : KotlinModuleBuilderTarget(jpsModuleBuildTarget) {
|
||||
class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
|
||||
KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) {
|
||||
|
||||
override fun compileModuleChunk(
|
||||
allCompiledFiles: MutableSet<File>,
|
||||
chunk: ModuleChunk,
|
||||
commonArguments: CommonCompilerArguments,
|
||||
context: CompileContext,
|
||||
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
||||
environment: JpsCompilerEnvironment,
|
||||
filesToCompile: MultiMap<ModuleBuildTarget, File>,
|
||||
@@ -111,7 +112,7 @@ class KotlinJvmModuleBuildTarget(jpsModuleBuildTarget: ModuleBuildTarget) : Kotl
|
||||
|
||||
var noSources = true
|
||||
|
||||
val targets = chunk.targets.mapNotNull { it.kotlinData as? KotlinJvmModuleBuildTarget }
|
||||
val targets = chunk.targets.mapNotNull { this.context.kotlinBuildTargets[it] as? KotlinJvmModuleBuildTarget }
|
||||
|
||||
val outputDirs = targets.map { it.outputDir }.toSet()
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.io.File
|
||||
/**
|
||||
* Properties and actions for Kotlin test / production module build target.
|
||||
*/
|
||||
abstract class KotlinModuleBuilderTarget(val jpsModuleBuildTarget: ModuleBuildTarget) {
|
||||
abstract class KotlinModuleBuilderTarget(val context: CompileContext, val jpsModuleBuildTarget: ModuleBuildTarget) {
|
||||
val module: JpsModule
|
||||
get() = jpsModuleBuildTarget.module
|
||||
|
||||
@@ -66,8 +66,8 @@ abstract class KotlinModuleBuilderTarget(val jpsModuleBuildTarget: ModuleBuildTa
|
||||
val result = mutableListOf<KotlinModuleBuilderTarget>()
|
||||
|
||||
if (isTests) {
|
||||
result.addIfNotNull(module.productionBuildTarget.kotlinData)
|
||||
result.addIfNotNull(relatedProductionModule?.productionBuildTarget?.kotlinData)
|
||||
result.addIfNotNull(context.kotlinBuildTargets[module.productionBuildTarget])
|
||||
result.addIfNotNull(context.kotlinBuildTargets[relatedProductionModule?.productionBuildTarget])
|
||||
}
|
||||
|
||||
return result.filter { it.sources.isNotEmpty() }
|
||||
@@ -95,7 +95,7 @@ abstract class KotlinModuleBuilderTarget(val jpsModuleBuildTarget: ModuleBuildTa
|
||||
|
||||
return allDependencies.modules
|
||||
.filter { it.name in implementedModuleNames }
|
||||
.map { ModuleBuildTarget(it, isTests).kotlinData!! }
|
||||
.map { context.kotlinBuildTargets[ModuleBuildTarget(it, isTests)]!! }
|
||||
}
|
||||
|
||||
val sources by lazy {
|
||||
@@ -134,7 +134,6 @@ abstract class KotlinModuleBuilderTarget(val jpsModuleBuildTarget: ModuleBuildTa
|
||||
allCompiledFiles: MutableSet<File>,
|
||||
chunk: ModuleChunk,
|
||||
commonArguments: CommonCompilerArguments,
|
||||
context: CompileContext,
|
||||
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
||||
environment: JpsCompilerEnvironment,
|
||||
filesToCompile: MultiMap<ModuleBuildTarget, File>,
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.jps.platforms
|
||||
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import com.intellij.openapi.util.Key
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.jps.model.java.JpsJavaModuleType
|
||||
import org.jetbrains.jps.model.library.JpsOrderRootType
|
||||
@@ -26,50 +27,68 @@ val JpsModule.productionBuildTarget
|
||||
val JpsModule.testBuildTarget
|
||||
get() = ModuleBuildTarget(this, true)
|
||||
|
||||
private val kotlinBuildTargetsData = ConcurrentHashMap<ModuleBuildTarget, KotlinModuleBuilderTarget>()
|
||||
private val kotlinBuildTargetsCompileContextKey = Key<KotlinBuildTargets>("kotlinBuildTargets")
|
||||
|
||||
val ModuleBuildTarget.kotlinData: KotlinModuleBuilderTarget?
|
||||
val CompileContext.kotlinBuildTargets: KotlinBuildTargets
|
||||
get() {
|
||||
if (module.moduleType != JpsJavaModuleType.INSTANCE) return null
|
||||
val value = getUserData(kotlinBuildTargetsCompileContextKey)
|
||||
if (value != null) return value
|
||||
|
||||
return kotlinBuildTargetsData.computeIfAbsent(this) {
|
||||
when (module.targetPlatform ?: detectTargetPlatform()) {
|
||||
is TargetPlatformKind.Common -> KotlinCommonModuleBuildTarget(this)
|
||||
is TargetPlatformKind.JavaScript -> KotlinJsModuleBuildTarget(this)
|
||||
is TargetPlatformKind.Jvm -> KotlinJvmModuleBuildTarget(this)
|
||||
synchronized(this) {
|
||||
val actualValue = getUserData(kotlinBuildTargetsCompileContextKey)
|
||||
if (actualValue != null) return actualValue
|
||||
|
||||
val newValue = KotlinBuildTargets(this)
|
||||
putUserData(kotlinBuildTargetsCompileContextKey, newValue)
|
||||
return newValue
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinBuildTargets internal constructor(val compileContext: CompileContext) {
|
||||
private val byJpsModuleBuildTarget = ConcurrentHashMap<ModuleBuildTarget, KotlinModuleBuilderTarget>()
|
||||
private val isKotlinJsStdlibJar = ConcurrentHashMap<String, Boolean>()
|
||||
|
||||
@JvmName("getNullable")
|
||||
operator fun get(target: ModuleBuildTarget?): KotlinModuleBuilderTarget? {
|
||||
if (target == null) return null
|
||||
return get(target)
|
||||
}
|
||||
|
||||
operator fun get(target: ModuleBuildTarget): KotlinModuleBuilderTarget? {
|
||||
if (target.module.moduleType != JpsJavaModuleType.INSTANCE) return null
|
||||
|
||||
return byJpsModuleBuildTarget.computeIfAbsent(target) {
|
||||
when (target.module.targetPlatform ?: detectTargetPlatform(target)) {
|
||||
is TargetPlatformKind.Common -> KotlinCommonModuleBuildTarget(compileContext, target)
|
||||
is TargetPlatformKind.JavaScript -> KotlinJsModuleBuildTarget(compileContext, target)
|
||||
is TargetPlatformKind.Jvm -> KotlinJvmModuleBuildTarget(compileContext, target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compatibility for KT-14082
|
||||
* todo: remove when all projects migrated to facets
|
||||
*/
|
||||
private fun ModuleBuildTarget.detectTargetPlatform(): TargetPlatformKind<*> {
|
||||
if (hasJsStdLib()) return TargetPlatformKind.JavaScript
|
||||
/**
|
||||
* Compatibility for KT-14082
|
||||
* todo: remove when all projects migrated to facets
|
||||
*/
|
||||
private fun detectTargetPlatform(target: ModuleBuildTarget): TargetPlatformKind<*> {
|
||||
if (hasJsStdLib(target)) return TargetPlatformKind.JavaScript
|
||||
|
||||
return TargetPlatformKind.DEFAULT_PLATFORM
|
||||
}
|
||||
|
||||
private val IS_KOTLIN_JS_STDLIB_JAR_CACHE = ConcurrentHashMap<String, Boolean>()
|
||||
|
||||
private fun ModuleBuildTarget.hasJsStdLib(): Boolean {
|
||||
KotlinJvmModuleBuildTarget(this).allDependencies.libraries.forEach { library ->
|
||||
for (root in library.getRoots(JpsOrderRootType.COMPILED)) {
|
||||
val url = root.url
|
||||
|
||||
val isKotlinJsLib = IS_KOTLIN_JS_STDLIB_JAR_CACHE.computeIfAbsent(url) {
|
||||
LibraryUtils.isKotlinJavascriptStdLibrary(JpsPathUtil.urlToFile(url))
|
||||
}
|
||||
|
||||
if (isKotlinJsLib) return true
|
||||
}
|
||||
return TargetPlatformKind.DEFAULT_PLATFORM
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
private fun hasJsStdLib(target: ModuleBuildTarget): Boolean {
|
||||
KotlinJvmModuleBuildTarget(compileContext, target).allDependencies.libraries.forEach { library ->
|
||||
for (root in library.getRoots(JpsOrderRootType.COMPILED)) {
|
||||
val url = root.url
|
||||
|
||||
@TestOnly
|
||||
internal fun clearKotlinModuleBuildTargetDataBindings() {
|
||||
kotlinBuildTargetsData.clear()
|
||||
val isKotlinJsLib = isKotlinJsStdlibJar.computeIfAbsent(url) {
|
||||
LibraryUtils.isKotlinJavascriptStdLibrary(JpsPathUtil.urlToFile(url))
|
||||
}
|
||||
|
||||
if (isKotlinJsLib) return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user