diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt index 4c08b813650..793991eb7e9 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt @@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader import org.jetbrains.jet.descriptors.serialization.BitEncoding import org.jetbrains.jet.utils.intellij.* +import java.util.Arrays public class IncrementalCache(baseDir: File) { class object { @@ -72,17 +73,26 @@ public class IncrementalCache(baseDir: File) { }) } - public fun saveFileToCache(moduleId: String, file: File) { + public fun saveFileToCache(moduleId: String, file: File): Boolean { val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(file.readBytes()) - if (classNameAndHeader == null) return + if (classNameAndHeader == null) return false val (className, header) = classNameAndHeader if (header.kind == KotlinClassHeader.Kind.PACKAGE_FACADE) { - putPackageData(moduleId, className.getFqNameForClassNameWithoutDollars().parent(), BitEncoding.decodeBytes(header.annotationData!!)) + val fqName = className.getFqNameForClassNameWithoutDollars().parent() + val data = BitEncoding.decodeBytes(header.annotationData!!) + val oldData = getPackageData(moduleId, fqName) + if (Arrays.equals(data, oldData)) { + return false + } + putPackageData(moduleId, fqName, data) + return true } + // TODO Check class signatures, too! + return false } - public fun putPackageData(moduleId: String, fqName: FqName, data: ByteArray) { + private fun putPackageData(moduleId: String, fqName: FqName, data: ByteArray) { packageFacadeData.put(PackageFacadeId(moduleId, fqName), data) } diff --git a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java index 801220bb004..3469225ec74 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java +++ b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java @@ -198,6 +198,8 @@ public class KotlinBuilder extends ModuleLevelBuilder { IncrementalCache cache = new IncrementalCache(KotlinBuilderModuleScriptGenerator.getIncrementalCacheDir(context)); try { + boolean significantChanges = false; + for (SimpleOutputItem outputItem : outputItemCollector.getOutputs()) { BuildTarget target = null; Collection sourceFiles = outputItem.getSourceFiles(); @@ -215,7 +217,9 @@ public class KotlinBuilder extends ModuleLevelBuilder { File outputFile = outputItem.getOutputFile(); if (IncrementalCompilation.ENABLED) { - cache.saveFileToCache(target.getId(), outputFile); + if (cache.saveFileToCache(target.getId(), outputFile)) { + significantChanges = true; + } } outputConsumer.registerOutputFile(target, outputFile, paths(sourceFiles)); @@ -223,18 +227,21 @@ public class KotlinBuilder extends ModuleLevelBuilder { if (IncrementalCompilation.ENABLED) { // TODO should mark dependencies as dirty, as well - FSOperations.markDirty(context, chunk, new FileFilter() { - @Override - public boolean accept(@NotNull File file) { - return !allCompiledFiles.contains(file); - } - }); + if (significantChanges) { + FSOperations.markDirty(context, chunk, new FileFilter() { + @Override + public boolean accept(@NotNull File file) { + return !allCompiledFiles.contains(file); + } + }); + } return ExitCode.ADDITIONAL_PASS_REQUIRED; } else { return ExitCode.OK; } - } finally { + } + finally { cache.close(); } } diff --git a/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt b/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt index 26b23e69b33..b456e666d29 100644 --- a/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt +++ b/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt @@ -108,6 +108,14 @@ public class IncrementalJpsTest : JpsBuildTestCase() { doTest() } + fun testReturnTypeChanged() { + doTest() + } + + fun testTopLevelFunctionSameSignature() { + doTest() + } + private class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase() { private val logBuf = StringBuilder() public val log: String diff --git a/jps-plugin/testData/incremental/independentClasses/build.log b/jps-plugin/testData/incremental/independentClasses/build.log index 0d52aa1b838..b33bb4d2a49 100644 --- a/jps-plugin/testData/incremental/independentClasses/build.log +++ b/jps-plugin/testData/incremental/independentClasses/build.log @@ -3,10 +3,4 @@ out/production/module/test/Foo.class End of files Compiling files: src/Foo.kt -End of files -Cleaning output files: -out/production/module/test/Bar.class -End of files -Compiling files: -src/Bar.kt -End of files +End of files \ No newline at end of file diff --git a/jps-plugin/testData/incremental/returnTypeChanged/build.log b/jps-plugin/testData/incremental/returnTypeChanged/build.log new file mode 100644 index 00000000000..22b74887df0 --- /dev/null +++ b/jps-plugin/testData/incremental/returnTypeChanged/build.log @@ -0,0 +1,14 @@ +Cleaning output files: +out/production/module/test/TestPackage-fun-*.class +out/production/module/test/TestPackage.class +End of files +Compiling files: +src/fun.kt +End of files +Cleaning output files: +out/production/module/test/TestPackage-usage-*.class +out/production/module/test/TestPackage.class +End of files +Compiling files: +src/usage.kt +End of files diff --git a/jps-plugin/testData/incremental/returnTypeChanged/fun.kt b/jps-plugin/testData/incremental/returnTypeChanged/fun.kt new file mode 100644 index 00000000000..8387e08ec93 --- /dev/null +++ b/jps-plugin/testData/incremental/returnTypeChanged/fun.kt @@ -0,0 +1,4 @@ +package test + +fun foo() { +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/returnTypeChanged/fun.kt.new b/jps-plugin/testData/incremental/returnTypeChanged/fun.kt.new new file mode 100644 index 00000000000..059cb5d8478 --- /dev/null +++ b/jps-plugin/testData/incremental/returnTypeChanged/fun.kt.new @@ -0,0 +1,3 @@ +package test + +fun foo(): String = ":)" \ No newline at end of file diff --git a/jps-plugin/testData/incremental/returnTypeChanged/usage.kt b/jps-plugin/testData/incremental/returnTypeChanged/usage.kt new file mode 100644 index 00000000000..ce711cd81b5 --- /dev/null +++ b/jps-plugin/testData/incremental/returnTypeChanged/usage.kt @@ -0,0 +1,5 @@ +package test + +fun usage() { + foo() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/simpleClassDependency/build.log b/jps-plugin/testData/incremental/simpleClassDependency/build.log index 6c95f57482f..2cfeb2be275 100644 --- a/jps-plugin/testData/incremental/simpleClassDependency/build.log +++ b/jps-plugin/testData/incremental/simpleClassDependency/build.log @@ -4,10 +4,4 @@ out/production/module/test/Foo.class End of files Compiling files: src/Foo.kt -End of files -Cleaning output files: -out/production/module/test/Bar.class -End of files -Compiling files: -src/Bar.kt End of files \ No newline at end of file diff --git a/jps-plugin/testData/incremental/topLevelFunctionSameSignature/build.log b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/build.log new file mode 100644 index 00000000000..4a956843b6d --- /dev/null +++ b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/build.log @@ -0,0 +1,7 @@ +Cleaning output files: +out/production/module/test/TestPackage-fun-*.class +out/production/module/test/TestPackage.class +End of files +Compiling files: +src/fun.kt +End of files diff --git a/jps-plugin/testData/incremental/topLevelFunctionSameSignature/fun.kt b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/fun.kt new file mode 100644 index 00000000000..8387e08ec93 --- /dev/null +++ b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/fun.kt @@ -0,0 +1,4 @@ +package test + +fun foo() { +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/topLevelFunctionSameSignature/fun.kt.new b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/fun.kt.new new file mode 100644 index 00000000000..9c3c1518d9e --- /dev/null +++ b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/fun.kt.new @@ -0,0 +1,5 @@ +package test + +fun foo() { + println("body is changed, but it doesn't matter, we won't rebuild dependencies") +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/topLevelFunctionSameSignature/usage.kt b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/usage.kt new file mode 100644 index 00000000000..ce711cd81b5 --- /dev/null +++ b/jps-plugin/testData/incremental/topLevelFunctionSameSignature/usage.kt @@ -0,0 +1,5 @@ +package test + +fun usage() { + foo() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/topLevelMembersInTwoPackages/build.log b/jps-plugin/testData/incremental/topLevelMembersInTwoPackages/build.log index 08cb50b84f3..6e7a5e35e00 100644 --- a/jps-plugin/testData/incremental/topLevelMembersInTwoPackages/build.log +++ b/jps-plugin/testData/incremental/topLevelMembersInTwoPackages/build.log @@ -4,11 +4,4 @@ out/production/module/test/TestPackage.class End of files Compiling files: src/a.kt -End of files -Cleaning output files: -out/production/module/test/TestPackage-b-*.class -out/production/module/test/TestPackage.class -End of files -Compiling files: -src/b.kt -End of files +End of files \ No newline at end of file