[Gradle] Implement IdeaKotlinClasspath interner
This very simple interner mechanism ensures that when import runs within the IDE process, we de-duplicate existing file instances. This might have an effect, because during GradleProjectResolution we could have plenty source sets that refer to the same files. ^KT-55492 Verification Pending
This commit is contained in:
committed by
Space Team
parent
e32cff3b38
commit
38f310467a
+13
-1
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.idea.tcs
|
||||
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
fun IdeaKotlinClasspath(files: Iterable<File>): IdeaKotlinClasspath = IdeaKotlinClasspath.from(files)
|
||||
|
||||
@@ -76,7 +78,8 @@ class IdeaKotlinClasspath private constructor(private val files: MutableSet<File
|
||||
private const val serialVersionUID = 0L
|
||||
|
||||
fun normalise(file: File): File {
|
||||
return file.absoluteFile.normalize()
|
||||
val normalized = file.absoluteFile.normalize()
|
||||
return intern(normalized)
|
||||
}
|
||||
|
||||
fun from(files: Iterable<File>): IdeaKotlinClasspath {
|
||||
@@ -88,5 +91,14 @@ class IdeaKotlinClasspath private constructor(private val files: MutableSet<File
|
||||
}
|
||||
|
||||
fun empty() = IdeaKotlinClasspath(mutableSetOf())
|
||||
|
||||
private val interner = WeakHashMap<File, WeakReference<File>>()
|
||||
|
||||
private fun intern(file: File): File {
|
||||
return interner.getOrPut(file) { WeakReference(file) }.get() ?: run {
|
||||
interner[file] = WeakReference(file)
|
||||
file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-4
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.gradle.idea.test.tcs
|
||||
|
||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinClasspath
|
||||
import java.io.File
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.*
|
||||
|
||||
class IdeaKotlinClasspathTest {
|
||||
|
||||
@@ -62,4 +59,19 @@ class IdeaKotlinClasspathTest {
|
||||
classpath.remove(File("test").absoluteFile)
|
||||
assertTrue(classpath.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - classpath interner`() {
|
||||
val classpath1 = IdeaKotlinClasspath()
|
||||
val classpath2 = IdeaKotlinClasspath()
|
||||
|
||||
val fileAInstance1 = File("a")
|
||||
val fileAInstance2 = File("a")
|
||||
|
||||
classpath1.add(fileAInstance1)
|
||||
classpath2.add(fileAInstance2)
|
||||
|
||||
/* Check that fileAInstance2 got interned and will re-use instance 1 */
|
||||
assertSame(classpath1.single(), classpath2.single())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user