Fix issues with incremental cache version change
#KT-9360 fixed
Original commit: a564724fa8
This commit is contained in:
@@ -30,15 +30,11 @@ import org.jetbrains.jps.builders.java.JavaBuilderUtil
|
|||||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||||
import org.jetbrains.jps.builders.java.dependencyView.Mappings
|
import org.jetbrains.jps.builders.java.dependencyView.Mappings
|
||||||
import org.jetbrains.jps.incremental.*
|
import org.jetbrains.jps.incremental.*
|
||||||
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.ABORT
|
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.*
|
||||||
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.fs.CompilationRound
|
import org.jetbrains.jps.incremental.fs.CompilationRound
|
||||||
import org.jetbrains.jps.incremental.java.JavaBuilder
|
import org.jetbrains.jps.incremental.java.JavaBuilder
|
||||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
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.JpsProject
|
||||||
import org.jetbrains.jps.model.JpsSimpleElement
|
import org.jetbrains.jps.model.JpsSimpleElement
|
||||||
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
|
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() }) {
|
if (chunk.targets.any { dataManager.dataPaths.getKotlinCacheVersion(it).isIncompatible() }) {
|
||||||
LOG.info("Clearing caches for " + chunk.targets.map { it.presentableName }.join())
|
LOG.info("Clearing caches for " + chunk.targets.map { it.presentableName }.join())
|
||||||
val incrementalCaches = getIncrementalCaches(chunk, context)
|
chunk.targets.forEach { dataManager.getKotlinCache(it).clean() }
|
||||||
incrementalCaches.values().forEach(StorageOwner::clean)
|
return CHUNK_REBUILD_REQUIRED
|
||||||
FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk)
|
|
||||||
return ADDITIONAL_PASS_REQUIRED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dirtyFilesHolder.hasDirtyFiles() && !dirtyFilesHolder.hasRemovedFiles()
|
if (!dirtyFilesHolder.hasDirtyFiles() && !dirtyFilesHolder.hasRemovedFiles()
|
||||||
@@ -238,13 +232,22 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ChangesInfo.doProcessChanges() {
|
private fun ChangesInfo.doProcessChanges() {
|
||||||
|
fun isKotlin(file: File) = KotlinSourceFileCollector.isKotlinSourceFile(file)
|
||||||
|
fun isNotCompiled(file: File) = file !in allCompiledFiles
|
||||||
|
|
||||||
when {
|
when {
|
||||||
inlineAdded -> {
|
inlineAdded -> {
|
||||||
recompileEverything()
|
allCompiledFiles.clear()
|
||||||
|
FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, ::isKotlin)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
constantsChanged -> recompileOtherAndDependents()
|
constantsChanged -> {
|
||||||
protoChanged -> recompileOtherKotlinInChunk()
|
FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, ::isNotCompiled)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
protoChanged -> {
|
||||||
|
FSOperations.markDirty(context, CompilationRound.NEXT, chunk, { isKotlin(it) && isNotCompiled(it) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlineChanged) {
|
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(
|
private fun doCompileModuleChunk(
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import org.jetbrains.jps.incremental.ModuleBuildTarget
|
|||||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||||
import org.jetbrains.jps.model.JpsElementFactory
|
import org.jetbrains.jps.model.JpsElementFactory
|
||||||
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
||||||
|
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
|
||||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||||
import org.jetbrains.jps.util.JpsPathUtil
|
import org.jetbrains.jps.util.JpsPathUtil
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
@@ -249,18 +250,17 @@ public abstract class AbstractIncrementalJpsTest(
|
|||||||
rebuildAndCheckOutput(makeOverallResult)
|
rebuildAndCheckOutput(makeOverallResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readModuleDependencies(): Map<String, List<String>>? {
|
private fun readModuleDependencies(): Map<String, List<DependencyDescriptor>>? {
|
||||||
val dependenciesTxt = File(testDataDir, "dependencies.txt")
|
val dependenciesTxt = File(testDataDir, "dependencies.txt")
|
||||||
if (!dependenciesTxt.exists()) return null
|
if (!dependenciesTxt.exists()) return null
|
||||||
|
|
||||||
val result = HashMap<String, List<String>>()
|
val result = HashMap<String, List<DependencyDescriptor>>()
|
||||||
for (line in dependenciesTxt.readLines()) {
|
for (line in dependenciesTxt.readLines()) {
|
||||||
val split = line.split("->")
|
val split = line.split("->")
|
||||||
val module = split[0]
|
val module = split[0]
|
||||||
val dependencies = if (split.size() > 1) split[1] else ""
|
val dependencies = if (split.size() > 1) split[1] else ""
|
||||||
val dependencyList = dependencies.split(",").filterNot { it.isEmpty() }
|
val dependencyList = dependencies.split(",").filterNot { it.isEmpty() }
|
||||||
|
result[module] = dependencyList.map(::parseDependency)
|
||||||
result[module] = dependencyList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -377,8 +377,10 @@ public abstract class AbstractIncrementalJpsTest(
|
|||||||
|
|
||||||
for ((moduleName, dependencies) in moduleDependencies) {
|
for ((moduleName, dependencies) in moduleDependencies) {
|
||||||
val module = nameToModule[moduleName]!!
|
val module = nameToModule[moduleName]!!
|
||||||
|
|
||||||
for (dependency in dependencies) {
|
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<ModuleBuildTarget>
|
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
|
||||||
get() = buildTargetIndex.allTargets.filterIsInstance<ModuleBuildTarget>()
|
get() = buildTargetIndex.allTargets.filterIsInstance<ModuleBuildTarget>()
|
||||||
|
|
||||||
|
private class DependencyDescriptor(val name: String, val exported: Boolean)
|
||||||
|
|
||||||
|
private fun parseDependency(dependency: String): DependencyDescriptor =
|
||||||
|
DependencyDescriptor(dependency.removeSuffix(EXPORTED_SUFFIX), dependency.endsWith(EXPORTED_SUFFIX))
|
||||||
|
|
||||||
|
private val EXPORTED_SUFFIX = "[exported]"
|
||||||
|
|||||||
+18
@@ -35,6 +35,12 @@ public class IncrementalCacheVersionChangedTestGenerated extends AbstractIncreme
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged"), Pattern.compile("^([^\\.]+)$"), true);
|
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")
|
@TestMetadata("module1Modified")
|
||||||
public void testModule1Modified() throws Exception {
|
public void testModule1Modified() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified/");
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified/");
|
||||||
@@ -47,6 +53,18 @@ public class IncrementalCacheVersionChangedTestGenerated extends AbstractIncreme
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("touchedFile")
|
||||||
public void testTouchedFile() throws Exception {
|
public void testTouchedFile() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile/");
|
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile/");
|
||||||
|
|||||||
@@ -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
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
module1->
|
||||||
|
module2->module1[exported]
|
||||||
|
module3->module2
|
||||||
|
module4->module3
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
open class A
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
open class A
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package b
|
||||||
|
|
||||||
|
import a.A
|
||||||
|
|
||||||
|
open class B {
|
||||||
|
val a = A()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package c
|
||||||
|
|
||||||
|
import b.B
|
||||||
|
|
||||||
|
open class C {
|
||||||
|
val b = B()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package D
|
||||||
|
|
||||||
|
import c.C
|
||||||
|
|
||||||
|
open class D {
|
||||||
|
val c = C()
|
||||||
|
}
|
||||||
+18
@@ -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
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
module1->
|
||||||
|
module2->module1
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
val X = 10
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
val X = 11
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package b
|
||||||
|
|
||||||
|
class B {
|
||||||
|
val x = a.X
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package b;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
C() {
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -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
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
module1->
|
||||||
|
module2->module1
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
open class A
|
||||||
|
|
||||||
|
inline fun f(): A {
|
||||||
|
return A()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
open class A
|
||||||
|
|
||||||
|
inline fun f(): A {
|
||||||
|
return A()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package b
|
||||||
|
|
||||||
|
import a.*
|
||||||
|
|
||||||
|
open class B {
|
||||||
|
val a = f()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package b;
|
||||||
|
|
||||||
|
class C {
|
||||||
|
C() {
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user