IDEA-239003 Fix PIEAE in NGram IDEA-CR-62219

Use SmartPsiElementPointer in NGramFileListener to survive reparsing

GitOrigin-RevId: c21626d554c550d6f8db5c8cf3a43d8a93e5b8d2
This commit is contained in:
Sergey Stoyanovsky
2020-05-04 21:40:56 +00:00
committed by intellij-monorepo-bot
parent 02a0da5198
commit 374bb1b021
3 changed files with 11 additions and 6 deletions
@@ -8,15 +8,16 @@ import com.intellij.completion.ngram.slp.modeling.Model
import com.intellij.completion.ngram.slp.modeling.ngram.JMModel
import com.intellij.completion.ngram.slp.modeling.runners.ModelRunner
import com.intellij.psi.PsiFile
import com.intellij.psi.SmartPsiElementPointer
internal class ModelRunnerWithCache(model: Model = JMModel()) : ModelRunner(model) {
private val myCache = FilePath2Tokens(this)
internal fun processFile(file: PsiFile) {
val filePath = file.virtualFile.path
internal fun processFile(filePointer: SmartPsiElementPointer<PsiFile>) {
val filePath = filePointer.virtualFile?.path ?: return
if (filePath in myCache) return
val tokens = lexPsiFile(file, TEXT_RANGE_LIMIT)
val tokens = lexPsiFile(filePointer.element ?: return, TEXT_RANGE_LIMIT)
myCache[filePath] = tokens
learnTokens(tokens)
}
@@ -9,6 +9,7 @@ import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import com.intellij.psi.SmartPointerManager
class NGramFileListener(private val project: Project) : FileEditorManagerListener.Before {
@@ -16,9 +17,11 @@ class NGramFileListener(private val project: Project) : FileEditorManagerListene
val psiFile = PsiManager.getInstance(project).findFile(file) ?: return
val language = psiFile.language
if (NGram.isSupported(language)) {
val filePointer = SmartPointerManager.createPointer(psiFile)
ApplicationManager.getApplication().executeOnPooledThread {
DumbService.getInstance(project).runReadActionInSmartMode {
ServiceManager.getService(project, NGramModelRunnerManager::class.java).processFile(psiFile, language)
ServiceManager.getService(project, NGramModelRunnerManager::class.java).processFile(filePointer, language)
SmartPointerManager.getInstance(project).removePointer(filePointer)
}
}
}
@@ -6,13 +6,14 @@ import com.intellij.lang.Language
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.psi.SmartPsiElementPointer
class NGramModelRunnerManager {
private val myModelRunners: MutableMap<Language, ModelRunnerWithCache> = mutableMapOf()
fun processFile(file: PsiFile, language: Language) {
myModelRunners.getOrPut(language, { ModelRunnerWithCache() }).processFile(file)
fun processFile(filePointer: SmartPsiElementPointer<PsiFile>, language: Language) {
myModelRunners.getOrPut(language, { ModelRunnerWithCache() }).processFile(filePointer)
}
fun getModelRunnerForLanguage(language: Language): ModelRunner? {