From 374bb1b0215a09ad5ea6b867308c69d9f5a69194 Mon Sep 17 00:00:00 2001 From: Sergey Stoyanovsky Date: Thu, 30 Apr 2020 12:53:54 +0300 Subject: [PATCH] IDEA-239003 Fix PIEAE in NGram IDEA-CR-62219 Use SmartPsiElementPointer in NGramFileListener to survive reparsing GitOrigin-RevId: c21626d554c550d6f8db5c8cf3a43d8a93e5b8d2 --- .../com/intellij/completion/ngram/ModelRunnerWithCache.kt | 7 ++++--- .../src/com/intellij/completion/ngram/NGramFileListener.kt | 5 ++++- .../intellij/completion/ngram/NGramModelRunnerManager.kt | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/stats-collector/src/com/intellij/completion/ngram/ModelRunnerWithCache.kt b/plugins/stats-collector/src/com/intellij/completion/ngram/ModelRunnerWithCache.kt index 15ef7d903104..4112955950a5 100644 --- a/plugins/stats-collector/src/com/intellij/completion/ngram/ModelRunnerWithCache.kt +++ b/plugins/stats-collector/src/com/intellij/completion/ngram/ModelRunnerWithCache.kt @@ -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) { + 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) } diff --git a/plugins/stats-collector/src/com/intellij/completion/ngram/NGramFileListener.kt b/plugins/stats-collector/src/com/intellij/completion/ngram/NGramFileListener.kt index 997616a34c0e..7569657695f4 100644 --- a/plugins/stats-collector/src/com/intellij/completion/ngram/NGramFileListener.kt +++ b/plugins/stats-collector/src/com/intellij/completion/ngram/NGramFileListener.kt @@ -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) } } } diff --git a/plugins/stats-collector/src/com/intellij/completion/ngram/NGramModelRunnerManager.kt b/plugins/stats-collector/src/com/intellij/completion/ngram/NGramModelRunnerManager.kt index 51233dd6b38c..e1564194e287 100644 --- a/plugins/stats-collector/src/com/intellij/completion/ngram/NGramModelRunnerManager.kt +++ b/plugins/stats-collector/src/com/intellij/completion/ngram/NGramModelRunnerManager.kt @@ -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 = mutableMapOf() - fun processFile(file: PsiFile, language: Language) { - myModelRunners.getOrPut(language, { ModelRunnerWithCache() }).processFile(file) + fun processFile(filePointer: SmartPsiElementPointer, language: Language) { + myModelRunners.getOrPut(language, { ModelRunnerWithCache() }).processFile(filePointer) } fun getModelRunnerForLanguage(language: Language): ModelRunner? {