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