diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheCommon.kt b/build-common/src/org/jetbrains/kotlin/incremental/AbstractIncrementalCache.kt similarity index 63% rename from build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheCommon.kt rename to build-common/src/org/jetbrains/kotlin/incremental/AbstractIncrementalCache.kt index bec45213131..a4da1c255e2 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCacheCommon.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/AbstractIncrementalCache.kt @@ -25,24 +25,41 @@ import org.jetbrains.kotlin.metadata.deserialization.supertypes import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.deserialization.getClassId import java.io.File +import java.util.* /** - * Incremental cache common for JVM and JS + * Incremental cache common for JVM and JS, ClassName type aware */ -abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(workingDir) { +interface IncrementalCacheCommon { + val thisWithDependentCaches: Iterable> + fun classesFqNamesBySources(files: Iterable): Collection + fun getSubtypesOf(className: FqName): Sequence + fun getSourceFileIfClass(fqName: FqName): File? + fun markDirty(removedAndCompiledSources: Collection) + fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) + fun clearComplementaryFilesMapping(dirtyFiles: Collection): Collection + fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl) + fun dump(): String +} + +/** + * Incremental cache common for JVM and JS for specifit ClassName type + */ +abstract class AbstractIncrementalCache(workingDir: File) : BasicMapsOwner(workingDir), IncrementalCacheCommon { companion object { private val SUBTYPES = "subtypes" private val SUPERTYPES = "supertypes" private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source" + private val COMPLEMENTARY_FILES = "complementary-files" @JvmStatic protected val SOURCE_TO_CLASSES = "source-to-classes" @JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes" } - private val dependents = arrayListOf>() - fun addDependentCache(cache: IncrementalCacheCommon) { + private val dependents = arrayListOf>() + fun addDependentCache(cache: AbstractIncrementalCache) { dependents.add(cache) } - val thisWithDependentCaches: Iterable> by lazy { + override val thisWithDependentCaches: Iterable> by lazy { val result = arrayListOf(this) result.addAll(dependents) result @@ -54,16 +71,24 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOw internal abstract val sourceToClassesMap: AbstractSourceToOutputMap internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap - fun classesFqNamesBySources(files: Iterable): Collection = + /** + * 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): Collection = files.flatMapTo(HashSet()) { sourceToClassesMap.getFqNames(it) } - fun getSubtypesOf(className: FqName): Sequence = + override fun getSubtypesOf(className: FqName): Sequence = subtypesMap[className].asSequence() - fun getSourceFileIfClass(fqName: FqName): File? = + override fun getSourceFileIfClass(fqName: FqName): File? = classFqNameToSourceMap[fqName] - open fun markDirty(removedAndCompiledSources: Collection) { + override fun markDirty(removedAndCompiledSources: Collection) { for (sourceFile in removedAndCompiledSources) { val classes = sourceToClassesMap[sourceFile] classes.forEach { @@ -90,8 +115,6 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOw classFqNameToSourceMap[child] = srcFile } - abstract fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) - protected fun removeAllFromClassStorage(removedClasses: Collection, changesCollector: ChangesCollector) { if (removedClasses.isEmpty()) return @@ -141,4 +164,29 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOw override fun dumpValue(value: String) = value } + + override fun clearComplementaryFilesMapping(dirtyFiles: Collection): Collection { + val complementaryFiles = HashSet() + 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>() + 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 + } + } } \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/incremental/CacheVersion.kt b/build-common/src/org/jetbrains/kotlin/incremental/CacheVersion.kt index 64aea2041a6..b0c16ffa9a9 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/CacheVersion.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/CacheVersion.kt @@ -23,8 +23,8 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion import java.io.File import java.io.IOException -private val NORMAL_VERSION = 8 -private val DATA_CONTAINER_VERSION = 2 +private val NORMAL_VERSION = 9 +private val DATA_CONTAINER_VERSION = 3 private val NORMAL_VERSION_FILE_NAME = "format-version.txt" private val DATA_CONTAINER_VERSION_FILE_NAME = "data-container-format-version.txt" diff --git a/build-common/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt new file mode 100644 index 00000000000..0adf1e19019 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt @@ -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>() + + val expectToActualMap: Map> + get() = expectToActual + + override fun report(expectedFile: File, actualFile: File) { + expectToActual.getOrPut(expectedFile) { hashSetOf() }.add(actualFile) + } +} \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt index 02e2c90f8c2..9696d78fd66 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJsCache.kt @@ -36,7 +36,7 @@ import java.io.DataInput import java.io.DataOutput import java.io.File -open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDir) { +open class IncrementalJsCache(cachesDir: File) : AbstractIncrementalCache(cachesDir) { companion object { private val TRANSLATION_RESULT_MAP = "translation-result" private val INLINE_FUNCTIONS = "inline-functions" diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt index 50951d30aad..add0da9a48b 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalJvmCache.kt @@ -44,7 +44,7 @@ val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin" open class IncrementalJvmCache( private val targetDataRoot: File, targetOutputDir: File? -) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache { +) : AbstractIncrementalCache(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache { companion object { private val PROTO_MAP = "proto" private val CONSTANTS_MAP = "constants" diff --git a/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt b/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt index 8b50223288a..c8bb5385cc3 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/buildUtil.kt @@ -81,10 +81,10 @@ fun makeCompileServices( } fun updateIncrementalCache( - generatedFiles: Iterable, - cache: IncrementalJvmCache, - changesCollector: ChangesCollector, - javaChangesTracker: JavaClassesTrackerImpl? + generatedFiles: Iterable, + cache: IncrementalJvmCache, + changesCollector: ChangesCollector, + javaChangesTracker: JavaClassesTrackerImpl? ) { for (generatedFile in generatedFiles) { when { @@ -119,8 +119,8 @@ data class DirtyData( ) fun ChangesCollector.getDirtyData( - caches: Iterable>, - reporter: ICReporter + caches: Iterable, + reporter: ICReporter ): DirtyData { val dirtyLookupSymbols = HashSet() val dirtyClassesFqNames = HashSet() @@ -173,10 +173,10 @@ fun mapLookupSymbolsToFiles( } fun mapClassesFqNamesToFiles( - caches: Iterable>, - classesFqNames: Iterable, - reporter: ICReporter, - excludes: Set = emptySet() + caches: Iterable, + classesFqNames: Iterable, + reporter: ICReporter, + excludes: Set = emptySet() ): Set { val dirtyFiles = HashSet() @@ -195,7 +195,7 @@ fun mapClassesFqNamesToFiles( fun withSubtypes( typeFqName: FqName, - caches: Iterable> + caches: Iterable ): Set { val types = LinkedList(listOf(typeFqName)) val subtypes = hashSetOf() diff --git a/build-common/src/org/jetbrains/kotlin/incremental/storage/FilesMap.kt b/build-common/src/org/jetbrains/kotlin/incremental/storage/FilesMap.kt new file mode 100644 index 00000000000..a1a650aaaa0 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/incremental/storage/FilesMap.kt @@ -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>(storageFile, PathStringDescriptor, StringCollectionExternalizer) { + + operator fun set(sourceFile: File, outputFiles: Collection) { + storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath } + } + + operator fun get(sourceFile: File): Collection = + storage[sourceFile.absolutePath].orEmpty().map(::File) + + override fun dumpValue(value: Collection) = + value.dumpCollection() + + fun remove(file: File): Collection = + get(file).also { storage.remove(file.absolutePath) } +} \ No newline at end of file diff --git a/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/incrementalModificationUtils.kt b/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/incrementalModificationUtils.kt index 8f8ace23c98..7962d50a918 100644 --- a/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/incrementalModificationUtils.kt +++ b/build-common/test/org/jetbrains/kotlin/incremental/testingUtils/incrementalModificationUtils.kt @@ -67,12 +67,18 @@ fun getModificationsToPerform( val underscore = fileName.indexOf("_") if (underscore != -1) { - val module = fileName.substring(0, underscore) + var moduleName = fileName.substring(0, underscore) + var moduleFileName = fileName.substring(underscore + 1) + if (moduleName.all { it.isDigit() }) { + val (moduleName1, moduleFileName1) = moduleFileName.split("_") + moduleName = moduleName1 + moduleFileName = moduleFileName1 + } assert(moduleNames != null) { "File name has module prefix, but multi-module environment is absent" } - assert(module in moduleNames!!) { "Module not found for file with prefix: $fileName" } + assert(moduleName in moduleNames!!) { "Module not found for file with prefix: $fileName" } - return Pair(module, fileName.substring(underscore + 1)) + return Pair(moduleName, moduleFileName) } assert(moduleNames == null) { "Test is multi-module, but file has no module prefix: $fileName" } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt index 0a1d23f4c2d..7d28460a90f 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2MetadataCompilerArguments.kt @@ -34,4 +34,10 @@ class K2MetadataCompilerArguments : CommonCompilerArguments() { @Argument(value = "-module-name", valueDescription = "", description = "Name of the generated .kotlin_module file") var moduleName: String? by FreezableVar(null) + + @Argument( + value = "-Xjps", + description = "Enable in JPS" + ) + var enabledInJps: Boolean by FreezableVar(false) } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt deleted file mode 100644 index 2fe9360b836..00000000000 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt +++ /dev/null @@ -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>() - - val expectToActualMap: Map> - get() = expectToActual - - override fun report(expectedFile: File, actualFile: File) { - expectToActual.getOrPut(expectedFile) { hashSetOf() }.add(actualFile) - } -} \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt index 8b6a5511ce0..4a408c0cceb 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCachesManager.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.incremental import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner import java.io.File -abstract class IncrementalCachesManager>( +abstract class IncrementalCachesManager>( protected val cachesRootDir: File, protected val reporter: ICReporter ) { diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index 691cf1f2ecd..1588fcafbe0 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -200,7 +200,7 @@ abstract class IncrementalCompilerRunner< var exitCode = ExitCode.OK while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) { - val complementaryFiles = caches.inputsCache.clearComplementaryFilesMapping(dirtySources) + val complementaryFiles = caches.platformCache.clearComplementaryFilesMapping(dirtySources) dirtySources.addAll(complementaryFiles) caches.platformCache.markDirty(dirtySources) caches.inputsCache.removeOutputForSourceFiles(dirtySources) @@ -239,7 +239,7 @@ abstract class IncrementalCompilerRunner< } } - caches.inputsCache.registerComplementaryFiles(expectActualTracker) + caches.platformCache.registerComplementaryFiles(expectActualTracker) caches.inputsCache.registerOutputForSourceFiles(generatedFiles) caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources) val changesCollector = ChangesCollector() diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt index 4656f3d6a34..657b80886f8 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt @@ -19,10 +19,7 @@ package org.jetbrains.kotlin.incremental import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.build.GeneratedFile import org.jetbrains.kotlin.incremental.snapshots.FileSnapshotMap -import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner -import org.jetbrains.kotlin.incremental.storage.BasicStringMap -import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor -import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer +import org.jetbrains.kotlin.incremental.storage.* import java.io.File import java.util.* import kotlin.collections.HashSet @@ -34,43 +31,10 @@ class InputsCache( companion object { private val SOURCE_SNAPSHOTS = "source-snapshot" private val SOURCE_TO_OUTPUT_FILES = "source-to-output" - private val COMPLEMENTARY_FILES = "complementary-files" } internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile)) private val sourceToOutputMap = registerMap(FilesMap(SOURCE_TO_OUTPUT_FILES.storageFile)) - /** - * A file X is a complementary to a file Y if they contain corresponding expect/actual declarations. - * Complementary files should be compiled together during IC so the compiler does not complain - * about missing parts. - * TODO: provide a better solution (maintain an index of expect/actual declarations akin to IncrementalPackagePartProvider) - */ - private val complementaryFilesMap = registerMap(FilesMap(COMPLEMENTARY_FILES.storageFile)) - - fun clearComplementaryFilesMapping(dirtyFiles: Collection): Collection { - val complementaryFiles = HashSet() - 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>() - 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) { for (sourceFile in sources) { @@ -96,21 +60,4 @@ class InputsCache( sourceToOutputMap[source] = outputs } } -} - -private class FilesMap(storageFile: File) - : BasicStringMap>(storageFile, PathStringDescriptor, StringCollectionExternalizer) { - - operator fun set(sourceFile: File, outputFiles: Collection) { - storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath } - } - - operator fun get(sourceFile: File): Collection = - storage[sourceFile.absolutePath].orEmpty().map(::File) - - override fun dumpValue(value: Collection) = - value.dumpCollection() - - fun remove(file: File): Collection = - get(file).also { storage.remove(file.absolutePath) } } \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java index df323630eed..58b1b6eaf99 100644 --- a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java @@ -17,7 +17,7 @@ import java.util.regex.Pattern; /** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@TestMetadata("jps-plugin/testData/incremental/multiplatform") +@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJsCompilerRunnerTest { @@ -25,21 +25,21 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); } - public void testAllFilesPresentInMultiplatform() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + public void testAllFilesPresentInSingleModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); } @TestMetadata("touchActual") public void testTouchActual() throws Exception { - runTest("jps-plugin/testData/incremental/multiplatform/touchActual/"); + runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/"); } @TestMetadata("touchExpect") public void testTouchExpect() throws Exception { - runTest("jps-plugin/testData/incremental/multiplatform/touchExpect/"); + runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/"); } - @TestMetadata("jps-plugin/testData/incremental/multiplatform/touchActual") + @TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class TouchActual extends AbstractIncrementalMultiplatformJsCompilerRunnerTest { @@ -48,11 +48,11 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr } public void testAllFilesPresentInTouchActual() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); } } - @TestMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect") + @TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class TouchExpect extends AbstractIncrementalMultiplatformJsCompilerRunnerTest { @@ -61,7 +61,7 @@ public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends Abstr } public void testAllFilesPresentInTouchExpect() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); } } } diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java index c6a98165729..ffc862c2217 100644 --- a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java @@ -17,7 +17,7 @@ import java.util.regex.Pattern; /** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@TestMetadata("jps-plugin/testData/incremental/multiplatform") +@TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest { @@ -25,21 +25,21 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); } - public void testAllFilesPresentInMultiplatform() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + public void testAllFilesPresentInSingleModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); } @TestMetadata("touchActual") public void testTouchActual() throws Exception { - runTest("jps-plugin/testData/incremental/multiplatform/touchActual/"); + runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/"); } @TestMetadata("touchExpect") public void testTouchExpect() throws Exception { - runTest("jps-plugin/testData/incremental/multiplatform/touchExpect/"); + runTest("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/"); } - @TestMetadata("jps-plugin/testData/incremental/multiplatform/touchActual") + @TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class TouchActual extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest { @@ -48,11 +48,11 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst } public void testAllFilesPresentInTouchActual() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchActual"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); } } - @TestMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect") + @TestMetadata("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class TouchExpect extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest { @@ -61,7 +61,7 @@ public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends Abst } public void testAllFilesPresentInTouchExpect() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); } } } diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 6f881c52535..f98a33c0665 100755 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -148,6 +148,7 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterMultiFileTest import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest import org.jetbrains.kotlin.jps.build.* import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase +import org.jetbrains.kotlin.jps.build.dependeciestxt.actualizeMppJpsIncTestCaseDirs import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest @@ -929,6 +930,15 @@ fun main(args: Array) { model("incremental/classHierarchyAffected", extension = null, excludeParentDirs = true) } + actualizeMppJpsIncTestCaseDirs(testDataRoot, "incremental/multiplatform/multiModule") + + testClass { + model( + "incremental/multiplatform/multiModule", extension = null, excludeParentDirs = true, + testClassName = "MultiplatformMultiModule", recursive = true + ) + } + testClass { model("incremental/lookupTracker/jvm", extension = null, recursive = false) } @@ -990,10 +1000,10 @@ fun main(args: Array) { } testClass { - model("incremental/multiplatform", extension = null, excludeParentDirs = true) + model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true) } testClass { - model("incremental/multiplatform", extension = null, excludeParentDirs = true) + model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true) } } diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.172 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.172 index 9a18559f28a..6e518c29288 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.172 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.172 @@ -919,6 +919,15 @@ fun main(args: Array) { model("incremental/classHierarchyAffected", extension = null, excludeParentDirs = true) } + actualizeMppJpsIncTestCaseDirs(testDataRoot, "incremental/multiplatform/multiModule") + + testClass { + model( + "incremental/multiplatform/multiModule", extension = null, excludeParentDirs = true, + testClassName = "MultiplatformMultiModule", recursive = true + ) + } + testClass { model("incremental/lookupTracker/jvm", extension = null, recursive = false) } @@ -980,10 +989,10 @@ fun main(args: Array) { } testClass { - model("incremental/multiplatform", extension = null, excludeParentDirs = true) + model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true) } testClass { - model("incremental/multiplatform", extension = null, excludeParentDirs = true) + model("incremental/multiplatform/singleModule", extension = null, excludeParentDirs = true) } } diff --git a/jps-plugin/build.gradle.kts b/jps-plugin/build.gradle.kts index 1ef61071065..19f2822366e 100644 --- a/jps-plugin/build.gradle.kts +++ b/jps-plugin/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { compile(project(":compiler:daemon-common")) compile(projectRuntimeJar(":kotlin-daemon-client")) compile(project(":compiler:frontend.java")) + compile(project(":js:js.frontend")) compile(projectRuntimeJar(":kotlin-preloader")) compile(project(":idea:idea-jps-common")) compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") diff --git a/jps-plugin/build.gradle.kts.173 b/jps-plugin/build.gradle.kts.173 index d4ff8f3f456..abd1359101f 100644 --- a/jps-plugin/build.gradle.kts.173 +++ b/jps-plugin/build.gradle.kts.173 @@ -13,6 +13,7 @@ dependencies { compile(project(":compiler:daemon-common")) compile(projectRuntimeJar(":kotlin-daemon-client")) compile(project(":compiler:frontend.java")) + compile(project(":js:js.frontend")) compile(projectRuntimeJar(":kotlin-preloader")) compile(project(":idea:idea-jps-common")) compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") diff --git a/jps-plugin/build.gradle.kts.as31 b/jps-plugin/build.gradle.kts.as31 index 5edfc059557..57283672607 100644 --- a/jps-plugin/build.gradle.kts.as31 +++ b/jps-plugin/build.gradle.kts.as31 @@ -13,6 +13,7 @@ dependencies { compile(project(":compiler:daemon-common")) compile(projectRuntimeJar(":kotlin-daemon-client")) compile(project(":compiler:frontend.java")) + compile(project(":js:js.frontend")) compile(projectRuntimeJar(":kotlin-preloader")) compile(project(":idea:idea-jps-common")) compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") diff --git a/jps-plugin/build.gradle.kts.as32 b/jps-plugin/build.gradle.kts.as32 index 06df796d5d8..6f017d7c087 100644 --- a/jps-plugin/build.gradle.kts.as32 +++ b/jps-plugin/build.gradle.kts.as32 @@ -13,6 +13,7 @@ dependencies { compile(project(":compiler:daemon-common")) compile(projectRuntimeJar(":kotlin-daemon-client")) compile(project(":compiler:frontend.java")) + compile(project(":js:js.frontend")) compile(projectRuntimeJar(":kotlin-preloader")) compile(project(":idea:idea-jps-common")) compileOnly(group = "org.jetbrains", name = "annotations", version = "13.0") diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt index dc4c42170a4..6a5a16971e9 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt @@ -40,29 +40,34 @@ import org.jetbrains.jps.cmdline.ProjectDescriptor import org.jetbrains.jps.incremental.* import org.jetbrains.jps.incremental.messages.BuildMessage import org.jetbrains.jps.model.JpsModuleRootModificationUtil -import org.jetbrains.jps.model.java.JpsJavaDependencyScope import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.util.JpsPathUtil +import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.incremental.CacheVersion import org.jetbrains.kotlin.incremental.LookupSymbol import org.jetbrains.kotlin.incremental.isJavaFile import org.jetbrains.kotlin.incremental.testingUtils.* +import org.jetbrains.kotlin.jps.build.dependeciestxt.DependenciesTxt +import org.jetbrains.kotlin.jps.build.dependeciestxt.DependenciesTxtBuilder import org.jetbrains.kotlin.jps.incremental.getKotlinCache import org.jetbrains.kotlin.jps.incremental.withLookupStorage import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension +import org.jetbrains.kotlin.jps.platforms.kotlinBuildTargets import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.utils.Printer -import org.jetbrains.kotlin.utils.keysToMap -import java.io.* +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.PrintStream import java.util.* import java.util.concurrent.Future import kotlin.reflect.jvm.javaField abstract class AbstractIncrementalJpsTest( - private val allowNoFilesWithSuffixInTestData: Boolean = false, - private val checkDumpsCaseInsensitively: Boolean = false, - private val allowNoBuildLogFileInTestData: Boolean = false + private val allowNoFilesWithSuffixInTestData: Boolean = false, + private val checkDumpsCaseInsensitively: Boolean = false, + private val allowNoBuildLogFileInTestData: Boolean = false ) : BaseKotlinJpsBuildTestCase() { companion object { private val COMPILATION_FAILED = "COMPILATION FAILED" @@ -79,6 +84,7 @@ abstract class AbstractIncrementalJpsTest( // is used to compare lookup dumps in a human readable way (lookup symbols are hashed in an actual lookup storage) protected lateinit var lookupsDuringTest: MutableSet private var isICEnabledBackup: Boolean = false + private var isJSICEnabledBackup: Boolean = false protected var mapWorkingToOriginalFile: MutableMap = hashMapOf() @@ -115,7 +121,10 @@ abstract class AbstractIncrementalJpsTest( super.setUp() lookupsDuringTest = hashSetOf() isICEnabledBackup = IncrementalCompilation.isEnabled() + isJSICEnabledBackup = IncrementalCompilation.isEnabledForJs() + IncrementalCompilation.setIsEnabled(true) + IncrementalCompilation.setIsEnabledForJs(true) if (DEBUG_LOGGING_ENABLED) { enableDebugLogging() @@ -129,6 +138,7 @@ abstract class AbstractIncrementalJpsTest( (AbstractIncrementalJpsTest::systemPropertiesBackup).javaField!![this] = null lookupsDuringTest.clear() IncrementalCompilation.setIsEnabled(isICEnabledBackup) + IncrementalCompilation.setIsEnabledForJs(isJSICEnabledBackup) super.tearDown() } @@ -138,7 +148,7 @@ abstract class AbstractIncrementalJpsTest( private val mockConstantSearch: Callbacks.ConstantAffectionResolver? get() = MockJavaConstantSearch(workDir) - private fun build(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules()): MakeResult { + private fun build(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules(), name: String? = null): MakeResult { val workDirPath = FileUtil.toSystemIndependentName(workDir.absolutePath) val logger = MyLogger(workDirPath) @@ -148,48 +158,67 @@ abstract class AbstractIncrementalJpsTest( projectDescriptor.project.setTestingContext(TestingContext(lookupTracker, logger)) try { - val builder = IncProjectBuilder(projectDescriptor, BuilderRegistry.getInstance(), myBuildParams, CanceledStatus.NULL, mockConstantSearch, true) + val builder = IncProjectBuilder( + projectDescriptor, + BuilderRegistry.getInstance(), + myBuildParams, + CanceledStatus.NULL, + mockConstantSearch, + true + ) val buildResult = BuildResult() builder.addMessageHandler(buildResult) - builder.build(scope.build(), false) + + val finalScope = scope.build() + builder.build(finalScope, false) lookupTracker.lookups.mapTo(lookupsDuringTest) { LookupSymbol(it.name, it.scopeFqName) } + // for getting kotlin platform only + val dummyCompileContext = CompileContextImpl.createContextForTests(finalScope, projectDescriptor) + if (!buildResult.isSuccessful) { val errorMessages = - buildResult - .getMessages(BuildMessage.Kind.ERROR) - .map { it.messageText } - .map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() } - .joinToString("\n") - return MakeResult(logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n", true, null) + buildResult + .getMessages(BuildMessage.Kind.ERROR) + .map { it.messageText } + .map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() } + .joinToString("\n") + return MakeResult( + logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n", + true, + null, + name + ) + } else { + return MakeResult( + logger.log, + false, + createMappingsDump(projectDescriptor, dummyCompileContext), + name + ) } - else { - return MakeResult(logger.log, false, createMappingsDump(projectDescriptor)) - } - } - finally { + } finally { projectDescriptor.dataManager.flush(false) projectDescriptor.release() } } - private fun initialMake(): MakeResult { - val makeResult = build() + protected fun initialMake(): MakeResult { + val makeResult = build(name = "initial") val initBuildLogFile = File(testDataDir, "init-build.log") if (initBuildLogFile.exists()) { UsefulTestCase.assertSameLinesWithFile(initBuildLogFile.absolutePath, makeResult.log) - } - else { + } else { assertFalse("Initial make failed:\n$makeResult", makeResult.makeFailed) } return makeResult } - private fun make(): MakeResult { - return build() + private fun make(name: String?): MakeResult { + return build(name = name) } private fun rebuild(): MakeResult { @@ -205,21 +234,21 @@ abstract class AbstractIncrementalJpsTest( } val rebuildResult = rebuild() - assertEquals("Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult", - rebuildResult.makeFailed, makeOverallResult.makeFailed) + assertEquals( + "Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult", + rebuildResult.makeFailed, makeOverallResult.makeFailed + ) if (!outAfterMake.exists()) { assertFalse(outDir.exists()) - } - else { - assertEqualDirectories(outDir, outAfterMake, makeOverallResult.makeFailed) + } else { + assertEqualDirectories(outAfterMake, outDir, makeOverallResult.makeFailed) } if (!makeOverallResult.makeFailed) { if (checkDumpsCaseInsensitively && rebuildResult.mappingsDump?.toLowerCase() == makeOverallResult.mappingsDump?.toLowerCase()) { // do nothing - } - else { + } else { TestCase.assertEquals(rebuildResult.mappingsDump, makeOverallResult.mappingsDump) } } @@ -233,30 +262,27 @@ abstract class AbstractIncrementalJpsTest( rebuildAndCheckOutput(makeOverallResult) } - private fun readModuleDependencies(): Map>? { - val dependenciesTxt = File(testDataDir, "dependencies.txt") - if (!dependenciesTxt.exists()) return null + open protected val dependenciesTxtFile get() = File(testDataDir, "dependencies.txt") - val result = HashMap>() - for (line in dependenciesTxt.readLines()) { - val split = line.split("->") - val module = split[0] - val dependencies = if (split.size > 1) split[1] else "" - val dependencyList = dependencies.split(",").filterNot { it.isEmpty() } - result[module] = dependencyList.map(::parseDependency) - } + private fun readModuleDependencies(): DependenciesTxt? { + val dependenciesTxtFile = dependenciesTxtFile + if (!dependenciesTxtFile.exists()) return null - return result + return DependenciesTxtBuilder().readFile(dependenciesTxtFile) } protected open fun createBuildLog(incrementalMakeResults: List): String = - buildString { - incrementalMakeResults.forEachIndexed { i, makeResult -> - if (i > 0) append("\n") + buildString { + incrementalMakeResults.forEachIndexed { i, makeResult -> + if (i > 0) append("\n") + if (makeResult.name != null) { + append("================ Step #${i + 1} ${makeResult.name} =================\n\n") + } else { append("================ Step #${i + 1} =================\n\n") - append(makeResult.log) } + append(makeResult.log) } + } protected open fun doTest(testDataPath: String) { testDataDir = File(testDataPath) @@ -272,8 +298,7 @@ abstract class AbstractIncrementalJpsTest( if (buildLogFile != null && buildLogFile.exists()) { UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, logs) - } - else if (!allowNoBuildLogFileInTestData) { + } else if (!allowNoBuildLogFileInTestData) { throw IllegalStateException("No build log file in $testDataDir") } @@ -282,17 +307,38 @@ abstract class AbstractIncrementalJpsTest( clearCachesRebuildAndCheckOutput(lastMakeResult) } - private fun createMappingsDump(project: ProjectDescriptor) = - createKotlinIncrementalCacheDump(project) + "\n\n\n" + - createLookupCacheDump(project) + "\n\n\n" + - createCommonMappingsDump(project) + "\n\n\n" + - createJavaMappingsDump(project) + protected open fun doInitialMakeTest(testDataPath: String) { + testDataDir = File(testDataPath) + workDir = FileUtilRt.createTempDirectory(TEMP_DIRECTORY_TO_USE, "jps-build", null) + Disposer.register(testRootDisposable, Disposable { FileUtilRt.delete(workDir) }) - private fun createKotlinIncrementalCacheDump(project: ProjectDescriptor): String { + configureModules() + val results = initialMake() + + val buildLogFile = buildLogFinder.findBuildLog(testDataDir) + + if (buildLogFile != null && buildLogFile.exists()) { + UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, results.log) + } else throw IllegalStateException("No build log file in $testDataDir") + } + + private fun createMappingsDump( + project: ProjectDescriptor, + dummyCompileContext: CompileContext + ) = + createKotlinIncrementalCacheDump(project, dummyCompileContext) + "\n\n\n" + + createLookupCacheDump(project) + "\n\n\n" + + createCommonMappingsDump(project) + "\n\n\n" + + createJavaMappingsDump(project) + + private fun createKotlinIncrementalCacheDump( + project: ProjectDescriptor, + dummyCompileContext: CompileContext + ): String { return buildString { for (target in project.allModuleTargets.sortedBy { it.presentableName }) { append("\n") - append(project.dataManager.getKotlinCache(target).dump()) + append(project.dataManager.getKotlinCache(dummyCompileContext.kotlinBuildTargets[target]!!).dump()) append("\n\n\n") } } @@ -350,23 +396,35 @@ abstract class AbstractIncrementalJpsTest( return byteArrayOutputStream.toString() } - protected data class MakeResult(val log: String, val makeFailed: Boolean, val mappingsDump: String?) + protected data class MakeResult( + val log: String, + val makeFailed: Boolean, + val mappingsDump: String?, + val name: String? + ) + + open val testDataSrc: File + get() = testDataDir private fun performModificationsAndMake(moduleNames: Set?): List { val results = arrayListOf() - val modifications = getModificationsToPerform(testDataDir, moduleNames, allowNoFilesWithSuffixInTestData, TouchPolicy.TIMESTAMP) + val modifications = getModificationsToPerform(testDataSrc, moduleNames, allowNoFilesWithSuffixInTestData, TouchPolicy.TIMESTAMP) - for (step in modifications) { + val stepsTxt = File(testDataSrc, "steps.txt") + val modificationNames = if (stepsTxt.exists()) stepsTxt.readLines() else null + + modifications.forEachIndexed { index, step -> step.forEach { it.perform(workDir, mapWorkingToOriginalFile) } performAdditionalModifications(step) if (moduleNames == null) { preProcessSources(File(workDir, "src")) - } - else { + } else { moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) } } - results.add(make()) + val name = modificationNames?.getOrNull(index) + val makeResult = make(name) + results.add(makeResult) } return results } @@ -374,54 +432,92 @@ abstract class AbstractIncrementalJpsTest( protected open fun performAdditionalModifications(modifications: List) { } - // null means one module - private fun configureModules(): Set? { - fun prepareModuleSources(moduleName: String?) { - val sourceDirName = moduleName?.let { "$it/src" } ?: "src" - val filePrefix = moduleName?.let { "${it}_" } ?: "" - val sourceDestinationDir = File(workDir, sourceDirName) - val sourcesMapping = copyTestSources(testDataDir, sourceDestinationDir, filePrefix) - mapWorkingToOriginalFile.putAll(sourcesMapping) - preProcessSources(sourceDestinationDir) - } + protected open fun generateModuleSources(dependenciesTxt: DependenciesTxt) { - JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl = JpsPathUtil.pathToUrl(getAbsolutePath("out")) + } + + protected open fun prepareModuleSources(module: DependenciesTxt.Module? = null) { + if (module != null) { + prepareModuleSourcesByName("${module.name}/src", "${module.name}_") + } else { + prepareModuleSourcesByName("src", "") + } + } + + protected fun prepareIndexedModuleSources(module: DependenciesTxt.Module) { + prepareModuleSourcesByName("${module.name}/src", "${module.indexedName}_") + } + + private fun prepareModuleSourcesByName(sourceDirName: String, filePrefix: String) { + val sourceDestinationDir = File(workDir, sourceDirName) + val sourcesMapping = copyTestSources(testDataSrc, sourceDestinationDir, filePrefix) + mapWorkingToOriginalFile.putAll(sourcesMapping) + preProcessSources(sourceDestinationDir) + } + + // null means one module + protected fun configureModules(): Set? { + val outputUrl = JpsPathUtil.pathToUrl(getAbsolutePath("out")) + JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl = outputUrl val jdk = addJdk("my jdk") - val moduleDependencies = readModuleDependencies() + val dependenciesTxt = readModuleDependencies() mapWorkingToOriginalFile = hashMapOf() val moduleNames: Set? - if (moduleDependencies == null) { + if (dependenciesTxt == null) { addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk) - prepareModuleSources(moduleName = null) + prepareModuleSources(module = null) moduleNames = null - } - else { - val nameToModule = moduleDependencies.keys - .keysToMap { addModule(it, arrayOf(getAbsolutePath("$it/src")), null, null, jdk)!! } + } else { + dependenciesTxt.modules.forEach { + val module = addModule( + it.name, + arrayOf(getAbsolutePath("${it.name}/src")), + null, + null, + jdk + )!! - for ((moduleName, dependencies) in moduleDependencies) { - val module = nameToModule[moduleName]!! + val kotlinFacetSettings = it.kotlinFacetSettings + if (kotlinFacetSettings != null) { + val compilerArguments = kotlinFacetSettings.compilerArguments + if (compilerArguments is K2MetadataCompilerArguments) { + val out = getAbsolutePath("${it.name}/out") + File(out).mkdirs() + compilerArguments.destination = out + } - for (dependency in dependencies) { - JpsModuleRootModificationUtil.addDependency(module, nameToModule[dependency.name], - JpsJavaDependencyScope.COMPILE, dependency.exported) + module.container.setChild( + JpsKotlinFacetModuleExtension.KIND, + JpsKotlinFacetModuleExtension(kotlinFacetSettings) + ) } + + it.jpsModule = module } - for (module in nameToModule.values) { - prepareModuleSources(module.name) + dependenciesTxt.dependencies.forEach { + JpsModuleRootModificationUtil.addDependency( + it.from.jpsModule, + it.to.jpsModule, + it.scope, + it.exported + ) } - moduleNames = nameToModule.keys + generateModuleSources(dependenciesTxt) + dependenciesTxt.modules.forEach { + prepareModuleSources(it) + } + + moduleNames = dependenciesTxt.modules.map { it.name }.toSet() } AbstractKotlinJpsBuildTestCase.addKotlinStdlibDependency(myProject) AbstractKotlinJpsBuildTestCase.addKotlinTestDependency(myProject) return moduleNames } - protected open fun preProcessSources(srcDir: File) { } @@ -530,10 +626,3 @@ private class MockJavaConstantSearch(private val workDir: File) : Callbacks.Cons internal val ProjectDescriptor.allModuleTargets: Collection get() = buildTargetIndex.allTargets.filterIsInstance() - -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]" diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractMultiplatformJpsTest.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractMultiplatformJpsTest.kt new file mode 100644 index 00000000000..87bb89f8fd9 --- /dev/null +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractMultiplatformJpsTest.kt @@ -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!!) + } +} \ No newline at end of file diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/MultiplatformJpsTestGenerated.java b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/MultiplatformJpsTestGenerated.java new file mode 100644 index 00000000000..11922fcd579 --- /dev/null +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/MultiplatformJpsTestGenerated.java @@ -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); + } + } + } +} diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/DependenciesTxt.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/DependenciesTxt.kt new file mode 100644 index 00000000000..6dc02d73831 --- /dev/null +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/DependenciesTxt.kt @@ -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, + val dependencies: List +) { + 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() + val usages = mutableListOf() + + 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> = Module::class.memberProperties + .filter { it.findAnnotation() != null } + .filterIsInstance>() + .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() + private val dependencies = mutableListOf() + + /** + * 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 = 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): 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) + } + } + } +} \ No newline at end of file diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/MppJpsIncTestsGenerator.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/MppJpsIncTestsGenerator.kt new file mode 100644 index 00000000000..2e73598e607 --- /dev/null +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/MppJpsIncTestsGenerator.kt @@ -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 + + init { + val testCases = mutableListOf() + + 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() + 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 = 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() + + var step = 1 + val steps = mutableListOf() + + 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, + 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 + } +} \ No newline at end of file diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/PACKAGE.md b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/PACKAGE.md new file mode 100644 index 00000000000..0a6c97f838e --- /dev/null +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/PACKAGE.md @@ -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` \ No newline at end of file diff --git a/jps-plugin/src/META-INF/services/org.jetbrains.jps.builders.AdditionalRootsProviderService b/jps-plugin/src/META-INF/services/org.jetbrains.jps.builders.AdditionalRootsProviderService new file mode 100644 index 00000000000..07ac7d506ad --- /dev/null +++ b/jps-plugin/src/META-INF/services/org.jetbrains.jps.builders.AdditionalRootsProviderService @@ -0,0 +1 @@ +org.jetbrains.kotlin.jps.build.KotlinMppCommonSourceRootProvider \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt index ba5552fbb43..fbcb65c15ba 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt @@ -88,10 +88,18 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { k2MetadataArguments: K2MetadataCompilerArguments, compilerSettings: CompilerSettings, environment: JpsCompilerEnvironment, + destination: String, + classpath: Collection, sourceFiles: Collection ) { val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2MetadataArguments)) + + val classpathSet = arguments.classpath?.split(File.pathSeparator)?.toMutableSet() ?: mutableSetOf() + classpathSet.addAll(classpath) + arguments.classpath = classpath.joinToString(File.pathSeparator) arguments.freeArgs = sourceFiles.map { it.absolutePath } + arguments.destination = arguments.destination ?: destination + withCompilerSettings(compilerSettings) { runCompiler(K2METADATA_COMPILER, arguments, environment) } diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/FSOperationsHelper.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/FSOperationsHelper.kt index f5a1f636b23..98e8dea6940 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/FSOperationsHelper.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/FSOperationsHelper.kt @@ -19,9 +19,7 @@ package org.jetbrains.kotlin.jps.build import com.intellij.openapi.diagnostic.Logger import com.intellij.util.containers.ContainerUtil import org.jetbrains.jps.ModuleChunk -import org.jetbrains.jps.builders.BuildRootIndex import org.jetbrains.jps.builders.BuildTarget -import org.jetbrains.jps.builders.BuildTargetIndex import org.jetbrains.jps.builders.java.dependencyView.Mappings import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.FSOperations @@ -43,7 +41,7 @@ class FSOperationsHelper( fun markChunk(recursively: Boolean, kotlinOnly: Boolean, excludeFiles: Set = setOf()) { fun shouldMark(file: File): Boolean { - if (kotlinOnly && !KotlinSourceFileCollector.isKotlinSourceFile(file)) return false + if (kotlinOnly && !file.isKotlinSourceFile) return false if (file in excludeFiles) return false diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 2e5efb90006..4d9ef62aa63 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -17,11 +17,7 @@ package org.jetbrains.kotlin.jps.build import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.util.Key -import com.intellij.openapi.util.io.FileUtil import com.intellij.util.containers.ContainerUtil -import com.intellij.util.containers.MultiMap -import gnu.trove.THashSet import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.builders.BuildTarget import org.jetbrains.jps.builders.DirtyFilesHolder @@ -32,44 +28,35 @@ import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor import org.jetbrains.jps.incremental.* import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.* import org.jetbrains.jps.incremental.java.JavaBuilder -import org.jetbrains.jps.incremental.messages.BuildMessage -import org.jetbrains.jps.incremental.messages.CompilerMessage -import org.jetbrains.jps.incremental.messages.ProgressMessage import org.jetbrains.jps.incremental.storage.BuildDataManager import org.jetbrains.jps.model.JpsProject import org.jetbrains.jps.model.java.JpsJavaClasspathKind import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.kotlin.build.GeneratedFile -import org.jetbrains.kotlin.build.GeneratedJvmClass import org.jetbrains.kotlin.build.JvmBuildMetaInfo import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* -import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil import org.jetbrains.kotlin.compilerRunner.* -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.config.CompilerRunnerConstants.INTERNAL_ERROR_PREFIX +import org.jetbrains.kotlin.config.IncrementalCompilation +import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.daemon.common.isDaemonEnabled import org.jetbrains.kotlin.incremental.* +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments import org.jetbrains.kotlin.jps.incremental.* +import org.jetbrains.kotlin.jps.platforms.KotlinCommonModuleBuildTarget import org.jetbrains.kotlin.jps.platforms.KotlinJsModuleBuildTarget +import org.jetbrains.kotlin.jps.platforms.KotlinModuleBuildTarget import org.jetbrains.kotlin.jps.platforms.kotlinBuildTargets -import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache -import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.preloading.ClassCondition -import org.jetbrains.kotlin.progress.CompilationCanceledException -import org.jetbrains.kotlin.progress.CompilationCanceledStatus import org.jetbrains.kotlin.utils.KotlinPaths import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir import org.jetbrains.kotlin.utils.PathUtil -import org.jetbrains.kotlin.utils.keysToMap -import org.jetbrains.org.objectweb.asm.ClassReader +import org.jetbrains.kotlin.utils.keysToMapExceptNulls import java.io.File import java.util.* import kotlin.collections.HashSet @@ -167,29 +154,39 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { context: CompileContext, fsOperations: FSOperationsHelper ) { - val dirtyFilesHolder = object : DirtyFilesHolderBase(context) { - override fun processDirtyFiles(processor: FileProcessor) { - FSOperations.processFilesToRecompile(context, chunk, processor) + val roundDirtyFiles = KotlinRoundDirtySourceFilesHolder( + chunk, + context, + fsOperations, + object : DirtyFilesHolderBase(context) { + override fun processDirtyFiles(processor: FileProcessor) { + FSOperations.processFilesToRecompile(context, chunk, processor) + } } - } - val chunkDirtyFiles = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder) - val chunkRemovedFiles = chunk.targets.keysToMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) } + ) + val representativeTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return val incrementalCaches = getIncrementalCaches(chunk, context) - val messageCollector = MessageCollectorAdapter(context) - val environment = createCompileEnvironment(incrementalCaches, LookupTracker.DO_NOTHING, context, chunk, messageCollector) - if (environment == null) return + val messageCollector = MessageCollectorAdapter(context, representativeTarget) + val environment = createCompileEnvironment( + representativeTarget, + incrementalCaches, + LookupTracker.DO_NOTHING, + ExpectActualTracker.DoNothing, + chunk, + messageCollector + ) ?: return val removedClasses = HashSet() for (target in chunk.targets) { - val cache = incrementalCaches[target]!! - val dirtyFiles = chunkDirtyFiles[target] - val removedFiles = chunkRemovedFiles[target] ?: emptyList() + val cache = incrementalCaches[target] ?: continue + val dirtyFiles = roundDirtyFiles.getDirtyFiles(target) + val removedFiles = roundDirtyFiles.getRemovedFilesSet(target) - val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles.toHashSet()) - val previousClasses = cache.classesBySources(dirtyFiles + removedFiles) + val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles) + val previousClasses = cache.classesFqNamesBySources(dirtyFiles + removedFiles) for (jvmClassName in previousClasses) { - val fqName = jvmClassName.fqNameForClassNameWithoutDollars.asString() + val fqName = jvmClassName.asString() if (fqName !in existingClasses) { removedClasses.add(fqName) } @@ -214,50 +211,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val allVersions = cacheVersionsProvider.allVersions(targets) val actions = allVersions.map { it.checkVersion() }.toMutableSet() - val kotlinModuleBuilderTarget = context.kotlinBuildTargets[chunk.representativeTarget()] - if (kotlinModuleBuilderTarget !is KotlinJsModuleBuildTarget) { - val args = compilerArgumentsForChunk(chunk) - val currentBuildMetaInfo = JvmBuildMetaInfo(args) - - for (target in chunk.targets) { - val file = jvmBuildMetaInfoFile(target, dataManager) - if (!file.exists()) continue - - val lastBuildMetaInfo = - try { - JvmBuildMetaInfo.deserializeFromString(file.readText()) ?: continue - } catch (e: Exception) { - LOG.error("Could not deserialize jvm build meta info", e) - continue - } - - val lastBuildLangVersion = LanguageVersion.fromVersionString(lastBuildMetaInfo.languageVersionString) - val lastBuildApiVersion = ApiVersion.parse(lastBuildMetaInfo.apiVersionString) - val currentLangVersion = - args.languageVersion?.let { LanguageVersion.fromVersionString(it) } ?: LanguageVersion.LATEST_STABLE - val currentApiVersion = - args.apiVersion?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(currentLangVersion) - - val reasonToRebuild = when { - currentLangVersion != lastBuildLangVersion -> { - "Language version was changed ($lastBuildLangVersion -> $currentLangVersion)" - } - currentApiVersion != lastBuildApiVersion -> { - "Api version was changed ($lastBuildApiVersion -> $currentApiVersion)" - } - lastBuildLangVersion != LanguageVersion.KOTLIN_1_0 && lastBuildMetaInfo.isEAP && !currentBuildMetaInfo.isEAP -> { - // If EAP->Non-EAP build with IC, then rebuild all kotlin - "Last build was compiled with EAP-plugin" - } - else -> null - } - - if (reasonToRebuild != null) { - LOG.info("$reasonToRebuild. Performing non-incremental rebuild (kotlin only)") - actions.add(CacheVersion.Action.REBUILD_ALL_KOTLIN) - } - } - } + val kotlinModuleBuilderTarget = context.kotlinBuildTargets[chunk.representativeTarget()]!! + kotlinModuleBuilderTarget.checkCachesVersions(chunk, dataManager, actions) return actions } @@ -276,14 +231,20 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { dirtyFilesHolder: DirtyFilesHolder, outputConsumer: ModuleLevelBuilder.OutputConsumer ): ModuleLevelBuilder.ExitCode { + JavaBuilderUtil.registerFilterToSkipMarkingAffectedFileDirty(context) { + it.isKotlinSourceFile + } + if (chunk.isDummy(context)) return NOTHING_DONE - val messageCollector = MessageCollectorAdapter(context) + val kotlinTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return OK + + val messageCollector = MessageCollectorAdapter(context, kotlinTarget) val fsOperations = FSOperationsHelper(context, chunk, LOG) try { - val proposedExitCode = doBuild(chunk, context, dirtyFilesHolder, messageCollector, outputConsumer, fsOperations) + val proposedExitCode = doBuild(chunk, kotlinTarget, context, dirtyFilesHolder, messageCollector, outputConsumer, fsOperations) val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode @@ -304,6 +265,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { private fun doBuild( chunk: ModuleChunk, + representativeTarget: KotlinModuleBuildTarget, context: CompileContext, dirtyFilesHolder: DirtyFilesHolder, messageCollector: MessageCollectorAdapter, @@ -311,12 +273,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { fsOperations: FSOperationsHelper ): ModuleLevelBuilder.ExitCode { // Workaround for Android Studio - val isJsModule = context.kotlinBuildTargets[chunk.representativeTarget()] is KotlinJsModuleBuildTarget + val isJsModule = representativeTarget is KotlinJsModuleBuildTarget if (!JavaBuilder.IS_ENABLED[context, true] && !isJsModule) { messageCollector.report(INFO, "Kotlin JPS plugin is disabled") return NOTHING_DONE } + val roundDirtyFilesHolder = KotlinRoundDirtySourceFilesHolder(chunk, context, fsOperations, dirtyFilesHolder) val projectDescriptor = context.projectDescriptor val dataManager = projectDescriptor.dataManager val targets = chunk.targets @@ -325,7 +288,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val isChunkRebuilding = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context) || targets.any { rebuildAfterCacheVersionChanged[it] == true } - if (hasKotlinDirtyOrRemovedFiles(dirtyFilesHolder, chunk)) { + if (roundDirtyFilesHolder.hasDirtyOrRemovedFiles) { if (!isChunkRebuilding && !IncrementalCompilation.isEnabled()) { targets.forEach { rebuildAfterCacheVersionChanged[it] = true } return CHUNK_REBUILD_REQUIRED @@ -347,23 +310,30 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val project = projectDescriptor.project val lookupTracker = getLookupTracker(project) + val exceptActualTracer = ExpectActualTrackerImpl() val incrementalCaches = getIncrementalCaches(chunk, context) - val environment = createCompileEnvironment(incrementalCaches, lookupTracker, context, chunk, messageCollector) ?: return ABORT + val environment = createCompileEnvironment( + representativeTarget, + incrementalCaches, + lookupTracker, + exceptActualTracer, + chunk, + messageCollector + ) ?: return ABORT - val commonArguments = compilerArgumentsForChunk(chunk).apply { + val commonArguments = representativeTarget.compilerArgumentsForChunk(chunk).apply { reportOutputFiles = true version = true // Always report the version to help diagnosing user issues if they submit the compiler output } - val allCompiledFiles = getAllCompiledFilesContainer(context) - val filesToCompile = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder) - - LOG.debug("Compiling files: ${filesToCompile.values()}") + if (LOG.isDebugEnabled) { + LOG.debug("Compiling files: ${roundDirtyFilesHolder.dirtyFiles}") + } val start = System.nanoTime() val outputItemCollector = doCompileModuleChunk( - allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder, - environment, filesToCompile, incrementalCaches, fsOperations + chunk, representativeTarget, commonArguments, context, roundDirtyFilesHolder, environment, + incrementalCaches ) statisticsLogger.registerStatistic(chunk, System.nanoTime() - start) @@ -386,7 +356,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { saveVersions(context, chunk, commonArguments) if (targets.any { hasKotlin[it] == null }) { - fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = filesToCompile.values().toSet()) + fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = roundDirtyFilesHolder.dirtyFiles) } for (target in targets) { @@ -398,7 +368,12 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { context.kotlinBuildTargets[it]?.doAfterBuild() } - updateJavaMappings(chunk, context, dirtyFilesHolder, filesToCompile, generatedFiles, incrementalCaches) + representativeTarget.updateChunkMappings( + chunk, + roundDirtyFilesHolder, + generatedFiles, + incrementalCaches + ) if (!IncrementalCompilation.isEnabled()) { return OK @@ -410,14 +385,17 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { progress.progress("updating IC caches") val changesCollector = ChangesCollector() + for ((target, files) in generatedFiles) { - updateIncrementalCache(files, incrementalCaches[target]!!, changesCollector, null) + val kotlinModuleBuilderTarget = context.kotlinBuildTargets[target]!! + kotlinModuleBuilderTarget.updateCaches(incrementalCaches[target]!!, files, changesCollector, environment) } - updateLookupStorage(chunk, lookupTracker, dataManager, dirtyFilesHolder, filesToCompile) + + updateLookupStorage(lookupTracker, dataManager, roundDirtyFilesHolder) if (!isChunkRebuilding) { changesCollector.processChangesUsingLookups( - filesToCompile.values().toSet(), + roundDirtyFilesHolder.dirtyFiles, dataManager, fsOperations, incrementalCaches.values @@ -451,8 +429,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { LOG.info("Clearing caches for " + targets.joinToString { it.presentableName }) val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) + val kotlinBuildTargets = context.kotlinBuildTargets for (target in targets) { - dataManager.getKotlinCache(target).clean() + dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean() hasKotlin.clean(target) rebuildAfterCacheVersionChanged[target] = true } @@ -464,8 +443,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { CacheVersion.Action.CLEAN_NORMAL_CACHES -> { LOG.info("Clearing caches for all targets") + val kotlinBuildTargets = context.kotlinBuildTargets for (target in context.allTargets()) { - dataManager.getKotlinCache(target).clean() + dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean() } } CacheVersion.Action.CLEAN_DATA_CONTAINER -> { @@ -491,12 +471,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager) for (sourceRoot in sourceRoots) { - val ktFiles = sourceRoot.file.walk().filter { KotlinSourceFileCollector.isKotlinSourceFile(it) } + val ktFiles = sourceRoot.file.walk().filter { it.isKotlinSourceFile } fsOperations.markFiles(ktFiles.toList()) } + val kotlinBuildTargets = context.kotlinBuildTargets for (target in context.allTargets()) { - dataManager.getKotlinCache(target).clean() + dataManager.getKotlinCache(kotlinBuildTargets[target]!!).clean() rebuildAfterCacheVersionChanged[target] = true } @@ -520,19 +501,14 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { } } - private fun compilerArgumentsForChunk(chunk: ModuleChunk): CommonCompilerArguments = - chunk.representativeTarget().module.kotlinCompilerArguments - private fun doCompileModuleChunk( - allCompiledFiles: MutableSet, chunk: ModuleChunk, + kotlinTarget: KotlinModuleBuildTarget, commonArguments: CommonCompilerArguments, context: CompileContext, - dirtyFilesHolder: DirtyFilesHolder, + roundDirtyFilesHolder: KotlinRoundDirtySourceFilesHolder, environment: JpsCompilerEnvironment, - filesToCompile: MultiMap, - incrementalCaches: Map, - fsOperations: FSOperationsHelper + incrementalCaches: Map ): OutputItemsCollector? { val representativeTarget = chunk.representativeTarget() @@ -556,39 +532,40 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { if (IncrementalCompilation.isEnabled()) { for (target in chunk.targets) { - val cache = incrementalCaches[target]!! - val removedAndDirtyFiles = filesToCompile[target] + dirtyFilesHolder.getRemovedFiles(target).map(::File) - cache.markDirty(removedAndDirtyFiles) + val cache = incrementalCaches[target] + val targetDirtyFiles = roundDirtyFilesHolder.byTarget[target] + + if (cache != null && targetDirtyFiles != null) { + val removedAndDirtyFiles: MutableSet = mutableSetOf() + + removedAndDirtyFiles.addAll(roundDirtyFilesHolder.getDirtyFiles(target)) + removedAndDirtyFiles.addAll(roundDirtyFilesHolder.getRemovedFilesSet(target)) + + val complementaryFiles = cache.clearComplementaryFilesMapping(targetDirtyFiles.dirtyOrRemovedFiles) + targetDirtyFiles.markDirty(complementaryFiles) + + cache.markDirty(targetDirtyFiles.dirtyOrRemovedFiles) + } } } - val kotlinModuleBuilderTarget = context.kotlinBuildTargets[representativeTarget] - val isDoneSomething = kotlinModuleBuilderTarget?.compileModuleChunk( - allCompiledFiles, chunk, commonArguments, dirtyFilesHolder, - environment, filesToCompile, fsOperations - ) ?: false + val isDoneSomething = kotlinTarget.compileModuleChunk( + chunk, commonArguments, roundDirtyFilesHolder, environment + ) return if (isDoneSomething) environment.outputItemsCollector else null } private fun createCompileEnvironment( - incrementalCaches: Map, + kotlinModuleBuilderTarget: KotlinModuleBuildTarget, + incrementalCaches: Map, lookupTracker: LookupTracker, - context: CompileContext, + exceptActualTracer: ExpectActualTracker, chunk: ModuleChunk, messageCollector: MessageCollectorAdapter ): JpsCompilerEnvironment? { val compilerServices = with(Services.Builder()) { - register(LookupTracker::class.java, lookupTracker) - register( - IncrementalCompilationComponents::class.java, - IncrementalCompilationComponentsImpl(incrementalCaches.mapKeys { context.kotlinBuildTargets[it.key]!!.targetId }) - ) - register(CompilationCanceledStatus::class.java, object : CompilationCanceledStatus { - override fun checkCanceled() { - if (context.cancelStatus.isCanceled) throw CompilationCanceledException() - } - }) + kotlinModuleBuilderTarget.makeServices(this, incrementalCaches, lookupTracker, exceptActualTracer) build() } @@ -607,7 +584,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { classesToLoadByParent, messageCollector, OutputItemsCollectorImpl(), - ProgressReporterImpl(context, chunk) + ProgressReporterImpl(kotlinModuleBuilderTarget.context, chunk) ) } @@ -641,7 +618,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val sourceToTarget = HashMap() if (chunk.targets.size > 1) { for (target in chunk.targets) { - context.kotlinBuildTargets[target]?.sources?.forEach { + context.kotlinBuildTargets[target]?.sourceFiles?.forEach { sourceToTarget[it] = target } } @@ -650,64 +627,14 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val representativeTarget = chunk.representativeTarget() fun SimpleOutputItem.target() = sourceFiles.firstOrNull()?.let { sourceToTarget[it] } ?: chunk.targets.singleOrNull { - it.outputDir?.let { - outputFile.startsWith(it) - } ?: false - } ?: representativeTarget + it.outputDir?.let { + outputFile.startsWith(it) + } ?: false + } ?: representativeTarget return outputItemCollector.outputs.groupBy(SimpleOutputItem::target, SimpleOutputItem::toGeneratedFile) } - private fun updateJavaMappings( - chunk: ModuleChunk, - context: CompileContext, - dirtyFilesHolder: DirtyFilesHolder, - filesToCompile: MultiMap, - outputItems: Map>, - incrementalCaches: Map - ) { - val previousMappings = context.projectDescriptor.dataManager.mappings - val callback = JavaBuilderUtil.getDependenciesRegistrar(context) - - val targetDirtyFiles: Map> = chunk.targets.keysToMap { - val files = HashSet() - dirtyFilesHolder.getRemovedFiles(it).mapTo(files, ::File) - files.addAll(filesToCompile.get(it)) - files - } - - fun getOldSourceFiles(target: ModuleBuildTarget, generatedClass: GeneratedJvmClass): Set { - 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>) { for ((target, outputs) in outputItems) { for (output in outputs) { @@ -717,67 +644,18 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { } private fun updateLookupStorage( - chunk: ModuleChunk, lookupTracker: LookupTracker, dataManager: BuildDataManager, - dirtyFilesHolder: DirtyFilesHolder, - filesToCompile: MultiMap + dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder ) { if (lookupTracker !is LookupTrackerImpl) throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}") - val removedFiles = chunk.targets.flatMap { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it) } dataManager.withLookupStorage { lookupStorage -> - lookupStorage.removeLookupsFrom(filesToCompile.values().asSequence() + removedFiles.asSequence()) + lookupStorage.removeLookupsFrom(dirtyFilesHolder.dirtyOrRemovedFilesSet.asSequence()) lookupStorage.addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values) } } - - - class MessageCollectorAdapter(private val context: CompileContext) : MessageCollector { - private var hasErrors = false - - override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { - hasErrors = hasErrors or severity.isError - var prefix = "" - if (severity == EXCEPTION) { - prefix = INTERNAL_ERROR_PREFIX - } - val kind = kind(severity) - if (kind != null) { - context.processMessage( - CompilerMessage( - CompilerRunnerConstants.KOTLIN_COMPILER_NAME, - kind, - prefix + message, - location?.path, - -1, -1, -1, - location?.line?.toLong() ?: -1, - location?.column?.toLong() ?: -1 - ) - ) - } else { - val path = if (location != null) "${location.path}:${location.line}:${location.column}: " else "" - KotlinBuilder.LOG.debug(path + message) - } - } - - override fun clear() { - hasErrors = false - } - - override fun hasErrors(): Boolean = hasErrors - - private fun kind(severity: CompilerMessageSeverity): BuildMessage.Kind? { - return when (severity) { - INFO -> BuildMessage.Kind.INFO - ERROR, EXCEPTION -> BuildMessage.Kind.ERROR - WARNING, STRONG_WARNING -> BuildMessage.Kind.WARNING - LOGGING -> null - else -> throw IllegalArgumentException("Unsupported severity: $severity") - } - } - } } private class JpsICReporter : ICReporter { @@ -792,7 +670,7 @@ private fun ChangesCollector.processChangesUsingLookups( compiledFiles: Set, dataManager: BuildDataManager, fsOperations: FSOperationsHelper, - caches: Iterable + caches: Iterable ) { val allCaches = caches.flatMap { it.thisWithDependentCaches } val reporter = JpsICReporter() @@ -806,7 +684,7 @@ private fun ChangesCollector.processChangesUsingLookups( } private fun ChangesCollector.getDirtyFiles( - caches: Iterable>, + caches: Iterable, dataManager: BuildDataManager ): Set { val reporter = JpsICReporter() @@ -825,16 +703,32 @@ private fun getLookupTracker(project: JpsProject): LookupTracker { return testLookupTracker } -private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): Map { +private fun getIncrementalCaches( + chunk: ModuleChunk, + context: CompileContext +): Map { val dependentTargets = getDependentTargets(chunk, context) val dataManager = context.projectDescriptor.dataManager - val chunkCaches = chunk.targets.keysToMap { dataManager.getKotlinCache(it) } - val dependentCaches = dependentTargets.map { dataManager.getKotlinCache(it) } + val kotlinBuildTargets = context.kotlinBuildTargets + + val chunkCaches = chunk.targets.keysToMapExceptNulls { + val kotlinModuleBuilderTarget = kotlinBuildTargets[it] + if (kotlinModuleBuilderTarget !is KotlinCommonModuleBuildTarget) { + dataManager.getKotlinCache(kotlinBuildTargets[it]!!) + } else null + } + + val dependentCaches = dependentTargets.mapNotNull { + val kotlinModuleBuilderTarget = kotlinBuildTargets[it] + if (kotlinModuleBuilderTarget !is KotlinCommonModuleBuildTarget) { + dataManager.getKotlinCache(kotlinModuleBuilderTarget!!) + } else null + } for (chunkCache in chunkCaches.values) { for (dependentCache in dependentCaches) { - chunkCache.addDependentCache(dependentCache) + chunkCache.addJpsDependentCache(dependentCache) } } @@ -876,41 +770,5 @@ fun getDependentTargets( private fun getDependenciesRecursively(module: JpsModule, kind: JpsJavaClasspathKind): Set = JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().modules -// TODO: investigate thread safety -private val ALL_COMPILED_FILES_KEY = Key.create>("_all_kotlin_compiled_files_") - -fun getAllCompiledFilesContainer(context: CompileContext): MutableSet { - 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>("_processed_targets_with_removed_files_") - -val CompileContext.processedTargetsWithRemovedFilesContainer: MutableSet - 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, - chunk: ModuleChunk -): Boolean { - if (!dirtyFilesHolder.hasDirtyFiles() && !dirtyFilesHolder.hasRemovedFiles()) return false - - if (!KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder).isEmpty) return true - - return chunk.targets.any { KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, it).isNotEmpty() } -} - fun jvmBuildMetaInfoFile(target: ModuleBuildTarget, dataManager: BuildDataManager): File = File(dataManager.dataPaths.getTargetDataRoot(target), KotlinBuilder.JVM_BUILD_META_INFO_FILE_NAME) \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinMppCommonSourceRootProvider.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinMppCommonSourceRootProvider.kt new file mode 100644 index 00000000000..1b1d0c4001b --- /dev/null +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinMppCommonSourceRootProvider.kt @@ -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(JavaModuleBuildTargetType.ALL_TYPES) { + override fun getAdditionalRoots( + target: BuildTarget, + dataPaths: BuildDataPaths? + ): List { + val moduleBuildTarget = target as? ModuleBuildTarget ?: return listOf() + val module = moduleBuildTarget.module + + val result = mutableListOf() + + module.expectedByModules.forEach { commonModule -> + addSourceRoots(result, commonModule, target) + } + + return result + } + + private fun addSourceRoots( + result: MutableList, + 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 +) : JavaSourceRootDescriptor(root, target, isGenerated, isTemp, packagePrefix, excludes) \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinRoundDirtySourceFilesHolder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinRoundDirtySourceFilesHolder.kt new file mode 100644 index 00000000000..51ca301b5d1 --- /dev/null +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinRoundDirtySourceFilesHolder.kt @@ -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 +) : DirtyFilesHolderBase(context) { + val byTarget: Map + + inner class TargetFiles(val target: ModuleBuildTarget, val removed: Collection) { + val dirty: MutableSet = mutableSetOf() + + val dirtyOrRemovedFiles: Set + get() { + val result = mutableSetOf() + dirty.forEach { result.add(it.file) } + removed.forEach { result.add(File(it)) } + return result + } + + fun markDirty(files: Collection) { + 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() + 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) { + for ((target, info) in byTarget) { + info.dirty.forEach { + if (!processor.apply(target, it.file, it.root)) return + } + } + } + + fun getDirtyFiles(target: ModuleBuildTarget): Set = + byTarget[target]?.dirty?.mapTo(mutableSetOf()) { it.file } ?: setOf() + + fun getRemovedFilesSet(target: ModuleBuildTarget): Set = + byTarget[target]?.removed?.mapTo(mutableSetOf()) { File(it) } ?: setOf() + + override fun getRemovedFiles(target: ModuleBuildTarget): Collection = + byTarget.flatMap { it.value.removed } + + val removedFilesCount + get() = byTarget.values.flatMapTo(mutableSetOf()) { it.removed }.size + + val dirtyFiles: Set + get() = byTarget.flatMapTo(mutableSetOf()) { it.value.dirty.map { it.file } } + + val dirtyOrRemovedFilesSet: Set + get() { + val result = mutableSetOf() + 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") diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinSourceFileCollector.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinSourceFileCollector.kt deleted file mode 100644 index f5e38e66f5a..00000000000 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinSourceFileCollector.kt +++ /dev/null @@ -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): MultiMap { - val result = MultiMap() - - 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, - target: ModuleBuildTarget - ): List = - 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") - } -} diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/MessageCollectorAdapter.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/MessageCollectorAdapter.kt new file mode 100644 index 00000000000..86f692bcbb0 --- /dev/null +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/MessageCollectorAdapter.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") + } + } +} \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalJvmCache.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalCache.kt similarity index 59% rename from jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalJvmCache.kt rename to jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalCache.kt index a50527e2d48..6306c9eb171 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalJvmCache.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalCache.kt @@ -21,32 +21,50 @@ import org.jetbrains.jps.builders.storage.StorageProvider import org.jetbrains.jps.incremental.ModuleBuildTarget import org.jetbrains.jps.incremental.storage.BuildDataManager import org.jetbrains.jps.incremental.storage.StorageOwner +import org.jetbrains.kotlin.incremental.IncrementalCacheCommon +import org.jetbrains.kotlin.incremental.IncrementalJsCache import org.jetbrains.kotlin.incremental.IncrementalJvmCache import org.jetbrains.kotlin.jps.build.KotlinBuilder +import org.jetbrains.kotlin.jps.platforms.KotlinModuleBuildTarget import java.io.File +interface JpsIncrementalCache : IncrementalCacheCommon, StorageOwner { + fun addJpsDependentCache(cache: JpsIncrementalCache) +} + class JpsIncrementalJvmCache( target: ModuleBuildTarget, paths: BuildDataPaths -) : IncrementalJvmCache(paths.getTargetDataRoot(target), target.outputDir), StorageOwner { +) : IncrementalJvmCache(paths.getTargetDataRoot(target), target.outputDir), JpsIncrementalCache { + override fun addJpsDependentCache(cache: JpsIncrementalCache) { + addDependentCache(cache as JpsIncrementalJvmCache) + } + override fun debugLog(message: String) { KotlinBuilder.LOG.debug(message) } } -private class KotlinIncrementalStorageProvider( - private val target: ModuleBuildTarget, - private val paths: BuildDataPaths -) : StorageProvider() { +class JpsIncrementalJsCache( + target: ModuleBuildTarget, + paths: BuildDataPaths +) : IncrementalJsCache(paths.getTargetDataRoot(target)), JpsIncrementalCache { + override fun addJpsDependentCache(cache: JpsIncrementalCache) { + addDependentCache(cache as JpsIncrementalJsCache) + } +} +private class KotlinIncrementalStorageProvider( + private val target: KotlinModuleBuildTarget, + private val paths: BuildDataPaths +) : StorageProvider() { override fun equals(other: Any?) = other is KotlinIncrementalStorageProvider && target == other.target override fun hashCode() = target.hashCode() - override fun createStorage(targetDataDir: File): JpsIncrementalJvmCache = - JpsIncrementalJvmCache(target, paths) + override fun createStorage(targetDataDir: File): JpsIncrementalCache = target.createCacheStorage(paths) } -fun BuildDataManager.getKotlinCache(target: ModuleBuildTarget): JpsIncrementalJvmCache = - getStorage(target, KotlinIncrementalStorageProvider(target, dataPaths)) +fun BuildDataManager.getKotlinCache(target: KotlinModuleBuildTarget): JpsIncrementalCache = + getStorage(target.jpsModuleBuildTarget, KotlinIncrementalStorageProvider(target, dataPaths)) diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/model/ModuleSettings.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/model/ModuleSettings.kt index 7d7faf3d48f..0e3ccdde578 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/model/ModuleSettings.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/model/ModuleSettings.kt @@ -5,8 +5,11 @@ package org.jetbrains.kotlin.jps.model +import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor import org.jetbrains.jps.model.ex.JpsElementBase import org.jetbrains.jps.model.ex.JpsElementChildRoleBase +import org.jetbrains.jps.model.java.JavaSourceRootType +import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.config.CompilerSettings @@ -19,6 +22,25 @@ val JpsModule.kotlinFacet: JpsKotlinFacetModuleExtension? val JpsModule.targetPlatform: TargetPlatformKind<*>? get() = kotlinFacet?.settings?.targetPlatformKind +val JpsModule.expectedByModules: List + get() { + val kotlinFacetExtension = kotlinFacet + val implementedModuleNames = kotlinFacetExtension?.settings?.implementedModuleNames ?: return listOf() + if (implementedModuleNames.isEmpty()) return listOf() + + val result = ArrayList(implementedModuleNames.size) + + JpsJavaExtensionService.dependencies(this) + .processModules { + if (it.name in implementedModuleNames) { + // Note, production sources should be added for both production and tests targets + result.add(it) + } + } + + return result + } + val JpsModule.productionOutputFilePath: String? get() { val facetSettings = kotlinFacet?.settings ?: return null @@ -59,7 +81,7 @@ private inline fun JpsModule.getCompilerAr val facetSettings = kotlinFacet?.settings ?: return projectSettingsCopy if (facetSettings.useProjectSettings) return projectSettingsCopy - return facetSettings.compilerArguments as? T ?: projectSettingsCopy + return facetSettings.mergedCompilerArguments as? T ?: projectSettingsCopy } class JpsKotlinFacetModuleExtension(settings: KotlinFacetSettings) : JpsElementBase() { diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt index cf782ec4abd..74ad52a3caa 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt @@ -5,49 +5,87 @@ package org.jetbrains.kotlin.jps.platforms -import com.intellij.util.containers.MultiMap +import com.intellij.util.xmlb.XmlSerializerUtil import org.jetbrains.jps.ModuleChunk -import org.jetbrains.jps.builders.DirtyFilesHolder -import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor -import com.intellij.openapi.compiler.CompileContext as JpsCompileContext +import org.jetbrains.jps.builders.storage.BuildDataPaths import org.jetbrains.jps.incremental.CompileContext -import org.jetbrains.jps.incremental.FSOperations import org.jetbrains.jps.incremental.ModuleBuildTarget -import org.jetbrains.jps.incremental.fs.CompilationRound +import org.jetbrains.jps.model.library.JpsOrderRootType +import org.jetbrains.jps.model.module.JpsModule +import org.jetbrains.jps.util.JpsPathUtil import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.mergeBeans import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner -import org.jetbrains.kotlin.jps.build.FSOperationsHelper +import org.jetbrains.kotlin.jps.build.KotlinRoundDirtySourceFilesHolder +import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache import org.jetbrains.kotlin.jps.model.k2MetadataCompilerArguments import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings -import java.io.File -class KotlinCommonModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : - KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) { +class KotlinCommonModuleBuildTarget(context: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : + KotlinModuleBuildTarget(context, jpsModuleBuildTarget) { override fun compileModuleChunk( - allCompiledFiles: MutableSet, chunk: ModuleChunk, commonArguments: CommonCompilerArguments, - dirtyFilesHolder: DirtyFilesHolder, - environment: JpsCompilerEnvironment, - filesToCompile: MultiMap, - fsOperations: FSOperationsHelper + dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder, + environment: JpsCompilerEnvironment ): Boolean { - require(chunk.representativeTarget() == jpsModuleBuildTarget) - if (reportAndSkipCircular(chunk, environment)) return false + reportAndSkipCircular(chunk, environment) - // Incremental compilation is not supported, so mark all dependents as dirty - FSOperations.markDirtyRecursively(context, CompilationRound.CURRENT, chunk) - - JpsKotlinCompilerRunner().runK2MetadataCompiler( - commonArguments, - module.k2MetadataCompilerArguments, - module.kotlinCompilerSettings, - environment, - sources - ) + val k2MetadataArguments = module.k2MetadataCompilerArguments + if (k2MetadataArguments.enabledInJps || (commonArguments as? K2MetadataCompilerArguments)?.enabledInJps == true) { + JpsKotlinCompilerRunner().runK2MetadataCompiler( + commonArguments, + k2MetadataArguments, + module.kotlinCompilerSettings, + environment, + destination, + dependenciesOutputDirs + libraryFiles, + sourceFiles // incremental K2MetadataCompiler not supported yet + ) + } return true } + + private val libraryFiles: List + get() = mutableListOf().also { result -> + for (library in allDependencies.libraries) { + for (root in library.getRoots(JpsOrderRootType.COMPILED)) { + result.add(JpsPathUtil.urlToPath(root.url)) + } + } + } + + private val dependenciesOutputDirs: List + get() = mutableListOf().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, + 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 } \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt index 73627b4930c..819f38be4ef 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt @@ -5,19 +5,30 @@ package org.jetbrains.kotlin.jps.platforms -import com.intellij.util.containers.MultiMap import org.jetbrains.jps.ModuleChunk -import org.jetbrains.jps.builders.DirtyFilesHolder -import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor +import org.jetbrains.jps.builders.storage.BuildDataPaths import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.ModuleBuildTarget import org.jetbrains.jps.model.library.JpsOrderRootType import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.util.JpsPathUtil +import org.jetbrains.kotlin.build.GeneratedFile import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner -import org.jetbrains.kotlin.jps.build.FSOperationsHelper +import org.jetbrains.kotlin.config.IncrementalCompilation +import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.incremental.ChangesCollector +import org.jetbrains.kotlin.incremental.IncrementalJsCache +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider +import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer +import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl +import org.jetbrains.kotlin.incremental.js.TranslationResultValue +import org.jetbrains.kotlin.jps.build.KotlinRoundDirtySourceFilesHolder +import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache +import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJsCache import org.jetbrains.kotlin.jps.model.k2JsCompilerArguments import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings import org.jetbrains.kotlin.jps.model.productionOutputFilePath @@ -28,23 +39,56 @@ import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.META_JS_SUFFIX import java.io.File import java.net.URI +internal class IncrementalDataProviderFromCache(private val cache: IncrementalJsCache) : IncrementalDataProvider { + override val headerMetadata: ByteArray + get() = cache.header + + override val compiledPackageParts: Map + get() = cache.nonDirtyPackageParts() +} + class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : - KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) { + KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) { + + val sourceToOutputMap + get() = context.projectDescriptor.dataManager.getSourceToOutputMap(jpsModuleBuildTarget) + + val isFirstBuild + get() = sourceToOutputMap.sources.isEmpty() + + override fun makeServices( + builder: Services.Builder, + incrementalCaches: Map, + lookupTracker: LookupTracker, + exceptActualTracer: ExpectActualTracker + ) { + super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer) + + with(builder) { + register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl()) + + if (IncrementalCompilation.isEnabled() && !isFirstBuild) { + val cache = incrementalCaches[jpsModuleBuildTarget] as IncrementalJsCache + + register( + IncrementalDataProvider::class.java, + IncrementalDataProviderFromCache(cache) + ) + } + } + } override fun compileModuleChunk( - allCompiledFiles: MutableSet, chunk: ModuleChunk, commonArguments: CommonCompilerArguments, - dirtyFilesHolder: DirtyFilesHolder, - environment: JpsCompilerEnvironment, - filesToCompile: MultiMap, - fsOperations: FSOperationsHelper + dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder, + environment: JpsCompilerEnvironment ): Boolean { require(chunk.representativeTarget() == jpsModuleBuildTarget) if (reportAndSkipCircular(chunk, environment)) return false - val sources = sources - if (sources.isEmpty()) return false + val sources = collectSourcesToCompile(dirtyFilesHolder) + if (!checkShouldCompileAndLog(dirtyFilesHolder, sources)) return false val libraries = libraryFiles + dependenciesMetaFiles @@ -144,7 +188,7 @@ class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTa if (dependencyBuildTarget != this@KotlinJsModuleBuildTarget && dependencyBuildTarget is KotlinJsModuleBuildTarget && - dependencyBuildTarget.sources.isNotEmpty() + dependencyBuildTarget.sourceFiles.isNotEmpty() ) { val metaFile = dependencyBuildTarget.outputMetaFile if (metaFile.exists()) { @@ -152,4 +196,24 @@ class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTa } } } + + override fun createCacheStorage(paths: BuildDataPaths) = + JpsIncrementalJsCache(jpsModuleBuildTarget, paths) + + override fun updateCaches( + jpsIncrementalCache: JpsIncrementalCache, + files: List, + 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) + } } \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt index dbd20214a49..dca8457cec1 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt @@ -9,42 +9,120 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.util.containers.ContainerUtil -import com.intellij.util.containers.MultiMap import com.intellij.util.io.URLUtil +import gnu.trove.THashSet import org.jetbrains.jps.ModuleChunk -import org.jetbrains.jps.builders.DirtyFilesHolder -import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor +import org.jetbrains.jps.builders.java.JavaBuilderUtil +import org.jetbrains.jps.builders.storage.BuildDataPaths import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.ModuleBuildTarget +import org.jetbrains.jps.incremental.storage.BuildDataManager import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.module.JpsSdkDependency +import org.jetbrains.kotlin.build.GeneratedFile +import org.jetbrains.kotlin.build.GeneratedJvmClass +import org.jetbrains.kotlin.build.JvmBuildMetaInfo import org.jetbrains.kotlin.build.JvmSourceRoot import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner -import org.jetbrains.kotlin.config.IncrementalCompilation -import org.jetbrains.kotlin.jps.build.FSOperationsHelper +import org.jetbrains.kotlin.config.ApiVersion +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.incremental.* +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker +import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.jps.build.KotlinBuilder -import org.jetbrains.kotlin.jps.build.KotlinSourceFileCollector -import org.jetbrains.kotlin.jps.build.processedTargetsWithRemovedFilesContainer +import org.jetbrains.kotlin.jps.build.KotlinRoundDirtySourceFilesHolder +import org.jetbrains.kotlin.jps.build.jvmBuildMetaInfoFile +import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache +import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache import org.jetbrains.kotlin.jps.model.k2JvmCompilerArguments import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.utils.keysToMap +import org.jetbrains.org.objectweb.asm.ClassReader import java.io.File import java.io.IOException class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : - KotlinModuleBuilderTarget(compileContext, jpsModuleBuildTarget) { + KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) { + + override fun createCacheStorage(paths: BuildDataPaths) = JpsIncrementalJvmCache(jpsModuleBuildTarget, paths) + + override fun checkCachesVersions(chunk: ModuleChunk, dataManager: BuildDataManager, actions: MutableSet) { + 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, + 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 + ) + ) + } + } override fun compileModuleChunk( - allCompiledFiles: MutableSet, chunk: ModuleChunk, commonArguments: CommonCompilerArguments, - dirtyFilesHolder: DirtyFilesHolder, - environment: JpsCompilerEnvironment, - filesToCompile: MultiMap, - fsOperations: FSOperationsHelper + dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder, + environment: JpsCompilerEnvironment ): Boolean { if (chunk.modules.size > 1) { environment.messageCollector.report( @@ -55,34 +133,28 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT ) } - allCompiledFiles.addAll(filesToCompile.values()) + val filesSet = dirtyFilesHolder.dirtyFiles - val processedTargetsWithRemoved = context.processedTargetsWithRemovedFilesContainer - - var totalRemovedFiles = 0 - for (target in chunk.targets) { - val removedFilesInTarget = KotlinSourceFileCollector.getRemovedKotlinFiles(dirtyFilesHolder, target) - if (!removedFilesInTarget.isEmpty()) { - if (processedTargetsWithRemoved.add(target)) { - totalRemovedFiles += removedFilesInTarget.size - } - } - } - - val moduleFile = generateModuleDescription(context, chunk, filesToCompile, totalRemovedFiles != 0) + val moduleFile = generateModuleDescription(chunk, dirtyFilesHolder) if (moduleFile == null) { - KotlinBuilder.LOG.debug( - "Not compiling, because no files affected: " + filesToCompile.keySet().joinToString { it.presentableName } - ) + if (KotlinBuilder.LOG.isDebugEnabled) { + KotlinBuilder.LOG.debug( + "Not compiling, because no files affected: " + chunk.targets.joinToString { it.presentableName } + ) + } + // No Kotlin sources found return false } val module = chunk.representativeTarget().module - KotlinBuilder.LOG.debug("Compiling to JVM ${filesToCompile.values().size} files" - + (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)") - + " in " + filesToCompile.keySet().joinToString { it.presentableName }) + if (KotlinBuilder.LOG.isDebugEnabled) { + val totalRemovedFiles = dirtyFilesHolder.removedFilesCount + KotlinBuilder.LOG.debug("Compiling to JVM ${filesSet.size} files" + + (if (totalRemovedFiles == 0) "" else " ($totalRemovedFiles removed files)") + + " in " + chunk.targets.joinToString { it.presentableName }) + } try { val compilerRunner = JpsKotlinCompilerRunner() @@ -102,39 +174,22 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT return true } - fun generateModuleDescription( - context: CompileContext, - chunk: ModuleChunk, - sourceFiles: MultiMap, // ignored for non-incremental compilation - hasRemovedFiles: Boolean - ): File? { + fun generateModuleDescription(chunk: ModuleChunk, dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder): File? { val builder = KotlinModuleXmlBuilder() - var noSources = true + var hasDirtySources = false val targets = chunk.targets.mapNotNull { this.context.kotlinBuildTargets[it] as? KotlinJvmModuleBuildTarget } val outputDirs = targets.map { it.outputDir }.toSet() - val logger = context.loggingManager.projectBuilderLogger for (target in targets) { val outputDir = target.outputDir val friendDirs = target.friendOutputDirs - val moduleSources = - if (IncrementalCompilation.isEnabled() && target.expectedBy.isEmpty()) { - sourceFiles.get(target.jpsModuleBuildTarget) - } else { - target.sources - } - - if (moduleSources.isNotEmpty() || hasRemovedFiles) { - noSources = false - - if (logger.isEnabled) { - logger.logCompiledFiles(moduleSources, KotlinBuilder.KOTLIN_BUILDER_NAME, "Compiling files:") - } - } + val moduleSources = collectSourcesToCompile(target, dirtyFilesHolder) + val hasDirtyOrRemovedSources = checkShouldCompileAndLog(target, dirtyFilesHolder, moduleSources) + if (hasDirtyOrRemovedSources) hasDirtySources = true val kotlinModuleId = target.targetId builder.addModule( @@ -152,7 +207,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT ) } - if (noSources) return null + if (!hasDirtySources) return null val scriptFile = createTempFileForModuleDesc(chunk) FileUtil.writeToFile(scriptFile, builder.asText().toString()) @@ -192,7 +247,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT val extension = file.extension // Don't filter out files, we want to report warnings about absence through the common place - if (!(extension == "class" || extension == "jar")) { + if (extension != "class" && extension != "jar") { return@filter false } } @@ -213,7 +268,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT return File(url.substringAfter(StandardFileSystems.JRT_PROTOCOL_PREFIX).substringBeforeLast(URLUtil.JAR_SEPARATOR)) } - fun findSourceRoots(context: CompileContext): List { + private fun findSourceRoots(context: CompileContext): List { val roots = context.projectDescriptor.buildRootIndex.getTargetRoots(jpsModuleBuildTarget, context) val result = ContainerUtil.newArrayList() for (root in roots) { @@ -225,4 +280,64 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT } return result } + + override fun updateCaches( + jpsIncrementalCache: JpsIncrementalCache, + files: List, + 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>, + incrementalCaches: Map + ) { + val previousMappings = context.projectDescriptor.dataManager.mappings + val callback = JavaBuilderUtil.getDependenciesRegistrar(context) + + val targetDirtyFiles: Map> = chunk.targets.keysToMap { + val files = HashSet() + dirtyFilesHolder.getRemovedFiles(it).mapTo(files, ::File) + files.addAll(dirtyFilesHolder.getDirtyFiles(it)) + files + } + + fun getOldSourceFiles(target: ModuleBuildTarget, generatedClass: GeneratedJvmClass): Set { + 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) + } } \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuildTarget.kt new file mode 100644 index 00000000000..e5db4555619 --- /dev/null +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuildTarget.kt @@ -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 + get() { + val result = mutableListOf() + + if (isTests) { + result.addIfNotNull(context.kotlinBuildTargets[module.productionBuildTarget]) + result.addIfNotNull(context.kotlinBuildTargets[relatedProductionModule?.productionBuildTarget]) + } + + return result.filter { it.sourceFiles.isNotEmpty() } + } + + val friendOutputDirs: List + 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().also { result -> + collectSources(result) + } + } + + private fun collectSources(receiver: MutableMap) { + 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>, + incrementalCaches: Map + ) { + // by default do nothing + } + + open fun updateCaches( + jpsIncrementalCache: JpsIncrementalCache, + files: List, + changesCollector: ChangesCollector, + environment: JpsCompilerEnvironment + ) { + val expectActualTracker = environment.services[ExpectActualTracker::class.java] as ExpectActualTrackerImpl + jpsIncrementalCache.registerComplementaryFiles(expectActualTracker) + } + + open fun makeServices( + builder: Services.Builder, + incrementalCaches: Map, + 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 { + // 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) = + checkShouldCompileAndLog(this, dirtyFilesHolder, moduleSources) + + /** + * Should be used only for particular target in chunk (jvm) + */ + protected fun checkShouldCompileAndLog( + target: KotlinModuleBuildTarget, + dirtyFilesHolder: KotlinRoundDirtySourceFilesHolder, + moduleSources: Collection + ): 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) { + + } +} \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuilderTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuilderTarget.kt deleted file mode 100644 index d911e923906..00000000000 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuilderTarget.kt +++ /dev/null @@ -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> - 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 - get() { - val result = mutableListOf() - - if (isTests) { - result.addIfNotNull(context.kotlinBuildTargets[module.productionBuildTarget]) - result.addIfNotNull(context.kotlinBuildTargets[relatedProductionModule?.productionBuildTarget]) - } - - return result.filter { it.sources.isNotEmpty() } - } - - val friendOutputDirs: List - 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 { - 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().also { result -> - // add all common libs sources - expectedBy.forEach { - it.collectSources(result) - } - - collectSources(result) - } - } - - private fun collectSources(receiver: MutableList) { - 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, - chunk: ModuleChunk, - commonArguments: CommonCompilerArguments, - dirtyFilesHolder: DirtyFilesHolder, - environment: JpsCompilerEnvironment, - filesToCompile: MultiMap, - 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() { - } -} \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt index 5db26796c95..1f85c07e7a9 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.jps.platforms import com.intellij.openapi.util.Key -import org.jetbrains.jps.builders.ModuleBasedBuildTargetType import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.ModuleBuildTarget @@ -46,17 +45,17 @@ val CompileContext.kotlinBuildTargets: KotlinBuildTargets } class KotlinBuildTargets internal constructor(val compileContext: CompileContext) { - private val byJpsModuleBuildTarget = ConcurrentHashMap() + private val byJpsModuleBuildTarget = ConcurrentHashMap() private val isKotlinJsStdlibJar = ConcurrentHashMap() @JvmName("getNullable") - operator fun get(target: ModuleBuildTarget?): KotlinModuleBuilderTarget? { + operator fun get(target: ModuleBuildTarget?): KotlinModuleBuildTarget? { if (target == null) return null return get(target) } - operator fun get(target: ModuleBuildTarget): KotlinModuleBuilderTarget? { - if (target.targetType !is ModuleBasedBuildTargetType) return null + operator fun get(target: ModuleBuildTarget): KotlinModuleBuildTarget? { + if (target.module.moduleType != JpsJavaModuleType.INSTANCE) return null return byJpsModuleBuildTarget.computeIfAbsent(target) { when (target.module.targetPlatform ?: detectTargetPlatform(target)) { diff --git a/jps-plugin/testData/incremental/multiModule/twoDependants/build.log b/jps-plugin/testData/incremental/multiModule/twoDependants/build.log index 10e8f1351b5..e15db13f406 100644 --- a/jps-plugin/testData/incremental/multiModule/twoDependants/build.log +++ b/jps-plugin/testData/incremental/multiModule/twoDependants/build.log @@ -16,16 +16,6 @@ Exit code: ADDITIONAL_PASS_REQUIRED ------------------------------------------ Exit code: NOTHING_DONE ------------------------------------------ -Building module2 -Cleaning output files: - out/production/module2/META-INF/module2.kotlin_module - out/production/module2/b/BKt.class -End of files -Compiling files: - module2/src/b.kt -End of files -Exit code: OK ------------------------------------------- Building module3 Cleaning output files: out/production/module3/META-INF/module3.kotlin_module @@ -36,3 +26,13 @@ Compiling files: End of files Exit code: OK ------------------------------------------ +Building module2 +Cleaning output files: + out/production/module2/META-INF/module2.kotlin_module + out/production/module2/b/BKt.class +End of files +Compiling files: + module2/src/b.kt +End of files +Exit code: OK +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/README.md b/jps-plugin/testData/incremental/multiplatform/multiModule/README.md new file mode 100644 index 00000000000..de6291b9598 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/README.md @@ -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 +... +``` \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simple/dependencies.txt b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/dependencies.txt new file mode 100644 index 00000000000..c2e118f8a40 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/dependencies.txt @@ -0,0 +1,7 @@ +c [common, edit, editExpectActual] + +pJvm [jvm, edit, editJvm] +pJvm -> c [expectedBy] + +pJs [js, edit] +pJs -> c [expectedBy] \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCExpectActual/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCExpectActual/build.log new file mode 100644 index 00000000000..8d19707f7fe --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCExpectActual/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCKotlin/build.log new file mode 100644 index 00000000000..98636b11ea1 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingCKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJsKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJsKotlin/build.log new file mode 100644 index 00000000000..8eef251fc12 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJsKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmJava/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmJava/build.log new file mode 100644 index 00000000000..645746606b8 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmJava/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmKotlin/build.log new file mode 100644 index 00000000000..6f72ea725c4 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simple/editingPJvmKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/dependencies.txt b/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/dependencies.txt new file mode 100644 index 00000000000..af1aab5b690 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/dependencies.txt @@ -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] \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCMainExpectActual/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCMainExpectActual/build.log new file mode 100644 index 00000000000..538446ab4e8 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCMainExpectActual/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCTestsExpectActual/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCTestsExpectActual/build.log new file mode 100644 index 00000000000..f730f3aaa46 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/simpleJsJvmProjectWithTests/editingCTestsExpectActual/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/dependencies.txt b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/dependencies.txt new file mode 100644 index 00000000000..cd21bb1f718 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/dependencies.txt @@ -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] \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingACommonExpectActual/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingACommonExpectActual/build.log new file mode 100644 index 00000000000..9332eed5a4e --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingACommonExpectActual/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJsClientKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJsClientKotlin/build.log new file mode 100644 index 00000000000..c40d297bd31 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJsClientKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientJava/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientJava/build.log new file mode 100644 index 00000000000..bba9b709aca --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientJava/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientKotlin/build.log new file mode 100644 index 00000000000..6b9f4da6f69 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingAJvmClientKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingBCommonExpectActual/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingBCommonExpectActual/build.log new file mode 100644 index 00000000000..d6daa69d34c --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingBCommonExpectActual/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJsKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJsKotlin/build.log new file mode 100644 index 00000000000..a9340c97fa4 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJsKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJvmKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJvmKotlin/build.log new file mode 100644 index 00000000000..a24b2dbaf68 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRJvmKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJsKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJsKotlin/build.log new file mode 100644 index 00000000000..4e31381fb24 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJsKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJvmKotlin/build.log b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJvmKotlin/build.log new file mode 100644 index 00000000000..de81e4c2eb7 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/multiModule/ultimate/editingRaJvmKotlin/build.log @@ -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 +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/X.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/X.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/X.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/X.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/X.kt.touch.1 b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/X.kt.touch.1 similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/X.kt.touch.1 rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/X.kt.touch.1 diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/Y.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/Y.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/Y.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/Y.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/Z.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/Z.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/Z.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/Z.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/build.log b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/build.log similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/build.log rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/build.log diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/commonX.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/commonX.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/commonX.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/commonX.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/commonY.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/commonY.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/commonY.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/commonY.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/commonZ.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/commonZ.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/commonZ.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/commonZ.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/dummy.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/dummy.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/dummy.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/dummy.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/useX.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/useX.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/useX.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/useX.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/useYZ.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/useYZ.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt.touch.2 b/jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/useYZ.kt.touch.2 similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt.touch.2 rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchActual/useYZ.kt.touch.2 diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/X.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/X.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/X.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/X.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/Y.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/Y.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/Y.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/Y.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/Z.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/Z.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/Z.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/Z.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/build.log b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/build.log similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/build.log rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/build.log diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonX.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonX.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt.touch.1 b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonX.kt.touch.1 similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt.touch.1 rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonX.kt.touch.1 diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonY.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonY.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt.touch.2 b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonY.kt.touch.2 similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt.touch.2 rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonY.kt.touch.2 diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonZ.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonZ.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/commonZ.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/commonZ.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/dummy.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/dummy.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/dummy.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/dummy.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/useX.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/useX.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/useX.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/useX.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/useXIncompatible.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/useXIncompatible.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/useXIncompatible.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/useXIncompatible.kt diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/useYZ.kt b/jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/useYZ.kt similarity index 100% rename from jps-plugin/testData/incremental/multiplatform/touchExpect/useYZ.kt rename to jps-plugin/testData/incremental/multiplatform/singleModule/touchExpect/useYZ.kt