Refactor FIR total resolve in IDE test fixing various problems
Related to KT-24077
This commit is contained in:
committed by
Mikhail Glukhikh
parent
5cef869d36
commit
a6297f5f2f
@@ -5,12 +5,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.fir
|
package org.jetbrains.kotlin.idea.fir
|
||||||
|
|
||||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
import com.intellij.ide.impl.ProjectUtil
|
||||||
import com.intellij.openapi.vfs.VfsUtil
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.application.ex.ApplicationEx
|
||||||
|
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||||
|
import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.search.FileTypeIndex
|
import com.intellij.psi.search.FileTypeIndex
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.testFramework.LightPlatformTestCase
|
||||||
import com.intellij.testFramework.ModuleTestCase
|
import com.intellij.testFramework.ModuleTestCase
|
||||||
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
@@ -22,72 +27,79 @@ import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
|||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.service
|
import org.jetbrains.kotlin.fir.service
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.caches.project.productionSourceInfo
|
import org.jetbrains.kotlin.idea.caches.project.*
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
class FirTotalKotlinResolveInIdeTest : ModuleTestCase() {
|
class FirTotalKotlinResolveInIdeTest : ModuleTestCase() {
|
||||||
private val forbiddenDirectories = listOf("testdata", "resources")
|
private val projectRootFile = File("../testProject")
|
||||||
|
|
||||||
private val projectRootFile = File(".")
|
|
||||||
|
|
||||||
override fun setUpModule() {
|
|
||||||
super.setUpModule()
|
|
||||||
|
|
||||||
ModuleRootModificationUtil.addContentRoot(module, VfsUtil.findFileByIoFile(projectRootFile, true)!!)
|
|
||||||
|
|
||||||
ModuleRootModificationUtil.updateModel(module) {
|
|
||||||
projectRootFile.walkTopDown().onEnter {
|
|
||||||
it.name.toLowerCase() !in forbiddenDirectories
|
|
||||||
}.filter {
|
|
||||||
it.isDirectory
|
|
||||||
}.forEach { dir ->
|
|
||||||
val vdir by lazy { VfsUtil.findFileByIoFile(dir, true)!! }
|
|
||||||
if (dir.name in setOf("src", "test", "tests")) {
|
|
||||||
it.contentEntries.single().addSourceFolder(vdir, false)
|
|
||||||
} else if (dir.name in setOf("build")) {
|
|
||||||
it.contentEntries.single().addExcludeFolder(vdir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
override fun setUpProject() {
|
||||||
|
(ApplicationManager.getApplication() as ApplicationEx).doNotSave()
|
||||||
|
myProject = ProjectUtil.openOrImport(projectRootFile.path, null, false)
|
||||||
|
LightPlatformTestCase.clearUncommittedDocuments(this.project)
|
||||||
|
this.runStartupActivities()
|
||||||
|
(FileTypeManager.getInstance() as FileTypeManagerImpl).drainReDetectQueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSession(): FirSession {
|
private lateinit var sessionProvider: FirProjectSessionProvider
|
||||||
val moduleInfo = module.productionSourceInfo()!!
|
|
||||||
val sessionProvider = FirProjectSessionProvider(project)
|
private fun IdeaModuleInfo.createSession(): FirSession {
|
||||||
|
val moduleInfo = this
|
||||||
|
|
||||||
return FirJavaModuleBasedSession(
|
return FirJavaModuleBasedSession(
|
||||||
moduleInfo, sessionProvider, moduleInfo.contentScope(),
|
moduleInfo, sessionProvider, moduleInfo.contentScope(),
|
||||||
IdeFirDependenciesSymbolProvider(moduleInfo, project, sessionProvider)
|
IdeFirDependenciesSymbolProvider(moduleInfo as ModuleSourceInfo, project, sessionProvider)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T> Collection<T>.progress(label: String, step: Double = 0.1): Sequence<T> {
|
||||||
|
val intStep = (this.size * step).toInt()
|
||||||
|
val percentStep = ceil(this.size * 0.01).toInt()
|
||||||
|
var progress = 0
|
||||||
|
return asSequence().onEach {
|
||||||
|
if (progress % intStep == 0) {
|
||||||
|
println("$label: ${progress / percentStep}% ($progress/${this.size})")
|
||||||
|
}
|
||||||
|
progress++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setUp() {
|
||||||
|
super.setUp()
|
||||||
|
sessionProvider = FirProjectSessionProvider(project)
|
||||||
|
}
|
||||||
|
|
||||||
fun testTotalKotlin() {
|
fun testTotalKotlin() {
|
||||||
val session = createSession()
|
|
||||||
|
|
||||||
val firFiles = mutableListOf<FirFile>()
|
|
||||||
val builder = RawFirBuilder(session, stubMode = true)
|
|
||||||
val psiManager = PsiManager.getInstance(project)
|
val psiManager = PsiManager.getInstance(project)
|
||||||
|
val files = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))
|
||||||
val files = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, GlobalSearchScope.moduleScope(module))
|
val firFiles = mutableListOf<FirFile>()
|
||||||
|
val sessionPerModule = mutableMapOf<ModuleInfo, FirSession>()
|
||||||
|
|
||||||
println("Got vfiles: ${files.size}")
|
println("Got vfiles: ${files.size}")
|
||||||
files.forEach {
|
files.mapNotNull {
|
||||||
val file = psiManager.findFile(it) as? KtFile ?: return@forEach
|
val file = psiManager.findFile(it) as? KtFile ?: return@mapNotNull null
|
||||||
|
val moduleInfo = file.getNullableModuleInfo() as? ModuleSourceInfo ?: return@mapNotNull null
|
||||||
|
file to moduleInfo
|
||||||
|
}.progress("Loading FIR").forEach { (file, moduleInfo) ->
|
||||||
|
|
||||||
|
val session = sessionPerModule.getOrPut(moduleInfo) {
|
||||||
|
moduleInfo.createSession()
|
||||||
|
}
|
||||||
|
val builder = RawFirBuilder(session, stubMode = true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val firFile = builder.buildFirFile(file)
|
val firFile = builder.buildFirFile(file)
|
||||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||||
firFiles += firFile
|
firFiles += firFile
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
System.err.println("Error building fir for $it")
|
System.err.println("Error building fir for $file")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Raw fir up, files: ${firFiles.size}")
|
println("Raw fir up, files: ${firFiles.size}")
|
||||||
|
|
||||||
doFirResolveTestBench(firFiles, FirTotalResolveTransformer().transformers)
|
doFirResolveTestBench(firFiles, FirTotalResolveTransformer().transformers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user