Rebuild only if proto changed.

This commit is contained in:
Evgeny Gerashchenko
2014-05-15 16:47:52 +04:00
parent 4cf2dc665e
commit 018b58b51f
14 changed files with 86 additions and 33 deletions
@@ -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.lang.resolve.kotlin.header.KotlinClassHeader
import org.jetbrains.jet.descriptors.serialization.BitEncoding import org.jetbrains.jet.descriptors.serialization.BitEncoding
import org.jetbrains.jet.utils.intellij.* import org.jetbrains.jet.utils.intellij.*
import java.util.Arrays
public class IncrementalCache(baseDir: File) { public class IncrementalCache(baseDir: File) {
class object { 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()) val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(file.readBytes())
if (classNameAndHeader == null) return if (classNameAndHeader == null) return false
val (className, header) = classNameAndHeader val (className, header) = classNameAndHeader
if (header.kind == KotlinClassHeader.Kind.PACKAGE_FACADE) { 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) packageFacadeData.put(PackageFacadeId(moduleId, fqName), data)
} }
@@ -198,6 +198,8 @@ public class KotlinBuilder extends ModuleLevelBuilder {
IncrementalCache cache = new IncrementalCache(KotlinBuilderModuleScriptGenerator.getIncrementalCacheDir(context)); IncrementalCache cache = new IncrementalCache(KotlinBuilderModuleScriptGenerator.getIncrementalCacheDir(context));
try { try {
boolean significantChanges = false;
for (SimpleOutputItem outputItem : outputItemCollector.getOutputs()) { for (SimpleOutputItem outputItem : outputItemCollector.getOutputs()) {
BuildTarget<?> target = null; BuildTarget<?> target = null;
Collection<File> sourceFiles = outputItem.getSourceFiles(); Collection<File> sourceFiles = outputItem.getSourceFiles();
@@ -215,7 +217,9 @@ public class KotlinBuilder extends ModuleLevelBuilder {
File outputFile = outputItem.getOutputFile(); File outputFile = outputItem.getOutputFile();
if (IncrementalCompilation.ENABLED) { if (IncrementalCompilation.ENABLED) {
cache.saveFileToCache(target.getId(), outputFile); if (cache.saveFileToCache(target.getId(), outputFile)) {
significantChanges = true;
}
} }
outputConsumer.registerOutputFile(target, outputFile, paths(sourceFiles)); outputConsumer.registerOutputFile(target, outputFile, paths(sourceFiles));
@@ -223,18 +227,21 @@ public class KotlinBuilder extends ModuleLevelBuilder {
if (IncrementalCompilation.ENABLED) { if (IncrementalCompilation.ENABLED) {
// TODO should mark dependencies as dirty, as well // TODO should mark dependencies as dirty, as well
FSOperations.markDirty(context, chunk, new FileFilter() { if (significantChanges) {
@Override FSOperations.markDirty(context, chunk, new FileFilter() {
public boolean accept(@NotNull File file) { @Override
return !allCompiledFiles.contains(file); public boolean accept(@NotNull File file) {
} return !allCompiledFiles.contains(file);
}); }
});
}
return ExitCode.ADDITIONAL_PASS_REQUIRED; return ExitCode.ADDITIONAL_PASS_REQUIRED;
} }
else { else {
return ExitCode.OK; return ExitCode.OK;
} }
} finally { }
finally {
cache.close(); cache.close();
} }
} }
@@ -108,6 +108,14 @@ public class IncrementalJpsTest : JpsBuildTestCase() {
doTest() doTest()
} }
fun testReturnTypeChanged() {
doTest()
}
fun testTopLevelFunctionSameSignature() {
doTest()
}
private class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase() { private class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase() {
private val logBuf = StringBuilder() private val logBuf = StringBuilder()
public val log: String public val log: String
@@ -4,9 +4,3 @@ End of files
Compiling files: Compiling files:
src/Foo.kt src/Foo.kt
End of files End of files
Cleaning output files:
out/production/module/test/Bar.class
End of files
Compiling files:
src/Bar.kt
End of files
@@ -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
@@ -0,0 +1,4 @@
package test
fun foo() {
}
@@ -0,0 +1,3 @@
package test
fun foo(): String = ":)"
@@ -0,0 +1,5 @@
package test
fun usage() {
foo()
}
@@ -5,9 +5,3 @@ End of files
Compiling files: Compiling files:
src/Foo.kt src/Foo.kt
End of files End of files
Cleaning output files:
out/production/module/test/Bar.class
End of files
Compiling files:
src/Bar.kt
End of files
@@ -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
@@ -0,0 +1,4 @@
package test
fun foo() {
}
@@ -0,0 +1,5 @@
package test
fun foo() {
println("body is changed, but it doesn't matter, we won't rebuild dependencies")
}
@@ -0,0 +1,5 @@
package test
fun usage() {
foo()
}
@@ -5,10 +5,3 @@ End of files
Compiling files: Compiling files:
src/a.kt src/a.kt
End of files 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