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 5905b0899f6..e7d99df6db9 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -30,15 +30,11 @@ import org.jetbrains.jps.builders.java.JavaBuilderUtil import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor import org.jetbrains.jps.builders.java.dependencyView.Mappings import org.jetbrains.jps.incremental.* -import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.ABORT -import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.ADDITIONAL_PASS_REQUIRED -import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.NOTHING_DONE -import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.OK +import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.* import org.jetbrains.jps.incremental.fs.CompilationRound 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.storage.StorageOwner import org.jetbrains.jps.model.JpsProject import org.jetbrains.jps.model.JpsSimpleElement import org.jetbrains.jps.model.ex.JpsElementChildRoleBase @@ -141,10 +137,8 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR if (chunk.targets.any { dataManager.dataPaths.getKotlinCacheVersion(it).isIncompatible() }) { LOG.info("Clearing caches for " + chunk.targets.map { it.presentableName }.join()) - val incrementalCaches = getIncrementalCaches(chunk, context) - incrementalCaches.values().forEach(StorageOwner::clean) - FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk) - return ADDITIONAL_PASS_REQUIRED + chunk.targets.forEach { dataManager.getKotlinCache(it).clean() } + return CHUNK_REBUILD_REQUIRED } if (!dirtyFilesHolder.hasDirtyFiles() && !dirtyFilesHolder.hasRemovedFiles() @@ -238,13 +232,22 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR } private fun ChangesInfo.doProcessChanges() { + fun isKotlin(file: File) = KotlinSourceFileCollector.isKotlinSourceFile(file) + fun isNotCompiled(file: File) = file !in allCompiledFiles + when { inlineAdded -> { - recompileEverything() + allCompiledFiles.clear() + FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, ::isKotlin) return } - constantsChanged -> recompileOtherAndDependents() - protoChanged -> recompileOtherKotlinInChunk() + constantsChanged -> { + FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, ::isNotCompiled) + return + } + protoChanged -> { + FSOperations.markDirty(context, CompilationRound.NEXT, chunk, { isKotlin(it) && isNotCompiled(it) }) + } } if (inlineChanged) { @@ -261,28 +264,6 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR } } } - - private fun recompileEverything() { - allCompiledFiles.clear() - FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk) - } - - private fun recompileOtherAndDependents() { - // Workaround for IDEA 14.0-14.0.2: extended version of markDirtyRecursively is not available - try { - Class.forName("org.jetbrains.jps.incremental.fs.CompilationRound") - - FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, { file -> file !in allCompiledFiles }) - } catch (e: ClassNotFoundException) { - recompileEverything() - } - } - - private fun recompileOtherKotlinInChunk() { - FSOperations.markDirty(context, chunk, { file -> - KotlinSourceFileCollector.isKotlinSourceFile(file) && file !in allCompiledFiles - }) - } } private fun doCompileModuleChunk( diff --git a/jps-plugin/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt b/jps-plugin/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt index 4ccda971bda..c47e195ec9e 100644 --- a/jps-plugin/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt +++ b/jps-plugin/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalJpsTest.kt @@ -40,6 +40,7 @@ import org.jetbrains.jps.incremental.ModuleBuildTarget import org.jetbrains.jps.incremental.messages.BuildMessage import org.jetbrains.jps.model.JpsElementFactory 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.incremental.components.LookupTracker @@ -249,18 +250,17 @@ public abstract class AbstractIncrementalJpsTest( rebuildAndCheckOutput(makeOverallResult) } - private fun readModuleDependencies(): Map>? { + private fun readModuleDependencies(): Map>? { val dependenciesTxt = File(testDataDir, "dependencies.txt") if (!dependenciesTxt.exists()) return null - val result = HashMap>() + 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 + result[module] = dependencyList.map(::parseDependency) } return result @@ -377,8 +377,10 @@ public abstract class AbstractIncrementalJpsTest( for ((moduleName, dependencies) in moduleDependencies) { val module = nameToModule[moduleName]!! + for (dependency in dependencies) { - JpsModuleRootModificationUtil.addDependency(module, nameToModule[dependency]) + JpsModuleRootModificationUtil.addDependency(module, nameToModule[dependency.name], + JpsJavaDependencyScope.COMPILE, dependency.exported) } } @@ -449,3 +451,10 @@ public abstract class AbstractIncrementalJpsTest( 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/test/org/jetbrains/kotlin/jps/build/IncrementalCacheVersionChangedTestGenerated.java b/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalCacheVersionChangedTestGenerated.java index 84a96d9ec60..eea8bc8cd4f 100644 --- a/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalCacheVersionChangedTestGenerated.java +++ b/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalCacheVersionChangedTestGenerated.java @@ -35,6 +35,12 @@ public class IncrementalCacheVersionChangedTestGenerated extends AbstractIncreme JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged"), Pattern.compile("^([^\\.]+)$"), true); } + @TestMetadata("exportedModule") + public void testExportedModule() throws Exception { + String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/"); + doTest(fileName); + } + @TestMetadata("module1Modified") public void testModule1Modified() throws Exception { String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified/"); @@ -47,6 +53,18 @@ public class IncrementalCacheVersionChangedTestGenerated extends AbstractIncreme doTest(fileName); } + @TestMetadata("moduleWithConstantModified") + public void testModuleWithConstantModified() throws Exception { + String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/"); + doTest(fileName); + } + + @TestMetadata("moduleWithInlineModified") + public void testModuleWithInlineModified() throws Exception { + String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/"); + doTest(fileName); + } + @TestMetadata("touchedFile") public void testTouchedFile() throws Exception { String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile/"); diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/build.log b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/build.log new file mode 100644 index 00000000000..f3a965ea35b --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/build.log @@ -0,0 +1,24 @@ +Cleaning output files: +out/production/module1/a/A.class +End of files +Compiling files: +module1/src/module1_A.kt +End of files +Cleaning output files: +out/production/module2/b/B.class +End of files +Compiling files: +module2/src/module2_B.kt +End of files +Cleaning output files: +out/production/module3/c/C.class +End of files +Compiling files: +module3/src/module3_C.kt +End of files +Cleaning output files: +out/production/module4/D/D.class +End of files +Compiling files: +module4/src/module4_D.kt +End of files \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/dependencies.txt b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/dependencies.txt new file mode 100644 index 00000000000..f5f92433d7f --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/dependencies.txt @@ -0,0 +1,4 @@ +module1-> +module2->module1[exported] +module3->module2 +module4->module3 diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module1_A.kt b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module1_A.kt new file mode 100644 index 00000000000..21df9b5ad05 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module1_A.kt @@ -0,0 +1,3 @@ +package a + +open class A \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module1_A.kt.new b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module1_A.kt.new new file mode 100644 index 00000000000..21df9b5ad05 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module1_A.kt.new @@ -0,0 +1,3 @@ +package a + +open class A \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module2_B.kt b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module2_B.kt new file mode 100644 index 00000000000..48d8f912431 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module2_B.kt @@ -0,0 +1,7 @@ +package b + +import a.A + +open class B { + val a = A() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module3_C.kt b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module3_C.kt new file mode 100644 index 00000000000..3ed85781d90 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module3_C.kt @@ -0,0 +1,7 @@ +package c + +import b.B + +open class C { + val b = B() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module4_D.kt b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module4_D.kt new file mode 100644 index 00000000000..828f5775eb5 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/module4_D.kt @@ -0,0 +1,7 @@ +package D + +import c.C + +open class D { + val c = C() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/build.log b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/build.log new file mode 100644 index 00000000000..96b3e5069a8 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/build.log @@ -0,0 +1,18 @@ +Cleaning output files: +out/production/module1/META-INF/module1.kotlin_module +out/production/module1/a/APackage.class +out/production/module1/a/Module1_AKt.class +End of files +Compiling files: +module1/src/module1_A.kt +End of files +Cleaning output files: +out/production/module2/b/B.class +out/production/module2/b/C.class +End of files +Compiling files: +module2/src/module2_B.kt +End of files +Compiling files: +module2/src/module2_C.java +End of files \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/dependencies.txt b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/dependencies.txt new file mode 100644 index 00000000000..827bf04cc58 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/dependencies.txt @@ -0,0 +1,2 @@ +module1-> +module2->module1 diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module1_A.kt b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module1_A.kt new file mode 100644 index 00000000000..04406896cf1 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module1_A.kt @@ -0,0 +1,3 @@ +package a + +val X = 10 \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module1_A.kt.new b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module1_A.kt.new new file mode 100644 index 00000000000..7702c5904f0 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module1_A.kt.new @@ -0,0 +1,3 @@ +package a + +val X = 11 \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module2_B.kt b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module2_B.kt new file mode 100644 index 00000000000..fac015d2d49 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module2_B.kt @@ -0,0 +1,5 @@ +package b + +class B { + val x = a.X +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module2_C.java b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module2_C.java new file mode 100644 index 00000000000..6eb41bfcd2d --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/module2_C.java @@ -0,0 +1,7 @@ +package b; + +class C { + C() { + new B(); + } +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/build.log b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/build.log new file mode 100644 index 00000000000..35f17a0b6cc --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/build.log @@ -0,0 +1,21 @@ +Cleaning output files: +out/production/module1/META-INF/module1.kotlin_module +out/production/module1/a/A.class +out/production/module1/a/APackage.class +out/production/module1/a/Module1_AKt.class +End of files +Compiling files: +module1/src/module1_A.kt +End of files +Cleaning output files: +out/production/module2/b/B.class +End of files +Cleaning output files: +out/production/module2/b/C.class +End of files +Compiling files: +module2/src/module2_B.kt +End of files +Compiling files: +module2/src/module2_C.java +End of files \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/dependencies.txt b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/dependencies.txt new file mode 100644 index 00000000000..827bf04cc58 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/dependencies.txt @@ -0,0 +1,2 @@ +module1-> +module2->module1 diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module1_A.kt b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module1_A.kt new file mode 100644 index 00000000000..557b1805d4c --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module1_A.kt @@ -0,0 +1,7 @@ +package a + +open class A + +inline fun f(): A { + return A() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module1_A.kt.new b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module1_A.kt.new new file mode 100644 index 00000000000..557b1805d4c --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module1_A.kt.new @@ -0,0 +1,7 @@ +package a + +open class A + +inline fun f(): A { + return A() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module2_B.kt b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module2_B.kt new file mode 100644 index 00000000000..3edc9740e23 --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module2_B.kt @@ -0,0 +1,7 @@ +package b + +import a.* + +open class B { + val a = f() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module2_C.java b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module2_C.java new file mode 100644 index 00000000000..6eb41bfcd2d --- /dev/null +++ b/jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/module2_C.java @@ -0,0 +1,7 @@ +package b; + +class C { + C() { + new B(); + } +} \ No newline at end of file