[AA] ensure psi files from stdlib do not leak

This commit is contained in:
Anna Kozlova
2023-05-31 15:49:01 +02:00
committed by teamcity
parent 4d97e4c572
commit 86bed92a46
@@ -17,10 +17,11 @@ import com.intellij.psi.PsiManager
import com.intellij.psi.SingleRootFileViewProvider
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StubElement
import com.intellij.util.containers.CollectionFactory
import com.intellij.util.containers.CollectionFactory.createConcurrentWeakValueMap
import com.intellij.util.indexing.FileContent
import com.intellij.util.indexing.FileContentImpl
import com.intellij.util.io.URLUtil
import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInDecompiler
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
import org.jetbrains.kotlin.analysis.decompiler.stub.file.KotlinClsStubBuilder
@@ -306,35 +307,30 @@ public class KotlinStaticDeclarationProviderFactory(
val binaryClassCache = ClsKotlinBinaryClassCache.getInstance()
for (root in additionalRoots) {
KotlinFakeClsStubsCache.processAdditionalRoot(root) { additionalRoot ->
val stubs = mutableListOf<KotlinFileStubImpl>()
val stubs = hashMapOf<VirtualFile, KotlinFileStubImpl>()
VfsUtilCore.visitChildrenRecursively(additionalRoot, object : VirtualFileVisitor<Void>() {
override fun visitFile(file: VirtualFile): Boolean {
if (!file.isDirectory) {
val fileContent = FileContentImpl.createByFile(file)
if (!binaryClassCache.isKotlinJvmCompiledFile(file, fileContent.content)) return true
val stub: KotlinFileStubImpl = when {
file.fileType == JavaClassFileType.INSTANCE -> {
if (!binaryClassCache.isKotlinJvmCompiledFile(file, fileContent.content)) return true
KotlinClsStubBuilder().buildFileStub(fileContent) as? KotlinFileStubImpl ?: return true
}
file.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION -> {
if (!builtins.add(file.name)) return true
builtInDecompiler.stubBuilder.buildFileStub(fileContent) as? KotlinFileStubImpl ?: return true
}
else -> return true
if (binaryClassCache.isKotlinJvmCompiledFile(file, fileContent.content) &&
file.fileType == JavaClassFileType.INSTANCE
) {
(KotlinClsStubBuilder().buildFileStub(fileContent) as? KotlinFileStubImpl)?.let { stubs.put(file, it) }
}
val fakeFile = object : KtFile(KtClassFileViewProvider(psiManager, fileContent.file), isCompiled = true) {
override fun getStub() = stub
override fun isPhysical() = false
}
stub.psi = fakeFile
stubs.add(stub)
}
return true
}
})
stubs
}?.forEach { processStub(it) }
}?.forEach { entry ->
val stub = entry.value
val fakeFile = object : KtFile(KtClassFileViewProvider(psiManager, entry.key), isCompiled = true) {
override fun getStub() = stub
override fun isPhysical() = false
}
stub.psi = fakeFile
processStub(stub)
}
}
// Indexing user source files
@@ -354,10 +350,13 @@ public class KotlinStaticDeclarationProviderFactory(
* Otherwise, each test would start indexing of stdlib from scratch,
* and under the lock which makes tests extremely slow*/
public class KotlinFakeClsStubsCache {
private val fakeFileClsStubs = CollectionFactory.createConcurrentWeakValueMap<String, List<KotlinFileStubImpl>>()
private val fakeFileClsStubs = ConcurrentHashMap<String, Map<VirtualFile, KotlinFileStubImpl>>()
public companion object {
public fun processAdditionalRoot(root: VirtualFile, storage: (VirtualFile) -> List<KotlinFileStubImpl>): List<KotlinFileStubImpl>? {
public fun processAdditionalRoot(
root: VirtualFile,
storage: (VirtualFile) -> Map<VirtualFile, KotlinFileStubImpl>
): Map<VirtualFile, KotlinFileStubImpl>? {
val service = ApplicationManager.getApplication().getService(KotlinFakeClsStubsCache::class.java) ?: return null
if (service.fakeFileClsStubs[root.path] == null) {
service.fakeFileClsStubs[root.path] = storage(root)