Inline function changed – rebuild all chunk.
Original commit: aa9f7a73c9
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.jet.jps.build;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
@@ -237,7 +236,7 @@ public class KotlinBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
cache.clearCacheForRemovedFiles(moduleIdsAndFiles, outDirectories);
|
||||
|
||||
boolean significantChanges = false;
|
||||
IncrementalCacheImpl.RecompilationDecision recompilationDecision = IncrementalCacheImpl.RecompilationDecision.DO_NOTHING;
|
||||
|
||||
for (SimpleOutputItem outputItem : outputItemCollector.getOutputs()) {
|
||||
BuildTarget<?> target = null;
|
||||
@@ -253,17 +252,20 @@ public class KotlinBuilder extends ModuleLevelBuilder {
|
||||
File outputFile = outputItem.getOutputFile();
|
||||
|
||||
if (IncrementalCompilation.ENABLED) {
|
||||
if (cache.saveFileToCache(target.getId(), sourceFiles, outputFile)) {
|
||||
significantChanges = true;
|
||||
}
|
||||
IncrementalCacheImpl.RecompilationDecision newDecision = cache.saveFileToCache(target.getId(), sourceFiles, outputFile);
|
||||
recompilationDecision = recompilationDecision.merge(newDecision);
|
||||
}
|
||||
|
||||
outputConsumer.registerOutputFile(target, outputFile, paths(sourceFiles));
|
||||
}
|
||||
|
||||
if (IncrementalCompilation.ENABLED) {
|
||||
// TODO should mark dependencies as dirty, as well
|
||||
if (significantChanges) {
|
||||
if (recompilationDecision == IncrementalCacheImpl.RecompilationDecision.RECOMPILE_ALL) {
|
||||
allCompiledFiles.clear();
|
||||
return ExitCode.CHUNK_REBUILD_REQUIRED;
|
||||
}
|
||||
if (recompilationDecision == IncrementalCacheImpl.RecompilationDecision.COMPILE_OTHERS) {
|
||||
// TODO should mark dependencies as dirty, as well
|
||||
FSOperations.markDirty(context, chunk, new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(@NotNull File file) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.jps.incremental
|
||||
|
||||
import org.jetbrains.jet.jps.incremental.IncrementalCacheImpl.RecompilationDecision.*
|
||||
import java.io.File
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.DataOutput
|
||||
@@ -56,10 +57,10 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache {
|
||||
private val inlineFunctionsMap = InlineFunctionsMap()
|
||||
private val packagePartMap = PackagePartMap()
|
||||
|
||||
public fun saveFileToCache(moduleId: String, sourceFiles: Collection<File>, classFile: File): Boolean {
|
||||
public fun saveFileToCache(moduleId: String, sourceFiles: Collection<File>, classFile: File): RecompilationDecision {
|
||||
val fileBytes = classFile.readBytes()
|
||||
val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(fileBytes)
|
||||
if (classNameAndHeader == null) return false
|
||||
if (classNameAndHeader == null) return RecompilationDecision.DO_NOTHING
|
||||
|
||||
val (className, header) = classNameAndHeader
|
||||
val annotationDataEncoded = header.annotationData
|
||||
@@ -67,10 +68,13 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache {
|
||||
val data = BitEncoding.decodeBytes(annotationDataEncoded)
|
||||
when (header.kind) {
|
||||
KotlinClassHeader.Kind.PACKAGE_FACADE -> {
|
||||
return protoMap.put(moduleId, className, data)
|
||||
return if (protoMap.put(moduleId, className, data)) COMPILE_OTHERS else DO_NOTHING
|
||||
}
|
||||
KotlinClassHeader.Kind.CLASS -> {
|
||||
return inlineFunctionsMap.process(moduleId, sourceFiles.first(), fileBytes) or protoMap.put(moduleId, className, data)
|
||||
val inlinesChanged = inlineFunctionsMap.process(moduleId, sourceFiles.first(), fileBytes)
|
||||
val protoChanged = protoMap.put(moduleId, className, data)
|
||||
|
||||
return if (inlinesChanged) RECOMPILE_ALL else if (protoChanged) COMPILE_OTHERS else DO_NOTHING
|
||||
}
|
||||
else -> {
|
||||
throw IllegalStateException("Unexpected kind with annotationData: ${header.kind}")
|
||||
@@ -80,10 +84,12 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache {
|
||||
if (header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART) {
|
||||
assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" }
|
||||
packagePartMap.putPackagePartSourceData(moduleId, sourceFiles.first(), className)
|
||||
return inlineFunctionsMap.process(moduleId, sourceFiles.first(), fileBytes) or constantsMap.process(moduleId, sourceFiles.first(), fileBytes)
|
||||
val inlinesChanged = inlineFunctionsMap.process(moduleId, sourceFiles.first(), fileBytes)
|
||||
val constantsChanged = constantsMap.process(moduleId, sourceFiles.first(), fileBytes)
|
||||
return if (inlinesChanged) RECOMPILE_ALL else if (constantsChanged) COMPILE_OTHERS else DO_NOTHING
|
||||
}
|
||||
|
||||
return false
|
||||
return DO_NOTHING
|
||||
}
|
||||
|
||||
public fun clearCacheForRemovedFiles(moduleIdsAndFiles: Collection<Pair<String, File>>, outDirectories: Map<String, File>) {
|
||||
@@ -286,7 +292,7 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache {
|
||||
return moduleId + File.pathSeparator + sourceFile.getAbsolutePath()
|
||||
}
|
||||
|
||||
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long> {
|
||||
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long>? {
|
||||
val result = HashMap<String, Long>()
|
||||
|
||||
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
|
||||
@@ -315,21 +321,23 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache {
|
||||
|
||||
}, 0)
|
||||
|
||||
return result
|
||||
return if (result.isEmpty()) null else result
|
||||
}
|
||||
|
||||
public fun process(moduleId: String, file: File, bytes: ByteArray): Boolean {
|
||||
return put(moduleId, file, getInlineFunctionsMap(bytes))
|
||||
}
|
||||
|
||||
private fun put(moduleId: String, file: File, inlineFunctionsMap: Map<String, Long>): Boolean {
|
||||
private fun put(moduleId: String, file: File, inlineFunctionsMap: Map<String, Long>?): Boolean {
|
||||
val key = getKey(moduleId, file)
|
||||
|
||||
val oldMap = map[key]
|
||||
if (oldMap == inlineFunctionsMap) {
|
||||
return false
|
||||
}
|
||||
map.put(key, inlineFunctionsMap)
|
||||
if (inlineFunctionsMap != null) {
|
||||
map.put(key, inlineFunctionsMap)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -436,6 +444,16 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache {
|
||||
map.close()
|
||||
}
|
||||
}
|
||||
|
||||
enum class RecompilationDecision {
|
||||
DO_NOTHING
|
||||
COMPILE_OTHERS
|
||||
RECOMPILE_ALL
|
||||
|
||||
fun merge(other: RecompilationDecision): RecompilationDecision {
|
||||
return if (other.ordinal() > this.ordinal()) other else this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object ByteArrayExternalizer: DataExternalizer<ByteArray> {
|
||||
|
||||
@@ -105,7 +105,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
||||
public void testIndependentClasses() throws Exception {
|
||||
doTest("jps-plugin/testData/incremental/independentClasses/");
|
||||
}
|
||||
|
||||
|
||||
@TestMetadata("inlineFunctionsCircularDependency")
|
||||
public void testInlineFunctionsCircularDependency() throws Exception {
|
||||
doTest("jps-plugin/testData/incremental/inlineFunctionsCircularDependency/");
|
||||
}
|
||||
|
||||
@TestMetadata("multiplePackagesModified")
|
||||
public void testMultiplePackagesModified() throws Exception {
|
||||
doTest("jps-plugin/testData/incremental/multiplePackagesModified/");
|
||||
|
||||
@@ -5,9 +5,11 @@ Compiling files:
|
||||
src/inline.kt
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/inline/Klass.class
|
||||
out/production/module/usage/UsagePackage-usage-*.class
|
||||
out/production/module/usage/UsagePackage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/inline.kt
|
||||
src/usage.kt
|
||||
End of files
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package test
|
||||
|
||||
inline fun a(body: () -> Unit) {
|
||||
println("i'm inline function a")
|
||||
body()
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
b { println("to be inlined") }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package test
|
||||
|
||||
inline fun a(body: () -> Unit) {
|
||||
body()
|
||||
println("i'm inline function a")
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
b { println("to be inlined") }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
inline fun b(body: () -> Unit) {
|
||||
println("I'm inline function b")
|
||||
body()
|
||||
a { println("To be inlined from b") }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
Cleaning output files:
|
||||
out/production/module/test/TestPackage-a-*.class
|
||||
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-a-*.class
|
||||
out/production/module/test/TestPackage-b-*.class
|
||||
out/production/module/test/TestPackage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/a.kt
|
||||
src/b.kt
|
||||
End of files
|
||||
@@ -6,9 +6,12 @@ Compiling files:
|
||||
src/inline.kt
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/inline/InlinePackage-inline-*.class
|
||||
out/production/module/inline/InlinePackage.class
|
||||
out/production/module/usage/UsagePackage-usage-*.class
|
||||
out/production/module/usage/UsagePackage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/inline.kt
|
||||
src/usage.kt
|
||||
End of files
|
||||
Reference in New Issue
Block a user