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.name.FqName
import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getClassId
import java.io.File 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 { companion object {
private val SUBTYPES = "subtypes" private val SUBTYPES = "subtypes"
private val SUPERTYPES = "supertypes" private val SUPERTYPES = "supertypes"
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source" 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 SOURCE_TO_CLASSES = "source-to-classes"
@JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes" @JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
} }
private val dependents = arrayListOf<IncrementalCacheCommon<ClassName>>() private val dependents = arrayListOf<AbstractIncrementalCache<ClassName>>()
fun addDependentCache(cache: IncrementalCacheCommon<ClassName>) { fun addDependentCache(cache: AbstractIncrementalCache<ClassName>) {
dependents.add(cache) dependents.add(cache)
} }
val thisWithDependentCaches: Iterable<IncrementalCacheCommon<ClassName>> by lazy { override val thisWithDependentCaches: Iterable<AbstractIncrementalCache<ClassName>> by lazy {
val result = arrayListOf(this) val result = arrayListOf(this)
result.addAll(dependents) result.addAll(dependents)
result result
@@ -54,16 +71,24 @@ abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOw
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName> internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<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) } files.flatMapTo(HashSet()) { sourceToClassesMap.getFqNames(it) }
fun getSubtypesOf(className: FqName): Sequence<FqName> = override fun getSubtypesOf(className: FqName): Sequence<FqName> =
subtypesMap[className].asSequence() subtypesMap[className].asSequence()
fun getSourceFileIfClass(fqName: FqName): File? = override fun getSourceFileIfClass(fqName: FqName): File? =
classFqNameToSourceMap[fqName] classFqNameToSourceMap[fqName]
open fun markDirty(removedAndCompiledSources: Collection<File>) { override fun markDirty(removedAndCompiledSources: Collection<File>) {
for (sourceFile in removedAndCompiledSources) { for (sourceFile in removedAndCompiledSources) {
val classes = sourceToClassesMap[sourceFile] val classes = sourceToClassesMap[sourceFile]
classes.forEach { classes.forEach {
@@ -90,8 +115,6 @@ abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOw
classFqNameToSourceMap[child] = srcFile classFqNameToSourceMap[child] = srcFile
} }
abstract fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>, changesCollector: ChangesCollector) { protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>, changesCollector: ChangesCollector) {
if (removedClasses.isEmpty()) return if (removedClasses.isEmpty()) return
@@ -141,4 +164,29 @@ abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOw
override fun dumpValue(value: String) = value 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.File
import java.io.IOException import java.io.IOException
private val NORMAL_VERSION = 8 private val NORMAL_VERSION = 9
private val DATA_CONTAINER_VERSION = 2 private val DATA_CONTAINER_VERSION = 3
private val NORMAL_VERSION_FILE_NAME = "format-version.txt" private val NORMAL_VERSION_FILE_NAME = "format-version.txt"
private val DATA_CONTAINER_VERSION_FILE_NAME = "data-container-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.DataOutput
import java.io.File import java.io.File
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon<FqName>(cachesDir) { open class IncrementalJsCache(cachesDir: File) : AbstractIncrementalCache<FqName>(cachesDir) {
companion object { companion object {
private val TRANSLATION_RESULT_MAP = "translation-result" private val TRANSLATION_RESULT_MAP = "translation-result"
private val INLINE_FUNCTIONS = "inline-functions" private val INLINE_FUNCTIONS = "inline-functions"
@@ -44,7 +44,7 @@ val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache( open class IncrementalJvmCache(
private val targetDataRoot: File, private val targetDataRoot: File,
targetOutputDir: File? targetOutputDir: File?
) : IncrementalCacheCommon<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache { ) : AbstractIncrementalCache<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
companion object { companion object {
private val PROTO_MAP = "proto" private val PROTO_MAP = "proto"
private val CONSTANTS_MAP = "constants" private val CONSTANTS_MAP = "constants"
@@ -81,10 +81,10 @@ fun makeCompileServices(
} }
fun updateIncrementalCache( fun updateIncrementalCache(
generatedFiles: Iterable<GeneratedFile>, generatedFiles: Iterable<GeneratedFile>,
cache: IncrementalJvmCache, cache: IncrementalJvmCache,
changesCollector: ChangesCollector, changesCollector: ChangesCollector,
javaChangesTracker: JavaClassesTrackerImpl? javaChangesTracker: JavaClassesTrackerImpl?
) { ) {
for (generatedFile in generatedFiles) { for (generatedFile in generatedFiles) {
when { when {
@@ -119,8 +119,8 @@ data class DirtyData(
) )
fun ChangesCollector.getDirtyData( fun ChangesCollector.getDirtyData(
caches: Iterable<IncrementalCacheCommon<*>>, caches: Iterable<IncrementalCacheCommon>,
reporter: ICReporter reporter: ICReporter
): DirtyData { ): DirtyData {
val dirtyLookupSymbols = HashSet<LookupSymbol>() val dirtyLookupSymbols = HashSet<LookupSymbol>()
val dirtyClassesFqNames = HashSet<FqName>() val dirtyClassesFqNames = HashSet<FqName>()
@@ -173,10 +173,10 @@ fun mapLookupSymbolsToFiles(
} }
fun mapClassesFqNamesToFiles( fun mapClassesFqNamesToFiles(
caches: Iterable<IncrementalCacheCommon<*>>, caches: Iterable<IncrementalCacheCommon>,
classesFqNames: Iterable<FqName>, classesFqNames: Iterable<FqName>,
reporter: ICReporter, reporter: ICReporter,
excludes: Set<File> = emptySet() excludes: Set<File> = emptySet()
): Set<File> { ): Set<File> {
val dirtyFiles = HashSet<File>() val dirtyFiles = HashSet<File>()
@@ -195,7 +195,7 @@ fun mapClassesFqNamesToFiles(
fun withSubtypes( fun withSubtypes(
typeFqName: FqName, typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon<*>> caches: Iterable<IncrementalCacheCommon>
): Set<FqName> { ): Set<FqName> {
val types = LinkedList(listOf(typeFqName)) val types = LinkedList(listOf(typeFqName))
val subtypes = hashSetOf<FqName>() 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("_") val underscore = fileName.indexOf("_")
if (underscore != -1) { 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(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" } 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") @Argument(value = "-module-name", valueDescription = "<name>", description = "Name of the generated .kotlin_module file")
var moduleName: String? by FreezableVar(null) 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 org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import java.io.File import java.io.File
abstract class IncrementalCachesManager<PlatformCache : IncrementalCacheCommon<*>>( abstract class IncrementalCachesManager<PlatformCache : AbstractIncrementalCache<*>>(
protected val cachesRootDir: File, protected val cachesRootDir: File,
protected val reporter: ICReporter protected val reporter: ICReporter
) { ) {
@@ -200,7 +200,7 @@ abstract class IncrementalCompilerRunner<
var exitCode = ExitCode.OK var exitCode = ExitCode.OK
while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) { while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) {
val complementaryFiles = caches.inputsCache.clearComplementaryFilesMapping(dirtySources) val complementaryFiles = caches.platformCache.clearComplementaryFilesMapping(dirtySources)
dirtySources.addAll(complementaryFiles) dirtySources.addAll(complementaryFiles)
caches.platformCache.markDirty(dirtySources) caches.platformCache.markDirty(dirtySources)
caches.inputsCache.removeOutputForSourceFiles(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.inputsCache.registerOutputForSourceFiles(generatedFiles)
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources) caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
val changesCollector = ChangesCollector() val changesCollector = ChangesCollector()
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.incremental
import com.intellij.util.containers.MultiMap import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.build.GeneratedFile import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.incremental.snapshots.FileSnapshotMap import org.jetbrains.kotlin.incremental.snapshots.FileSnapshotMap
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner import org.jetbrains.kotlin.incremental.storage.*
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor
import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer
import java.io.File import java.io.File
import java.util.* import java.util.*
import kotlin.collections.HashSet import kotlin.collections.HashSet
@@ -34,43 +31,10 @@ class InputsCache(
companion object { companion object {
private val SOURCE_SNAPSHOTS = "source-snapshot" private val SOURCE_SNAPSHOTS = "source-snapshot"
private val SOURCE_TO_OUTPUT_FILES = "source-to-output" private val SOURCE_TO_OUTPUT_FILES = "source-to-output"
private val COMPLEMENTARY_FILES = "complementary-files"
} }
internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile)) internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile))
private val sourceToOutputMap = registerMap(FilesMap(SOURCE_TO_OUTPUT_FILES.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>) { fun removeOutputForSourceFiles(sources: Iterable<File>) {
for (sourceFile in sources) { for (sourceFile in sources) {
@@ -97,20 +61,3 @@ class InputsCache(
} }
} }
} }
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 */ /** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all") @SuppressWarnings("all")
@TestMetadata("jps-plugin/testData/incremental/multiplatform") @TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJsCompilerRunnerTest { public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJsCompilerRunnerTest {
@@ -25,21 +25,21 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
} }
public void testAllFilesPresentInMultiplatform() throws Exception { public void testAllFilesPresentInSingleModule() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
} }
@TestMetadata("touchActual") @TestMetadata("touchActual")
public void testTouchActual() throws Exception { public void testTouchActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/touchActual/"); runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/");
} }
@TestMetadata("touchExpect") @TestMetadata("touchExpect")
public void testTouchExpect() throws Exception { 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") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
public static class TouchActual extends AbstractIncrementalMultiplatformJsCompilerRunnerTest { public static class TouchActual extends AbstractIncrementalMultiplatformJsCompilerRunnerTest {
@@ -48,11 +48,11 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr
} }
public void testAllFilesPresentInTouchActual() throws Exception { 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") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
public static class TouchExpect extends AbstractIncrementalMultiplatformJsCompilerRunnerTest { public static class TouchExpect extends AbstractIncrementalMultiplatformJsCompilerRunnerTest {
@@ -61,7 +61,7 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr
} }
public void testAllFilesPresentInTouchExpect() throws Exception { 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 */ /** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all") @SuppressWarnings("all")
@TestMetadata("jps-plugin/testData/incremental/multiplatform") @TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest { public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest {
@@ -25,21 +25,21 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
} }
public void testAllFilesPresentInMultiplatform() throws Exception { public void testAllFilesPresentInSingleModule() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
} }
@TestMetadata("touchActual") @TestMetadata("touchActual")
public void testTouchActual() throws Exception { public void testTouchActual() throws Exception {
runTest("jps-plugin/testData/incremental/multiplatform/touchActual/"); runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/");
} }
@TestMetadata("touchExpect") @TestMetadata("touchExpect")
public void testTouchExpect() throws Exception { 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") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
public static class TouchActual extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest { public static class TouchActual extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest {
@@ -48,11 +48,11 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst
} }
public void testAllFilesPresentInTouchActual() throws Exception { 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") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
public static class TouchExpect extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest { public static class TouchExpect extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest {
@@ -61,7 +61,7 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst
} }
public void testAllFilesPresentInTouchExpect() throws Exception { 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.j2k.AbstractJavaToKotlinConverterSingleFileTest
import org.jetbrains.kotlin.jps.build.* import org.jetbrains.kotlin.jps.build.*
import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase 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.AbstractJsProtoComparisonTest
import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
@@ -929,6 +930,15 @@ fun main(args: Array<String>) {
model("incremental/classHierarchyAffected", extension = null, excludeParentDirs = true) 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> { testClass<AbstractJvmLookupTrackerTest> {
model("incremental/lookupTracker/jvm", extension = null, recursive = false) model("incremental/lookupTracker/jvm", extension = null, recursive = false)
} }
@@ -990,10 +1000,10 @@ fun main(args: Array<String>) {
} }
testClass<AbstractIncrementalMultiplatformJvmCompilerRunnerTest> { testClass<AbstractIncrementalMultiplatformJvmCompilerRunnerTest> {
model("incremental/multiplatform", extension = null, excludeParentDirs = true) model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true)
} }
testClass<AbstractIncrementalMultiplatformJsCompilerRunnerTest> { 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) 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> { testClass<AbstractJvmLookupTrackerTest> {
model("incremental/lookupTracker/jvm", extension = null, recursive = false) model("incremental/lookupTracker/jvm", extension = null, recursive = false)
} }
@@ -980,10 +989,10 @@ fun main(args: Array<String>) {
} }
testClass<AbstractIncrementalMultiplatformJvmCompilerRunnerTest> { testClass<AbstractIncrementalMultiplatformJvmCompilerRunnerTest> {
model("incremental/multiplatform", extension = null, excludeParentDirs = true) model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true)
} }
testClass<AbstractIncrementalMultiplatformJsCompilerRunnerTest> { 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(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client")) compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java")) compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader")) compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common")) compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0")
+1
View File
@@ -13,6 +13,7 @@ dependencies {
compile(project(":compiler:daemon-common")) compile(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client")) compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java")) compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader")) compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common")) compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0")
+1
View File
@@ -13,6 +13,7 @@ dependencies {
compile(project(":compiler:daemon-common")) compile(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client")) compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java")) compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader")) compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common")) compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0")
+1
View File
@@ -13,6 +13,7 @@ dependencies {
compile(project(":compiler:daemon-common")) compile(project(":compiler:daemon-common"))
compile(projectRuntimeJar(":kotlin-daemon-client")) compile(projectRuntimeJar(":kotlin-daemon-client"))
compile(project(":compiler:frontend.java")) compile(project(":compiler:frontend.java"))
compile(project(":js:js.frontend"))
compile(projectRuntimeJar(":kotlin-preloader")) compile(projectRuntimeJar(":kotlin-preloader"))
compile(project(":idea:idea-jps-common")) compile(project(":idea:idea-jps-common"))
compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") 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.*
import org.jetbrains.jps.incremental.messages.BuildMessage import org.jetbrains.jps.incremental.messages.BuildMessage
import org.jetbrains.jps.model.JpsModuleRootModificationUtil import org.jetbrains.jps.model.JpsModuleRootModificationUtil
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.util.JpsPathUtil import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.incremental.CacheVersion import org.jetbrains.kotlin.incremental.CacheVersion
import org.jetbrains.kotlin.incremental.LookupSymbol import org.jetbrains.kotlin.incremental.LookupSymbol
import org.jetbrains.kotlin.incremental.isJavaFile import org.jetbrains.kotlin.incremental.isJavaFile
import org.jetbrains.kotlin.incremental.testingUtils.* 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.getKotlinCache
import org.jetbrains.kotlin.jps.incremental.withLookupStorage import org.jetbrains.kotlin.jps.incremental.withLookupStorage
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
import org.jetbrains.kotlin.jps.platforms.kotlinBuildTargets
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.keysToMap import java.io.ByteArrayInputStream
import java.io.* import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.util.* import java.util.*
import java.util.concurrent.Future import java.util.concurrent.Future
import kotlin.reflect.jvm.javaField import kotlin.reflect.jvm.javaField
abstract class AbstractIncrementalJpsTest( abstract class AbstractIncrementalJpsTest(
private val allowNoFilesWithSuffixInTestData: Boolean = false, private val allowNoFilesWithSuffixInTestData: Boolean = false,
private val checkDumpsCaseInsensitively: Boolean = false, private val checkDumpsCaseInsensitively: Boolean = false,
private val allowNoBuildLogFileInTestData: Boolean = false private val allowNoBuildLogFileInTestData: Boolean = false
) : BaseKotlinJpsBuildTestCase() { ) : BaseKotlinJpsBuildTestCase() {
companion object { companion object {
private val COMPILATION_FAILED = "COMPILATION FAILED" 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) // 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> protected lateinit var lookupsDuringTest: MutableSet<LookupSymbol>
private var isICEnabledBackup: Boolean = false private var isICEnabledBackup: Boolean = false
private var isJSICEnabledBackup: Boolean = false
protected var mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf() protected var mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf()
@@ -115,7 +121,10 @@ abstract class AbstractIncrementalJpsTest(
super.setUp() super.setUp()
lookupsDuringTest = hashSetOf() lookupsDuringTest = hashSetOf()
isICEnabledBackup = IncrementalCompilation.isEnabled() isICEnabledBackup = IncrementalCompilation.isEnabled()
isJSICEnabledBackup = IncrementalCompilation.isEnabledForJs()
IncrementalCompilation.setIsEnabled(true) IncrementalCompilation.setIsEnabled(true)
IncrementalCompilation.setIsEnabledForJs(true)
if (DEBUG_LOGGING_ENABLED) { if (DEBUG_LOGGING_ENABLED) {
enableDebugLogging() enableDebugLogging()
@@ -129,6 +138,7 @@ abstract class AbstractIncrementalJpsTest(
(AbstractIncrementalJpsTest::systemPropertiesBackup).javaField!![this] = null (AbstractIncrementalJpsTest::systemPropertiesBackup).javaField!![this] = null
lookupsDuringTest.clear() lookupsDuringTest.clear()
IncrementalCompilation.setIsEnabled(isICEnabledBackup) IncrementalCompilation.setIsEnabled(isICEnabledBackup)
IncrementalCompilation.setIsEnabledForJs(isJSICEnabledBackup)
super.tearDown() super.tearDown()
} }
@@ -138,7 +148,7 @@ abstract class AbstractIncrementalJpsTest(
private val mockConstantSearch: Callbacks.ConstantAffectionResolver? private val mockConstantSearch: Callbacks.ConstantAffectionResolver?
get() = MockJavaConstantSearch(workDir) 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 workDirPath = FileUtil.toSystemIndependentName(workDir.absolutePath)
val logger = MyLogger(workDirPath) val logger = MyLogger(workDirPath)
@@ -148,48 +158,67 @@ abstract class AbstractIncrementalJpsTest(
projectDescriptor.project.setTestingContext(TestingContext(lookupTracker, logger)) projectDescriptor.project.setTestingContext(TestingContext(lookupTracker, logger))
try { 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() val buildResult = BuildResult()
builder.addMessageHandler(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) } lookupTracker.lookups.mapTo(lookupsDuringTest) { LookupSymbol(it.name, it.scopeFqName) }
// for getting kotlin platform only
val dummyCompileContext = CompileContextImpl.createContextForTests(finalScope, projectDescriptor)
if (!buildResult.isSuccessful) { if (!buildResult.isSuccessful) {
val errorMessages = val errorMessages =
buildResult buildResult
.getMessages(BuildMessage.Kind.ERROR) .getMessages(BuildMessage.Kind.ERROR)
.map { it.messageText } .map { it.messageText }
.map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() } .map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() }
.joinToString("\n") .joinToString("\n")
return MakeResult(logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n", true, null) return MakeResult(
logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n",
true,
null,
name
)
} else {
return MakeResult(
logger.log,
false,
createMappingsDump(projectDescriptor, dummyCompileContext),
name
)
} }
else { } finally {
return MakeResult(logger.log, false, createMappingsDump(projectDescriptor))
}
}
finally {
projectDescriptor.dataManager.flush(false) projectDescriptor.dataManager.flush(false)
projectDescriptor.release() projectDescriptor.release()
} }
} }
private fun initialMake(): MakeResult { protected fun initialMake(): MakeResult {
val makeResult = build() val makeResult = build(name = "initial")
val initBuildLogFile = File(testDataDir, "init-build.log") val initBuildLogFile = File(testDataDir, "init-build.log")
if (initBuildLogFile.exists()) { if (initBuildLogFile.exists()) {
UsefulTestCase.assertSameLinesWithFile(initBuildLogFile.absolutePath, makeResult.log) UsefulTestCase.assertSameLinesWithFile(initBuildLogFile.absolutePath, makeResult.log)
} } else {
else {
assertFalse("Initial make failed:\n$makeResult", makeResult.makeFailed) assertFalse("Initial make failed:\n$makeResult", makeResult.makeFailed)
} }
return makeResult return makeResult
} }
private fun make(): MakeResult { private fun make(name: String?): MakeResult {
return build() return build(name = name)
} }
private fun rebuild(): MakeResult { private fun rebuild(): MakeResult {
@@ -205,21 +234,21 @@ abstract class AbstractIncrementalJpsTest(
} }
val rebuildResult = rebuild() val rebuildResult = rebuild()
assertEquals("Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult", assertEquals(
rebuildResult.makeFailed, makeOverallResult.makeFailed) "Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult",
rebuildResult.makeFailed, makeOverallResult.makeFailed
)
if (!outAfterMake.exists()) { if (!outAfterMake.exists()) {
assertFalse(outDir.exists()) assertFalse(outDir.exists())
} } else {
else { assertEqualDirectories(outAfterMake, outDir, makeOverallResult.makeFailed)
assertEqualDirectories(outDir, outAfterMake, makeOverallResult.makeFailed)
} }
if (!makeOverallResult.makeFailed) { if (!makeOverallResult.makeFailed) {
if (checkDumpsCaseInsensitively && rebuildResult.mappingsDump?.toLowerCase() == makeOverallResult.mappingsDump?.toLowerCase()) { if (checkDumpsCaseInsensitively && rebuildResult.mappingsDump?.toLowerCase() == makeOverallResult.mappingsDump?.toLowerCase()) {
// do nothing // do nothing
} } else {
else {
TestCase.assertEquals(rebuildResult.mappingsDump, makeOverallResult.mappingsDump) TestCase.assertEquals(rebuildResult.mappingsDump, makeOverallResult.mappingsDump)
} }
} }
@@ -233,30 +262,27 @@ abstract class AbstractIncrementalJpsTest(
rebuildAndCheckOutput(makeOverallResult) rebuildAndCheckOutput(makeOverallResult)
} }
private fun readModuleDependencies(): Map<String, List<DependencyDescriptor>>? { open protected val dependenciesTxtFile get() = File(testDataDir, "dependencies.txt")
val dependenciesTxt = File(testDataDir, "dependencies.txt")
if (!dependenciesTxt.exists()) return null
val result = HashMap<String, List<DependencyDescriptor>>() private fun readModuleDependencies(): DependenciesTxt? {
for (line in dependenciesTxt.readLines()) { val dependenciesTxtFile = dependenciesTxtFile
val split = line.split("->") if (!dependenciesTxtFile.exists()) return null
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)
}
return result return DependenciesTxtBuilder().readFile(dependenciesTxtFile)
} }
protected open fun createBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String = protected open fun createBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
buildString { buildString {
incrementalMakeResults.forEachIndexed { i, makeResult -> incrementalMakeResults.forEachIndexed { i, makeResult ->
if (i > 0) append("\n") 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("================ Step #${i + 1} =================\n\n")
append(makeResult.log)
} }
append(makeResult.log)
} }
}
protected open fun doTest(testDataPath: String) { protected open fun doTest(testDataPath: String) {
testDataDir = File(testDataPath) testDataDir = File(testDataPath)
@@ -272,8 +298,7 @@ abstract class AbstractIncrementalJpsTest(
if (buildLogFile != null && buildLogFile.exists()) { if (buildLogFile != null && buildLogFile.exists()) {
UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, logs) UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, logs)
} } else if (!allowNoBuildLogFileInTestData) {
else if (!allowNoBuildLogFileInTestData) {
throw IllegalStateException("No build log file in $testDataDir") throw IllegalStateException("No build log file in $testDataDir")
} }
@@ -282,17 +307,38 @@ abstract class AbstractIncrementalJpsTest(
clearCachesRebuildAndCheckOutput(lastMakeResult) clearCachesRebuildAndCheckOutput(lastMakeResult)
} }
private fun createMappingsDump(project: ProjectDescriptor) = protected open fun doInitialMakeTest(testDataPath: String) {
createKotlinIncrementalCacheDump(project) + "\n\n\n" + testDataDir = File(testDataPath)
createLookupCacheDump(project) + "\n\n\n" + workDir = FileUtilRt.createTempDirectory(TEMP_DIRECTORY_TO_USE, "jps-build", null)
createCommonMappingsDump(project) + "\n\n\n" + Disposer.register(testRootDisposable, Disposable { FileUtilRt.delete(workDir) })
createJavaMappingsDump(project)
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 { return buildString {
for (target in project.allModuleTargets.sortedBy { it.presentableName }) { for (target in project.allModuleTargets.sortedBy { it.presentableName }) {
append("<target $target>\n") append("<target $target>\n")
append(project.dataManager.getKotlinCache(target).dump()) append(project.dataManager.getKotlinCache(dummyCompileContext.kotlinBuildTargets[target]!!).dump())
append("</target $target>\n\n\n") append("</target $target>\n\n\n")
} }
} }
@@ -350,23 +396,35 @@ abstract class AbstractIncrementalJpsTest(
return byteArrayOutputStream.toString() 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> { private fun performModificationsAndMake(moduleNames: Set<String>?): List<MakeResult> {
val results = arrayListOf<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) } step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
performAdditionalModifications(step) performAdditionalModifications(step)
if (moduleNames == null) { if (moduleNames == null) {
preProcessSources(File(workDir, "src")) preProcessSources(File(workDir, "src"))
} } else {
else {
moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) } moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) }
} }
results.add(make()) val name = modificationNames?.getOrNull(index)
val makeResult = make(name)
results.add(makeResult)
} }
return results return results
} }
@@ -374,54 +432,92 @@ abstract class AbstractIncrementalJpsTest(
protected open fun performAdditionalModifications(modifications: List<Modification>) { protected open fun performAdditionalModifications(modifications: List<Modification>) {
} }
// null means one module protected open fun generateModuleSources(dependenciesTxt: DependenciesTxt) {
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)
}
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 jdk = addJdk("my jdk")
val moduleDependencies = readModuleDependencies() val dependenciesTxt = readModuleDependencies()
mapWorkingToOriginalFile = hashMapOf() mapWorkingToOriginalFile = hashMapOf()
val moduleNames: Set<String>? val moduleNames: Set<String>?
if (moduleDependencies == null) { if (dependenciesTxt == null) {
addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk) addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk)
prepareModuleSources(moduleName = null) prepareModuleSources(module = null)
moduleNames = null moduleNames = null
} } else {
else { dependenciesTxt.modules.forEach {
val nameToModule = moduleDependencies.keys val module = addModule(
.keysToMap { addModule(it, arrayOf(getAbsolutePath("$it/src")), null, null, jdk)!! } it.name,
arrayOf(getAbsolutePath("${it.name}/src")),
null,
null,
jdk
)!!
for ((moduleName, dependencies) in moduleDependencies) { val kotlinFacetSettings = it.kotlinFacetSettings
val module = nameToModule[moduleName]!! 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) { module.container.setChild(
JpsModuleRootModificationUtil.addDependency(module, nameToModule[dependency.name], JpsKotlinFacetModuleExtension.KIND,
JpsJavaDependencyScope.COMPILE, dependency.exported) JpsKotlinFacetModuleExtension(kotlinFacetSettings)
)
} }
it.jpsModule = module
} }
for (module in nameToModule.values) { dependenciesTxt.dependencies.forEach {
prepareModuleSources(module.name) 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.addKotlinStdlibDependency(myProject)
AbstractKotlinJpsBuildTestCase.addKotlinTestDependency(myProject) AbstractKotlinJpsBuildTestCase.addKotlinTestDependency(myProject)
return moduleNames return moduleNames
} }
protected open fun preProcessSources(srcDir: File) { 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> internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
get() = buildTargetIndex.allTargets.filterIsInstance<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, k2MetadataArguments: K2MetadataCompilerArguments,
compilerSettings: CompilerSettings, compilerSettings: CompilerSettings,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment,
destination: String,
classpath: Collection<String>,
sourceFiles: Collection<File> sourceFiles: Collection<File>
) { ) {
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2MetadataArguments)) 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.freeArgs = sourceFiles.map { it.absolutePath }
arguments.destination = arguments.destination ?: destination
withCompilerSettings(compilerSettings) { withCompilerSettings(compilerSettings) {
runCompiler(K2METADATA_COMPILER, arguments, environment) runCompiler(K2METADATA_COMPILER, arguments, environment)
} }
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.jps.build
import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.containers.ContainerUtil import com.intellij.util.containers.ContainerUtil
import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.BuildRootIndex
import org.jetbrains.jps.builders.BuildTarget import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.BuildTargetIndex
import org.jetbrains.jps.builders.java.dependencyView.Mappings import org.jetbrains.jps.builders.java.dependencyView.Mappings
import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.FSOperations import org.jetbrains.jps.incremental.FSOperations
@@ -43,7 +41,7 @@ class FSOperationsHelper(
fun markChunk(recursively: Boolean, kotlinOnly: Boolean, excludeFiles: Set<File> = setOf()) { fun markChunk(recursively: Boolean, kotlinOnly: Boolean, excludeFiles: Set<File> = setOf()) {
fun shouldMark(file: File): Boolean { fun shouldMark(file: File): Boolean {
if (kotlinOnly && !KotlinSourceFileCollector.isKotlinSourceFile(file)) return false if (kotlinOnly && !file.isKotlinSourceFile) return false
if (file in excludeFiles) return false if (file in excludeFiles) return false
@@ -17,11 +17,7 @@
package org.jetbrains.kotlin.jps.build package org.jetbrains.kotlin.jps.build
import com.intellij.openapi.diagnostic.Logger 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.ContainerUtil
import com.intellij.util.containers.MultiMap
import gnu.trove.THashSet
import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.BuildTarget import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.DirtyFilesHolder 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.*
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.* import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.*
import org.jetbrains.jps.incremental.java.JavaBuilder 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.incremental.storage.BuildDataManager
import org.jetbrains.jps.model.JpsProject import org.jetbrains.jps.model.JpsProject
import org.jetbrains.jps.model.java.JpsJavaClasspathKind import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.kotlin.build.GeneratedFile import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.build.JvmBuildMetaInfo import org.jetbrains.kotlin.build.JvmBuildMetaInfo
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil
import org.jetbrains.kotlin.compilerRunner.* import org.jetbrains.kotlin.compilerRunner.*
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.CompilerRunnerConstants.INTERNAL_ERROR_PREFIX import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.common.isDaemonEnabled import org.jetbrains.kotlin.daemon.common.isDaemonEnabled
import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker 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.incremental.*
import org.jetbrains.kotlin.jps.platforms.KotlinCommonModuleBuildTarget
import org.jetbrains.kotlin.jps.platforms.KotlinJsModuleBuildTarget 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.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.name.FqName
import org.jetbrains.kotlin.preloading.ClassCondition 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.KotlinPaths
import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir
import org.jetbrains.kotlin.utils.PathUtil import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.kotlin.utils.keysToMapExceptNulls
import org.jetbrains.org.objectweb.asm.ClassReader
import java.io.File import java.io.File
import java.util.* import java.util.*
import kotlin.collections.HashSet import kotlin.collections.HashSet
@@ -167,29 +154,39 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
context: CompileContext, context: CompileContext,
fsOperations: FSOperationsHelper fsOperations: FSOperationsHelper
) { ) {
val dirtyFilesHolder = object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) { val roundDirtyFiles = KotlinRoundDirtySourceFilesHolder(
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) { chunk,
FSOperations.processFilesToRecompile(context, chunk, processor) 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 representativeTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return
val chunkRemovedFiles = chunk.targets.keysToMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) }
val incrementalCaches = getIncrementalCaches(chunk, context) val incrementalCaches = getIncrementalCaches(chunk, context)
val messageCollector = MessageCollectorAdapter(context) val messageCollector = MessageCollectorAdapter(context, representativeTarget)
val environment = createCompileEnvironment(incrementalCaches, LookupTracker.DO_NOTHING, context, chunk, messageCollector) val environment = createCompileEnvironment(
if (environment == null) return representativeTarget,
incrementalCaches,
LookupTracker.DO_NOTHING,
ExpectActualTracker.DoNothing,
chunk,
messageCollector
) ?: return
val removedClasses = HashSet<String>() val removedClasses = HashSet<String>()
for (target in chunk.targets) { for (target in chunk.targets) {
val cache = incrementalCaches[target]!! val cache = incrementalCaches[target] ?: continue
val dirtyFiles = chunkDirtyFiles[target] val dirtyFiles = roundDirtyFiles.getDirtyFiles(target)
val removedFiles = chunkRemovedFiles[target] ?: emptyList() val removedFiles = roundDirtyFiles.getRemovedFilesSet(target)
val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles.toHashSet()) val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles)
val previousClasses = cache.classesBySources(dirtyFiles + removedFiles) val previousClasses = cache.classesFqNamesBySources(dirtyFiles + removedFiles)
for (jvmClassName in previousClasses) { for (jvmClassName in previousClasses) {
val fqName = jvmClassName.fqNameForClassNameWithoutDollars.asString() val fqName = jvmClassName.asString()
if (fqName !in existingClasses) { if (fqName !in existingClasses) {
removedClasses.add(fqName) removedClasses.add(fqName)
} }
@@ -214,50 +211,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val allVersions = cacheVersionsProvider.allVersions(targets) val allVersions = cacheVersionsProvider.allVersions(targets)
val actions = allVersions.map { it.checkVersion() }.toMutableSet() val actions = allVersions.map { it.checkVersion() }.toMutableSet()
val kotlinModuleBuilderTarget = context.kotlinBuildTargets[chunk.representativeTarget()] val kotlinModuleBuilderTarget = context.kotlinBuildTargets[chunk.representativeTarget()]!!
if (kotlinModuleBuilderTarget !is KotlinJsModuleBuildTarget) { kotlinModuleBuilderTarget.checkCachesVersions(chunk, dataManager, actions)
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)
}
}
}
return actions return actions
} }
@@ -276,14 +231,20 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
outputConsumer: ModuleLevelBuilder.OutputConsumer outputConsumer: ModuleLevelBuilder.OutputConsumer
): ModuleLevelBuilder.ExitCode { ): ModuleLevelBuilder.ExitCode {
JavaBuilderUtil.registerFilterToSkipMarkingAffectedFileDirty(context) {
it.isKotlinSourceFile
}
if (chunk.isDummy(context)) if (chunk.isDummy(context))
return NOTHING_DONE 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) val fsOperations = FSOperationsHelper(context, chunk, LOG)
try { 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 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( private fun doBuild(
chunk: ModuleChunk, chunk: ModuleChunk,
representativeTarget: KotlinModuleBuildTarget,
context: CompileContext, context: CompileContext,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
messageCollector: MessageCollectorAdapter, messageCollector: MessageCollectorAdapter,
@@ -311,12 +273,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
fsOperations: FSOperationsHelper fsOperations: FSOperationsHelper
): ModuleLevelBuilder.ExitCode { ): ModuleLevelBuilder.ExitCode {
// Workaround for Android Studio // Workaround for Android Studio
val isJsModule = context.kotlinBuildTargets[chunk.representativeTarget()] is KotlinJsModuleBuildTarget val isJsModule = representativeTarget is KotlinJsModuleBuildTarget
if (!JavaBuilder.IS_ENABLED[context, true] && !isJsModule) { if (!JavaBuilder.IS_ENABLED[context, true] && !isJsModule) {
messageCollector.report(INFO, "Kotlin JPS plugin is disabled") messageCollector.report(INFO, "Kotlin JPS plugin is disabled")
return NOTHING_DONE return NOTHING_DONE
} }
val roundDirtyFilesHolder = KotlinRoundDirtySourceFilesHolder(chunk, context, fsOperations, dirtyFilesHolder)
val projectDescriptor = context.projectDescriptor val projectDescriptor = context.projectDescriptor
val dataManager = projectDescriptor.dataManager val dataManager = projectDescriptor.dataManager
val targets = chunk.targets val targets = chunk.targets
@@ -325,7 +288,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val isChunkRebuilding = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context) val isChunkRebuilding = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)
|| targets.any { rebuildAfterCacheVersionChanged[it] == true } || targets.any { rebuildAfterCacheVersionChanged[it] == true }
if (hasKotlinDirtyOrRemovedFiles(dirtyFilesHolder, chunk)) { if (roundDirtyFilesHolder.hasDirtyOrRemovedFiles) {
if (!isChunkRebuilding && !IncrementalCompilation.isEnabled()) { if (!isChunkRebuilding && !IncrementalCompilation.isEnabled()) {
targets.forEach { rebuildAfterCacheVersionChanged[it] = true } targets.forEach { rebuildAfterCacheVersionChanged[it] = true }
return CHUNK_REBUILD_REQUIRED return CHUNK_REBUILD_REQUIRED
@@ -347,23 +310,30 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val project = projectDescriptor.project val project = projectDescriptor.project
val lookupTracker = getLookupTracker(project) val lookupTracker = getLookupTracker(project)
val exceptActualTracer = ExpectActualTrackerImpl()
val incrementalCaches = getIncrementalCaches(chunk, context) 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 reportOutputFiles = true
version = true // Always report the version to help diagnosing user issues if they submit the compiler output version = true // Always report the version to help diagnosing user issues if they submit the compiler output
} }
val allCompiledFiles = getAllCompiledFilesContainer(context) if (LOG.isDebugEnabled) {
val filesToCompile = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder) LOG.debug("Compiling files: ${roundDirtyFilesHolder.dirtyFiles}")
}
LOG.debug("Compiling files: ${filesToCompile.values()}")
val start = System.nanoTime() val start = System.nanoTime()
val outputItemCollector = doCompileModuleChunk( val outputItemCollector = doCompileModuleChunk(
allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder, chunk, representativeTarget, commonArguments, context, roundDirtyFilesHolder, environment,
environment, filesToCompile, incrementalCaches, fsOperations incrementalCaches
) )
statisticsLogger.registerStatistic(chunk, System.nanoTime() - start) statisticsLogger.registerStatistic(chunk, System.nanoTime() - start)
@@ -386,7 +356,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
saveVersions(context, chunk, commonArguments) saveVersions(context, chunk, commonArguments)
if (targets.any { hasKotlin[it] == null }) { 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) { for (target in targets) {
@@ -398,7 +368,12 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
context.kotlinBuildTargets[it]?.doAfterBuild() context.kotlinBuildTargets[it]?.doAfterBuild()
} }
updateJavaMappings(chunk, context, dirtyFilesHolder, filesToCompile, generatedFiles, incrementalCaches) representativeTarget.updateChunkMappings(
chunk,
roundDirtyFilesHolder,
generatedFiles,
incrementalCaches
)
if (!IncrementalCompilation.isEnabled()) { if (!IncrementalCompilation.isEnabled()) {
return OK return OK
@@ -410,14 +385,17 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
progress.progress("updating IC caches") progress.progress("updating IC caches")
val changesCollector = ChangesCollector() val changesCollector = ChangesCollector()
for ((target, files) in generatedFiles) { 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) { if (!isChunkRebuilding) {
changesCollector.processChangesUsingLookups( changesCollector.processChangesUsingLookups(
filesToCompile.values().toSet(), roundDirtyFilesHolder.dirtyFiles,
dataManager, dataManager,
fsOperations, fsOperations,
incrementalCaches.values incrementalCaches.values
@@ -451,8 +429,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
LOG.info("Clearing caches for " + targets.joinToString { it.presentableName }) LOG.info("Clearing caches for " + targets.joinToString { it.presentableName })
val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager)
val kotlinBuildTargets = context.kotlinBuildTargets
for (target in targets) { for (target in targets) {
dataManager.getKotlinCache(target).clean() dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean()
hasKotlin.clean(target) hasKotlin.clean(target)
rebuildAfterCacheVersionChanged[target] = true rebuildAfterCacheVersionChanged[target] = true
} }
@@ -464,8 +443,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
CacheVersion.Action.CLEAN_NORMAL_CACHES -> { CacheVersion.Action.CLEAN_NORMAL_CACHES -> {
LOG.info("Clearing caches for all targets") LOG.info("Clearing caches for all targets")
val kotlinBuildTargets = context.kotlinBuildTargets
for (target in context.allTargets()) { for (target in context.allTargets()) {
dataManager.getKotlinCache(target).clean() dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean()
} }
} }
CacheVersion.Action.CLEAN_DATA_CONTAINER -> { CacheVersion.Action.CLEAN_DATA_CONTAINER -> {
@@ -491,12 +471,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager)
for (sourceRoot in sourceRoots) { 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()) fsOperations.markFiles(ktFiles.toList())
} }
val kotlinBuildTargets = context.kotlinBuildTargets
for (target in context.allTargets()) { for (target in context.allTargets()) {
dataManager.getKotlinCache(target).clean() dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean()
rebuildAfterCacheVersionChanged[target] = true 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( private fun doCompileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk, chunk: ModuleChunk,
kotlinTarget: KotlinModuleBuildTarget,
commonArguments: CommonCompilerArguments, commonArguments: CommonCompilerArguments,
context: CompileContext, context: CompileContext,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, roundDirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>, incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>
incrementalCaches: Map<ModuleBuildTarget, IncrementalJvmCache>,
fsOperations: FSOperationsHelper
): OutputItemsCollector? { ): OutputItemsCollector? {
val representativeTarget = chunk.representativeTarget() val representativeTarget = chunk.representativeTarget()
@@ -556,39 +532,40 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
if (IncrementalCompilation.isEnabled()) { if (IncrementalCompilation.isEnabled()) {
for (target in chunk.targets) { for (target in chunk.targets) {
val cache = incrementalCaches[target]!! val cache = incrementalCaches[target]
val removedAndDirtyFiles = filesToCompile[target] + dirtyFilesHolder.getRemovedFiles(target).map(::File) val targetDirtyFiles = roundDirtyFilesHolder.byTarget[target]
cache.markDirty(removedAndDirtyFiles)
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 = kotlinTarget.compileModuleChunk(
val isDoneSomething = kotlinModuleBuilderTarget?.compileModuleChunk( chunk, commonArguments, roundDirtyFilesHolder, environment
allCompiledFiles, chunk, commonArguments, dirtyFilesHolder, )
environment, filesToCompile, fsOperations
) ?: false
return if (isDoneSomething) environment.outputItemsCollector else null return if (isDoneSomething) environment.outputItemsCollector else null
} }
private fun createCompileEnvironment( private fun createCompileEnvironment(
incrementalCaches: Map<ModuleBuildTarget, IncrementalCache>, kotlinModuleBuilderTarget: KotlinModuleBuildTarget,
incrementalCaches: Map<ModuleBuildTarget, JpsIncrementalCache>,
lookupTracker: LookupTracker, lookupTracker: LookupTracker,
context: CompileContext, exceptActualTracer: ExpectActualTracker,
chunk: ModuleChunk, chunk: ModuleChunk,
messageCollector: MessageCollectorAdapter messageCollector: MessageCollectorAdapter
): JpsCompilerEnvironment? { ): JpsCompilerEnvironment? {
val compilerServices = with(Services.Builder()) { val compilerServices = with(Services.Builder()) {
register(LookupTracker::class.java, lookupTracker) kotlinModuleBuilderTarget.makeServices(this, incrementalCaches, lookupTracker, exceptActualTracer)
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()
}
})
build() build()
} }
@@ -607,7 +584,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
classesToLoadByParent, classesToLoadByParent,
messageCollector, messageCollector,
OutputItemsCollectorImpl(), OutputItemsCollectorImpl(),
ProgressReporterImpl(context, chunk) ProgressReporterImpl(kotlinModuleBuilderTarget.context, chunk)
) )
} }
@@ -641,7 +618,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val sourceToTarget = HashMap<File, ModuleBuildTarget>() val sourceToTarget = HashMap<File, ModuleBuildTarget>()
if (chunk.targets.size > 1) { if (chunk.targets.size > 1) {
for (target in chunk.targets) { for (target in chunk.targets) {
context.kotlinBuildTargets[target]?.sources?.forEach { context.kotlinBuildTargets[target]?.sourceFiles?.forEach {
sourceToTarget[it] = target sourceToTarget[it] = target
} }
} }
@@ -650,64 +627,14 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val representativeTarget = chunk.representativeTarget() val representativeTarget = chunk.representativeTarget()
fun SimpleOutputItem.target() = fun SimpleOutputItem.target() =
sourceFiles.firstOrNull()?.let { sourceToTarget[it] } ?: chunk.targets.singleOrNull { sourceFiles.firstOrNull()?.let { sourceToTarget[it] } ?: chunk.targets.singleOrNull {
it.outputDir?.let { it.outputDir?.let {
outputFile.startsWith(it) outputFile.startsWith(it)
} ?: false } ?: false
} ?: representativeTarget } ?: representativeTarget
return outputItemCollector.outputs.groupBy(SimpleOutputItem::target, SimpleOutputItem::toGeneratedFile) 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>>) { private fun registerOutputItems(outputConsumer: OutputConsumer, outputItems: Map<ModuleBuildTarget, List<GeneratedFile>>) {
for ((target, outputs) in outputItems) { for ((target, outputs) in outputItems) {
for (output in outputs) { for (output in outputs) {
@@ -717,67 +644,18 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
} }
private fun updateLookupStorage( private fun updateLookupStorage(
chunk: ModuleChunk,
lookupTracker: LookupTracker, lookupTracker: LookupTracker,
dataManager: BuildDataManager, dataManager: BuildDataManager,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder
filesToCompile: MultiMap<ModuleBuildTarget, File>
) { ) {
if (lookupTracker !is LookupTrackerImpl) if (lookupTracker !is LookupTrackerImpl)
throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}") 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 -> dataManager.withLookupStorage { lookupStorage ->
lookupStorage.removeLookupsFrom(filesToCompile.values().asSequence() + removedFiles.asSequence()) lookupStorage.removeLookupsFrom(dirtyFilesHolder.dirtyOrRemovedFilesSet.asSequence())
lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values) 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 { private class JpsICReporter : ICReporter {
@@ -792,7 +670,7 @@ private fun ChangesCollector.processChangesUsingLookups(
compiledFiles: Set<File>, compiledFiles: Set<File>,
dataManager: BuildDataManager, dataManager: BuildDataManager,
fsOperations: FSOperationsHelper, fsOperations: FSOperationsHelper,
caches: Iterable<IncrementalJvmCache> caches: Iterable<JpsIncrementalCache>
) { ) {
val allCaches = caches.flatMap { it.thisWithDependentCaches } val allCaches = caches.flatMap { it.thisWithDependentCaches }
val reporter = JpsICReporter() val reporter = JpsICReporter()
@@ -806,7 +684,7 @@ private fun ChangesCollector.processChangesUsingLookups(
} }
private fun ChangesCollector.getDirtyFiles( private fun ChangesCollector.getDirtyFiles(
caches: Iterable<IncrementalCacheCommon<*>>, caches: Iterable<IncrementalCacheCommon>,
dataManager: BuildDataManager dataManager: BuildDataManager
): Set<File> { ): Set<File> {
val reporter = JpsICReporter() val reporter = JpsICReporter()
@@ -825,16 +703,32 @@ private fun getLookupTracker(project: JpsProject): LookupTracker {
return testLookupTracker 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 dependentTargets = getDependentTargets(chunk, context)
val dataManager = context.projectDescriptor.dataManager val dataManager = context.projectDescriptor.dataManager
val chunkCaches = chunk.targets.keysToMap { dataManager.getKotlinCache(it) } val kotlinBuildTargets = context.kotlinBuildTargets
val dependentCaches = dependentTargets.map { dataManager.getKotlinCache(it) }
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 (chunkCache in chunkCaches.values) {
for (dependentCache in dependentCaches) { 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> = private fun getDependenciesRecursively(module: JpsModule, kind: JpsJavaClasspathKind): Set<JpsModule> =
JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().modules 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 = fun jvmBuildMetaInfoFile(target: ModuleBuildTarget, dataManager: BuildDataManager): File =
File(dataManager.dataPaths.getTargetDataRoot(target), KotlinBuilder.JVM_BUILD_META_INFO_FILE_NAME) 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.ModuleBuildTarget
import org.jetbrains.jps.incremental.storage.BuildDataManager import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.incremental.storage.StorageOwner 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.incremental.IncrementalJvmCache
import org.jetbrains.kotlin.jps.build.KotlinBuilder import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.platforms.KotlinModuleBuildTarget
import java.io.File import java.io.File
interface JpsIncrementalCache : IncrementalCacheCommon, StorageOwner {
fun addJpsDependentCache(cache: JpsIncrementalCache)
}
class JpsIncrementalJvmCache( class JpsIncrementalJvmCache(
target: ModuleBuildTarget, target: ModuleBuildTarget,
paths: BuildDataPaths 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) { override fun debugLog(message: String) {
KotlinBuilder.LOG.debug(message) KotlinBuilder.LOG.debug(message)
} }
} }
private class KotlinIncrementalStorageProvider( class JpsIncrementalJsCache(
private val target: ModuleBuildTarget, target: ModuleBuildTarget,
private val paths: BuildDataPaths paths: BuildDataPaths
) : StorageProvider<JpsIncrementalJvmCache>() { ) : 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 equals(other: Any?) = other is KotlinIncrementalStorageProvider && target == other.target
override fun hashCode() = target.hashCode() override fun hashCode() = target.hashCode()
override fun createStorage(targetDataDir: File): JpsIncrementalJvmCache = override fun createStorage(targetDataDir: File): JpsIncrementalCache = target.createCacheStorage(paths)
JpsIncrementalJvmCache(target, paths)
} }
fun BuildDataManager.getKotlinCache(target: ModuleBuildTarget): JpsIncrementalJvmCache = fun BuildDataManager.getKotlinCache(target: KotlinModuleBuildTarget): JpsIncrementalCache =
getStorage(target, KotlinIncrementalStorageProvider(target, dataPaths)) getStorage(target.jpsModuleBuildTarget, KotlinIncrementalStorageProvider(target, dataPaths))
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.jps.model 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.JpsElementBase
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase 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.jps.model.module.JpsModule
import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.config.CompilerSettings import org.jetbrains.kotlin.config.CompilerSettings
@@ -19,6 +22,25 @@ val JpsModule.kotlinFacet: JpsKotlinFacetModuleExtension?
val JpsModule.targetPlatform: TargetPlatformKind<*>? val JpsModule.targetPlatform: TargetPlatformKind<*>?
get() = kotlinFacet?.settings?.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? val JpsModule.productionOutputFilePath: String?
get() { get() {
val facetSettings = kotlinFacet?.settings ?: return null val facetSettings = kotlinFacet?.settings ?: return null
@@ -59,7 +81,7 @@ private inline fun <reified T : CommonCompilerArguments> JpsModule.getCompilerAr
val facetSettings = kotlinFacet?.settings ?: return projectSettingsCopy val facetSettings = kotlinFacet?.settings ?: return projectSettingsCopy
if (facetSettings.useProjectSettings) 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>() { class JpsKotlinFacetModuleExtension(settings: KotlinFacetSettings) : JpsElementBase<JpsKotlinFacetModuleExtension>() {
@@ -5,49 +5,87 @@
package org.jetbrains.kotlin.jps.platforms 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.ModuleChunk
import org.jetbrains.jps.builders.DirtyFilesHolder import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import com.intellij.openapi.compiler.CompileContext as JpsCompileContext
import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.FSOperations
import org.jetbrains.jps.incremental.ModuleBuildTarget 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.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.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner 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.k2MetadataCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
import java.io.File
class KotlinCommonModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : class KotlinCommonModuleBuildTarget(context: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) { KotlinModuleBuildTarget(context, jpsModuleBuildTarget) {
override fun compileModuleChunk( override fun compileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk, chunk: ModuleChunk,
commonArguments: CommonCompilerArguments, commonArguments: CommonCompilerArguments,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment
filesToCompile: MultiMap<ModuleBuildTarget, File>,
fsOperations: FSOperationsHelper
): Boolean { ): Boolean {
require(chunk.representativeTarget() == jpsModuleBuildTarget) reportAndSkipCircular(chunk, environment)
if (reportAndSkipCircular(chunk, environment)) return false
// Incremental compilation is not supported, so mark all dependents as dirty val k2MetadataArguments = module.k2MetadataCompilerArguments
FSOperations.markDirtyRecursively(context, CompilationRound.CURRENT, chunk) if (k2MetadataArguments.enabledInJps || (commonArguments as? K2MetadataCompilerArguments)?.enabledInJps == true) {
JpsKotlinCompilerRunner().runK2MetadataCompiler(
JpsKotlinCompilerRunner().runK2MetadataCompiler( commonArguments,
commonArguments, k2MetadataArguments,
module.k2MetadataCompilerArguments, module.kotlinCompilerSettings,
module.kotlinCompilerSettings, environment,
environment, destination,
sources dependenciesOutputDirs + libraryFiles,
) sourceFiles // incremental K2MetadataCompiler not supported yet
)
}
return true 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 package org.jetbrains.kotlin.jps.platforms
import com.intellij.util.containers.MultiMap
import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.DirtyFilesHolder import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.library.JpsOrderRootType import org.jetbrains.jps.model.library.JpsOrderRootType
import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil 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.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner 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.k2JsCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
import org.jetbrains.kotlin.jps.model.productionOutputFilePath 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.io.File
import java.net.URI 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) : 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( override fun compileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk, chunk: ModuleChunk,
commonArguments: CommonCompilerArguments, commonArguments: CommonCompilerArguments,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment
filesToCompile: MultiMap<ModuleBuildTarget, File>,
fsOperations: FSOperationsHelper
): Boolean { ): Boolean {
require(chunk.representativeTarget() == jpsModuleBuildTarget) require(chunk.representativeTarget() == jpsModuleBuildTarget)
if (reportAndSkipCircular(chunk, environment)) return false if (reportAndSkipCircular(chunk, environment)) return false
val sources = sources val sources = collectSourcesToCompile(dirtyFilesHolder)
if (sources.isEmpty()) return false if (!checkShouldCompileAndLog(dirtyFilesHolder, sources)) return false
val libraries = libraryFiles + dependenciesMetaFiles val libraries = libraryFiles + dependenciesMetaFiles
@@ -144,7 +188,7 @@ class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTa
if (dependencyBuildTarget != this@KotlinJsModuleBuildTarget && if (dependencyBuildTarget != this@KotlinJsModuleBuildTarget &&
dependencyBuildTarget is KotlinJsModuleBuildTarget && dependencyBuildTarget is KotlinJsModuleBuildTarget &&
dependencyBuildTarget.sources.isNotEmpty() dependencyBuildTarget.sourceFiles.isNotEmpty()
) { ) {
val metaFile = dependencyBuildTarget.outputMetaFile val metaFile = dependencyBuildTarget.outputMetaFile
if (metaFile.exists()) { 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.util.text.StringUtil
import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.util.containers.ContainerUtil import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.MultiMap
import com.intellij.util.io.URLUtil import com.intellij.util.io.URLUtil
import gnu.trove.THashSet
import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.builders.DirtyFilesHolder import org.jetbrains.jps.builders.java.JavaBuilderUtil
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.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget 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.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsSdkDependency 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.build.JvmSourceRoot
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.jps.build.FSOperationsHelper 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.KotlinBuilder
import org.jetbrains.kotlin.jps.build.KotlinSourceFileCollector import org.jetbrains.kotlin.jps.build.KotlinRoundDirtySourceFilesHolder
import org.jetbrains.kotlin.jps.build.processedTargetsWithRemovedFilesContainer 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.k2JvmCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings 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.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.File
import java.io.IOException import java.io.IOException
class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : 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( override fun compileModuleChunk(
allCompiledFiles: MutableSet<File>,
chunk: ModuleChunk, chunk: ModuleChunk,
commonArguments: CommonCompilerArguments, commonArguments: CommonCompilerArguments,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment
filesToCompile: MultiMap<ModuleBuildTarget, File>,
fsOperations: FSOperationsHelper
): Boolean { ): Boolean {
if (chunk.modules.size > 1) { if (chunk.modules.size > 1) {
environment.messageCollector.report( environment.messageCollector.report(
@@ -55,34 +133,28 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
) )
} }
allCompiledFiles.addAll(filesToCompile.values()) val filesSet = dirtyFilesHolder.dirtyFiles
val processedTargetsWithRemoved = context.processedTargetsWithRemovedFilesContainer val moduleFile = generateModuleDescription(chunk, dirtyFilesHolder)
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)
if (moduleFile == null) { if (moduleFile == null) {
KotlinBuilder.LOG.debug( if (KotlinBuilder.LOG.isDebugEnabled) {
"Not compiling, because no files affected: " + filesToCompile.keySet().joinToString { it.presentableName } KotlinBuilder.LOG.debug(
) "Not compiling, because no files affected: " + chunk.targets.joinToString { it.presentableName }
)
}
// No Kotlin sources found // No Kotlin sources found
return false return false
} }
val module = chunk.representativeTarget().module val module = chunk.representativeTarget().module
KotlinBuilder.LOG.debug("Compiling to JVM ${filesToCompile.values().size} files" if (KotlinBuilder.LOG.isDebugEnabled) {
+ (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)") val totalRemovedFiles = dirtyFilesHolder.removedFilesCount
+ " in " + filesToCompile.keySet().joinToString { it.presentableName }) KotlinBuilder.LOG.debug("Compiling to JVM ${filesSet.size} files"
+ (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)")
+ " in " + chunk.targets.joinToString { it.presentableName })
}
try { try {
val compilerRunner = JpsKotlinCompilerRunner() val compilerRunner = JpsKotlinCompilerRunner()
@@ -102,39 +174,22 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
return true return true
} }
fun generateModuleDescription( fun generateModuleDescription(chunk: ModuleChunk, dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder): File? {
context: CompileContext,
chunk: ModuleChunk,
sourceFiles: MultiMap<ModuleBuildTarget, File>, // ignored for non-incremental compilation
hasRemovedFiles: Boolean
): File? {
val builder = KotlinModuleXmlBuilder() val builder = KotlinModuleXmlBuilder()
var noSources = true var hasDirtySources = false
val targets = chunk.targets.mapNotNull { this.context.kotlinBuildTargets[it] as? KotlinJvmModuleBuildTarget } val targets = chunk.targets.mapNotNull { this.context.kotlinBuildTargets[it] as? KotlinJvmModuleBuildTarget }
val outputDirs = targets.map { it.outputDir }.toSet() val outputDirs = targets.map { it.outputDir }.toSet()
val logger = context.loggingManager.projectBuilderLogger
for (target in targets) { for (target in targets) {
val outputDir = target.outputDir val outputDir = target.outputDir
val friendDirs = target.friendOutputDirs val friendDirs = target.friendOutputDirs
val moduleSources = val moduleSources = collectSourcesToCompile(target, dirtyFilesHolder)
if (IncrementalCompilation.isEnabled() && target.expectedBy.isEmpty()) { val hasDirtyOrRemovedSources = checkShouldCompileAndLog(target, dirtyFilesHolder, moduleSources)
sourceFiles.get(target.jpsModuleBuildTarget) if (hasDirtyOrRemovedSources) hasDirtySources = true
} else {
target.sources
}
if (moduleSources.isNotEmpty() || hasRemovedFiles) {
noSources = false
if (logger.isEnabled) {
logger.logCompiledFiles(moduleSources, KotlinBuilder.KOTLIN_BUILDER_NAME, "Compiling files:")
}
}
val kotlinModuleId = target.targetId val kotlinModuleId = target.targetId
builder.addModule( builder.addModule(
@@ -152,7 +207,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
) )
} }
if (noSources) return null if (!hasDirtySources) return null
val scriptFile = createTempFileForModuleDesc(chunk) val scriptFile = createTempFileForModuleDesc(chunk)
FileUtil.writeToFile(scriptFile, builder.asText().toString()) FileUtil.writeToFile(scriptFile, builder.asText().toString())
@@ -192,7 +247,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
val extension = file.extension val extension = file.extension
// Don't filter out files, we want to report warnings about absence through the common place // 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 return@filter false
} }
} }
@@ -213,7 +268,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
return File(url.substringAfter(StandardFileSystems.JRT_PROTOCOL_PREFIX).substringBeforeLast(URLUtil.JAR_SEPARATOR)) 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 roots = context.projectDescriptor.buildRootIndex.getTargetRoots(jpsModuleBuildTarget, context)
val result = ContainerUtil.newArrayList<JvmSourceRoot>() val result = ContainerUtil.newArrayList<JvmSourceRoot>()
for (root in roots) { for (root in roots) {
@@ -225,4 +280,64 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT
} }
return result 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 package org.jetbrains.kotlin.jps.platforms
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import org.jetbrains.jps.builders.ModuleBasedBuildTargetType
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget import org.jetbrains.jps.incremental.ModuleBuildTarget
@@ -46,17 +45,17 @@ val CompileContext.kotlinBuildTargets: KotlinBuildTargets
} }
class KotlinBuildTargets internal constructor(val compileContext: CompileContext) { 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>() private val isKotlinJsStdlibJar = ConcurrentHashMap<String, Boolean>()
@JvmName("getNullable") @JvmName("getNullable")
operator fun get(target: ModuleBuildTarget?): KotlinModuleBuilderTarget? { operator fun get(target: ModuleBuildTarget?): KotlinModuleBuildTarget? {
if (target == null) return null if (target == null) return null
return get(target) return get(target)
} }
operator fun get(target: ModuleBuildTarget): KotlinModuleBuilderTarget? { operator fun get(target: ModuleBuildTarget): KotlinModuleBuildTarget? {
if (target.targetType !is ModuleBasedBuildTargetType) return null if (target.module.moduleType != JpsJavaModuleType.INSTANCE) return null
return byJpsModuleBuildTarget.computeIfAbsent(target) { return byJpsModuleBuildTarget.computeIfAbsent(target) {
when (target.module.targetPlatform ?: detectTargetPlatform(target)) { when (target.module.targetPlatform ?: detectTargetPlatform(target)) {
@@ -16,16 +16,6 @@ Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------ ------------------------------------------
Exit code: NOTHING_DONE 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 Building module3
Cleaning output files: Cleaning output files:
out/production/module3/META-INF/module3.kotlin_module out/production/module3/META-INF/module3.kotlin_module
@@ -36,3 +26,13 @@ Compiling files:
End of files End of files
Exit code: OK 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
------------------------------------------