[IC] Refactor IC maps to reuse code and ensure consistency - Part 2
In commit 4e89dcf, we have prepared the API for IC maps in top
interfaces and provide the implementation in abstract classes.
In this commit, we refactor IC maps so that they directly inherit/reuse
the implementation from the superclasses without having to reimplement
the APIs for a map.
Test: Existing tests (refactoring change)
^KT-63456: In progress
Authored-by: Hung Nguyen <hungnv@google.com>
Merge-request: KOTLIN-MR-801
Merged-by: Evgenii Mazhukin <evgenii.mazhukin@jetbrains.com>
This commit is contained in:
+1
-8
@@ -50,20 +50,13 @@ abstract class IncrementalCachesManager<PlatformCache : AbstractIncrementalCache
|
||||
|
||||
val closer = Closer.create()
|
||||
caches.forEach {
|
||||
closer.register(CacheCloser(it))
|
||||
closer.register(it)
|
||||
}
|
||||
closer.close()
|
||||
|
||||
isClosed = true
|
||||
}
|
||||
|
||||
private class CacheCloser(private val cache: BasicMapsOwner) : Closeable {
|
||||
|
||||
override fun close() {
|
||||
cache.close()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open class IncrementalJvmCachesManager(
|
||||
|
||||
+3
-3
@@ -38,8 +38,8 @@ import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.parsing.classesFqNames
|
||||
import org.jetbrains.kotlin.incremental.storage.BasicFileToPathConverter
|
||||
import org.jetbrains.kotlin.incremental.storage.FileLocations
|
||||
import org.jetbrains.kotlin.incremental.storage.FileToAbsolutePathConverter
|
||||
import org.jetbrains.kotlin.incremental.util.BufferingMessageCollector
|
||||
import org.jetbrains.kotlin.incremental.util.ExceptionLocation
|
||||
import org.jetbrains.kotlin.incremental.util.reportException
|
||||
@@ -90,8 +90,8 @@ abstract class IncrementalCompilerRunner<
|
||||
fileLocations: FileLocations?,
|
||||
transaction: CompilationTransaction,
|
||||
) = IncrementalCompilationContext(
|
||||
pathConverterForSourceFiles = fileLocations?.let { it.getRelocatablePathConverterForSourceFiles() } ?: FileToAbsolutePathConverter,
|
||||
pathConverterForOutputFiles = fileLocations?.let { it.getRelocatablePathConverterForOutputFiles() } ?: FileToAbsolutePathConverter,
|
||||
pathConverterForSourceFiles = fileLocations?.let { it.getRelocatablePathConverterForSourceFiles() } ?: BasicFileToPathConverter,
|
||||
pathConverterForOutputFiles = fileLocations?.let { it.getRelocatablePathConverterForOutputFiles() } ?: BasicFileToPathConverter,
|
||||
transaction = transaction,
|
||||
reporter = reporter,
|
||||
trackChangesInLookupCache = shouldTrackChangesInLookupCache,
|
||||
|
||||
+2
-2
@@ -52,7 +52,7 @@ class InputsCache(
|
||||
// generatedFiles can contain multiple entries with the same source file
|
||||
// for example Kapt3 IC will generate a .java stub and .class stub for each source file
|
||||
fun registerOutputForSourceFiles(generatedFiles: List<GeneratedFile>) {
|
||||
val sourceToOutput = MultiMap<File, File>()
|
||||
val sourceToOutput = MultiMap.createLinked<File, File>()
|
||||
|
||||
for (generatedFile in generatedFiles) {
|
||||
for (source in generatedFile.sourceFiles) {
|
||||
@@ -61,7 +61,7 @@ class InputsCache(
|
||||
}
|
||||
|
||||
for ((source, outputs) in sourceToOutput.entrySet()) {
|
||||
sourceToOutputMap[source] = outputs
|
||||
sourceToOutputMap[source] = outputs.toSet()
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-17
@@ -18,41 +18,39 @@ package org.jetbrains.kotlin.incremental.snapshots
|
||||
|
||||
import org.jetbrains.kotlin.incremental.ChangedFiles
|
||||
import org.jetbrains.kotlin.incremental.IncrementalCompilationContext
|
||||
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
|
||||
import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor
|
||||
import org.jetbrains.kotlin.incremental.storage.AbstractBasicMap
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
class FileSnapshotMap(
|
||||
storageFile: File,
|
||||
icContext: IncrementalCompilationContext,
|
||||
) : BasicStringMap<FileSnapshot>(storageFile, PathStringDescriptor, FileSnapshotExternalizer, icContext) {
|
||||
|
||||
override fun dumpValue(value: FileSnapshot): String =
|
||||
value.toString()
|
||||
|
||||
) : AbstractBasicMap<File, FileSnapshot>(
|
||||
storageFile,
|
||||
icContext.fileDescriptorForSourceFiles,
|
||||
FileSnapshotExternalizer,
|
||||
icContext
|
||||
) {
|
||||
@Synchronized
|
||||
fun compareAndUpdate(newFiles: Iterable<File>): ChangedFiles.Known {
|
||||
val snapshotProvider = SimpleFileSnapshotProviderImpl()
|
||||
val newOrModified = ArrayList<File>()
|
||||
val removed = ArrayList<File>()
|
||||
|
||||
val newPaths = newFiles.mapTo(HashSet(), transform = pathConverter::toPath)
|
||||
for (oldPath in storage.keys) {
|
||||
if (oldPath !in newPaths) {
|
||||
storage.remove(oldPath)
|
||||
removed.add(pathConverter.toFile(oldPath))
|
||||
val newFilesSet = newFiles.toSet()
|
||||
for (oldFile in keys) {
|
||||
if (oldFile !in newFilesSet) {
|
||||
remove(oldFile)
|
||||
removed.add(oldFile)
|
||||
}
|
||||
}
|
||||
|
||||
for (path in newPaths) {
|
||||
val file = pathConverter.toFile(path)
|
||||
val oldSnapshot = storage[path]
|
||||
for (file in newFilesSet) {
|
||||
val oldSnapshot = this[file]
|
||||
val newSnapshot = snapshotProvider[file]
|
||||
|
||||
if (oldSnapshot == null || oldSnapshot != newSnapshot) {
|
||||
newOrModified.add(file)
|
||||
storage[path] = newSnapshot
|
||||
this[file] = newSnapshot
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-15
@@ -6,24 +6,21 @@
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.IncrementalCompilationContext
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import java.io.File
|
||||
|
||||
class SourceToOutputFilesMap(
|
||||
storageFile: File,
|
||||
icContext: IncrementalCompilationContext,
|
||||
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer, icContext) {
|
||||
operator fun set(sourceFile: File, outputFiles: Collection<File>) {
|
||||
storage[icContext.pathConverterForSourceFiles.toPath(sourceFile)] =
|
||||
outputFiles.toSet().map(icContext.pathConverterForOutputFiles::toPath)
|
||||
) : AppendableSetBasicMap<File, File>(
|
||||
storageFile,
|
||||
icContext.fileDescriptorForSourceFiles,
|
||||
icContext.fileDescriptorForOutputFiles,
|
||||
icContext
|
||||
) {
|
||||
@Synchronized
|
||||
fun getAndRemove(sourceFile: File): Set<File>? {
|
||||
return get(sourceFile).also {
|
||||
remove(sourceFile)
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(sourceFile: File): Collection<File>? =
|
||||
storage[icContext.pathConverterForSourceFiles.toPath(sourceFile)]?.map(icContext.pathConverterForOutputFiles::toFile)
|
||||
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
|
||||
fun getAndRemove(file: File): Collection<File>? =
|
||||
get(file).also { storage.remove(icContext.pathConverterForSourceFiles.toPath(file)) }
|
||||
}
|
||||
}
|
||||
|
||||
+21
-17
@@ -60,49 +60,53 @@ class SourceToOutputFilesMapTest {
|
||||
|
||||
@Test
|
||||
fun testSetOneGetReturnsOne() {
|
||||
stofMap[fooDotKt] = listOf(fooDotClass)
|
||||
stofMap[fooDotKt] = setOf(fooDotClass)
|
||||
|
||||
assertEquals(listOf(fooDotClass), stofMap[fooDotKt])
|
||||
assertEquals(setOf(fooDotClass), stofMap[fooDotKt])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetDupeGetReturnsUnique() {
|
||||
stofMap[fooDotKt] = listOf(fooDotClass, fooDotClass)
|
||||
stofMap.append(fooDotKt, fooDotClass)
|
||||
stofMap.append(fooDotKt, fooDotClass)
|
||||
|
||||
assertEquals(listOf(fooDotClass), stofMap[fooDotKt])
|
||||
assertEquals(setOf(fooDotClass), stofMap[fooDotKt])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetOverwriteGetReturnsNew() {
|
||||
val fooKtDotClass = classesDir.resolve("FooKt.class")
|
||||
stofMap[fooDotKt] = listOf(fooDotClass)
|
||||
stofMap[fooDotKt] = listOf(fooKtDotClass)
|
||||
stofMap[fooDotKt] = setOf(fooDotClass)
|
||||
stofMap[fooDotKt] = setOf(fooKtDotClass)
|
||||
|
||||
assertEquals(listOf(fooKtDotClass), stofMap[fooDotKt])
|
||||
assertEquals(setOf(fooKtDotClass), stofMap[fooDotKt])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetRelativeFails() {
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
stofMap[fooDotKt] = listOf(File("relativePath"))
|
||||
fun testSetRelativePathFails() {
|
||||
assertFailsWith<IllegalStateException> {
|
||||
stofMap[fooDotKt] = setOf(File("relativePath"))
|
||||
}
|
||||
assertFailsWith<IllegalStateException> {
|
||||
stofMap[File("relativePath")] = setOf(fooDotClass)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetRelativeFails() {
|
||||
stofMap[fooDotKt] = listOf(fooDotClass)
|
||||
fun testGetRelativePathFails() {
|
||||
stofMap[fooDotKt] = setOf(fooDotClass)
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
stofMap[fooDotKt.relativeTo(srcDir)]
|
||||
assertFailsWith<IllegalStateException> {
|
||||
stofMap[File("relativePath")]
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetAndRemove() {
|
||||
stofMap[fooDotKt] = listOf(fooDotClass)
|
||||
stofMap[fooDotKt] = setOf(fooDotClass)
|
||||
|
||||
assertEquals(listOf(fooDotClass), stofMap.getAndRemove(fooDotKt))
|
||||
assertEquals(setOf(fooDotClass), stofMap.getAndRemove(fooDotKt))
|
||||
assertNull(stofMap[fooDotKt])
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user