jps: support multiplatform incremental compilation for jvm and js

- support common modules metadata compilation under flag (it is not required since all common source roots are included transitively for now)
- introduce expect actual tracker in jps: move implementation from gradle to build-common
- support js incremental compilation: move implementation from gradle to build-common
This commit is contained in:
Sergey Rostov
2018-04-03 13:00:06 +03:00
parent 4a6554a36d
commit 0eee2729cd
89 changed files with 5829 additions and 870 deletions
@@ -25,24 +25,41 @@ import org.jetbrains.kotlin.metadata.deserialization.supertypes
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import java.io.File
import java.util.*
/**
* Incremental cache common for JVM and JS
* Incremental cache common for JVM and JS, ClassName type aware
*/
abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOwner(workingDir) {
interface IncrementalCacheCommon {
val thisWithDependentCaches: Iterable<AbstractIncrementalCache<*>>
fun classesFqNamesBySources(files: Iterable<File>): Collection<FqName>
fun getSubtypesOf(className: FqName): Sequence<FqName>
fun getSourceFileIfClass(fqName: FqName): File?
fun markDirty(removedAndCompiledSources: Collection<File>)
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
fun clearComplementaryFilesMapping(dirtyFiles: Collection<File>): Collection<File>
fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl)
fun dump(): String
}
/**
* Incremental cache common for JVM and JS for specifit ClassName type
*/
abstract class AbstractIncrementalCache<ClassName>(workingDir: File) : BasicMapsOwner(workingDir), IncrementalCacheCommon {
companion object {
private val SUBTYPES = "subtypes"
private val SUPERTYPES = "supertypes"
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source"
private val COMPLEMENTARY_FILES = "complementary-files"
@JvmStatic protected val SOURCE_TO_CLASSES = "source-to-classes"
@JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
}
private val dependents = arrayListOf<IncrementalCacheCommon<ClassName>>()
fun addDependentCache(cache: IncrementalCacheCommon<ClassName>) {
private val dependents = arrayListOf<AbstractIncrementalCache<ClassName>>()
fun addDependentCache(cache: AbstractIncrementalCache<ClassName>) {
dependents.add(cache)
}
val thisWithDependentCaches: Iterable<IncrementalCacheCommon<ClassName>> by lazy {
override val thisWithDependentCaches: Iterable<AbstractIncrementalCache<ClassName>> by lazy {
val result = arrayListOf(this)
result.addAll(dependents)
result
@@ -54,16 +71,24 @@ abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOw
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<ClassName>
fun classesFqNamesBySources(files: Iterable<File>): Collection<FqName> =
/**
* A file X is a complementary to a file Y if they contain corresponding expect/actual declarations.
* Complementary files should be compiled together during IC so the compiler does not complain
* about missing parts.
* TODO: provide a better solution (maintain an index of expect/actual declarations akin to IncrementalPackagePartProvider)
*/
private val complementaryFilesMap = registerMap(FilesMap(COMPLEMENTARY_FILES.storageFile))
override fun classesFqNamesBySources(files: Iterable<File>): Collection<FqName> =
files.flatMapTo(HashSet()) { sourceToClassesMap.getFqNames(it) }
fun getSubtypesOf(className: FqName): Sequence<FqName> =
override fun getSubtypesOf(className: FqName): Sequence<FqName> =
subtypesMap[className].asSequence()
fun getSourceFileIfClass(fqName: FqName): File? =
override fun getSourceFileIfClass(fqName: FqName): File? =
classFqNameToSourceMap[fqName]
open fun markDirty(removedAndCompiledSources: Collection<File>) {
override fun markDirty(removedAndCompiledSources: Collection<File>) {
for (sourceFile in removedAndCompiledSources) {
val classes = sourceToClassesMap[sourceFile]
classes.forEach {
@@ -90,8 +115,6 @@ abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOw
classFqNameToSourceMap[child] = srcFile
}
abstract fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>, changesCollector: ChangesCollector) {
if (removedClasses.isEmpty()) return
@@ -141,4 +164,29 @@ abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOw
override fun dumpValue(value: String) = value
}
override fun clearComplementaryFilesMapping(dirtyFiles: Collection<File>): Collection<File> {
val complementaryFiles = HashSet<File>()
val filesQueue = ArrayDeque(dirtyFiles)
while (filesQueue.isNotEmpty()) {
val file = filesQueue.pollFirst()
complementaryFilesMap.remove(file).filterTo(filesQueue) { complementaryFiles.add(it) }
}
complementaryFiles.removeAll(dirtyFiles)
return complementaryFiles
}
override fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl) {
val actualToExpect = hashMapOf<File, MutableSet<File>>()
for ((expect, actuals) in expectActualTracker.expectToActualMap) {
for (actual in actuals) {
actualToExpect.getOrPut(actual) { hashSetOf() }.add(expect)
}
complementaryFilesMap[expect] = actuals
}
for ((actual, expects) in actualToExpect) {
complementaryFilesMap[actual] = expects
}
}
}
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import java.io.File
import java.io.IOException
private val NORMAL_VERSION = 8
private val DATA_CONTAINER_VERSION = 2
private val NORMAL_VERSION = 9
private val DATA_CONTAINER_VERSION = 3
private val NORMAL_VERSION_FILE_NAME = "format-version.txt"
private val DATA_CONTAINER_VERSION_FILE_NAME = "data-container-format-version.txt"
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import java.io.File
class ExpectActualTrackerImpl : ExpectActualTracker {
private val expectToActual = hashMapOf<File, MutableSet<File>>()
val expectToActualMap: Map<File, Set<File>>
get() = expectToActual
override fun report(expectedFile: File, actualFile: File) {
expectToActual.getOrPut(expectedFile) { hashSetOf() }.add(actualFile)
}
}
@@ -36,7 +36,7 @@ import java.io.DataInput
import java.io.DataOutput
import java.io.File
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon<FqName>(cachesDir) {
open class IncrementalJsCache(cachesDir: File) : AbstractIncrementalCache<FqName>(cachesDir) {
companion object {
private val TRANSLATION_RESULT_MAP = "translation-result"
private val INLINE_FUNCTIONS = "inline-functions"
@@ -44,7 +44,7 @@ val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache(
private val targetDataRoot: File,
targetOutputDir: File?
) : IncrementalCacheCommon<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
) : AbstractIncrementalCache<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
companion object {
private val PROTO_MAP = "proto"
private val CONSTANTS_MAP = "constants"
@@ -81,10 +81,10 @@ fun makeCompileServices(
}
fun updateIncrementalCache(
generatedFiles: Iterable<GeneratedFile>,
cache: IncrementalJvmCache,
changesCollector: ChangesCollector,
javaChangesTracker: JavaClassesTrackerImpl?
generatedFiles: Iterable<GeneratedFile>,
cache: IncrementalJvmCache,
changesCollector: ChangesCollector,
javaChangesTracker: JavaClassesTrackerImpl?
) {
for (generatedFile in generatedFiles) {
when {
@@ -119,8 +119,8 @@ data class DirtyData(
)
fun ChangesCollector.getDirtyData(
caches: Iterable<IncrementalCacheCommon<*>>,
reporter: ICReporter
caches: Iterable<IncrementalCacheCommon>,
reporter: ICReporter
): DirtyData {
val dirtyLookupSymbols = HashSet<LookupSymbol>()
val dirtyClassesFqNames = HashSet<FqName>()
@@ -173,10 +173,10 @@ fun mapLookupSymbolsToFiles(
}
fun mapClassesFqNamesToFiles(
caches: Iterable<IncrementalCacheCommon<*>>,
classesFqNames: Iterable<FqName>,
reporter: ICReporter,
excludes: Set<File> = emptySet()
caches: Iterable<IncrementalCacheCommon>,
classesFqNames: Iterable<FqName>,
reporter: ICReporter,
excludes: Set<File> = emptySet()
): Set<File> {
val dirtyFiles = HashSet<File>()
@@ -195,7 +195,7 @@ fun mapClassesFqNamesToFiles(
fun withSubtypes(
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon<*>>
caches: Iterable<IncrementalCacheCommon>
): Set<FqName> {
val types = LinkedList(listOf(typeFqName))
val subtypes = hashSetOf<FqName>()
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import java.io.File
class FilesMap(storageFile: File)
: BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
operator fun set(sourceFile: File, outputFiles: Collection<File>) {
storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath }
}
operator fun get(sourceFile: File): Collection<File> =
storage[sourceFile.absolutePath].orEmpty().map(::File)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
fun remove(file: File): Collection<File> =
get(file).also { storage.remove(file.absolutePath) }
}
@@ -67,12 +67,18 @@ fun getModificationsToPerform(
val underscore = fileName.indexOf("_")
if (underscore != -1) {
val module = fileName.substring(0, underscore)
var moduleName = fileName.substring(0, underscore)
var moduleFileName = fileName.substring(underscore + 1)
if (moduleName.all { it.isDigit() }) {
val (moduleName1, moduleFileName1) = moduleFileName.split("_")
moduleName = moduleName1
moduleFileName = moduleFileName1
}
assert(moduleNames != null) { "File name has module prefix, but multi-module environment is absent" }
assert(module in moduleNames!!) { "Module not found for file with prefix: $fileName" }
assert(moduleName in moduleNames!!) { "Module not found for file with prefix: $fileName" }
return Pair(module, fileName.substring(underscore + 1))
return Pair(moduleName, moduleFileName)
}
assert(moduleNames == null) { "Test is multi-module, but file has no module prefix: $fileName" }
@@ -34,4 +34,10 @@ class K2MetadataCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-module-name", valueDescription = "<name>", description = "Name of the generated .kotlin_module file")
var moduleName: String? by FreezableVar(null)
@Argument(
value = "-Xjps",
description = "Enable in JPS"
)
var enabledInJps: Boolean by FreezableVar(false)
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2017 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.incremental
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import java.io.File
internal class ExpectActualTrackerImpl : ExpectActualTracker {
private val expectToActual = hashMapOf<File, MutableSet<File>>()
val expectToActualMap: Map<File, Set<File>>
get() = expectToActual
override fun report(expectedFile: File, actualFile: File) {
expectToActual.getOrPut(expectedFile) { hashSetOf() }.add(actualFile)
}
}
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import java.io.File
abstract class IncrementalCachesManager<PlatformCache : IncrementalCacheCommon<*>>(
abstract class IncrementalCachesManager<PlatformCache : AbstractIncrementalCache<*>>(
protected val cachesRootDir: File,
protected val reporter: ICReporter
) {
@@ -200,7 +200,7 @@ abstract class IncrementalCompilerRunner<
var exitCode = ExitCode.OK
while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) {
val complementaryFiles = caches.inputsCache.clearComplementaryFilesMapping(dirtySources)
val complementaryFiles = caches.platformCache.clearComplementaryFilesMapping(dirtySources)
dirtySources.addAll(complementaryFiles)
caches.platformCache.markDirty(dirtySources)
caches.inputsCache.removeOutputForSourceFiles(dirtySources)
@@ -239,7 +239,7 @@ abstract class IncrementalCompilerRunner<
}
}
caches.inputsCache.registerComplementaryFiles(expectActualTracker)
caches.platformCache.registerComplementaryFiles(expectActualTracker)
caches.inputsCache.registerOutputForSourceFiles(generatedFiles)
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
val changesCollector = ChangesCollector()
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.incremental
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.incremental.snapshots.FileSnapshotMap
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor
import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer
import org.jetbrains.kotlin.incremental.storage.*
import java.io.File
import java.util.*
import kotlin.collections.HashSet
@@ -34,43 +31,10 @@ class InputsCache(
companion object {
private val SOURCE_SNAPSHOTS = "source-snapshot"
private val SOURCE_TO_OUTPUT_FILES = "source-to-output"
private val COMPLEMENTARY_FILES = "complementary-files"
}
internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile))
private val sourceToOutputMap = registerMap(FilesMap(SOURCE_TO_OUTPUT_FILES.storageFile))
/**
* A file X is a complementary to a file Y if they contain corresponding expect/actual declarations.
* Complementary files should be compiled together during IC so the compiler does not complain
* about missing parts.
* TODO: provide a better solution (maintain an index of expect/actual declarations akin to IncrementalPackagePartProvider)
*/
private val complementaryFilesMap = registerMap(FilesMap(COMPLEMENTARY_FILES.storageFile))
fun clearComplementaryFilesMapping(dirtyFiles: Collection<File>): Collection<File> {
val complementaryFiles = HashSet<File>()
val filesQueue = ArrayDeque(dirtyFiles)
while (filesQueue.isNotEmpty()) {
val file = filesQueue.pollFirst()
complementaryFilesMap.remove(file).filterTo(filesQueue) { complementaryFiles.add(it) }
}
complementaryFiles.removeAll(dirtyFiles)
return complementaryFiles
}
internal fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl) {
val actualToExpect = hashMapOf<File, MutableSet<File>>()
for ((expect, actuals) in expectActualTracker.expectToActualMap) {
for (actual in actuals) {
actualToExpect.getOrPut(actual) { hashSetOf() }.add(expect)
}
complementaryFilesMap[expect] = actuals
}
for ((actual, expects) in actualToExpect) {
complementaryFilesMap[actual] = expects
}
}
fun removeOutputForSourceFiles(sources: Iterable<File>) {
for (sourceFile in sources) {
@@ -96,21 +60,4 @@ class InputsCache(
sourceToOutputMap[source] = outputs
}
}
}
private class FilesMap(storageFile: File)
: BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
operator fun set(sourceFile: File, outputFiles: Collection<File>) {
storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath }
}
operator fun get(sourceFile: File): Collection<File> =
storage[sourceFile.absolutePath].orEmpty().map(::File)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
fun remove(file: File): Collection<File> =
get(file).also { storage.remove(file.absolutePath) }
}
@@ -17,7 +17,7 @@ import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("jps-plugin/testData/incremental/multiplatform")
@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJsCompilerRunnerTest {
@@ -25,21 +25,21 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInMultiplatform() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
public void testAllFilesPresentInSingleModule() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
@TestMetadata("touchActual")
public void testTouchActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/touchActual/");
runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/");
}
@TestMetadata("touchExpect")
public void testTouchExpect() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/touchExpect/");
runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/");
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/touchActual")
@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class TouchActual extends AbstractIncrementalMultiplatformJsCompilerRunnerTest {
@@ -48,11 +48,11 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr
}
public void testAllFilesPresentInTouchActual() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect")
@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class TouchExpect extends AbstractIncrementalMultiplatformJsCompilerRunnerTest {
@@ -61,7 +61,7 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr
}
public void testAllFilesPresentInTouchExpect() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
}
@@ -17,7 +17,7 @@ import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("jps-plugin/testData/incremental/multiplatform")
@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest {
@@ -25,21 +25,21 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInMultiplatform() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
public void testAllFilesPresentInSingleModule() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
@TestMetadata("touchActual")
public void testTouchActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/touchActual/");
runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/");
}
@TestMetadata("touchExpect")
public void testTouchExpect() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/touchExpect/");
runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/");
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/touchActual")
@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class TouchActual extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest {
@@ -48,11 +48,11 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst
}
public void testAllFilesPresentInTouchActual() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect")
@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class TouchExpect extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest {
@@ -61,7 +61,7 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst
}
public void testAllFilesPresentInTouchExpect() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
}
@@ -148,6 +148,7 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterMultiFileTest
import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest
import org.jetbrains.kotlin.jps.build.*
import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase
import org.jetbrains.kotlin.jps.build.dependeciestxt.actualizeMppJpsIncTestCaseDirs
import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
@@ -929,6 +930,15 @@ fun main(args: Array<String>) {
model("incremental/classHierarchyAffected", extension = null, excludeParentDirs = true)
}
actualizeMppJpsIncTestCaseDirs(testDataRoot, "incremental/multiplatform/multiModule")
testClass<AbstractMultiplatformJpsTest> {
model(
"incremental/multiplatform/multiModule", extension = null, excludeParentDirs = true,
testClassName = "MultiplatformMultiModule", recursive = true
)
}
testClass<AbstractJvmLookupTrackerTest> {
model("incremental/lookupTracker/jvm", extension = null, recursive = false)
}
@@ -990,10 +1000,10 @@ fun main(args: Array<String>) {
}
testClass<AbstractIncrementalMultiplatformJvmCompilerRunnerTest> {
model("incremental/multiplatform", extension = null, excludeParentDirs = true)
model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true)
}
testClass<AbstractIncrementalMultiplatformJsCompilerRunnerTest> {
model("incremental/multiplatform", extension = null, excludeParentDirs = true)
model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true)
}
}
@@ -919,6 +919,15 @@ fun main(args: Array<String>) {
model("incremental/classHierarchyAffected", extension = null, excludeParentDirs = true)
}
actualizeMppJpsIncTestCaseDirs(testDataRoot, "incremental/multiplatform/multiModule")
testClass<AbstractMultiplatformJpsTest> {
model(
"incremental/multiplatform/multiModule", extension = null, excludeParentDirs = true,
testClassName = "MultiplatformMultiModule", recursive = true
)
}
testClass<AbstractJvmLookupTrackerTest> {
model("incremental/lookupTracker/jvm", extension = null, recursive = false)
}
@@ -980,10 +989,10 @@ fun main(args: Array<String>) {
}
testClass<AbstractIncrementalMultiplatformJvmCompilerRunnerTest> {
model("incremental/multiplatform", extension = null, excludeParentDirs = true)
model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true)
}
testClass<AbstractIncrementalMultiplatformJsCompilerRunnerTest> {
model("incremental/multiplatform", extension = null, excludeParentDirs = true)
model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true)
}
}
+1
View File
@@ -13,6 +13,7 @@ dependencies {
compile(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0")
+1
View File
@@ -13,6 +13,7 @@ dependencies {
compile(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0")
+1
View File
@@ -13,6 +13,7 @@ dependencies {
compile(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0")
+1
View File
@@ -13,6 +13,7 @@ dependencies {
compile(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0")
@@ -40,29 +40,34 @@ 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.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.incremental.CacheVersion
import org.jetbrains.kotlin.incremental.LookupSymbol
import org.jetbrains.kotlin.incremental.isJavaFile
import org.jetbrains.kotlin.incremental.testingUtils.*
import org.jetbrains.kotlin.jps.build.dependeciestxt.DependenciesTxt
import org.jetbrains.kotlin.jps.build.dependeciestxt.DependenciesTxtBuilder
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
import org.jetbrains.kotlin.jps.incremental.withLookupStorage
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
import org.jetbrains.kotlin.jps.platforms.kotlinBuildTargets
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.keysToMap
import java.io.*
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.util.*
import java.util.concurrent.Future
import kotlin.reflect.jvm.javaField
abstract class AbstractIncrementalJpsTest(
private val allowNoFilesWithSuffixInTestData: Boolean = false,
private val checkDumpsCaseInsensitively: Boolean = false,
private val allowNoBuildLogFileInTestData: Boolean = false
private val allowNoFilesWithSuffixInTestData: Boolean = false,
private val checkDumpsCaseInsensitively: Boolean = false,
private val allowNoBuildLogFileInTestData: Boolean = false
) : BaseKotlinJpsBuildTestCase() {
companion object {
private val COMPILATION_FAILED = "COMPILATION FAILED"
@@ -79,6 +84,7 @@ abstract class AbstractIncrementalJpsTest(
// is used to compare lookup dumps in a human readable way (lookup symbols are hashed in an actual lookup storage)
protected lateinit var lookupsDuringTest: MutableSet<LookupSymbol>
private var isICEnabledBackup: Boolean = false
private var isJSICEnabledBackup: Boolean = false
protected var mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf()
@@ -115,7 +121,10 @@ abstract class AbstractIncrementalJpsTest(
super.setUp()
lookupsDuringTest = hashSetOf()
isICEnabledBackup = IncrementalCompilation.isEnabled()
isJSICEnabledBackup = IncrementalCompilation.isEnabledForJs()
IncrementalCompilation.setIsEnabled(true)
IncrementalCompilation.setIsEnabledForJs(true)
if (DEBUG_LOGGING_ENABLED) {
enableDebugLogging()
@@ -129,6 +138,7 @@ abstract class AbstractIncrementalJpsTest(
(AbstractIncrementalJpsTest::systemPropertiesBackup).javaField!![this] = null
lookupsDuringTest.clear()
IncrementalCompilation.setIsEnabled(isICEnabledBackup)
IncrementalCompilation.setIsEnabledForJs(isJSICEnabledBackup)
super.tearDown()
}
@@ -138,7 +148,7 @@ abstract class AbstractIncrementalJpsTest(
private val mockConstantSearch: Callbacks.ConstantAffectionResolver?
get() = MockJavaConstantSearch(workDir)
private fun build(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules()): MakeResult {
private fun build(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules(), name: String? = null): MakeResult {
val workDirPath = FileUtil.toSystemIndependentName(workDir.absolutePath)
val logger = MyLogger(workDirPath)
@@ -148,48 +158,67 @@ abstract class AbstractIncrementalJpsTest(
projectDescriptor.project.setTestingContext(TestingContext(lookupTracker, logger))
try {
val builder = IncProjectBuilder(projectDescriptor, BuilderRegistry.getInstance(), myBuildParams, CanceledStatus.NULL, mockConstantSearch, true)
val builder = IncProjectBuilder(
projectDescriptor,
BuilderRegistry.getInstance(),
myBuildParams,
CanceledStatus.NULL,
mockConstantSearch,
true
)
val buildResult = BuildResult()
builder.addMessageHandler(buildResult)
builder.build(scope.build(), false)
val finalScope = scope.build()
builder.build(finalScope, false)
lookupTracker.lookups.mapTo(lookupsDuringTest) { LookupSymbol(it.name, it.scopeFqName) }
// for getting kotlin platform only
val dummyCompileContext = CompileContextImpl.createContextForTests(finalScope, projectDescriptor)
if (!buildResult.isSuccessful) {
val errorMessages =
buildResult
.getMessages(BuildMessage.Kind.ERROR)
.map { it.messageText }
.map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() }
.joinToString("\n")
return MakeResult(logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n", true, null)
buildResult
.getMessages(BuildMessage.Kind.ERROR)
.map { it.messageText }
.map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() }
.joinToString("\n")
return MakeResult(
logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n",
true,
null,
name
)
} else {
return MakeResult(
logger.log,
false,
createMappingsDump(projectDescriptor, dummyCompileContext),
name
)
}
else {
return MakeResult(logger.log, false, createMappingsDump(projectDescriptor))
}
}
finally {
} finally {
projectDescriptor.dataManager.flush(false)
projectDescriptor.release()
}
}
private fun initialMake(): MakeResult {
val makeResult = build()
protected fun initialMake(): MakeResult {
val makeResult = build(name = "initial")
val initBuildLogFile = File(testDataDir, "init-build.log")
if (initBuildLogFile.exists()) {
UsefulTestCase.assertSameLinesWithFile(initBuildLogFile.absolutePath, makeResult.log)
}
else {
} else {
assertFalse("Initial make failed:\n$makeResult", makeResult.makeFailed)
}
return makeResult
}
private fun make(): MakeResult {
return build()
private fun make(name: String?): MakeResult {
return build(name = name)
}
private fun rebuild(): MakeResult {
@@ -205,21 +234,21 @@ abstract class AbstractIncrementalJpsTest(
}
val rebuildResult = rebuild()
assertEquals("Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult",
rebuildResult.makeFailed, makeOverallResult.makeFailed)
assertEquals(
"Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult",
rebuildResult.makeFailed, makeOverallResult.makeFailed
)
if (!outAfterMake.exists()) {
assertFalse(outDir.exists())
}
else {
assertEqualDirectories(outDir, outAfterMake, makeOverallResult.makeFailed)
} else {
assertEqualDirectories(outAfterMake, outDir, makeOverallResult.makeFailed)
}
if (!makeOverallResult.makeFailed) {
if (checkDumpsCaseInsensitively && rebuildResult.mappingsDump?.toLowerCase() == makeOverallResult.mappingsDump?.toLowerCase()) {
// do nothing
}
else {
} else {
TestCase.assertEquals(rebuildResult.mappingsDump, makeOverallResult.mappingsDump)
}
}
@@ -233,30 +262,27 @@ abstract class AbstractIncrementalJpsTest(
rebuildAndCheckOutput(makeOverallResult)
}
private fun readModuleDependencies(): Map<String, List<DependencyDescriptor>>? {
val dependenciesTxt = File(testDataDir, "dependencies.txt")
if (!dependenciesTxt.exists()) return null
open protected val dependenciesTxtFile get() = File(testDataDir, "dependencies.txt")
val result = HashMap<String, List<DependencyDescriptor>>()
for (line in dependenciesTxt.readLines()) {
val split = line.split("->")
val module = split[0]
val dependencies = if (split.size > 1) split[1] else ""
val dependencyList = dependencies.split(",").filterNot { it.isEmpty() }
result[module] = dependencyList.map(::parseDependency)
}
private fun readModuleDependencies(): DependenciesTxt? {
val dependenciesTxtFile = dependenciesTxtFile
if (!dependenciesTxtFile.exists()) return null
return result
return DependenciesTxtBuilder().readFile(dependenciesTxtFile)
}
protected open fun createBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
buildString {
incrementalMakeResults.forEachIndexed { i, makeResult ->
if (i > 0) append("\n")
buildString {
incrementalMakeResults.forEachIndexed { i, makeResult ->
if (i > 0) append("\n")
if (makeResult.name != null) {
append("================ Step #${i + 1} ${makeResult.name} =================\n\n")
} else {
append("================ Step #${i + 1} =================\n\n")
append(makeResult.log)
}
append(makeResult.log)
}
}
protected open fun doTest(testDataPath: String) {
testDataDir = File(testDataPath)
@@ -272,8 +298,7 @@ abstract class AbstractIncrementalJpsTest(
if (buildLogFile != null && buildLogFile.exists()) {
UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, logs)
}
else if (!allowNoBuildLogFileInTestData) {
} else if (!allowNoBuildLogFileInTestData) {
throw IllegalStateException("No build log file in $testDataDir")
}
@@ -282,17 +307,38 @@ abstract class AbstractIncrementalJpsTest(
clearCachesRebuildAndCheckOutput(lastMakeResult)
}
private fun createMappingsDump(project: ProjectDescriptor) =
createKotlinIncrementalCacheDump(project) + "\n\n\n" +
createLookupCacheDump(project) + "\n\n\n" +
createCommonMappingsDump(project) + "\n\n\n" +
createJavaMappingsDump(project)
protected open fun doInitialMakeTest(testDataPath: String) {
testDataDir = File(testDataPath)
workDir = FileUtilRt.createTempDirectory(TEMP_DIRECTORY_TO_USE, "jps-build", null)
Disposer.register(testRootDisposable, Disposable { FileUtilRt.delete(workDir) })
private fun createKotlinIncrementalCacheDump(project: ProjectDescriptor): String {
configureModules()
val results = initialMake()
val buildLogFile = buildLogFinder.findBuildLog(testDataDir)
if (buildLogFile != null && buildLogFile.exists()) {
UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, results.log)
} else throw IllegalStateException("No build log file in $testDataDir")
}
private fun createMappingsDump(
project: ProjectDescriptor,
dummyCompileContext: CompileContext
) =
createKotlinIncrementalCacheDump(project, dummyCompileContext) + "\n\n\n" +
createLookupCacheDump(project) + "\n\n\n" +
createCommonMappingsDump(project) + "\n\n\n" +
createJavaMappingsDump(project)
private fun createKotlinIncrementalCacheDump(
project: ProjectDescriptor,
dummyCompileContext: CompileContext
): String {
return buildString {
for (target in project.allModuleTargets.sortedBy { it.presentableName }) {
append("<target $target>\n")
append(project.dataManager.getKotlinCache(target).dump())
append(project.dataManager.getKotlinCache(dummyCompileContext.kotlinBuildTargets[target]!!).dump())
append("</target $target>\n\n\n")
}
}
@@ -350,23 +396,35 @@ abstract class AbstractIncrementalJpsTest(
return byteArrayOutputStream.toString()
}
protected data class MakeResult(val log: String, val makeFailed: Boolean, val mappingsDump: String?)
protected data class MakeResult(
val log: String,
val makeFailed: Boolean,
val mappingsDump: String?,
val name: String?
)
open val testDataSrc: File
get() = testDataDir
private fun performModificationsAndMake(moduleNames: Set<String>?): List<MakeResult> {
val results = arrayListOf<MakeResult>()
val modifications = getModificationsToPerform(testDataDir, moduleNames, allowNoFilesWithSuffixInTestData, TouchPolicy.TIMESTAMP)
val modifications = getModificationsToPerform(testDataSrc, moduleNames, allowNoFilesWithSuffixInTestData, TouchPolicy.TIMESTAMP)
for (step in modifications) {
val stepsTxt = File(testDataSrc, "steps.txt")
val modificationNames = if (stepsTxt.exists()) stepsTxt.readLines() else null
modifications.forEachIndexed { index, step ->
step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
performAdditionalModifications(step)
if (moduleNames == null) {
preProcessSources(File(workDir, "src"))
}
else {
} else {
moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) }
}
results.add(make())
val name = modificationNames?.getOrNull(index)
val makeResult = make(name)
results.add(makeResult)
}
return results
}
@@ -374,54 +432,92 @@ abstract class AbstractIncrementalJpsTest(
protected open fun performAdditionalModifications(modifications: List<Modification>) {
}
// null means one module
private fun configureModules(): Set<String>? {
fun prepareModuleSources(moduleName: String?) {
val sourceDirName = moduleName?.let { "$it/src" } ?: "src"
val filePrefix = moduleName?.let { "${it}_" } ?: ""
val sourceDestinationDir = File(workDir, sourceDirName)
val sourcesMapping = copyTestSources(testDataDir, sourceDestinationDir, filePrefix)
mapWorkingToOriginalFile.putAll(sourcesMapping)
preProcessSources(sourceDestinationDir)
}
protected open fun generateModuleSources(dependenciesTxt: DependenciesTxt) {
JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl = JpsPathUtil.pathToUrl(getAbsolutePath("out"))
}
protected open fun prepareModuleSources(module: DependenciesTxt.Module? = null) {
if (module != null) {
prepareModuleSourcesByName("${module.name}/src", "${module.name}_")
} else {
prepareModuleSourcesByName("src", "")
}
}
protected fun prepareIndexedModuleSources(module: DependenciesTxt.Module) {
prepareModuleSourcesByName("${module.name}/src", "${module.indexedName}_")
}
private fun prepareModuleSourcesByName(sourceDirName: String, filePrefix: String) {
val sourceDestinationDir = File(workDir, sourceDirName)
val sourcesMapping = copyTestSources(testDataSrc, sourceDestinationDir, filePrefix)
mapWorkingToOriginalFile.putAll(sourcesMapping)
preProcessSources(sourceDestinationDir)
}
// null means one module
protected fun configureModules(): Set<String>? {
val outputUrl = JpsPathUtil.pathToUrl(getAbsolutePath("out"))
JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl = outputUrl
val jdk = addJdk("my jdk")
val moduleDependencies = readModuleDependencies()
val dependenciesTxt = readModuleDependencies()
mapWorkingToOriginalFile = hashMapOf()
val moduleNames: Set<String>?
if (moduleDependencies == null) {
if (dependenciesTxt == null) {
addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk)
prepareModuleSources(moduleName = null)
prepareModuleSources(module = null)
moduleNames = null
}
else {
val nameToModule = moduleDependencies.keys
.keysToMap { addModule(it, arrayOf(getAbsolutePath("$it/src")), null, null, jdk)!! }
} else {
dependenciesTxt.modules.forEach {
val module = addModule(
it.name,
arrayOf(getAbsolutePath("${it.name}/src")),
null,
null,
jdk
)!!
for ((moduleName, dependencies) in moduleDependencies) {
val module = nameToModule[moduleName]!!
val kotlinFacetSettings = it.kotlinFacetSettings
if (kotlinFacetSettings != null) {
val compilerArguments = kotlinFacetSettings.compilerArguments
if (compilerArguments is K2MetadataCompilerArguments) {
val out = getAbsolutePath("${it.name}/out")
File(out).mkdirs()
compilerArguments.destination = out
}
for (dependency in dependencies) {
JpsModuleRootModificationUtil.addDependency(module, nameToModule[dependency.name],
JpsJavaDependencyScope.COMPILE, dependency.exported)
module.container.setChild(
JpsKotlinFacetModuleExtension.KIND,
JpsKotlinFacetModuleExtension(kotlinFacetSettings)
)
}
it.jpsModule = module
}
for (module in nameToModule.values) {
prepareModuleSources(module.name)
dependenciesTxt.dependencies.forEach {
JpsModuleRootModificationUtil.addDependency(
it.from.jpsModule,
it.to.jpsModule,
it.scope,
it.exported
)
}
moduleNames = nameToModule.keys
generateModuleSources(dependenciesTxt)
dependenciesTxt.modules.forEach {
prepareModuleSources(it)
}
moduleNames = dependenciesTxt.modules.map { it.name }.toSet()
}
AbstractKotlinJpsBuildTestCase.addKotlinStdlibDependency(myProject)
AbstractKotlinJpsBuildTestCase.addKotlinTestDependency(myProject)
return moduleNames
}
protected open fun preProcessSources(srcDir: File) {
}
@@ -530,10 +626,3 @@ private class MockJavaConstantSearch(private val workDir: File) : Callbacks.Cons
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
get() = buildTargetIndex.allTargets.filterIsInstance<ModuleBuildTarget>()
private class DependencyDescriptor(val name: String, val exported: Boolean)
private fun parseDependency(dependency: String): DependencyDescriptor =
DependencyDescriptor(dependency.removeSuffix(EXPORTED_SUFFIX), dependency.endsWith(EXPORTED_SUFFIX))
private val EXPORTED_SUFFIX = "[exported]"
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.build
import org.jetbrains.kotlin.jps.build.dependeciestxt.DependenciesTxt
import org.jetbrains.kotlin.jps.build.dependeciestxt.MppJpsIncTestsGenerator
import java.io.File
abstract class AbstractMultiplatformJpsTest : AbstractIncrementalJpsTest() {
override val dependenciesTxtFile: File
get() = File(testDataDir.parent, "dependencies.txt").also {
check(it.exists()) {
"`dependencies.txt` should be in parent dir. " +
"See jps-plugin/testData/incremental/multiplatform/multiModule/README.md for details"
}
}
override val testDataSrc: File
get() = File(workDir, "generatedTestDataSources")
override fun generateModuleSources(dependenciesTxt: DependenciesTxt) {
testDataSrc.mkdirs()
val testCaseName = testDataDir.name
val generator = MppJpsIncTestsGenerator(dependenciesTxt) { testDataSrc }
val testCase = generator.testCases.find { it.name == testCaseName } ?: error("Unsupported test case name: $testCaseName")
testCase.generate()
}
override fun prepareModuleSources(module: DependenciesTxt.Module?) {
prepareIndexedModuleSources(module!!)
}
}
@@ -0,0 +1,358 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.build;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class MultiplatformJpsTestGenerated extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInMultiplatformMultiModule() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simple")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Simple extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInSimple() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simple"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
@TestMetadata("editingCExpectActual")
public void testEditingCExpectActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCExpectActual/");
}
@TestMetadata("editingCKotlin")
public void testEditingCKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCKotlin/");
}
@TestMetadata("editingPJsKotlin")
public void testEditingPJsKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJsKotlin/");
}
@TestMetadata("editingPJvmJava")
public void testEditingPJvmJava() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmJava/");
}
@TestMetadata("editingPJvmKotlin")
public void testEditingPJvmKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmKotlin/");
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCExpectActual")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingCExpectActual extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingCExpectActual() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCExpectActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingCKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingCKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJsKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingPJsKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingPJsKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJsKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmJava")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingPJvmJava extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingPJvmJava() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmJava"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingPJvmKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingPJvmKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class SimpleJsJvmProjectWithTests extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInSimpleJsJvmProjectWithTests() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
@TestMetadata("editingCMainExpectActual")
public void testEditingCMainExpectActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCMainExpectActual/");
}
@TestMetadata("editingCTestsExpectActual")
public void testEditingCTestsExpectActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCTestsExpectActual/");
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCMainExpectActual")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingCMainExpectActual extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingCMainExpectActual() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCMainExpectActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCTestsExpectActual")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingCTestsExpectActual extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingCTestsExpectActual() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCTestsExpectActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Ultimate extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInUltimate() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
@TestMetadata("editingACommonExpectActual")
public void testEditingACommonExpectActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingACommonExpectActual/");
}
@TestMetadata("editingAJsClientKotlin")
public void testEditingAJsClientKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJsClientKotlin/");
}
@TestMetadata("editingAJvmClientJava")
public void testEditingAJvmClientJava() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientJava/");
}
@TestMetadata("editingAJvmClientKotlin")
public void testEditingAJvmClientKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientKotlin/");
}
@TestMetadata("editingBCommonExpectActual")
public void testEditingBCommonExpectActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingBCommonExpectActual/");
}
@TestMetadata("editingRJsKotlin")
public void testEditingRJsKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJsKotlin/");
}
@TestMetadata("editingRJvmKotlin")
public void testEditingRJvmKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJvmKotlin/");
}
@TestMetadata("editingRaJsKotlin")
public void testEditingRaJsKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJsKotlin/");
}
@TestMetadata("editingRaJvmKotlin")
public void testEditingRaJvmKotlin() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJvmKotlin/");
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingACommonExpectActual")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingACommonExpectActual extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingACommonExpectActual() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingACommonExpectActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJsClientKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingAJsClientKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingAJsClientKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJsClientKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientJava")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingAJvmClientJava extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingAJvmClientJava() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientJava"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingAJvmClientKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingAJvmClientKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingBCommonExpectActual")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingBCommonExpectActual extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingBCommonExpectActual() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingBCommonExpectActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJsKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingRJsKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingRJsKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJsKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJvmKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingRJvmKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingRJvmKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJvmKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJsKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingRaJsKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingRaJsKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJsKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJvmKotlin")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class EditingRaJvmKotlin extends AbstractMultiplatformJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInEditingRaJvmKotlin() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJvmKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
}
}
@@ -0,0 +1,267 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.build.dependeciestxt
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.config.CompilerSettings
import org.jetbrains.kotlin.config.KotlinFacetSettings
import org.jetbrains.kotlin.config.TargetPlatformKind
import java.io.File
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.memberProperties
/**
* Dependencies description file.
* See [README.md] for more details.
*/
data class DependenciesTxt(
val file: File,
val fileName: String,
val modules: List<Module>,
val dependencies: List<Dependency>
) {
override fun toString() = fileName
data class Module(val name: String) {
var index: Int = -1
val indexedName
get() = "${index / 10}${index % 10}_$name"
/**
* Facet should not be created for old tests
*/
var kotlinFacetSettings: KotlinFacetSettings? = null
lateinit var jpsModule: JpsModule
val dependencies = mutableListOf<Dependency>()
val usages = mutableListOf<Dependency>()
val isCommonModule
get() = kotlinFacetSettings?.targetPlatformKind == TargetPlatformKind.Common
val isJvmModule
get() = kotlinFacetSettings?.targetPlatformKind is TargetPlatformKind.Jvm
val expectedBy
get() = dependencies.filter { it.expectedBy }
@Flag
var edit: Boolean = false
@Flag
var editJvm: Boolean = false
@Flag
var editExpectActual: Boolean = false
companion object {
val flags: Map<String, KMutableProperty1<Module, Boolean>> = Module::class.memberProperties
.filter { it.findAnnotation<Flag>() != null }
.filterIsInstance<KMutableProperty1<Module, Boolean>>()
.associateBy { it.name }
}
}
annotation class Flag
data class Dependency(
val from: Module,
val to: Module,
val scope: JpsJavaDependencyScope,
val expectedBy: Boolean,
val exported: Boolean
) {
val effectivelyExported
get() = expectedBy || exported
init {
from.dependencies.add(this)
to.usages.add(this)
}
}
}
class DependenciesTxtBuilder {
val modules = mutableMapOf<String, ModuleRef>()
private val dependencies = mutableListOf<DependencyBuilder>()
/**
* Reference to module which can be defined later
*/
class ModuleRef(name: String) {
var defined: Boolean = false
var actual: DependenciesTxt.Module = DependenciesTxt.Module(name)
override fun toString() = actual.name
fun build(index: Int): DependenciesTxt.Module {
val result = actual
result.index = index
val kotlinFacetSettings = result.kotlinFacetSettings
if (kotlinFacetSettings != null) {
kotlinFacetSettings.implementedModuleNames =
result.dependencies.filter { it.expectedBy }.map { it.to.name }
}
return result
}
}
/**
* Temporary object for resolving references to modules.
*/
data class DependencyBuilder(
val from: ModuleRef,
val to: ModuleRef,
val scope: JpsJavaDependencyScope,
val expectedBy: Boolean,
val exported: Boolean
) {
fun build(): DependenciesTxt.Dependency {
if (expectedBy) check(to.actual.isCommonModule) { "$this: ${to.actual} is not common module" }
return DependenciesTxt.Dependency(from.actual, to.actual, scope, expectedBy, exported)
}
}
fun readFile(file: File, fileTitle: String = file.toString()): DependenciesTxt {
file.forEachLine { line ->
parseDeclaration(line)
}
// module.build() requires built dependencies
val dependencies = dependencies.map { it.build() }
return DependenciesTxt(
file,
fileTitle,
modules.values.mapIndexed { index, moduleRef -> moduleRef.build(index) },
dependencies
)
}
private fun parseDeclaration(line: String) = doParseDeclaration(removeComments(line))
private fun removeComments(line: String) = line.split("//", limit = 2)[0].trim()
private fun doParseDeclaration(line: String) {
when {
line.isEmpty() -> Unit // skip empty lines
line.contains("->") -> {
val (from, rest) = line.split("->", limit = 2)
if (rest.isBlank()) {
// `name -> ` - module
newModule(ValueWithFlags(from))
} else {
val (to, flags) = parseValueWithFlags(rest.trim())
newDependency(from.trim(), to.trim(), flags) // `from -> to [flag1, flag2, ...]` - dependency
}
}
else -> newModule(parseValueWithFlags(line)) // `name [flag1, flag2, ...]` - module
}
}
/**
* `value [flag1, flag2, ...]`
*/
private fun parseValueWithFlags(str: String): ValueWithFlags {
val parts = str.split("[", limit = 2)
return if (parts.size > 1) {
val (value, flags) = parts
ValueWithFlags(
value = value.trim(),
flags = flags.trim()
.removeSuffix("]")
.split(",")
.map { it.trim() }
.filter { it.isNotEmpty() }
.toSet()
)
} else ValueWithFlags(str)
}
data class ValueWithFlags(val value: String, val flags: Set<String> = setOf())
private fun moduleRef(name: String) =
modules.getOrPut(name) { ModuleRef(name) }
private fun newModule(def: ValueWithFlags): DependenciesTxt.Module {
val name = def.value.trim()
val module = DependenciesTxt.Module(name)
val kotlinFacetSettings = KotlinFacetSettings()
module.kotlinFacetSettings = kotlinFacetSettings
kotlinFacetSettings.useProjectSettings = false
kotlinFacetSettings.compilerSettings = CompilerSettings().also {
it.additionalArguments = "-version -Xmulti-platform"
}
val moduleRef = moduleRef(name)
check(!moduleRef.defined) { "Module `$name` already defined" }
moduleRef.defined = true
moduleRef.actual = module
def.flags.forEach { flag ->
when (flag) {
"common" -> kotlinFacetSettings.compilerArguments = K2MetadataCompilerArguments()
"jvm" -> kotlinFacetSettings.compilerArguments = K2JVMCompilerArguments()
"js" -> kotlinFacetSettings.compilerArguments = K2JSCompilerArguments()
else -> {
val flagProperty = DependenciesTxt.Module.flags[flag]
if (flagProperty != null) flagProperty.set(module, true)
else error("Unknown module flag `$flag`")
}
}
}
return module
}
private fun newDependency(from: String, to: String, flags: Set<String>): DependencyBuilder? {
if (to.isEmpty()) {
// `x -> ` should just create undefined module `x`
moduleRef(from)
check(flags.isEmpty()) {
"`name -> [flag1, flag2, ...]` - not allowed due to the ambiguity of belonging to modules/dependencies. " +
"Please use `x [attrs...]` syntax for module attributes."
}
return null
} else {
var exported = false
var scope = JpsJavaDependencyScope.COMPILE
var expectedBy = false
flags.forEach { flag ->
when (flag) {
"exported" -> exported = true
"compile" -> scope = JpsJavaDependencyScope.COMPILE
"test" -> scope = JpsJavaDependencyScope.TEST
"runtime" -> scope = JpsJavaDependencyScope.RUNTIME
"provided" -> scope = JpsJavaDependencyScope.PROVIDED
"expectedBy" -> expectedBy = true
else -> error("Unknown dependency flag `$flag`")
}
}
return DependencyBuilder(
from = moduleRef(from),
to = moduleRef(to),
scope = scope,
expectedBy = expectedBy,
exported = exported
).also {
dependencies.add(it)
}
}
}
}
@@ -0,0 +1,432 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.build.dependeciestxt
import java.io.File
/**
* Utility for generating common/platform module stub contents based on it's dependencies.
*/
fun actualizeMppJpsIncTestCaseDirs(rootDir: String, dir: String) {
File("$rootDir/$dir").listFiles { it: File -> it.isDirectory }.forEach { dirFile ->
val dependenciesTxtFile = File(dirFile, "dependencies.txt")
if (dependenciesTxtFile.exists()) {
val fileTitle = "$dir/${dirFile.name}/dependencies.txt"
val dependenciesTxt = DependenciesTxtBuilder().readFile(dependenciesTxtFile, fileTitle)
MppJpsIncTestsGenerator(dependenciesTxt) { File(dirFile, it.name) }
.actualizeTestCasesDirs(dirFile)
}
}
return
}
class MppJpsIncTestsGenerator(val txt: DependenciesTxt, val testCaseDirProvider: (TestCase) -> File) {
val DependenciesTxt.Module.capitalName get() = name.capitalize()
val testCases: List<TestCase>
init {
val testCases = mutableListOf<TestCase>()
txt.modules.forEach {
if (it.edit)
testCases.add(EditingTestCase(it, changeJavaClass = false))
if (it.editJvm && it.isJvmModule)
testCases.add(EditingTestCase(it, changeJavaClass = true))
if (it.editExpectActual && it.isCommonModule)
testCases.add(EditingExpectActualTestCase(it))
}
this.testCases = testCases
}
fun actualizeTestCasesDirs(rootDir: File) {
val requiredDirs = mutableSetOf<File>()
testCases.forEach {
val dir = it.dir
check(requiredDirs.add(dir)) { "TestCase dir clash $dir" }
if (!dir.exists()) {
File(dir, "build.log").setFileContent("")
}
}
rootDir.listFiles().forEach {
if (it.isDirectory && it !in requiredDirs) {
it.deleteRecursively()
}
}
}
/**
* Set required content for [this] [File].
*/
fun File.setFileContent(content: String) {
check(!exists()) {
"File `$this` already exists," +
"\n\n============= contents ============\n" +
readText() +
"\n===================================\n" +
"\n============ new content ==========\n" +
content +
"\n===================================\n"
}
parentFile.mkdirs()
writeText(content)
}
data class ModuleContentSettings(
val module: DependenciesTxt.Module,
val serviceNameSuffix: String = "",
val generateActualDeclarationsFor: List<DependenciesTxt.Module> = module.expectedBy.map { it.to },
val generatePlatformDependent: Boolean = true,
var generateKtFile: Boolean = true,
var generateJavaFile: Boolean = true
)
inner class EditingTestCase(val module: DependenciesTxt.Module, val changeJavaClass: Boolean) : TestCase() {
override val name: String =
if (changeJavaClass) "editing${module.capitalName}Java"
else "editing${module.capitalName}Kotlin"
override val dir: File = testCaseDirProvider(this)
override fun generate() {
generateBaseContent()
// create new file with service implementation
// don't create expect/actual functions (generatePlatformDependent = false)
module.contentsSettings = ModuleContentSettings(
module,
serviceNameSuffix = "New",
generatePlatformDependent = false,
generateKtFile = !changeJavaClass,
generateJavaFile = changeJavaClass
)
when {
module.isCommonModule -> {
step("create new service") {
generateCommonFile(
module,
fileNameSuffix = ".new.$step"
)
}
step("edit new service") {
generateCommonFile(
module,
fileNameSuffix = ".touch.$step"
)
}
step("delete new service") {
serviceKtFile(
module,
fileNameSuffix = ".delete.$step"
).setFileContent("")
}
}
else -> {
step("create new service") {
// generateKtFile event if changeJavaClass requested (for test calling java from kotlin)
val prevModuleContentsSettings = module.contentsSettings
module.contentsSettings = module.contentsSettings.copy(generateKtFile = true)
generatePlatformFile(
module,
fileNameSuffix = ".new.$step"
)
module.contentsSettings = prevModuleContentsSettings
}
step("edit new service") {
generatePlatformFile(
module,
fileNameSuffix = ".touch.$step"
)
}
step("delete new service") {
if (changeJavaClass) serviceJavaFile(module, fileNameSuffix = ".delete.$step").setFileContent("")
// kotlin file also created for testing java class
serviceKtFile(module, fileNameSuffix = ".delete.$step").setFileContent("")
}
}
}
generateStepsTxt()
}
}
inner class EditingExpectActualTestCase(val commonModule: DependenciesTxt.Module) : TestCase() {
override val name: String = "editing${commonModule.capitalName}ExpectActual"
override val dir: File = testCaseDirProvider(this)
override fun generate() {
generateBaseContent()
check(commonModule.isCommonModule)
val implModules = commonModule.usages.filter { it.expectedBy }.map { it.from }
commonModule.contentsSettings = ModuleContentSettings(commonModule, serviceNameSuffix = "New")
implModules.forEach { implModule ->
implModule.contentsSettings = ModuleContentSettings(
implModule,
serviceNameSuffix = "New",
generateActualDeclarationsFor = listOf(commonModule)
)
}
step("create new service in ${commonModule.name}") {
generateCommonFile(commonModule, fileNameSuffix = ".new.$step")
}
implModules.forEach { implModule ->
step("create new service in ${implModule.name}") {
generatePlatformFile(implModule, fileNameSuffix = ".new.$step")
}
}
step("change new service in ${commonModule.name}") {
generateCommonFile(commonModule, fileNameSuffix = ".touch.$step")
}
implModules.forEach { implModule ->
if (implModule.isJvmModule) {
implModule.contentsSettings.generateKtFile = false
implModule.contentsSettings.generateJavaFile = true
step("change new service in ${implModule.name}: java") {
generatePlatformFile(implModule, fileNameSuffix = ".touch.$step")
}
implModule.contentsSettings.generateKtFile = true
implModule.contentsSettings.generateJavaFile = false
step("change new service in ${implModule.name}: kotlin") {
generatePlatformFile(implModule, fileNameSuffix = ".touch.$step")
}
} else {
step("change new service in ${implModule.name}") {
generatePlatformFile(implModule, fileNameSuffix = ".touch.$step")
}
}
}
implModules.forEach { implModule ->
step("delete new service in ${implModule.name}") {
serviceKtFile(implModule, fileNameSuffix = ".delete.$step").setFileContent("")
}
}
step("delete new service in ${commonModule.name}") {
serviceKtFile(commonModule, fileNameSuffix = ".delete.$step").setFileContent("")
}
generateStepsTxt()
}
}
abstract inner class TestCase() {
abstract val name: String
abstract fun generate()
abstract val dir: File
private val modules = mutableMapOf<DependenciesTxt.Module, ModuleContentSettings>()
var step = 1
val steps = mutableListOf<String>()
protected inline fun step(name: String, body: () -> Unit) {
body()
steps.add(name)
step++
}
var DependenciesTxt.Module.contentsSettings: ModuleContentSettings
get() = modules.getOrPut(this) { ModuleContentSettings(this) }
set(value) {
modules[this] = value
}
protected fun generateStepsTxt() {
File(dir, "steps.txt").setFileContent(steps.joinToString("\n"))
}
fun generateBaseContent() {
dir.mkdir()
txt.modules.forEach {
generateModuleContents(it)
}
}
private fun generateModuleContents(module: DependenciesTxt.Module) {
when {
module.isCommonModule -> {
// common module
generateCommonFile(module)
}
module.expectedBy.isEmpty() -> {
// regular module
generatePlatformFile(module)
}
else -> {
// common module platform implementation
generatePlatformFile(module)
}
}
}
private val DependenciesTxt.Module.serviceName
get() = "$capitalName${contentsSettings.serviceNameSuffix}"
private val DependenciesTxt.Module.javaClassName
get() = "${serviceName}JavaClass"
protected fun serviceKtFile(module: DependenciesTxt.Module, fileNameSuffix: String = ""): File {
val suffix =
if (module.isCommonModule) "${module.serviceName}Header"
else "${module.name.capitalize()}${module.contentsSettings.serviceNameSuffix}Impl"
return File(dir, "${module.indexedName}_service$suffix.kt$fileNameSuffix")
}
fun serviceJavaFile(module: DependenciesTxt.Module, fileNameSuffix: String = ""): File {
return File(dir, "${module.indexedName}_${module.javaClassName}.java$fileNameSuffix")
}
private val DependenciesTxt.Module.platformDependentFunName: String
get() {
check(isCommonModule)
return "${name}_platformDependent$serviceName"
}
private val DependenciesTxt.Module.platformIndependentFunName: String
get() {
check(isCommonModule)
return "${name}_platformIndependent$serviceName"
}
private val DependenciesTxt.Module.platformOnlyFunName: String
get() {
// platformOnly fun names already unique, so no module name prefix required
return "${name}_platformOnly${contentsSettings.serviceNameSuffix}"
}
protected fun generateCommonFile(
module: DependenciesTxt.Module,
fileNameSuffix: String = ""
) {
val settings = module.contentsSettings
serviceKtFile(module, fileNameSuffix).setFileContent(buildString {
if (settings.generatePlatformDependent)
appendln("expect fun ${module.platformDependentFunName}(): String")
appendln("fun ${module.platformIndependentFunName}() = \"common$fileNameSuffix\"")
appendTestFun(module, settings)
})
}
protected fun generatePlatformFile(
module: DependenciesTxt.Module,
fileNameSuffix: String = ""
) {
val isJvm = module.isJvmModule
val settings = module.contentsSettings
val javaClassName = module.javaClassName
if (settings.generateKtFile) {
serviceKtFile(module, fileNameSuffix).setFileContent(buildString {
if (settings.generatePlatformDependent) {
for (expectedBy in settings.generateActualDeclarationsFor) {
appendln(
"actual fun ${expectedBy.platformDependentFunName}(): String" +
" = \"${module.name}$fileNameSuffix\""
)
}
}
appendln(
"fun ${module.platformOnlyFunName}()" +
" = \"${module.name}$fileNameSuffix\""
)
appendTestFun(module, settings)
})
}
if (isJvm && settings.generateJavaFile) {
serviceJavaFile(module, fileNameSuffix).setFileContent(
"""
|public class $javaClassName {
| public String doStuff() {
| return "${module.name}$fileNameSuffix";
| }
|}
""".trimMargin()
)
}
}
// call all functions declared in this module and all of its dependencies recursively
private fun StringBuilder.appendTestFun(
module: DependenciesTxt.Module,
settings: ModuleContentSettings
) {
appendln()
appendln("fun Test${module.serviceName}() {")
val thisAndDependencies = mutableSetOf(module)
module.collectDependenciesRecursivelyTo(thisAndDependencies)
thisAndDependencies.forEach { thisOrDependent ->
if (thisOrDependent.isCommonModule) {
appendln(" ${thisOrDependent.platformIndependentFunName}()")
if (settings.generatePlatformDependent) {
appendln(" ${thisOrDependent.platformDependentFunName}()")
}
} else {
// platform module
appendln(" ${thisOrDependent.platformOnlyFunName}()")
if (thisOrDependent.isJvmModule && thisOrDependent.contentsSettings.generateJavaFile) {
appendln(" ${thisOrDependent.javaClassName}().doStuff()")
}
}
}
appendln("}")
}
private fun DependenciesTxt.Module.collectDependenciesRecursivelyTo(
collection: MutableCollection<DependenciesTxt.Module>,
exportedOnly: Boolean = false
) {
dependencies.forEach {
if (!exportedOnly || it.effectivelyExported) {
val dependentModule = it.to
collection.add(dependentModule)
dependentModule.collectDependenciesRecursivelyTo(collection, exportedOnly = true)
}
}
}
override fun toString() = name
}
}
@@ -0,0 +1,36 @@
Useful micro-language for concise description of project structure.
Mostly like the [DOT language](https://www.graphviz.org/doc/info/attrs.html).
## Example
```
c [common]
p1 [jvm]
p2 [jvm]
p1 -> c [expectedBy]
p2 -> c [expectedBy]
```
## Format
File contains declarations of modules and dependencies:
- Module: `module_name [flag1, key1=value1, ...]`
- Dependency: `source_module_name -> target_module_name [flag1, key1=value1, ...]`
Referring to undefined module is allowed (`jvm` module will be created at this case).
This modules can be defined after reference. Several declarations for same module is not allowed.
Supported module flags:
- `common`
- `jvm` (default)
- `js`
- `edit`, `editJvm`, `editExcpetActual` - see jps-plugin/testData/incremental/multiplatform/multiModule/README.md
Supported dependency flags:
- `compile` (default)
- `test`
- `runtime`
- `provided`
- `expectedBy`
- `exproted`
@@ -0,0 +1 @@
org.jetbrains.kotlin.jps.build.KotlinMppCommonSourceRootProvider
@@ -88,10 +88,18 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
k2MetadataArguments: K2MetadataCompilerArguments,
compilerSettings: CompilerSettings,
environment: JpsCompilerEnvironment,
destination: String,
classpath: Collection<String>,
sourceFiles: Collection<File>
) {
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2MetadataArguments))
val classpathSet = arguments.classpath?.split(File.pathSeparator)?.toMutableSet() ?: mutableSetOf()
classpathSet.addAll(classpath)
arguments.classpath = classpath.joinToString(File.pathSeparator)
arguments.freeArgs = sourceFiles.map { it.absolutePath }
arguments.destination = arguments.destination ?: destination
withCompilerSettings(compilerSettings) {
runCompiler(K2METADATA_COMPILER, arguments, environment)
}
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.jps.build
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.BuildRootIndex
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.BuildTargetIndex
import org.jetbrains.jps.builders.java.dependencyView.Mappings
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.FSOperations
@@ -43,7 +41,7 @@ class FSOperationsHelper(
fun markChunk(recursively: Boolean, kotlinOnly: Boolean, excludeFiles: Set<File> = setOf()) {
fun shouldMark(file: File): Boolean {
if (kotlinOnly && !KotlinSourceFileCollector.isKotlinSourceFile(file)) return false
if (kotlinOnly && !file.isKotlinSourceFile) return false
if (file in excludeFiles) return false
@@ -17,11 +17,7 @@
package org.jetbrains.kotlin.jps.build
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.MultiMap
import gnu.trove.THashSet
import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.DirtyFilesHolder
@@ -32,44 +28,35 @@ import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.incremental.*
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.*
import org.jetbrains.jps.incremental.java.JavaBuilder
import org.jetbrains.jps.incremental.messages.BuildMessage
import org.jetbrains.jps.incremental.messages.CompilerMessage
import org.jetbrains.jps.incremental.messages.ProgressMessage
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.model.JpsProject
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.build.JvmBuildMetaInfo
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil
import org.jetbrains.kotlin.compilerRunner.*
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.CompilerRunnerConstants.INTERNAL_ERROR_PREFIX
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.common.isDaemonEnabled
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
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.KotlinCommonModuleBuildTarget
import org.jetbrains.kotlin.jps.platforms.KotlinJsModuleBuildTarget
import org.jetbrains.kotlin.jps.platforms.KotlinModuleBuildTarget
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
import org.jetbrains.kotlin.preloading.ClassCondition
import org.jetbrains.kotlin.progress.CompilationCanceledException
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.utils.KotlinPaths
import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.keysToMap
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
import java.io.File
import java.util.*
import kotlin.collections.HashSet
@@ -167,29 +154,39 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
context: CompileContext,
fsOperations: FSOperationsHelper
) {
val dirtyFilesHolder = object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
FSOperations.processFilesToRecompile(context, chunk, processor)
val roundDirtyFiles = KotlinRoundDirtySourceFilesHolder(
chunk,
context,
fsOperations,
object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
FSOperations.processFilesToRecompile(context, chunk, processor)
}
}
}
val chunkDirtyFiles = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder)
val chunkRemovedFiles = chunk.targets.keysToMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) }
)
val representativeTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return
val incrementalCaches = getIncrementalCaches(chunk, context)
val messageCollector = MessageCollectorAdapter(context)
val environment = createCompileEnvironment(incrementalCaches, LookupTracker.DO_NOTHING, context, chunk, messageCollector)
if (environment == null) return
val messageCollector = MessageCollectorAdapter(context, representativeTarget)
val environment = createCompileEnvironment(
representativeTarget,
incrementalCaches,
LookupTracker.DO_NOTHING,
ExpectActualTracker.DoNothing,
chunk,
messageCollector
) ?: return
val removedClasses = HashSet<String>()
for (target in chunk.targets) {
val cache = incrementalCaches[target]!!
val dirtyFiles = chunkDirtyFiles[target]
val removedFiles = chunkRemovedFiles[target] ?: emptyList()
val cache = incrementalCaches[target] ?: continue
val dirtyFiles = roundDirtyFiles.getDirtyFiles(target)
val removedFiles = roundDirtyFiles.getRemovedFilesSet(target)
val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles.toHashSet())
val previousClasses = cache.classesBySources(dirtyFiles + removedFiles)
val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles)
val previousClasses = cache.classesFqNamesBySources(dirtyFiles + removedFiles)
for (jvmClassName in previousClasses) {
val fqName = jvmClassName.fqNameForClassNameWithoutDollars.asString()
val fqName = jvmClassName.asString()
if (fqName !in existingClasses) {
removedClasses.add(fqName)
}
@@ -214,50 +211,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val allVersions = cacheVersionsProvider.allVersions(targets)
val actions = allVersions.map { it.checkVersion() }.toMutableSet()
val kotlinModuleBuilderTarget = context.kotlinBuildTargets[chunk.representativeTarget()]
if (kotlinModuleBuilderTarget !is KotlinJsModuleBuildTarget) {
val args = compilerArgumentsForChunk(chunk)
val currentBuildMetaInfo = JvmBuildMetaInfo(args)
for (target in chunk.targets) {
val file = jvmBuildMetaInfoFile(target, dataManager)
if (!file.exists()) continue
val lastBuildMetaInfo =
try {
JvmBuildMetaInfo.deserializeFromString(file.readText()) ?: continue
} catch (e: Exception) {
LOG.error("Could not deserialize jvm build meta info", e)
continue
}
val lastBuildLangVersion = LanguageVersion.fromVersionString(lastBuildMetaInfo.languageVersionString)
val lastBuildApiVersion = ApiVersion.parse(lastBuildMetaInfo.apiVersionString)
val currentLangVersion =
args.languageVersion?.let { LanguageVersion.fromVersionString(it) } ?: LanguageVersion.LATEST_STABLE
val currentApiVersion =
args.apiVersion?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(currentLangVersion)
val reasonToRebuild = when {
currentLangVersion != lastBuildLangVersion -> {
"Language version was changed ($lastBuildLangVersion -> $currentLangVersion)"
}
currentApiVersion != lastBuildApiVersion -> {
"Api version was changed ($lastBuildApiVersion -> $currentApiVersion)"
}
lastBuildLangVersion != LanguageVersion.KOTLIN_1_0 && lastBuildMetaInfo.isEAP && !currentBuildMetaInfo.isEAP -> {
// If EAP->Non-EAP build with IC, then rebuild all kotlin
"Last build was compiled with EAP-plugin"
}
else -> null
}
if (reasonToRebuild != null) {
LOG.info("$reasonToRebuild. Performing non-incremental rebuild (kotlin only)")
actions.add(CacheVersion.Action.REBUILD_ALL_KOTLIN)
}
}
}
val kotlinModuleBuilderTarget = context.kotlinBuildTargets[chunk.representativeTarget()]!!
kotlinModuleBuilderTarget.checkCachesVersions(chunk, dataManager, actions)
return actions
}
@@ -276,14 +231,20 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
outputConsumer: ModuleLevelBuilder.OutputConsumer
): ModuleLevelBuilder.ExitCode {
JavaBuilderUtil.registerFilterToSkipMarkingAffectedFileDirty(context) {
it.isKotlinSourceFile
}
if (chunk.isDummy(context))
return NOTHING_DONE
val messageCollector = MessageCollectorAdapter(context)
val kotlinTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return OK
val messageCollector = MessageCollectorAdapter(context, kotlinTarget)
val fsOperations = FSOperationsHelper(context, chunk, LOG)
try {
val proposedExitCode = doBuild(chunk, context, dirtyFilesHolder, messageCollector, outputConsumer, fsOperations)
val proposedExitCode = doBuild(chunk, kotlinTarget, context, dirtyFilesHolder, messageCollector, outputConsumer, fsOperations)
val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode
@@ -304,6 +265,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
private fun doBuild(
chunk: ModuleChunk,
representativeTarget: KotlinModuleBuildTarget,
context: CompileContext,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
messageCollector: MessageCollectorAdapter,
@@ -311,12 +273,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
fsOperations: FSOperationsHelper
): ModuleLevelBuilder.ExitCode {
// Workaround for Android Studio
val isJsModule = context.kotlinBuildTargets[chunk.representativeTarget()] is KotlinJsModuleBuildTarget
val isJsModule = representativeTarget is KotlinJsModuleBuildTarget
if (!JavaBuilder.IS_ENABLED[context, true] && !isJsModule) {
messageCollector.report(INFO, "Kotlin JPS plugin is disabled")
return NOTHING_DONE
}
val roundDirtyFilesHolder = KotlinRoundDirtySourceFilesHolder(chunk, context, fsOperations, dirtyFilesHolder)
val projectDescriptor = context.projectDescriptor
val dataManager = projectDescriptor.dataManager
val targets = chunk.targets
@@ -325,7 +288,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val isChunkRebuilding = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)
|| targets.any { rebuildAfterCacheVersionChanged[it] == true }
if (hasKotlinDirtyOrRemovedFiles(dirtyFilesHolder, chunk)) {
if (roundDirtyFilesHolder.hasDirtyOrRemovedFiles) {
if (!isChunkRebuilding && !IncrementalCompilation.isEnabled()) {
targets.forEach { rebuildAfterCacheVersionChanged[it] = true }
return CHUNK_REBUILD_REQUIRED
@@ -347,23 +310,30 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val project = projectDescriptor.project
val lookupTracker = getLookupTracker(project)
val exceptActualTracer = ExpectActualTrackerImpl()
val incrementalCaches = getIncrementalCaches(chunk, context)
val environment = createCompileEnvironment(incrementalCaches, lookupTracker, context, chunk, messageCollector) ?: return ABORT
val environment = createCompileEnvironment(
representativeTarget,
incrementalCaches,
lookupTracker,
exceptActualTracer,
chunk,
messageCollector
) ?: return ABORT
val commonArguments = compilerArgumentsForChunk(chunk).apply {
val commonArguments = representativeTarget.compilerArgumentsForChunk(chunk).apply {
reportOutputFiles = true
version = true // Always report the version to help diagnosing user issues if they submit the compiler output
}
val allCompiledFiles = getAllCompiledFilesContainer(context)
val filesToCompile = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder)
LOG.debug("Compiling files: ${filesToCompile.values()}")
if (LOG.isDebugEnabled) {
LOG.debug("Compiling files: ${roundDirtyFilesHolder.dirtyFiles}")
}
val start = System.nanoTime()
val outputItemCollector = doCompileModuleChunk(
allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder,
environment, filesToCompile, incrementalCaches, fsOperations
chunk, representativeTarget, commonArguments, context, roundDirtyFilesHolder, environment,
incrementalCaches
)
statisticsLogger.registerStatistic(chunk, System.nanoTime() - start)
@@ -386,7 +356,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
saveVersions(context, chunk, commonArguments)
if (targets.any { hasKotlin[it] == null }) {
fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = filesToCompile.values().toSet())
fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = roundDirtyFilesHolder.dirtyFiles)
}
for (target in targets) {
@@ -398,7 +368,12 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
context.kotlinBuildTargets[it]?.doAfterBuild()
}
updateJavaMappings(chunk, context, dirtyFilesHolder, filesToCompile, generatedFiles, incrementalCaches)
representativeTarget.updateChunkMappings(
chunk,
roundDirtyFilesHolder,
generatedFiles,
incrementalCaches
)
if (!IncrementalCompilation.isEnabled()) {
return OK
@@ -410,14 +385,17 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
progress.progress("updating IC caches")
val changesCollector = ChangesCollector()
for ((target, files) in generatedFiles) {
updateIncrementalCache(files, incrementalCaches[target]!!, changesCollector, null)
val kotlinModuleBuilderTarget = context.kotlinBuildTargets[target]!!
kotlinModuleBuilderTarget.updateCaches(incrementalCaches[target]!!, files, changesCollector, environment)
}
updateLookupStorage(chunk, lookupTracker, dataManager, dirtyFilesHolder, filesToCompile)
updateLookupStorage(lookupTracker, dataManager, roundDirtyFilesHolder)
if (!isChunkRebuilding) {
changesCollector.processChangesUsingLookups(
filesToCompile.values().toSet(),
roundDirtyFilesHolder.dirtyFiles,
dataManager,
fsOperations,
incrementalCaches.values
@@ -451,8 +429,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
LOG.info("Clearing caches for " + targets.joinToString { it.presentableName })
val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager)
val kotlinBuildTargets = context.kotlinBuildTargets
for (target in targets) {
dataManager.getKotlinCache(target).clean()
dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean()
hasKotlin.clean(target)
rebuildAfterCacheVersionChanged[target] = true
}
@@ -464,8 +443,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
CacheVersion.Action.CLEAN_NORMAL_CACHES -> {
LOG.info("Clearing caches for all targets")
val kotlinBuildTargets = context.kotlinBuildTargets
for (target in context.allTargets()) {
dataManager.getKotlinCache(target).clean()
dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean()
}
}
CacheVersion.Action.CLEAN_DATA_CONTAINER -> {
@@ -491,12 +471,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager)
for (sourceRoot in sourceRoots) {
val ktFiles = sourceRoot.file.walk().filter { KotlinSourceFileCollector.isKotlinSourceFile(it) }
val ktFiles = sourceRoot.file.walk().filter { it.isKotlinSourceFile }
fsOperations.markFiles(ktFiles.toList())
}
val kotlinBuildTargets = context.kotlinBuildTargets
for (target in context.allTargets()) {
dataManager.getKotlinCache(target).clean()
dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean()
rebuildAfterCacheVersionChanged[target] = true
}
@@ -520,19 +501,14 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
}
}
private fun compilerArgumentsForChunk(chunk: ModuleChunk): CommonCompilerArguments =
chunk.representativeTarget().module.kotlinCompilerArguments
private fun doCompileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk,
kotlinTarget: KotlinModuleBuildTarget,
commonArguments: CommonCompilerArguments,
context: CompileContext,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
roundDirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>,
incrementalCaches: Map<ModuleBuildTarget, IncrementalJvmCache>,
fsOperations: FSOperationsHelper
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>
): OutputItemsCollector? {
val representativeTarget = chunk.representativeTarget()
@@ -556,39 +532,40 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
if (IncrementalCompilation.isEnabled()) {
for (target in chunk.targets) {
val cache = incrementalCaches[target]!!
val removedAndDirtyFiles = filesToCompile[target] + dirtyFilesHolder.getRemovedFiles(target).map(::File)
cache.markDirty(removedAndDirtyFiles)
val cache = incrementalCaches[target]
val targetDirtyFiles = roundDirtyFilesHolder.byTarget[target]
if (cache != null && targetDirtyFiles != null) {
val removedAndDirtyFiles: MutableSet<File> = mutableSetOf()
removedAndDirtyFiles.addAll(roundDirtyFilesHolder.getDirtyFiles(target))
removedAndDirtyFiles.addAll(roundDirtyFilesHolder.getRemovedFilesSet(target))
val complementaryFiles = cache.clearComplementaryFilesMapping(targetDirtyFiles.dirtyOrRemovedFiles)
targetDirtyFiles.markDirty(complementaryFiles)
cache.markDirty(targetDirtyFiles.dirtyOrRemovedFiles)
}
}
}
val kotlinModuleBuilderTarget = context.kotlinBuildTargets[representativeTarget]
val isDoneSomething = kotlinModuleBuilderTarget?.compileModuleChunk(
allCompiledFiles, chunk, commonArguments, dirtyFilesHolder,
environment, filesToCompile, fsOperations
) ?: false
val isDoneSomething = kotlinTarget.compileModuleChunk(
chunk, commonArguments, roundDirtyFilesHolder, environment
)
return if (isDoneSomething) environment.outputItemsCollector else null
}
private fun createCompileEnvironment(
incrementalCaches: Map<ModuleBuildTarget, IncrementalCache>,
kotlinModuleBuilderTarget: KotlinModuleBuildTarget,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>,
lookupTracker: LookupTracker,
context: CompileContext,
exceptActualTracer: ExpectActualTracker,
chunk: ModuleChunk,
messageCollector: MessageCollectorAdapter
): JpsCompilerEnvironment? {
val compilerServices = with(Services.Builder()) {
register(LookupTracker::class.java, lookupTracker)
register(
IncrementalCompilationComponents::class.java,
IncrementalCompilationComponentsImpl(incrementalCaches.mapKeys { context.kotlinBuildTargets[it.key]!!.targetId })
)
register(CompilationCanceledStatus::class.java, object : CompilationCanceledStatus {
override fun checkCanceled() {
if (context.cancelStatus.isCanceled) throw CompilationCanceledException()
}
})
kotlinModuleBuilderTarget.makeServices(this, incrementalCaches, lookupTracker, exceptActualTracer)
build()
}
@@ -607,7 +584,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
classesToLoadByParent,
messageCollector,
OutputItemsCollectorImpl(),
ProgressReporterImpl(context, chunk)
ProgressReporterImpl(kotlinModuleBuilderTarget.context, chunk)
)
}
@@ -641,7 +618,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val sourceToTarget = HashMap<File, ModuleBuildTarget>()
if (chunk.targets.size > 1) {
for (target in chunk.targets) {
context.kotlinBuildTargets[target]?.sources?.forEach {
context.kotlinBuildTargets[target]?.sourceFiles?.forEach {
sourceToTarget[it] = target
}
}
@@ -650,64 +627,14 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val representativeTarget = chunk.representativeTarget()
fun SimpleOutputItem.target() =
sourceFiles.firstOrNull()?.let { sourceToTarget[it] } ?: chunk.targets.singleOrNull {
it.outputDir?.let {
outputFile.startsWith(it)
} ?: false
} ?: representativeTarget
it.outputDir?.let {
outputFile.startsWith(it)
} ?: false
} ?: representativeTarget
return outputItemCollector.outputs.groupBy(SimpleOutputItem::target, SimpleOutputItem::toGeneratedFile)
}
private fun updateJavaMappings(
chunk: ModuleChunk,
context: CompileContext,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
filesToCompile: MultiMap<ModuleBuildTarget, File>,
outputItems: Map<ModuleBuildTarget, Iterable<GeneratedFile>>,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalJvmCache>
) {
val previousMappings = context.projectDescriptor.dataManager.mappings
val callback = JavaBuilderUtil.getDependenciesRegistrar(context)
val targetDirtyFiles: Map<ModuleBuildTarget, Set<File>> = chunk.targets.keysToMap {
val files = HashSet<File>()
dirtyFilesHolder.getRemovedFiles(it).mapTo(files, ::File)
files.addAll(filesToCompile.get(it))
files
}
fun getOldSourceFiles(target: ModuleBuildTarget, generatedClass: GeneratedJvmClass): Set<File> {
val cache = incrementalCaches[target] ?: return emptySet()
val className = generatedClass.outputClass.className
if (!cache.isMultifileFacade(className)) return emptySet()
val name = previousMappings.getName(className.internalName)
return previousMappings.getClassSources(name)?.toSet() ?: emptySet()
}
for ((target, outputs) in outputItems) {
for (output in outputs) {
if (output !is GeneratedJvmClass) continue
val sourceFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY)
sourceFiles.addAll(getOldSourceFiles(target, output))
sourceFiles.removeAll(targetDirtyFiles[target] ?: emptySet())
sourceFiles.addAll(output.sourceFiles)
callback.associate(
FileUtil.toSystemIndependentName(output.outputFile.canonicalPath),
sourceFiles.map { FileUtil.toSystemIndependentName(it.canonicalPath) },
ClassReader(output.outputClass.fileContents)
)
}
}
val allCompiled = filesToCompile.values()
JavaBuilderUtil.registerFilesToCompile(context, allCompiled)
JavaBuilderUtil.registerSuccessfullyCompiled(context, allCompiled)
}
private fun registerOutputItems(outputConsumer: OutputConsumer, outputItems: Map<ModuleBuildTarget, List<GeneratedFile>>) {
for ((target, outputs) in outputItems) {
for (output in outputs) {
@@ -717,67 +644,18 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
}
private fun updateLookupStorage(
chunk: ModuleChunk,
lookupTracker: LookupTracker,
dataManager: BuildDataManager,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
filesToCompile: MultiMap<ModuleBuildTarget, File>
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder
) {
if (lookupTracker !is LookupTrackerImpl)
throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
val removedFiles = chunk.targets.flatMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) }
dataManager.withLookupStorage { lookupStorage ->
lookupStorage.removeLookupsFrom(filesToCompile.values().asSequence() + removedFiles.asSequence())
lookupStorage.removeLookupsFrom(dirtyFilesHolder.dirtyOrRemovedFilesSet.asSequence())
lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
}
}
class MessageCollectorAdapter(private val context: CompileContext) : MessageCollector {
private var hasErrors = false
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
hasErrors = hasErrors or severity.isError
var prefix = ""
if (severity == EXCEPTION) {
prefix = INTERNAL_ERROR_PREFIX
}
val kind = kind(severity)
if (kind != null) {
context.processMessage(
CompilerMessage(
CompilerRunnerConstants.KOTLIN_COMPILER_NAME,
kind,
prefix + message,
location?.path,
-1, -1, -1,
location?.line?.toLong() ?: -1,
location?.column?.toLong() ?: -1
)
)
} else {
val path = if (location != null) "${location.path}:${location.line}:${location.column}: " else ""
KotlinBuilder.LOG.debug(path + message)
}
}
override fun clear() {
hasErrors = false
}
override fun hasErrors(): Boolean = hasErrors
private fun kind(severity: CompilerMessageSeverity): BuildMessage.Kind? {
return when (severity) {
INFO -> BuildMessage.Kind.INFO
ERROR, EXCEPTION -> BuildMessage.Kind.ERROR
WARNING, STRONG_WARNING -> BuildMessage.Kind.WARNING
LOGGING -> null
else -> throw IllegalArgumentException("Unsupported severity: $severity")
}
}
}
}
private class JpsICReporter : ICReporter {
@@ -792,7 +670,7 @@ private fun ChangesCollector.processChangesUsingLookups(
compiledFiles: Set<File>,
dataManager: BuildDataManager,
fsOperations: FSOperationsHelper,
caches: Iterable<IncrementalJvmCache>
caches: Iterable<JpsIncrementalCache>
) {
val allCaches = caches.flatMap { it.thisWithDependentCaches }
val reporter = JpsICReporter()
@@ -806,7 +684,7 @@ private fun ChangesCollector.processChangesUsingLookups(
}
private fun ChangesCollector.getDirtyFiles(
caches: Iterable<IncrementalCacheCommon<*>>,
caches: Iterable<IncrementalCacheCommon>,
dataManager: BuildDataManager
): Set<File> {
val reporter = JpsICReporter()
@@ -825,16 +703,32 @@ private fun getLookupTracker(project: JpsProject): LookupTracker {
return testLookupTracker
}
private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): Map<ModuleBuildTarget, JpsIncrementalJvmCache> {
private fun getIncrementalCaches(
chunk: ModuleChunk,
context: CompileContext
): Map<ModuleBuildTarget, JpsIncrementalCache> {
val dependentTargets = getDependentTargets(chunk, context)
val dataManager = context.projectDescriptor.dataManager
val chunkCaches = chunk.targets.keysToMap { dataManager.getKotlinCache(it) }
val dependentCaches = dependentTargets.map { dataManager.getKotlinCache(it) }
val kotlinBuildTargets = context.kotlinBuildTargets
val chunkCaches = chunk.targets.keysToMapExceptNulls {
val kotlinModuleBuilderTarget = kotlinBuildTargets[it]
if (kotlinModuleBuilderTarget !is KotlinCommonModuleBuildTarget) {
dataManager.getKotlinCache(kotlinBuildTargets[it]!!)
} else null
}
val dependentCaches = dependentTargets.mapNotNull {
val kotlinModuleBuilderTarget = kotlinBuildTargets[it]
if (kotlinModuleBuilderTarget !is KotlinCommonModuleBuildTarget) {
dataManager.getKotlinCache(kotlinModuleBuilderTarget!!)
} else null
}
for (chunkCache in chunkCaches.values) {
for (dependentCache in dependentCaches) {
chunkCache.addDependentCache(dependentCache)
chunkCache.addJpsDependentCache(dependentCache)
}
}
@@ -876,41 +770,5 @@ fun getDependentTargets(
private fun getDependenciesRecursively(module: JpsModule, kind: JpsJavaClasspathKind): Set<JpsModule> =
JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().modules
// TODO: investigate thread safety
private val ALL_COMPILED_FILES_KEY = Key.create<MutableSet<File>>("_all_kotlin_compiled_files_")
fun getAllCompiledFilesContainer(context: CompileContext): MutableSet<File> {
var allCompiledFiles = ALL_COMPILED_FILES_KEY.get(context)
if (allCompiledFiles == null) {
allCompiledFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY)
ALL_COMPILED_FILES_KEY.set(context, allCompiledFiles)
}
return allCompiledFiles
}
// TODO: investigate thread safety
private val PROCESSED_TARGETS_WITH_REMOVED_FILES = Key.create<MutableSet<ModuleBuildTarget>>("_processed_targets_with_removed_files_")
val CompileContext.processedTargetsWithRemovedFilesContainer: MutableSet<ModuleBuildTarget>
get() {
var set = PROCESSED_TARGETS_WITH_REMOVED_FILES.get(this)
if (set == null) {
set = HashSet()
PROCESSED_TARGETS_WITH_REMOVED_FILES.set(this, set)
}
return set
}
private fun hasKotlinDirtyOrRemovedFiles(
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
chunk: ModuleChunk
): Boolean {
if (!dirtyFilesHolder.hasDirtyFiles() && !dirtyFilesHolder.hasRemovedFiles()) return false
if (!KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder).isEmpty) return true
return chunk.targets.any { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it).isNotEmpty() }
}
fun jvmBuildMetaInfoFile(target: ModuleBuildTarget, dataManager: BuildDataManager): File =
File(dataManager.dataPaths.getTargetDataRoot(target), KotlinBuilder.JVM_BUILD_META_INFO_FILE_NAME)
@@ -0,0 +1,86 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.build
import org.jetbrains.jps.builders.AdditionalRootsProviderService
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.java.JavaSourceRootProperties
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
import org.jetbrains.kotlin.config.KotlinSourceRootType
import org.jetbrains.kotlin.jps.model.expectedByModules
import java.io.File
/**
* Required for Multiplatform Projects.
*
* Adds all the source roots of the expectedBy modules to the platform modules.
*/
class KotlinMppCommonSourceRootProvider : AdditionalRootsProviderService<JavaSourceRootDescriptor>(JavaModuleBuildTargetType.ALL_TYPES) {
override fun getAdditionalRoots(
target: BuildTarget<JavaSourceRootDescriptor>,
dataPaths: BuildDataPaths?
): List<JavaSourceRootDescriptor> {
val moduleBuildTarget = target as? ModuleBuildTarget ?: return listOf()
val module = moduleBuildTarget.module
val result = mutableListOf<JavaSourceRootDescriptor>()
module.expectedByModules.forEach { commonModule ->
addSourceRoots(result, commonModule, target)
}
return result
}
private fun addSourceRoots(
result: MutableList<JavaSourceRootDescriptor>,
commonModule: JpsModule,
target: ModuleBuildTarget
) {
for (commonSourceRoot in commonModule.sourceRoots) {
val isCommonTestsRootType = commonSourceRoot.rootType.isTestsRootType
if (isCommonTestsRootType == null || target.isTests == isCommonTestsRootType) {
val javaSourceRootProperties = commonSourceRoot.properties as? JavaSourceRootProperties
result.add(
KotlinCommonModuleSourceRoot(
commonModule,
commonSourceRoot.file,
target,
javaSourceRootProperties?.isForGeneratedSources ?: false,
false,
javaSourceRootProperties?.packagePrefix ?: "",
setOf()
)
)
}
}
}
}
private val JpsModuleSourceRootType<*>.isTestsRootType
get() = when (this) {
is KotlinSourceRootType -> this == KotlinSourceRootType.TestSource
is JavaSourceRootType -> this == JavaSourceRootType.TEST_SOURCE // for compatibility
else -> null
}
class KotlinCommonModuleSourceRoot(
val commonModule: JpsModule,
root: File,
target: ModuleBuildTarget,
isGenerated: Boolean,
isTemp: Boolean,
packagePrefix: String,
excludes: Set<File>
) : JavaSourceRootDescriptor(root, target, isGenerated, isTemp, packagePrefix, excludes)
@@ -0,0 +1,141 @@
/*
* Copyright 2010-2015 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 com.intellij.openapi.util.io.FileUtilRt
import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.DirtyFilesHolder
import org.jetbrains.jps.builders.FileProcessor
import org.jetbrains.jps.builders.impl.DirtyFilesHolderBase
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget
import java.io.File
/**
* Holding kotlin dirty files list for particular build round.
* Dirty and removed files set are initialized from [delegate].
*
* Probably should be merged with [FSOperationsHelper]
*/
class KotlinRoundDirtySourceFilesHolder(
val chunk: ModuleChunk,
val context: CompileContext,
val fsOperations: FSOperationsHelper,
delegate: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>
) : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
val byTarget: Map<ModuleBuildTarget, TargetFiles>
inner class TargetFiles(val target: ModuleBuildTarget, val removed: Collection<String>) {
val dirty: MutableSet<DirtyFile> = mutableSetOf()
val dirtyOrRemovedFiles: Set<File>
get() {
val result = mutableSetOf<File>()
dirty.forEach { result.add(it.file) }
removed.forEach { result.add(File(it)) }
return result
}
fun markDirty(files: Collection<File>) {
fsOperations.markFiles(files)
files.forEach {
dirty.add(DirtyFile(it, null))
}
}
}
data class DirtyFile(val file: File, val root: JavaSourceRootDescriptor?)
val hasRemovedFiles: Boolean
override fun hasRemovedFiles(): Boolean = hasRemovedFiles
val hasDirtyFiles: Boolean
override fun hasDirtyFiles(): Boolean = hasDirtyFiles
val hasDirtyOrRemovedFiles: Boolean
get() = hasRemovedFiles || hasDirtyFiles
init {
val byTarget = mutableMapOf<ModuleBuildTarget, TargetFiles>()
var hasDirtyFiles = false
var hasRemovedFiles = false
chunk.targets.forEach { target ->
val removedFiles = delegate.getRemovedFiles(target)
if (removedFiles.isNotEmpty()) {
hasRemovedFiles = true
}
byTarget[target] = TargetFiles(target, removedFiles)
}
delegate.processDirtyFiles { target, file, root ->
val targetInfo = byTarget[target]
?: error("processDirtyFiles should callback only on chunk `$chunk` targets (`$target` is not)")
if (file.isKotlinSourceFile) {
targetInfo.dirty.add(DirtyFile(file, root))
hasDirtyFiles = true
}
true
}
this.byTarget = byTarget
this.hasRemovedFiles = hasRemovedFiles
this.hasDirtyFiles = hasDirtyFiles
}
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
for ((target, info) in byTarget) {
info.dirty.forEach {
if (!processor.apply(target, it.file, it.root)) return
}
}
}
fun getDirtyFiles(target: ModuleBuildTarget): Set<File> =
byTarget[target]?.dirty?.mapTo(mutableSetOf()) { it.file } ?: setOf()
fun getRemovedFilesSet(target: ModuleBuildTarget): Set<File> =
byTarget[target]?.removed?.mapTo(mutableSetOf()) { File(it) } ?: setOf()
override fun getRemovedFiles(target: ModuleBuildTarget): Collection<String> =
byTarget.flatMap { it.value.removed }
val removedFilesCount
get() = byTarget.values.flatMapTo(mutableSetOf()) { it.removed }.size
val dirtyFiles: Set<File>
get() = byTarget.flatMapTo(mutableSetOf()) { it.value.dirty.map { it.file } }
val dirtyOrRemovedFilesSet: Set<File>
get() {
val result = mutableSetOf<File>()
byTarget.forEach {
it.value.dirty.forEach { result.add(it.file) }
it.value.removed.forEach { result.add(File(it)) }
}
return result
}
}
val File.isKotlinSourceFile: Boolean
get() = FileUtilRt.extensionEquals(name, "kt")
@@ -1,53 +0,0 @@
/*
* Copyright 2010-2015 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 com.intellij.openapi.util.io.FileUtilRt
import com.intellij.util.containers.MultiMap
import org.jetbrains.jps.builders.DirtyFilesHolder
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.incremental.ModuleBuildTarget
import java.io.File
object KotlinSourceFileCollector {
// For incremental compilation
fun getDirtySourceFiles(dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>): MultiMap<ModuleBuildTarget, File> {
val result = MultiMap<ModuleBuildTarget, File>()
dirtyFilesHolder.processDirtyFiles { target, file, root ->
//TODO this is a workaround for bug in JPS: the latter erroneously calls process with invalid parameters
if (root.getTarget() == target && isKotlinSourceFile(file)) {
result.putValue(target, file)
}
true
}
return result
}
fun getRemovedKotlinFiles(
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
target: ModuleBuildTarget
): List<File> =
dirtyFilesHolder
.getRemovedFiles(target)
.mapNotNull { if (FileUtilRt.extensionEquals(it, "kt")) File(it) else null }
internal fun isKotlinSourceFile(file: File): Boolean {
return FileUtilRt.extensionEquals(file.name, "kt")
}
}
@@ -0,0 +1,71 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.build
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.messages.BuildMessage
import org.jetbrains.jps.incremental.messages.CompilerMessage
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.CompilerRunnerConstants
import org.jetbrains.kotlin.jps.platforms.KotlinModuleBuildTarget
class MessageCollectorAdapter(
private val context: CompileContext,
val kotlinTarget: KotlinModuleBuildTarget?
) : MessageCollector {
private var hasErrors = false
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
hasErrors = hasErrors || severity.isError
var prefix = ""
if (severity == CompilerMessageSeverity.EXCEPTION) {
prefix = CompilerRunnerConstants.INTERNAL_ERROR_PREFIX
}
val kind = kind(severity)
if (kind != null) {
// Report target when cross-compiling common files
if (location != null && kotlinTarget != null && kotlinTarget.isCommonModuleFile(location.path)) {
val moduleName = kotlinTarget.module.name
prefix += "[$moduleName] "
}
context.processMessage(
CompilerMessage(
CompilerRunnerConstants.KOTLIN_COMPILER_NAME,
kind,
prefix + message,
location?.path,
-1, -1, -1,
location?.line?.toLong() ?: -1,
location?.column?.toLong() ?: -1
)
)
} else {
val path = if (location != null) "${location.path}:${location.line}:${location.column}: " else ""
KotlinBuilder.LOG.debug(path + message)
}
}
override fun clear() {
hasErrors = false
}
override fun hasErrors(): Boolean = hasErrors
private fun kind(severity: CompilerMessageSeverity): BuildMessage.Kind? {
return when (severity) {
CompilerMessageSeverity.INFO -> BuildMessage.Kind.INFO
CompilerMessageSeverity.ERROR, CompilerMessageSeverity.EXCEPTION -> BuildMessage.Kind.ERROR
CompilerMessageSeverity.WARNING, CompilerMessageSeverity.STRONG_WARNING -> BuildMessage.Kind.WARNING
CompilerMessageSeverity.LOGGING -> null
else -> throw IllegalArgumentException("Unsupported severity: $severity")
}
}
}
@@ -21,32 +21,50 @@ import org.jetbrains.jps.builders.storage.StorageProvider
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.incremental.storage.StorageOwner
import org.jetbrains.kotlin.incremental.IncrementalCacheCommon
import org.jetbrains.kotlin.incremental.IncrementalJsCache
import org.jetbrains.kotlin.incremental.IncrementalJvmCache
import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.platforms.KotlinModuleBuildTarget
import java.io.File
interface JpsIncrementalCache : IncrementalCacheCommon, StorageOwner {
fun addJpsDependentCache(cache: JpsIncrementalCache)
}
class JpsIncrementalJvmCache(
target: ModuleBuildTarget,
paths: BuildDataPaths
) : IncrementalJvmCache(paths.getTargetDataRoot(target), target.outputDir), StorageOwner {
) : IncrementalJvmCache(paths.getTargetDataRoot(target), target.outputDir), JpsIncrementalCache {
override fun addJpsDependentCache(cache: JpsIncrementalCache) {
addDependentCache(cache as JpsIncrementalJvmCache)
}
override fun debugLog(message: String) {
KotlinBuilder.LOG.debug(message)
}
}
private class KotlinIncrementalStorageProvider(
private val target: ModuleBuildTarget,
private val paths: BuildDataPaths
) : StorageProvider<JpsIncrementalJvmCache>() {
class JpsIncrementalJsCache(
target: ModuleBuildTarget,
paths: BuildDataPaths
) : IncrementalJsCache(paths.getTargetDataRoot(target)), JpsIncrementalCache {
override fun addJpsDependentCache(cache: JpsIncrementalCache) {
addDependentCache(cache as JpsIncrementalJsCache)
}
}
private class KotlinIncrementalStorageProvider(
private val target: KotlinModuleBuildTarget,
private val paths: BuildDataPaths
) : StorageProvider<JpsIncrementalCache>() {
override fun equals(other: Any?) = other is KotlinIncrementalStorageProvider && target == other.target
override fun hashCode() = target.hashCode()
override fun createStorage(targetDataDir: File): JpsIncrementalJvmCache =
JpsIncrementalJvmCache(target, paths)
override fun createStorage(targetDataDir: File): JpsIncrementalCache = target.createCacheStorage(paths)
}
fun BuildDataManager.getKotlinCache(target: ModuleBuildTarget): JpsIncrementalJvmCache =
getStorage(target, KotlinIncrementalStorageProvider(target, dataPaths))
fun BuildDataManager.getKotlinCache(target: KotlinModuleBuildTarget): JpsIncrementalCache =
getStorage(target.jpsModuleBuildTarget, KotlinIncrementalStorageProvider(target, dataPaths))
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.jps.model
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.model.ex.JpsElementBase
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.config.CompilerSettings
@@ -19,6 +22,25 @@ val JpsModule.kotlinFacet: JpsKotlinFacetModuleExtension?
val JpsModule.targetPlatform: TargetPlatformKind<*>?
get() = kotlinFacet?.settings?.targetPlatformKind
val JpsModule.expectedByModules: List<JpsModule>
get() {
val kotlinFacetExtension = kotlinFacet
val implementedModuleNames = kotlinFacetExtension?.settings?.implementedModuleNames ?: return listOf()
if (implementedModuleNames.isEmpty()) return listOf()
val result = ArrayList<JpsModule>(implementedModuleNames.size)
JpsJavaExtensionService.dependencies(this)
.processModules {
if (it.name in implementedModuleNames) {
// Note, production sources should be added for both production and tests targets
result.add(it)
}
}
return result
}
val JpsModule.productionOutputFilePath: String?
get() {
val facetSettings = kotlinFacet?.settings ?: return null
@@ -59,7 +81,7 @@ private inline fun <reified T : CommonCompilerArguments> JpsModule.getCompilerAr
val facetSettings = kotlinFacet?.settings ?: return projectSettingsCopy
if (facetSettings.useProjectSettings) return projectSettingsCopy
return facetSettings.compilerArguments as? T ?: projectSettingsCopy
return facetSettings.mergedCompilerArguments as? T ?: projectSettingsCopy
}
class JpsKotlinFacetModuleExtension(settings: KotlinFacetSettings) : JpsElementBase<JpsKotlinFacetModuleExtension>() {
@@ -5,49 +5,87 @@
package org.jetbrains.kotlin.jps.platforms
import com.intellij.util.containers.MultiMap
import com.intellij.util.xmlb.XmlSerializerUtil
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.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.FSOperations
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.fs.CompilationRound
import org.jetbrains.jps.model.library.JpsOrderRootType
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.mergeBeans
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.jps.build.FSOperationsHelper
import org.jetbrains.kotlin.jps.build.KotlinRoundDirtySourceFilesHolder
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache
import org.jetbrains.kotlin.jps.model.k2MetadataCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
import java.io.File
class KotlinCommonModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) {
class KotlinCommonModuleBuildTarget(context: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
KotlinModuleBuildTarget(context, jpsModuleBuildTarget) {
override fun compileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk,
commonArguments: CommonCompilerArguments,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>,
fsOperations: FSOperationsHelper
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment
): Boolean {
require(chunk.representativeTarget() == jpsModuleBuildTarget)
if (reportAndSkipCircular(chunk, environment)) return false
reportAndSkipCircular(chunk, environment)
// Incremental compilation is not supported, so mark all dependents as dirty
FSOperations.markDirtyRecursively(context, CompilationRound.CURRENT, chunk)
JpsKotlinCompilerRunner().runK2MetadataCompiler(
commonArguments,
module.k2MetadataCompilerArguments,
module.kotlinCompilerSettings,
environment,
sources
)
val k2MetadataArguments = module.k2MetadataCompilerArguments
if (k2MetadataArguments.enabledInJps || (commonArguments as? K2MetadataCompilerArguments)?.enabledInJps == true) {
JpsKotlinCompilerRunner().runK2MetadataCompiler(
commonArguments,
k2MetadataArguments,
module.kotlinCompilerSettings,
environment,
destination,
dependenciesOutputDirs + libraryFiles,
sourceFiles // incremental K2MetadataCompiler not supported yet
)
}
return true
}
private val libraryFiles: List<String>
get() = mutableListOf<String>().also { result ->
for (library in allDependencies.libraries) {
for (root in library.getRoots(JpsOrderRootType.COMPILED)) {
result.add(JpsPathUtil.urlToPath(root.url))
}
}
}
private val dependenciesOutputDirs: List<String>
get() = mutableListOf<String>().also { result ->
allDependencies.processModules { module ->
if (isTests) addDependencyMetaFile(module, result, isTests = true)
// note: production targets should be also added as dependency to test targets
addDependencyMetaFile(module, result, isTests = false)
}
}
val destination: String
get() = module.k2MetadataCompilerArguments.destination ?: outputDir.absolutePath
private fun addDependencyMetaFile(
module: JpsModule,
result: MutableList<String>,
isTests: Boolean
) {
val dependencyBuildTarget = context.kotlinBuildTargets[ModuleBuildTarget(module, isTests)]
if (dependencyBuildTarget != this@KotlinCommonModuleBuildTarget &&
dependencyBuildTarget is KotlinCommonModuleBuildTarget &&
dependencyBuildTarget.sourceFiles.isNotEmpty()
) {
result.add(dependencyBuildTarget.destination)
}
}
override fun createCacheStorage(paths: BuildDataPaths) = JpsIncrementalJvmCache(jpsModuleBuildTarget, paths) // todo: delete
}
@@ -5,19 +5,30 @@
package org.jetbrains.kotlin.jps.platforms
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 org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.library.JpsOrderRootType
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.jps.build.FSOperationsHelper
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.ChangesCollector
import org.jetbrains.kotlin.incremental.IncrementalJsCache
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
import org.jetbrains.kotlin.jps.build.KotlinRoundDirtySourceFilesHolder
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJsCache
import org.jetbrains.kotlin.jps.model.k2JsCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
@@ -28,23 +39,56 @@ import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.META_JS_SUFFIX
import java.io.File
import java.net.URI
internal class IncrementalDataProviderFromCache(private val cache: IncrementalJsCache) : IncrementalDataProvider {
override val headerMetadata: ByteArray
get() = cache.header
override val compiledPackageParts: Map<File, TranslationResultValue>
get() = cache.nonDirtyPackageParts()
}
class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) {
KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) {
val sourceToOutputMap
get() = context.projectDescriptor.dataManager.getSourceToOutputMap(jpsModuleBuildTarget)
val isFirstBuild
get() = sourceToOutputMap.sources.isEmpty()
override fun makeServices(
builder: Services.Builder,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker
) {
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer)
with(builder) {
register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl())
if (IncrementalCompilation.isEnabled() && !isFirstBuild) {
val cache = incrementalCaches[jpsModuleBuildTarget] as IncrementalJsCache
register(
IncrementalDataProvider::class.java,
IncrementalDataProviderFromCache(cache)
)
}
}
}
override fun compileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk,
commonArguments: CommonCompilerArguments,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>,
fsOperations: FSOperationsHelper
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment
): Boolean {
require(chunk.representativeTarget() == jpsModuleBuildTarget)
if (reportAndSkipCircular(chunk, environment)) return false
val sources = sources
if (sources.isEmpty()) return false
val sources = collectSourcesToCompile(dirtyFilesHolder)
if (!checkShouldCompileAndLog(dirtyFilesHolder, sources)) return false
val libraries = libraryFiles + dependenciesMetaFiles
@@ -144,7 +188,7 @@ class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTa
if (dependencyBuildTarget != this@KotlinJsModuleBuildTarget &&
dependencyBuildTarget is KotlinJsModuleBuildTarget &&
dependencyBuildTarget.sources.isNotEmpty()
dependencyBuildTarget.sourceFiles.isNotEmpty()
) {
val metaFile = dependencyBuildTarget.outputMetaFile
if (metaFile.exists()) {
@@ -152,4 +196,24 @@ class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTa
}
}
}
override fun createCacheStorage(paths: BuildDataPaths) =
JpsIncrementalJsCache(jpsModuleBuildTarget, paths)
override fun updateCaches(
jpsIncrementalCache: JpsIncrementalCache,
files: List<GeneratedFile>,
changesCollector: ChangesCollector,
environment: JpsCompilerEnvironment
) {
super.updateCaches(jpsIncrementalCache, files, changesCollector, environment)
val incrementalResults = environment.services[IncrementalResultsConsumer::class.java] as IncrementalResultsConsumerImpl
val jsCache = jpsIncrementalCache as IncrementalJsCache
jsCache.header = incrementalResults.headerMetadata
jsCache.compareAndUpdate(incrementalResults, changesCollector)
jsCache.clearCacheForRemovedClasses(changesCollector)
}
}
@@ -9,42 +9,120 @@ import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.MultiMap
import com.intellij.util.io.URLUtil
import gnu.trove.THashSet
import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.DirtyFilesHolder
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.builders.java.JavaBuilderUtil
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsSdkDependency
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.build.JvmBuildMetaInfo
import org.jetbrains.kotlin.build.JvmSourceRoot
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.jps.build.FSOperationsHelper
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.build.KotlinSourceFileCollector
import org.jetbrains.kotlin.jps.build.processedTargetsWithRemovedFilesContainer
import org.jetbrains.kotlin.jps.build.KotlinRoundDirtySourceFilesHolder
import org.jetbrains.kotlin.jps.build.jvmBuildMetaInfoFile
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache
import org.jetbrains.kotlin.jps.model.k2JvmCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.utils.keysToMap
import org.jetbrains.org.objectweb.asm.ClassReader
import java.io.File
import java.io.IOException
class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) {
KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) {
override fun createCacheStorage(paths: BuildDataPaths) = JpsIncrementalJvmCache(jpsModuleBuildTarget, paths)
override fun checkCachesVersions(chunk: ModuleChunk, dataManager: BuildDataManager, actions: MutableSet<CacheVersion.Action>) {
val args = compilerArgumentsForChunk(chunk)
val currentBuildMetaInfo = JvmBuildMetaInfo(args)
for (target in chunk.targets) {
val file = jvmBuildMetaInfoFile(target, dataManager)
if (!file.exists()) continue
val lastBuildMetaInfo =
try {
JvmBuildMetaInfo.deserializeFromString(file.readText()) ?: continue
} catch (e: Exception) {
KotlinBuilder.LOG.error("Could not deserialize jvm build meta info", e)
continue
}
val lastBuildLangVersion = LanguageVersion.fromVersionString(lastBuildMetaInfo.languageVersionString)
val lastBuildApiVersion = ApiVersion.parse(lastBuildMetaInfo.apiVersionString)
val currentLangVersion =
args.languageVersion?.let { LanguageVersion.fromVersionString(it) } ?: LanguageVersion.LATEST_STABLE
val currentApiVersion =
args.apiVersion?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(currentLangVersion)
val reasonToRebuild = when {
currentLangVersion != lastBuildLangVersion -> {
"Language version was changed ($lastBuildLangVersion -> $currentLangVersion)"
}
currentApiVersion != lastBuildApiVersion -> {
"Api version was changed ($lastBuildApiVersion -> $currentApiVersion)"
}
lastBuildLangVersion != LanguageVersion.KOTLIN_1_0 && lastBuildMetaInfo.isEAP && !currentBuildMetaInfo.isEAP -> {
// If EAP->Non-EAP build with IC, then rebuild all kotlin
"Last build was compiled with EAP-plugin"
}
else -> null
}
if (reasonToRebuild != null) {
KotlinBuilder.LOG.info("$reasonToRebuild. Performing non-incremental rebuild (kotlin only)")
actions.add(CacheVersion.Action.REBUILD_ALL_KOTLIN)
}
}
}
override fun makeServices(
builder: Services.Builder,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker
) {
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer)
with(builder) {
register(
IncrementalCompilationComponents::class.java,
IncrementalCompilationComponentsImpl(
incrementalCaches.mapKeys { context.kotlinBuildTargets[it.key]!!.targetId } as Map<TargetId, IncrementalCache>
)
)
}
}
override fun compileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk,
commonArguments: CommonCompilerArguments,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>,
fsOperations: FSOperationsHelper
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment
): Boolean {
if (chunk.modules.size > 1) {
environment.messageCollector.report(
@@ -55,34 +133,28 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
)
}
allCompiledFiles.addAll(filesToCompile.values())
val filesSet = dirtyFilesHolder.dirtyFiles
val processedTargetsWithRemoved = context.processedTargetsWithRemovedFilesContainer
var totalRemovedFiles = 0
for (target in chunk.targets) {
val removedFilesInTarget = KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, target)
if (!removedFilesInTarget.isEmpty()) {
if (processedTargetsWithRemoved.add(target)) {
totalRemovedFiles += removedFilesInTarget.size
}
}
}
val moduleFile = generateModuleDescription(context, chunk, filesToCompile, totalRemovedFiles != 0)
val moduleFile = generateModuleDescription(chunk, dirtyFilesHolder)
if (moduleFile == null) {
KotlinBuilder.LOG.debug(
"Not compiling, because no files affected: " + filesToCompile.keySet().joinToString { it.presentableName }
)
if (KotlinBuilder.LOG.isDebugEnabled) {
KotlinBuilder.LOG.debug(
"Not compiling, because no files affected: " + chunk.targets.joinToString { it.presentableName }
)
}
// No Kotlin sources found
return false
}
val module = chunk.representativeTarget().module
KotlinBuilder.LOG.debug("Compiling to JVM ${filesToCompile.values().size} files"
+ (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)")
+ " in " + filesToCompile.keySet().joinToString { it.presentableName })
if (KotlinBuilder.LOG.isDebugEnabled) {
val totalRemovedFiles = dirtyFilesHolder.removedFilesCount
KotlinBuilder.LOG.debug("Compiling to JVM ${filesSet.size} files"
+ (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)")
+ " in " + chunk.targets.joinToString { it.presentableName })
}
try {
val compilerRunner = JpsKotlinCompilerRunner()
@@ -102,39 +174,22 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
return true
}
fun generateModuleDescription(
context: CompileContext,
chunk: ModuleChunk,
sourceFiles: MultiMap<ModuleBuildTarget, File>, // ignored for non-incremental compilation
hasRemovedFiles: Boolean
): File? {
fun generateModuleDescription(chunk: ModuleChunk, dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder): File? {
val builder = KotlinModuleXmlBuilder()
var noSources = true
var hasDirtySources = false
val targets = chunk.targets.mapNotNull { this.context.kotlinBuildTargets[it] as? KotlinJvmModuleBuildTarget }
val outputDirs = targets.map { it.outputDir }.toSet()
val logger = context.loggingManager.projectBuilderLogger
for (target in targets) {
val outputDir = target.outputDir
val friendDirs = target.friendOutputDirs
val moduleSources =
if (IncrementalCompilation.isEnabled() && target.expectedBy.isEmpty()) {
sourceFiles.get(target.jpsModuleBuildTarget)
} else {
target.sources
}
if (moduleSources.isNotEmpty() || hasRemovedFiles) {
noSources = false
if (logger.isEnabled) {
logger.logCompiledFiles(moduleSources, KotlinBuilder.KOTLIN_BUILDER_NAME, "Compiling files:")
}
}
val moduleSources = collectSourcesToCompile(target, dirtyFilesHolder)
val hasDirtyOrRemovedSources = checkShouldCompileAndLog(target, dirtyFilesHolder, moduleSources)
if (hasDirtyOrRemovedSources) hasDirtySources = true
val kotlinModuleId = target.targetId
builder.addModule(
@@ -152,7 +207,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
)
}
if (noSources) return null
if (!hasDirtySources) return null
val scriptFile = createTempFileForModuleDesc(chunk)
FileUtil.writeToFile(scriptFile, builder.asText().toString())
@@ -192,7 +247,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
val extension = file.extension
// Don't filter out files, we want to report warnings about absence through the common place
if (!(extension == "class" || extension == "jar")) {
if (extension != "class" && extension != "jar") {
return@filter false
}
}
@@ -213,7 +268,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
return File(url.substringAfter(StandardFileSystems.JRT_PROTOCOL_PREFIX).substringBeforeLast(URLUtil.JAR_SEPARATOR))
}
fun findSourceRoots(context: CompileContext): List<JvmSourceRoot> {
private fun findSourceRoots(context: CompileContext): List<JvmSourceRoot> {
val roots = context.projectDescriptor.buildRootIndex.getTargetRoots(jpsModuleBuildTarget, context)
val result = ContainerUtil.newArrayList<JvmSourceRoot>()
for (root in roots) {
@@ -225,4 +280,64 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
}
return result
}
override fun updateCaches(
jpsIncrementalCache: JpsIncrementalCache,
files: List<GeneratedFile>,
changesCollector: ChangesCollector,
environment: JpsCompilerEnvironment
) {
super.updateCaches(jpsIncrementalCache, files, changesCollector, environment)
updateIncrementalCache(files, jpsIncrementalCache as IncrementalJvmCache, changesCollector, null)
}
override fun updateChunkMappings(
chunk: ModuleChunk,
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
outputItems: Map<ModuleBuildTarget, Iterable<GeneratedFile>>,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>
) {
val previousMappings = context.projectDescriptor.dataManager.mappings
val callback = JavaBuilderUtil.getDependenciesRegistrar(context)
val targetDirtyFiles: Map<ModuleBuildTarget, Set<File>> = chunk.targets.keysToMap {
val files = HashSet<File>()
dirtyFilesHolder.getRemovedFiles(it).mapTo(files, ::File)
files.addAll(dirtyFilesHolder.getDirtyFiles(it))
files
}
fun getOldSourceFiles(target: ModuleBuildTarget, generatedClass: GeneratedJvmClass): Set<File> {
val cache = incrementalCaches[target] ?: return emptySet()
cache as JpsIncrementalJvmCache
val className = generatedClass.outputClass.className
if (!cache.isMultifileFacade(className)) return emptySet()
val name = previousMappings.getName(className.internalName)
return previousMappings.getClassSources(name)?.toSet() ?: emptySet()
}
for ((target, outputs) in outputItems) {
for (output in outputs) {
if (output !is GeneratedJvmClass) continue
val sourceFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY)
sourceFiles.addAll(getOldSourceFiles(target, output))
sourceFiles.removeAll(targetDirtyFiles[target] ?: emptySet())
sourceFiles.addAll(output.sourceFiles)
callback.associate(
FileUtil.toSystemIndependentName(output.outputFile.canonicalPath),
sourceFiles.map { FileUtil.toSystemIndependentName(it.canonicalPath) },
ClassReader(output.outputClass.fileContents)
)
}
}
val allCompiled = dirtyFilesHolder.dirtyFiles
JavaBuilderUtil.registerFilesToCompile(context, allCompiled)
JavaBuilderUtil.registerSuccessfullyCompiled(context, allCompiled)
}
}
@@ -0,0 +1,263 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.platforms
import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.ProjectBuildException
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.CacheVersion
import org.jetbrains.kotlin.incremental.ChangesCollector
import org.jetbrains.kotlin.incremental.ExpectActualTrackerImpl
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.jps.build.*
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
import org.jetbrains.kotlin.jps.model.testOutputFilePath
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.progress.CompilationCanceledException
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.utils.addIfNotNull
import java.io.File
/**
* Properties and actions for Kotlin test / production module build target.
*/
abstract class KotlinModuleBuildTarget(val context: CompileContext, val jpsModuleBuildTarget: ModuleBuildTarget) {
val module: JpsModule
get() = jpsModuleBuildTarget.module
val isTests: Boolean
get() = jpsModuleBuildTarget.isTests
val targetId: TargetId
get() {
// Since IDEA 2016 each gradle source root is imported as a separate module.
// One gradle module X is imported as two JPS modules:
// 1. X-production with one production target;
// 2. X-test with one test target.
// This breaks kotlin code since internal members' names are mangled using module name.
// For example, a declaration of a function 'f' in 'X-production' becomes 'fXProduction', but a call 'f' in 'X-test' becomes 'fXTest()'.
// The workaround is to replace a name of such test target with the name of corresponding production module.
// See KT-11993.
val name = relatedProductionModule?.name ?: jpsModuleBuildTarget.id
return TargetId(name, jpsModuleBuildTarget.targetType.typeId)
}
val outputDir by lazy {
val explicitOutputPath = if (isTests) module.testOutputFilePath else module.productionOutputFilePath
val explicitOutputDir = explicitOutputPath?.let { File(it).absoluteFile.parentFile }
return@lazy explicitOutputDir
?: jpsModuleBuildTarget.outputDir
?: throw ProjectBuildException("No output directory found for " + this)
}
val friendBuildTargets: List<KotlinModuleBuildTarget>
get() {
val result = mutableListOf<KotlinModuleBuildTarget>()
if (isTests) {
result.addIfNotNull(context.kotlinBuildTargets[module.productionBuildTarget])
result.addIfNotNull(context.kotlinBuildTargets[relatedProductionModule?.productionBuildTarget])
}
return result.filter { it.sourceFiles.isNotEmpty() }
}
val friendOutputDirs: List<File>
get() = friendBuildTargets.mapNotNull {
JpsJavaExtensionService.getInstance().getOutputDirectory(it.module, false)
}
private val relatedProductionModule: JpsModule?
get() = JpsJavaExtensionService.getInstance().getTestModuleProperties(module)?.productionModule
val allDependencies by lazy {
JpsJavaExtensionService.dependencies(module).recursively().exportedOnly()
.includedIn(JpsJavaClasspathKind.compile(isTests))
}
val sources by lazy {
mutableMapOf<String, Source>().also { result ->
collectSources(result)
}
}
private fun collectSources(receiver: MutableMap<String, Source>) {
val moduleExcludes = module.excludeRootsList.urls.mapTo(java.util.HashSet(), JpsPathUtil::urlToFile)
val compilerExcludes = JpsJavaExtensionService.getInstance()
.getOrCreateCompilerConfiguration(module.project)
.compilerExcludes
val buildRootIndex = context.projectDescriptor.buildRootIndex
val roots = buildRootIndex.getTargetRoots(jpsModuleBuildTarget, context)
roots.forEach { rootDescriptor ->
val isCommonRoot = rootDescriptor is KotlinCommonModuleSourceRoot
rootDescriptor.root.walkTopDown()
.onEnter { file -> file !in moduleExcludes }
.forEach { file ->
if (!compilerExcludes.isExcluded(file) && file.isFile && file.isKotlinSourceFile) {
receiver[file.path] = Source(file, isCommonRoot)
}
}
}
}
/**
* @property isCommonModule for reporting errors during cross-compilation common module sources
*/
class Source(
val file: File,
val isCommonModule: Boolean
)
fun isCommonModuleFile(path: String): Boolean = sources[path]?.isCommonModule == true
val sourceFiles by lazy {
sources.values.map { it.file }
}
override fun toString() = jpsModuleBuildTarget.toString()
/**
* Called for `ModuleChunk.representativeTarget`
*/
abstract fun compileModuleChunk(
chunk: ModuleChunk,
commonArguments: CommonCompilerArguments,
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment
): Boolean
protected fun reportAndSkipCircular(
chunk: ModuleChunk,
environment: JpsCompilerEnvironment
): Boolean {
if (chunk.modules.size > 1) {
// We do not support circular dependencies, but if they are present, we do our best should not break the build,
// so we simply yield a warning and report NOTHING_DONE
environment.messageCollector.report(
CompilerMessageSeverity.STRONG_WARNING,
"Circular dependencies are not supported. The following modules depend on each other: "
+ chunk.modules.joinToString(", ") { it.name } + " "
+ "Kotlin is not compiled for these modules"
)
return true
}
return false
}
fun compilerArgumentsForChunk(chunk: ModuleChunk): CommonCompilerArguments =
chunk.representativeTarget().module.kotlinCompilerArguments
open fun doAfterBuild() {
}
abstract fun createCacheStorage(paths: BuildDataPaths): JpsIncrementalCache
/**
* Called for `ModuleChunk.representativeTarget`
*/
open fun updateChunkMappings(
chunk: ModuleChunk,
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
outputItems: Map<ModuleBuildTarget, Iterable<GeneratedFile>>,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>
) {
// by default do nothing
}
open fun updateCaches(
jpsIncrementalCache: JpsIncrementalCache,
files: List<GeneratedFile>,
changesCollector: ChangesCollector,
environment: JpsCompilerEnvironment
) {
val expectActualTracker = environment.services[ExpectActualTracker::class.java] as ExpectActualTrackerImpl
jpsIncrementalCache.registerComplementaryFiles(expectActualTracker)
}
open fun makeServices(
builder: Services.Builder,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker
) {
with(builder) {
register(LookupTracker::class.java, lookupTracker)
register(ExpectActualTracker::class.java, exceptActualTracer)
register(CompilationCanceledStatus::class.java, object : CompilationCanceledStatus {
override fun checkCanceled() {
if (context.cancelStatus.isCanceled) throw CompilationCanceledException()
}
})
}
}
protected fun collectSourcesToCompile(dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder) =
collectSourcesToCompile(this, dirtyFilesHolder)
/**
* Should be used only for particular target in chunk (jvm)
*/
protected fun collectSourcesToCompile(
target: KotlinModuleBuildTarget,
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder
): Collection<File> {
// Should not be cached since may be vary in different rounds
val jpsModuleTarget = target.jpsModuleBuildTarget
return if (IncrementalCompilation.isEnabled()) dirtyFilesHolder.getDirtyFiles(jpsModuleTarget)
else target.sourceFiles
}
protected fun checkShouldCompileAndLog(dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder, moduleSources: Collection<File>) =
checkShouldCompileAndLog(this, dirtyFilesHolder, moduleSources)
/**
* Should be used only for particular target in chunk (jvm)
*/
protected fun checkShouldCompileAndLog(
target: KotlinModuleBuildTarget,
dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
moduleSources: Collection<File>
): Boolean {
val hasRemovedSources = dirtyFilesHolder.getRemovedFiles(target.jpsModuleBuildTarget).isNotEmpty()
val hasDirtyOrRemovedSources = moduleSources.isNotEmpty() || hasRemovedSources
if (hasDirtyOrRemovedSources) {
val logger = context.loggingManager.projectBuilderLogger
if (logger.isEnabled) {
logger.logCompiledFiles(moduleSources, KotlinBuilder.KOTLIN_BUILDER_NAME, "Compiling files:")
}
}
return hasDirtyOrRemovedSources
}
open fun checkCachesVersions(chunk: ModuleChunk, dataManager: BuildDataManager, actions: MutableSet<CacheVersion.Action>) {
}
}
@@ -1,176 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.platforms
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 org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.ProjectBuildException
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.config.KotlinSourceRootType
import org.jetbrains.kotlin.jps.build.FSOperationsHelper
import org.jetbrains.kotlin.jps.build.KotlinSourceFileCollector
import org.jetbrains.kotlin.jps.model.kotlinFacet
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
import org.jetbrains.kotlin.jps.model.testOutputFilePath
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.utils.addIfNotNull
import java.io.File
/**
* Properties and actions for Kotlin test / production module build target.
*/
abstract class KotlinModuleBuilderTarget(val context: CompileContext, val jpsModuleBuildTarget: ModuleBuildTarget) {
val sourceRootTypes: Collection<JpsModuleSourceRootType<*>>
get() = if (isTests) {
listOf(JavaSourceRootType.TEST_SOURCE, KotlinSourceRootType.TestSource)
} else {
listOf(JavaSourceRootType.SOURCE, KotlinSourceRootType.Source)
}
val module: JpsModule
get() = jpsModuleBuildTarget.module
val isTests: Boolean
get() = jpsModuleBuildTarget.isTests
val targetId: TargetId
get() {
// Since IDEA 2016 each gradle source root is imported as a separate module.
// One gradle module X is imported as two JPS modules:
// 1. X-production with one production target;
// 2. X-test with one test target.
// This breaks kotlin code since internal members' names are mangled using module name.
// For example, a declaration of a function 'f' in 'X-production' becomes 'fXProduction', but a call 'f' in 'X-test' becomes 'fXTest()'.
// The workaround is to replace a name of such test target with the name of corresponding production module.
// See KT-11993.
val name = relatedProductionModule?.name ?: jpsModuleBuildTarget.id
return TargetId(name, jpsModuleBuildTarget.targetType.typeId)
}
val outputDir by lazy {
val explicitOutputPath = if (isTests) module.testOutputFilePath else module.productionOutputFilePath
val explicitOutputDir = explicitOutputPath?.let { File(it).absoluteFile.parentFile }
return@lazy explicitOutputDir
?: jpsModuleBuildTarget.outputDir
?: throw ProjectBuildException("No output directory found for " + this)
}
val friendBuildTargets: List<KotlinModuleBuilderTarget>
get() {
val result = mutableListOf<KotlinModuleBuilderTarget>()
if (isTests) {
result.addIfNotNull(context.kotlinBuildTargets[module.productionBuildTarget])
result.addIfNotNull(context.kotlinBuildTargets[relatedProductionModule?.productionBuildTarget])
}
return result.filter { it.sources.isNotEmpty() }
}
val friendOutputDirs: List<File>
get() = friendBuildTargets.mapNotNull {
JpsJavaExtensionService.getInstance().getOutputDirectory(it.module, false)
}
private val relatedProductionModule: JpsModule?
get() = JpsJavaExtensionService.getInstance().getTestModuleProperties(module)?.productionModule
val allDependencies by lazy {
JpsJavaExtensionService.dependencies(module).recursively().exportedOnly()
.includedIn(JpsJavaClasspathKind.compile(isTests))
}
val expectedBy by lazy(::findExpectedBy)
private fun findExpectedBy(): List<KotlinModuleBuilderTarget> {
val kotlinFacetExtension = module.kotlinFacet
val implementedModuleNames = kotlinFacetExtension?.settings?.implementedModuleNames ?: return listOf()
if (implementedModuleNames.isEmpty()) return listOf()
return allDependencies.modules
.filter { it.name in implementedModuleNames }
.map { context.kotlinBuildTargets[ModuleBuildTarget(it, isTests)]!! }
}
val sources by lazy {
mutableListOf<File>().also { result ->
// add all common libs sources
expectedBy.forEach {
it.collectSources(result)
}
collectSources(result)
}
}
private fun collectSources(receiver: MutableList<File>) {
val moduleExcludes = module.excludeRootsList.urls.mapTo(java.util.HashSet(), JpsPathUtil::urlToFile)
val compilerExcludes = JpsJavaExtensionService.getInstance()
.getOrCreateCompilerConfiguration(module.project)
.compilerExcludes
module
.sourceRoots
.filter { it.rootType in sourceRootTypes }
.forEach {
it.file.walkTopDown()
.onEnter { it !in moduleExcludes }
.filterTo(receiver) {
!compilerExcludes.isExcluded(it) &&
it.isFile &&
KotlinSourceFileCollector.isKotlinSourceFile(it)
}
}
}
override fun toString() = jpsModuleBuildTarget.toString()
abstract fun compileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk,
commonArguments: CommonCompilerArguments,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>,
fsOperations: FSOperationsHelper
): Boolean
protected fun reportAndSkipCircular(
chunk: ModuleChunk,
environment: JpsCompilerEnvironment
): Boolean {
if (chunk.modules.size > 1) {
// We do not support circular dependencies, but if they are present, we do our best should not break the build,
// so we simply yield a warning and report NOTHING_DONE
environment.messageCollector.report(
CompilerMessageSeverity.STRONG_WARNING,
"Circular dependencies are not supported. The following modules depend on each other: "
+ chunk.modules.joinToString(", ") { it.name } + " "
+ "Kotlin is not compiled for these modules"
)
return true
}
return false
}
open fun doAfterBuild() {
}
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.jps.platforms
import com.intellij.openapi.util.Key
import org.jetbrains.jps.builders.ModuleBasedBuildTargetType
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget
@@ -46,17 +45,17 @@ val CompileContext.kotlinBuildTargets: KotlinBuildTargets
}
class KotlinBuildTargets internal constructor(val compileContext: CompileContext) {
private val byJpsModuleBuildTarget = ConcurrentHashMap<ModuleBuildTarget, KotlinModuleBuilderTarget>()
private val byJpsModuleBuildTarget = ConcurrentHashMap<ModuleBuildTarget, KotlinModuleBuildTarget>()
private val isKotlinJsStdlibJar = ConcurrentHashMap<String, Boolean>()
@JvmName("getNullable")
operator fun get(target: ModuleBuildTarget?): KotlinModuleBuilderTarget? {
operator fun get(target: ModuleBuildTarget?): KotlinModuleBuildTarget? {
if (target == null) return null
return get(target)
}
operator fun get(target: ModuleBuildTarget): KotlinModuleBuilderTarget? {
if (target.targetType !is ModuleBasedBuildTargetType) return null
operator fun get(target: ModuleBuildTarget): KotlinModuleBuildTarget? {
if (target.module.moduleType != JpsJavaModuleType.INSTANCE) return null
return byJpsModuleBuildTarget.computeIfAbsent(target) {
when (target.module.targetPlatform ?: detectTargetPlatform(target)) {
@@ -16,16 +16,6 @@ Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building module2
Cleaning output files:
out/production/module2/META-INF/module2.kotlin_module
out/production/module2/b/BKt.class
End of files
Compiling files:
module2/src/b.kt
End of files
Exit code: OK
------------------------------------------
Building module3
Cleaning output files:
out/production/module3/META-INF/module3.kotlin_module
@@ -36,3 +26,13 @@ Compiling files:
End of files
Exit code: OK
------------------------------------------
Building module2
Cleaning output files:
out/production/module2/META-INF/module2.kotlin_module
out/production/module2/b/BKt.class
End of files
Compiling files:
module2/src/b.kt
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,32 @@
Multiplatform multi module tests.
This tests is autogenerated based on dependencies.txt by `MppJpsIncTestsGenerator`.
This things are generated:
- For each module content will be generated based on module type:
- `common`
- `jvm`
- `js`
- Modules can be marked with `edit`, `editJvm` and `editExpectActual`. For this modules, modification steps will be generated. For each module and each flag subdirectory will be created and empty `build.log` will be putted (if it wasn't already). This directory will be used to generate `MultiplatformJpsTestGenerated`.
- `edit`, `editJvm`:
- new services will be created
- service will be changed
- service will be deleted
- `editExpectActual`
- new services will be created in common module
- service will be created on each platform module as separate step (to test common files state tracking separately for each platform module)
- service will be changed on each platform module as separate step
- service will be deleted
Module contents will be generated at run time in the temporary directory. To see it contents please set breakpoint at `TODO`. To simplify mega-multi-modules tests debugging, all modules are sorted in topological order and prefixed with index. Example of generated project:
```
00_raJvmClient_RaJvmClientJavaClass.java
00_raJvmClient_serviceRaJvmClientImpl.kt
01_raJvmServer_RaJvmServerJavaClass.java
01_raJvmServer_serviceRaJvmServerImpl.kt
02_raJsClient_serviceRaJsClientImpl.kt
03_raJsServer_serviceRaJsServerImpl.kt
04_rbJvmClient_RbJvmClientJavaClass.java
04_rbJvmClient_serviceRbJvmClientImpl.kt
...
```
@@ -0,0 +1,7 @@
c [common, edit, editExpectActual]
pJvm [jvm, edit, editJvm]
pJvm -> c [expectedBy]
pJs [js, edit]
pJs -> c [expectedBy]
@@ -0,0 +1,236 @@
================ Step #1 create new service in c =================
Building c
Building pJs
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJs' production] Expected function 'c_platformDependentCNew' has no actual declaration in module
================ Step #2 create new service in pJvm =================
Building c
Building pJs
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJs' production] Expected function 'c_platformDependentCNew' has no actual declaration in module
================ Step #3 create new service in pJs =================
Building c
Building pJs
Compiling files:
c/src/serviceCNewHeader.kt
pJs/src/servicePJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building pJvm
Compiling files:
c/src/serviceCNewHeader.kt
pJvm/src/servicePJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
pJvm/src/PJvmNewJavaClass.java
End of files
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Compiling files:
c/src/serviceCNewHeader.kt
pJvm/src/servicePJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
c/src/serviceCNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #4 change new service in c =================
Building c
Building pJs
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Compiling files:
c/src/serviceCNewHeader.kt
pJs/src/servicePJsNewImpl.kt
End of files
Marked as dirty by Kotlin:
pJs/src/servicePJsNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Compiling files:
c/src/serviceCNewHeader.kt
pJs/src/servicePJsNewImpl.kt
End of files
Marked as dirty by Kotlin:
c/src/serviceCNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServiceCNewHeaderKt.class
End of files
Compiling files:
c/src/serviceCNewHeader.kt
pJvm/src/servicePJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
pJvm/src/servicePJvmNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Compiling files:
c/src/serviceCNewHeader.kt
pJvm/src/servicePJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
c/src/serviceCNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #5 change new service in pJvm: java =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Cleaning output files:
out/production/pJvm/PJvmNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
pJvm/src/PJvmNewJavaClass.java
End of files
================ Step #6 change new service in pJvm: kotlin =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Compiling files:
c/src/serviceCNewHeader.kt
pJvm/src/servicePJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
c/src/serviceCNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #7 change new service in pJs =================
Building c
Building pJs
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Compiling files:
c/src/serviceCNewHeader.kt
pJs/src/servicePJsNewImpl.kt
End of files
Marked as dirty by Kotlin:
c/src/serviceCNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #8 delete new service in pJvm =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Building pJvm
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Marked as dirty by Kotlin:
c/src/serviceCNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJvm' production] Expected function 'c_platformDependentCNew' has no actual declaration in module
================ Step #9 delete new service in pJs =================
Building c
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Building pJs
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Marked as dirty by Kotlin:
c/src/serviceCNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJs' production] Expected function 'c_platformDependentCNew' has no actual declaration in module
================ Step #10 delete new service in c =================
Building c
Building pJs
Compiling files:
End of files
Exit code: OK
------------------------------------------
Cleaning output files:
out/production/pJvm/ServiceCNewHeaderKt.class
End of files
Building pJvm
Compiling files:
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,63 @@
================ Step #1 create new service =================
Building c
Building pJs
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Exit code: OK
------------------------------------------
Building pJvm
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Exit code: OK
------------------------------------------
================ Step #2 edit new service =================
Building c
Building pJs
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Exit code: OK
------------------------------------------
Building pJvm
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServiceCNewHeaderKt.class
End of files
Compiling files:
c/src/serviceCNewHeader.kt
End of files
Exit code: OK
------------------------------------------
================ Step #3 delete new service =================
Building c
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Building pJs
Compiling files:
End of files
Exit code: OK
------------------------------------------
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServiceCNewHeaderKt.class
End of files
Building pJvm
Compiling files:
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,47 @@
================ Step #1 create new service =================
Building c
Building pJs
Compiling files:
pJs/src/servicePJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building pJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 edit new service =================
Building c
Building pJs
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Compiling files:
pJs/src/servicePJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building pJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #3 delete new service =================
Building c
Cleaning output files:
out/production/pJs/pJs.js
out/production/pJs/pJs.meta.js
out/production/pJs/pJs/root-package.kjsm
End of files
Building pJs
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building pJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,59 @@
================ Step #1 create new service =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Compiling files:
pJvm/src/servicePJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
pJvm/src/PJvmNewJavaClass.java
End of files
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Compiling files:
pJvm/src/servicePJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
================ Step #2 edit new service =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Cleaning output files:
out/production/pJvm/PJvmNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
pJvm/src/PJvmNewJavaClass.java
End of files
================ Step #3 delete new service =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/pJvm/PJvmNewJavaClass.class
End of files
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Building pJvm
Compiling files:
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,45 @@
================ Step #1 create new service =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Compiling files:
pJvm/src/servicePJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
================ Step #2 edit new service =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Building pJvm
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Compiling files:
pJvm/src/servicePJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
================ Step #3 delete new service =================
Building c
Building pJs
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/pJvm/META-INF/pJvm.kotlin_module
out/production/pJvm/ServicePJvmNewImplKt.class
End of files
Building pJvm
Compiling files:
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,20 @@
cMain [common, editExpectActual]
cTests [common, editExpectActual]
cTests -> cMain [compile]
// jvm
pJvmMain [jvm]
pJvmMain -> cMain [expectedBy]
pJvmTests [jvm]
pJvmTests -> pJvmMain [compile]
pJvmTests -> cTests [expectedBy]
// js
pJsMain [js]
pJsMain -> cMain [expectedBy]
pJsTests [js]
pJsTests -> pJsMain [compile]
pJsTests -> cTests [expectedBy]
@@ -0,0 +1,278 @@
================ Step #1 create new service in cMain =================
Building cMain
Building pJsMain
Compiling files:
cMain/src/serviceCMainNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJsMain' production] Expected function 'cMain_platformDependentCMainNew' has no actual declaration in module
================ Step #2 create new service in pJvmMain =================
Building cMain
Building pJsMain
Compiling files:
cMain/src/serviceCMainNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJsMain' production] Expected function 'cMain_platformDependentCMainNew' has no actual declaration in module
================ Step #3 create new service in pJsMain =================
Building cMain
Building pJsMain
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJsMain/src/servicePJsMainNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building pJvmMain
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJvmMain/src/servicePJvmMainNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
pJvmMain/src/PJvmMainNewJavaClass.java
End of files
Cleaning output files:
out/production/pJvmMain/META-INF/pJvmMain.kotlin_module
out/production/pJvmMain/ServicePJvmMainNewImplKt.class
End of files
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJvmMain/src/servicePJvmMainNewImpl.kt
End of files
Marked as dirty by Kotlin:
cMain/src/serviceCMainNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Exit code: NOTHING_DONE
------------------------------------------
================ Step #4 change new service in cMain =================
Building cMain
Building pJsMain
Cleaning output files:
out/production/pJsMain/pJsMain.js
out/production/pJsMain/pJsMain.meta.js
out/production/pJsMain/pJsMain/root-package.kjsm
End of files
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJsMain/src/servicePJsMainNewImpl.kt
End of files
Marked as dirty by Kotlin:
pJsMain/src/servicePJsMainNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/pJsMain/pJsMain.js
out/production/pJsMain/pJsMain.meta.js
out/production/pJsMain/pJsMain/root-package.kjsm
End of files
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJsMain/src/servicePJsMainNewImpl.kt
End of files
Marked as dirty by Kotlin:
cMain/src/serviceCMainNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Cleaning output files:
out/production/pJvmMain/META-INF/pJvmMain.kotlin_module
out/production/pJvmMain/ServiceCMainNewHeaderKt.class
End of files
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJvmMain/src/servicePJvmMainNewImpl.kt
End of files
Marked as dirty by Kotlin:
pJvmMain/src/servicePJvmMainNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/pJvmMain/META-INF/pJvmMain.kotlin_module
out/production/pJvmMain/ServicePJvmMainNewImplKt.class
End of files
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJvmMain/src/servicePJvmMainNewImpl.kt
End of files
Marked as dirty by Kotlin:
cMain/src/serviceCMainNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Exit code: NOTHING_DONE
------------------------------------------
================ Step #5 change new service in pJvmMain: java =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Cleaning output files:
out/production/pJvmMain/PJvmMainNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
pJvmMain/src/PJvmMainNewJavaClass.java
End of files
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Exit code: NOTHING_DONE
------------------------------------------
================ Step #6 change new service in pJvmMain: kotlin =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Cleaning output files:
out/production/pJvmMain/META-INF/pJvmMain.kotlin_module
out/production/pJvmMain/ServicePJvmMainNewImplKt.class
End of files
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJvmMain/src/servicePJvmMainNewImpl.kt
End of files
Marked as dirty by Kotlin:
cMain/src/serviceCMainNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Exit code: NOTHING_DONE
------------------------------------------
================ Step #7 change new service in pJsMain =================
Building cMain
Building pJsMain
Cleaning output files:
out/production/pJsMain/pJsMain.js
out/production/pJsMain/pJsMain.meta.js
out/production/pJsMain/pJsMain/root-package.kjsm
End of files
Compiling files:
cMain/src/serviceCMainNewHeader.kt
pJsMain/src/servicePJsMainNewImpl.kt
End of files
Marked as dirty by Kotlin:
cMain/src/serviceCMainNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Exit code: NOTHING_DONE
------------------------------------------
================ Step #8 delete new service in pJvmMain =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/pJvmMain/META-INF/pJvmMain.kotlin_module
out/production/pJvmMain/ServicePJvmMainNewImplKt.class
End of files
Building pJvmMain
Compiling files:
cMain/src/serviceCMainNewHeader.kt
End of files
Marked as dirty by Kotlin:
cMain/src/serviceCMainNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJvmMain' production] Expected function 'cMain_platformDependentCMainNew' has no actual declaration in module
================ Step #9 delete new service in pJsMain =================
Building cMain
Cleaning output files:
out/production/pJsMain/pJsMain.js
out/production/pJsMain/pJsMain.meta.js
out/production/pJsMain/pJsMain/root-package.kjsm
End of files
Building pJsMain
Compiling files:
cMain/src/serviceCMainNewHeader.kt
End of files
Marked as dirty by Kotlin:
cMain/src/serviceCMainNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJsMain' production] Expected function 'cMain_platformDependentCMainNew' has no actual declaration in module
================ Step #10 delete new service in cMain =================
Building cMain
Building pJsMain
Compiling files:
End of files
Exit code: OK
------------------------------------------
Cleaning output files:
out/production/pJvmMain/ServiceCMainNewHeaderKt.class
End of files
Building pJvmMain
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,306 @@
================ Step #1 create new service in cTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJsTests' production] Expected function 'cTests_platformDependentCTestsNew' has no actual declaration in module
================ Step #2 create new service in pJvmTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJsTests' production] Expected function 'cTests_platformDependentCTestsNew' has no actual declaration in module
================ Step #3 create new service in pJsTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJsTests/src/servicePJsTestsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building pJvmTests
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJvmTests/src/servicePJvmTestsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
pJvmTests/src/PJvmTestsNewJavaClass.java
End of files
Cleaning output files:
out/production/pJvmTests/META-INF/pJvmTests.kotlin_module
out/production/pJvmTests/ServicePJvmTestsNewImplKt.class
End of files
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJvmTests/src/servicePJvmTestsNewImpl.kt
End of files
Marked as dirty by Kotlin:
cTests/src/serviceCTestsNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #4 change new service in cTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Cleaning output files:
out/production/pJsTests/pJsTests.js
out/production/pJsTests/pJsTests.meta.js
out/production/pJsTests/pJsTests/root-package.kjsm
End of files
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJsTests/src/servicePJsTestsNewImpl.kt
End of files
Marked as dirty by Kotlin:
pJsTests/src/servicePJsTestsNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/pJsTests/pJsTests.js
out/production/pJsTests/pJsTests.meta.js
out/production/pJsTests/pJsTests/root-package.kjsm
End of files
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJsTests/src/servicePJsTestsNewImpl.kt
End of files
Marked as dirty by Kotlin:
cTests/src/serviceCTestsNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Cleaning output files:
out/production/pJvmTests/META-INF/pJvmTests.kotlin_module
out/production/pJvmTests/ServiceCTestsNewHeaderKt.class
End of files
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJvmTests/src/servicePJvmTestsNewImpl.kt
End of files
Marked as dirty by Kotlin:
pJvmTests/src/servicePJvmTestsNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/pJvmTests/META-INF/pJvmTests.kotlin_module
out/production/pJvmTests/ServicePJvmTestsNewImplKt.class
End of files
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJvmTests/src/servicePJvmTestsNewImpl.kt
End of files
Marked as dirty by Kotlin:
cTests/src/serviceCTestsNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #5 change new service in pJvmTests: java =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Cleaning output files:
out/production/pJvmTests/PJvmTestsNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
pJvmTests/src/PJvmTestsNewJavaClass.java
End of files
================ Step #6 change new service in pJvmTests: kotlin =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Cleaning output files:
out/production/pJvmTests/META-INF/pJvmTests.kotlin_module
out/production/pJvmTests/ServicePJvmTestsNewImplKt.class
End of files
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJvmTests/src/servicePJvmTestsNewImpl.kt
End of files
Marked as dirty by Kotlin:
cTests/src/serviceCTestsNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #7 change new service in pJsTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Cleaning output files:
out/production/pJsTests/pJsTests.js
out/production/pJsTests/pJsTests.meta.js
out/production/pJsTests/pJsTests/root-package.kjsm
End of files
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
pJsTests/src/servicePJsTestsNewImpl.kt
End of files
Marked as dirty by Kotlin:
cTests/src/serviceCTestsNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmTests
Exit code: NOTHING_DONE
------------------------------------------
================ Step #8 delete new service in pJvmTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/pJvmTests/META-INF/pJvmTests.kotlin_module
out/production/pJvmTests/ServicePJvmTestsNewImplKt.class
End of files
Building pJvmTests
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
End of files
Marked as dirty by Kotlin:
cTests/src/serviceCTestsNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJvmTests' production] Expected function 'cTests_platformDependentCTestsNew' has no actual declaration in module
================ Step #9 delete new service in pJsTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Cleaning output files:
out/production/pJsTests/pJsTests.js
out/production/pJsTests/pJsTests.meta.js
out/production/pJsTests/pJsTests/root-package.kjsm
End of files
Building pJsTests
Compiling files:
cTests/src/serviceCTestsNewHeader.kt
End of files
Marked as dirty by Kotlin:
cTests/src/serviceCTestsNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'pJsTests' production] Expected function 'cTests_platformDependentCTestsNew' has no actual declaration in module
================ Step #10 delete new service in cTests =================
Building cMain
Building pJsMain
Exit code: NOTHING_DONE
------------------------------------------
Building pJvmMain
Exit code: NOTHING_DONE
------------------------------------------
Building cTests
Building pJsTests
Compiling files:
End of files
Exit code: OK
------------------------------------------
Cleaning output files:
out/production/pJvmTests/ServiceCTestsNewHeaderKt.class
End of files
Building pJvmTests
Compiling files:
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,97 @@
//
// RA RB
// rAJvm <------- rBJvm
// rAJs <------- rBJs
//
// ^ ^
// | |
// A
// aCommon B
// aCommonClient bCommon R
// aJvmClient <------ bJvm <--- rJvm
// aJsClient <------ bJs <--- rJs
// aCommonServer
// aJvmServer
// aJsServer
//
// - `rA*`, `rB*` regular dependent module groups - for testing `common-on-platform -> regular` dependency
// - `aCommon*`, `bCommon` - common modules
// - `aCommonClient`, `aCommonServer` - for testings `common -> common` dependency
// - aJvmClient/aJvmServer, aJsClient/aJsServer - for testing two implementation on same platform
// - `b*` - for testings `common-on-platform -> common-on-platform` dependency
// - `r*` - regular modules for testings `regular -> common-on-platform` dependency
//
////// RA //////
raJvm [jvm, edit]
raJs [js, edit]
////// RB //////
rbJvm [jvm]
rbJvm -> raJvm [compile]
rbJs [js]
rbJs -> raJs [compile]
////// A //////
aCommon [common, editExpectActual]
aCommonClient [common]
aCommonClient -> aCommon [compile]
aCommonServer [common]
aCommonServer -> aCommon [compile]
aJvmClient [jvm, edit, editJvm]
aJvmClient -> aCommon [expectedBy]
aJvmClient -> aCommonClient [expectedBy]
aJvmClient -> raJvm [compile]
aJvmServer [jvm]
aJvmServer -> aCommon [expectedBy]
aJvmServer -> aCommonServer [expectedBy]
aJvmServer -> raJvm [compile]
aJsClient [js, edit]
aJsClient -> aCommon [expectedBy]
aJsClient -> aCommonClient [expectedBy]
aJsClient -> raJs [compile]
aJsServer [js]
aJsServer -> aCommon [expectedBy]
aJsServer -> aCommonServer [expectedBy]
aJsServer -> raJs [compile]
////// B //////
bCommon [common, editExpectActual]
bCommon -> aCommon [compile]
bJvm [jvm]
bJvm -> bCommon [expectedBy]
bJvm -> aJvmClient [compile]
bJvm -> raJvm [compile]
bJvm -> rbJvm [compile]
bJs [js]
bJs -> bCommon [expectedBy]
bJs -> aJsClient [compile]
bJs -> raJs [compile]
bJs -> rbJs [compile]
////// R //////
rJvm [jvm, edit]
rJvm -> raJvm [compile]
rJvm -> rbJvm [compile]
rJvm -> bJvm [compile]
rJvm -> aJvmClient [compile]
rJs [js, edit]
rJs -> raJs [compile]
rJs -> rbJs [compile]
rJs -> bJs [compile]
rJs -> aJsClient [compile]
@@ -0,0 +1,515 @@
================ Step #1 create new service in aCommon =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'aJsServer' production] Expected function 'aCommon_platformDependentACommonNew' has no actual declaration in module
================ Step #2 create new service in aJvmClient =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'aJsServer' production] Expected function 'aCommon_platformDependentACommonNew' has no actual declaration in module
================ Step #3 create new service in aJvmServer =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'aJsServer' production] Expected function 'aCommon_platformDependentACommonNew' has no actual declaration in module
================ Step #4 create new service in aJsClient =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'aJsServer' production] Expected function 'aCommon_platformDependentACommonNew' has no actual declaration in module
================ Step #5 create new service in aJsServer =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJsServer/src/serviceAJsServerNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building aJsClient
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJsClient/src/serviceAJsClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmServer/src/serviceAJvmServerNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
aJvmServer/src/AJvmServerNewJavaClass.java
End of files
Cleaning output files:
out/production/aJvmServer/META-INF/aJvmServer.kotlin_module
out/production/aJvmServer/ServiceAJvmServerNewImplKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmServer/src/serviceAJvmServerNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
aJvmClient/src/AJvmClientNewJavaClass.java
End of files
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceAJvmClientNewImplKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #6 change new service in aCommon =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Cleaning output files:
out/production/aJsServer/aJsServer.js
out/production/aJsServer/aJsServer.meta.js
out/production/aJsServer/aJsServer/root-package.kjsm
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJsServer/src/serviceAJsServerNewImpl.kt
End of files
Marked as dirty by Kotlin:
aJsServer/src/serviceAJsServerNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/aJsServer/aJsServer.js
out/production/aJsServer/aJsServer.meta.js
out/production/aJsServer/aJsServer/root-package.kjsm
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJsServer/src/serviceAJsServerNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Cleaning output files:
out/production/aJsClient/aJsClient.js
out/production/aJsClient/aJsClient.meta.js
out/production/aJsClient/aJsClient/root-package.kjsm
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJsClient/src/serviceAJsClientNewImpl.kt
End of files
Marked as dirty by Kotlin:
aJsClient/src/serviceAJsClientNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/aJsClient/aJsClient.js
out/production/aJsClient/aJsClient.meta.js
out/production/aJsClient/aJsClient/root-package.kjsm
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJsClient/src/serviceAJsClientNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Cleaning output files:
out/production/aJvmServer/META-INF/aJvmServer.kotlin_module
out/production/aJvmServer/ServiceACommonNewHeaderKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmServer/src/serviceAJvmServerNewImpl.kt
End of files
Marked as dirty by Kotlin:
aJvmServer/src/serviceAJvmServerNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/aJvmServer/META-INF/aJvmServer.kotlin_module
out/production/aJvmServer/ServiceAJvmServerNewImplKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmServer/src/serviceAJvmServerNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceACommonNewHeaderKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Marked as dirty by Kotlin:
aJvmClient/src/serviceAJvmClientNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceAJvmClientNewImplKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #7 change new service in aJvmClient: java =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Cleaning output files:
out/production/aJvmClient/AJvmClientNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
aJvmClient/src/AJvmClientNewJavaClass.java
End of files
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #8 change new service in aJvmClient: kotlin =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceAJvmClientNewImplKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #9 change new service in aJvmServer: java =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Cleaning output files:
out/production/aJvmServer/AJvmServerNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
aJvmServer/src/AJvmServerNewJavaClass.java
End of files
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #10 change new service in aJvmServer: kotlin =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Cleaning output files:
out/production/aJvmServer/META-INF/aJvmServer.kotlin_module
out/production/aJvmServer/ServiceAJvmServerNewImplKt.class
End of files
Compiling files:
aCommon/src/serviceACommonNewHeader.kt
aJvmServer/src/serviceAJvmServerNewImpl.kt
End of files
Marked as dirty by Kotlin:
aCommon/src/serviceACommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,146 @@
================ Step #1 create new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Compiling files:
aJsClient/src/serviceAJsClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 edit new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Cleaning output files:
out/production/aJsClient/aJsClient.js
out/production/aJsClient/aJsClient.meta.js
out/production/aJsClient/aJsClient/root-package.kjsm
End of files
Compiling files:
aJsClient/src/serviceAJsClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #3 delete new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/aJsClient/aJsClient.js
out/production/aJsClient/aJsClient.meta.js
out/production/aJsClient/aJsClient/root-package.kjsm
End of files
Building aJsClient
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,158 @@
================ Step #1 create new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Compiling files:
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
aJvmClient/src/AJvmClientNewJavaClass.java
End of files
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceAJvmClientNewImplKt.class
End of files
Compiling files:
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 edit new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Cleaning output files:
out/production/aJvmClient/AJvmClientNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
aJvmClient/src/AJvmClientNewJavaClass.java
End of files
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #3 delete new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/aJvmClient/AJvmClientNewJavaClass.class
End of files
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceAJvmClientNewImplKt.class
End of files
Building aJvmClient
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,144 @@
================ Step #1 create new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Compiling files:
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 edit new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceAJvmClientNewImplKt.class
End of files
Compiling files:
aJvmClient/src/serviceAJvmClientNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #3 delete new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/aJvmClient/META-INF/aJvmClient.kotlin_module
out/production/aJvmClient/ServiceAJvmClientNewImplKt.class
End of files
Building aJvmClient
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,509 @@
================ Step #1 create new service in bCommon =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'bJs' production] Expected function 'bCommon_platformDependentBCommonNew' has no actual declaration in module
================ Step #2 create new service in bJvm =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'bJs' production] Expected function 'bCommon_platformDependentBCommonNew' has no actual declaration in module
================ Step #3 create new service in bJs =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJs/src/serviceBJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJvm/src/serviceBJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
bJvm/src/BJvmNewJavaClass.java
End of files
Cleaning output files:
out/production/bJvm/META-INF/bJvm.kotlin_module
out/production/bJvm/ServiceBJvmNewImplKt.class
End of files
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJvm/src/serviceBJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
bCommon/src/serviceBCommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #4 change new service in bCommon =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Cleaning output files:
out/production/bJs/bJs.js
out/production/bJs/bJs.meta.js
out/production/bJs/bJs/root-package.kjsm
End of files
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJs/src/serviceBJsNewImpl.kt
End of files
Marked as dirty by Kotlin:
bJs/src/serviceBJsNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/bJs/bJs.js
out/production/bJs/bJs.meta.js
out/production/bJs/bJs/root-package.kjsm
End of files
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJs/src/serviceBJsNewImpl.kt
End of files
Marked as dirty by Kotlin:
bCommon/src/serviceBCommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Cleaning output files:
out/production/bJvm/META-INF/bJvm.kotlin_module
out/production/bJvm/ServiceBCommonNewHeaderKt.class
End of files
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJvm/src/serviceBJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
bJvm/src/serviceBJvmNewImpl.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/bJvm/META-INF/bJvm.kotlin_module
out/production/bJvm/ServiceBJvmNewImplKt.class
End of files
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJvm/src/serviceBJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
bCommon/src/serviceBCommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #5 change new service in bJvm: java =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Cleaning output files:
out/production/bJvm/BJvmNewJavaClass.class
End of files
Exit code: NOTHING_DONE
------------------------------------------
Compiling files:
bJvm/src/BJvmNewJavaClass.java
End of files
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #6 change new service in bJvm: kotlin =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Cleaning output files:
out/production/bJvm/META-INF/bJvm.kotlin_module
out/production/bJvm/ServiceBJvmNewImplKt.class
End of files
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJvm/src/serviceBJvmNewImpl.kt
End of files
Marked as dirty by Kotlin:
bCommon/src/serviceBCommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #7 change new service in bJs =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Cleaning output files:
out/production/bJs/bJs.js
out/production/bJs/bJs.meta.js
out/production/bJs/bJs/root-package.kjsm
End of files
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
bJs/src/serviceBJsNewImpl.kt
End of files
Marked as dirty by Kotlin:
bCommon/src/serviceBCommonNewHeader.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #8 delete new service in bJvm =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/bJvm/META-INF/bJvm.kotlin_module
out/production/bJvm/ServiceBJvmNewImplKt.class
End of files
Building bJvm
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
End of files
Marked as dirty by Kotlin:
bCommon/src/serviceBCommonNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'bJvm' production] Expected function 'bCommon_platformDependentBCommonNew' has no actual declaration in module
================ Step #9 delete new service in bJs =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/bJs/bJs.js
out/production/bJs/bJs.meta.js
out/production/bJs/bJs/root-package.kjsm
End of files
Building bJs
Compiling files:
bCommon/src/serviceBCommonNewHeader.kt
End of files
Marked as dirty by Kotlin:
bCommon/src/serviceBCommonNewHeader.kt
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
[Module 'bJs' production] Expected function 'bCommon_platformDependentBCommonNew' has no actual declaration in module
================ Step #10 delete new service in bCommon =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/bJvm/ServiceBCommonNewHeaderKt.class
End of files
Building bJvm
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,146 @@
================ Step #1 create new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Compiling files:
rJs/src/serviceRJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 edit new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Cleaning output files:
out/production/rJs/rJs.js
out/production/rJs/rJs.meta.js
out/production/rJs/rJs/root-package.kjsm
End of files
Compiling files:
rJs/src/serviceRJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #3 delete new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/rJs/rJs.js
out/production/rJs/rJs.meta.js
out/production/rJs/rJs/root-package.kjsm
End of files
Building rJs
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,144 @@
================ Step #1 create new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Compiling files:
rJvm/src/serviceRJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
================ Step #2 edit new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Cleaning output files:
out/production/rJvm/META-INF/rJvm.kotlin_module
out/production/rJvm/ServiceRJvmNewImplKt.class
End of files
Compiling files:
rJvm/src/serviceRJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
================ Step #3 delete new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/rJvm/META-INF/rJvm.kotlin_module
out/production/rJvm/ServiceRJvmNewImplKt.class
End of files
Building rJvm
Compiling files:
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,146 @@
================ Step #1 create new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Compiling files:
raJs/src/serviceRaJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 edit new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Cleaning output files:
out/production/raJs/raJs.js
out/production/raJs/raJs.meta.js
out/production/raJs/raJs/root-package.kjsm
End of files
Compiling files:
raJs/src/serviceRaJsNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #3 delete new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Cleaning output files:
out/production/raJs/raJs.js
out/production/raJs/raJs.meta.js
out/production/raJs/raJs/root-package.kjsm
End of files
Building raJs
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,144 @@
================ Step #1 create new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Compiling files:
raJvm/src/serviceRaJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 edit new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Building raJvm
Cleaning output files:
out/production/raJvm/META-INF/raJvm.kotlin_module
out/production/raJvm/ServiceRaJvmNewImplKt.class
End of files
Compiling files:
raJvm/src/serviceRaJvmNewImpl.kt
End of files
Exit code: OK
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------
================ Step #3 delete new service =================
Building aCommon
Building bCommon
Building aCommonServer
Building aCommonClient
Building raJs
Exit code: NOTHING_DONE
------------------------------------------
Building aJsServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJsClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJs
Exit code: NOTHING_DONE
------------------------------------------
Building bJs
Exit code: NOTHING_DONE
------------------------------------------
Building rJs
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/raJvm/META-INF/raJvm.kotlin_module
out/production/raJvm/ServiceRaJvmNewImplKt.class
End of files
Building raJvm
Compiling files:
End of files
Exit code: OK
------------------------------------------
Building aJvmServer
Exit code: NOTHING_DONE
------------------------------------------
Building aJvmClient
Exit code: NOTHING_DONE
------------------------------------------
Building rbJvm
Exit code: NOTHING_DONE
------------------------------------------
Building bJvm
Exit code: NOTHING_DONE
------------------------------------------
Building rJvm
Exit code: NOTHING_DONE
------------------------------------------