[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.File
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
fun IdeaKotlinClasspath(files: Iterable<File>): IdeaKotlinClasspath = IdeaKotlinClasspath.from(files)
|
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
|
private const val serialVersionUID = 0L
|
||||||
|
|
||||||
fun normalise(file: File): File {
|
fun normalise(file: File): File {
|
||||||
return file.absoluteFile.normalize()
|
val normalized = file.absoluteFile.normalize()
|
||||||
|
return intern(normalized)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun from(files: Iterable<File>): IdeaKotlinClasspath {
|
fun from(files: Iterable<File>): IdeaKotlinClasspath {
|
||||||
@@ -88,5 +91,14 @@ class IdeaKotlinClasspath private constructor(private val files: MutableSet<File
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun empty() = IdeaKotlinClasspath(mutableSetOf())
|
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 org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinClasspath
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.test.Test
|
import kotlin.test.*
|
||||||
import kotlin.test.assertEquals
|
|
||||||
import kotlin.test.assertNotEquals
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class IdeaKotlinClasspathTest {
|
class IdeaKotlinClasspathTest {
|
||||||
|
|
||||||
@@ -62,4 +59,19 @@ class IdeaKotlinClasspathTest {
|
|||||||
classpath.remove(File("test").absoluteFile)
|
classpath.remove(File("test").absoluteFile)
|
||||||
assertTrue(classpath.isEmpty())
|
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