mirror of
https://github.com/ilyakooo0/intellij-haskell.git
synced 2024-09-11 14:56:19 +03:00
Workaround to give right compilation result when file is not changed but annotator is triggered.
This commit is contained in:
parent
42ddd7386b
commit
6c58cb4cb6
@ -30,9 +30,9 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.source.tree.TreeUtil
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.{PsiElement, PsiFile}
|
||||
import intellij.haskell.editor.{HaskellImportOptimizer, HaskellProblemsView}
|
||||
import intellij.haskell.external.component.{StackProjectManager, _}
|
||||
import intellij.haskell.external.execution._
|
||||
@ -45,9 +45,9 @@ import scala.annotation.tailrec
|
||||
import scala.collection.Iterable
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
class HaskellAnnotator extends ExternalAnnotator[(PsiFile, Option[PsiElement]), CompilationResult] {
|
||||
class HaskellAnnotator extends ExternalAnnotator[PsiFile, CompilationResult] {
|
||||
|
||||
override def collectInformation(psiFile: PsiFile, editor: Editor, hasErrors: Boolean): (PsiFile, Option[PsiElement]) = {
|
||||
override def collectInformation(psiFile: PsiFile, editor: Editor, hasErrors: Boolean): PsiFile = {
|
||||
if (HaskellConsoleView.isConsoleFile(psiFile) || !HaskellProjectUtil.isSourceFile(psiFile)) {
|
||||
null
|
||||
} else if (StackProjectManager.isInitializing(psiFile.getProject)) {
|
||||
@ -61,24 +61,27 @@ class HaskellAnnotator extends ExternalAnnotator[(PsiFile, Option[PsiElement]),
|
||||
case (_, None) => null // can be in case if file is in memory only (just created file)
|
||||
case (_, Some(f)) if f.getFileType != HaskellFileType.Instance => null
|
||||
case (_, Some(_)) if !psiFile.isValid => null
|
||||
case (_, Some(_)) =>
|
||||
val currentElement = Option(psiFile.findElementAt(editor.getCaretModel.getOffset)).
|
||||
find(e => HaskellPsiUtil.findExpression(e).isDefined).
|
||||
flatMap(e => Option(PsiTreeUtil.prevVisibleLeaf(e))).filter(_.isValid)
|
||||
(psiFile, currentElement)
|
||||
case (_, Some(_)) => psiFile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def doAnnotate(psiFileElement: (PsiFile, Option[PsiElement])): CompilationResult = {
|
||||
val psiFile = psiFileElement._1
|
||||
// Workaround in case annotator is triggered but file is not changed.
|
||||
// In this case the result of REPL load is always empty.
|
||||
private var prevResult: Option[(PsiFile, CompilationResult)] = None
|
||||
|
||||
override def doAnnotate(psiFile: PsiFile): CompilationResult = {
|
||||
HaskellFileUtil.findVirtualFile(psiFile) match {
|
||||
case Some(virtualFile) =>
|
||||
val fileChanged = FileDocumentManager.getInstance().isFileModified(virtualFile)
|
||||
if (fileChanged) {
|
||||
HaskellFileUtil.saveFileInDispatchThread(psiFile.getProject, virtualFile)
|
||||
prevResult match {
|
||||
case Some((pf, r)) if !fileChanged && psiFile == pf => r
|
||||
case _ =>
|
||||
HaskellFileUtil.saveFileInDispatchThread(psiFile.getProject, virtualFile)
|
||||
val result = HaskellComponentsManager.loadHaskellFile(psiFile).orNull
|
||||
prevResult = Some((psiFile, result))
|
||||
result
|
||||
}
|
||||
HaskellComponentsManager.loadHaskellFile(psiFile, fileChanged, psiFileElement._2).orNull
|
||||
case None => CompilationResult(Iterable(), Iterable(), failed = false)
|
||||
}
|
||||
}
|
||||
|
@ -131,8 +131,8 @@ object HaskellComponentsManager {
|
||||
StackReplsManager.getReplsManager(project).map(_.moduleCabalInfos.map { case (_, ci) => ci }).getOrElse(Iterable())
|
||||
}
|
||||
|
||||
def loadHaskellFile(psiFile: PsiFile, fileChanged: Boolean, psiElement: Option[PsiElement]): Option[CompilationResult] = {
|
||||
LoadComponent.load(psiFile, fileChanged, psiElement)
|
||||
def loadHaskellFile(psiFile: PsiFile): Option[CompilationResult] = {
|
||||
LoadComponent.load(psiFile)
|
||||
}
|
||||
|
||||
def invalidateFileInfos(psiFile: PsiFile): Unit = {
|
||||
|
@ -18,7 +18,7 @@ package intellij.haskell.external.component
|
||||
|
||||
import com.intellij.codeInsight.documentation.DocumentationManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.psi.{PsiElement, PsiFile}
|
||||
import com.intellij.psi.PsiFile
|
||||
import intellij.haskell.external.execution.{CompilationResult, HaskellCompilationResultHelper}
|
||||
import intellij.haskell.external.repl.ProjectStackRepl.Loaded
|
||||
import intellij.haskell.external.repl._
|
||||
@ -37,7 +37,7 @@ private[component] object LoadComponent {
|
||||
}.contains(true)
|
||||
}
|
||||
|
||||
def load(psiFile: PsiFile, fileChanged: Boolean, currentElement: Option[PsiElement]): Option[CompilationResult] = {
|
||||
def load(psiFile: PsiFile): Option[CompilationResult] = {
|
||||
val project = psiFile.getProject
|
||||
|
||||
StackReplsManager.getProjectRepl(psiFile).flatMap(projectRepl => {
|
||||
@ -51,7 +51,7 @@ private[component] object LoadComponent {
|
||||
|
||||
ProjectLibraryFileWatcher.checkLibraryBuild(project, projectRepl.stackComponentInfo)
|
||||
|
||||
projectRepl.load(psiFile, Some(fileChanged)) match {
|
||||
projectRepl.load(psiFile) match {
|
||||
case Some((loadOutput, loadFailed)) =>
|
||||
ApplicationManager.getApplication.executeOnPooledThread(ScalaUtil.runnable {
|
||||
|
||||
|
@ -136,9 +136,9 @@ case class ProjectStackRepl(project: Project, stackComponentInfo: StackComponent
|
||||
loadedModuleNames.foreach(mn => everLoadedDependentModules.put(mn, DependentModuleInfo()))
|
||||
}
|
||||
|
||||
def load(psiFile: PsiFile, fileChanged: Option[Boolean], mustBeByteCode: Boolean = false): Option[(StackReplOutput, Boolean)] = synchronized {
|
||||
def load(psiFile: PsiFile, mustBeByteCode: Boolean = false): Option[(StackReplOutput, Boolean)] = synchronized {
|
||||
val forceBytecodeLoad = if (mustBeByteCode) objectCodeEnabled else false
|
||||
val reload = if (fileChanged.contains(true) && !forceBytecodeLoad) {
|
||||
val reload = if (!forceBytecodeLoad) {
|
||||
val loaded = isFileLoaded(psiFile)
|
||||
loaded == Loaded || loaded == Failed
|
||||
} else {
|
||||
@ -186,7 +186,7 @@ case class ProjectStackRepl(project: Project, stackComponentInfo: StackComponent
|
||||
}
|
||||
|
||||
def getModuleIdentifiers(moduleName: String, psiFile: Option[PsiFile]): Option[StackReplOutput] = synchronized {
|
||||
if (psiFile.isEmpty || isBrowseModuleLoaded(moduleName) || psiFile.exists(pf => load(pf, None).exists(_._2 == false))) {
|
||||
if (psiFile.isEmpty || isBrowseModuleLoaded(moduleName) || psiFile.exists(pf => load(pf).exists(_._2 == false))) {
|
||||
execute(s":browse! $moduleName")
|
||||
} else {
|
||||
HaskellNotificationGroup.logInfoEvent(project, s"Could not get module identifiers for module $moduleName because file ${psiFile.map(_.getName).getOrElse("-")} is not loaded")
|
||||
@ -214,7 +214,7 @@ case class ProjectStackRepl(project: Project, stackComponentInfo: StackComponent
|
||||
case Some(info) if info.psiFile == psiFile & !info.loadFailed & (if (mustBeByteCode) !objectCodeEnabled else true) => execute(command)
|
||||
case Some(info) if info.psiFile == psiFile & info.loadFailed => Some(StackReplOutput())
|
||||
case _ =>
|
||||
load(psiFile, fileChanged = None, mustBeByteCode)
|
||||
load(psiFile, mustBeByteCode)
|
||||
loadedFile match {
|
||||
case None => None
|
||||
case Some(info) if info.psiFile == psiFile && !info.loadFailed => execute(command)
|
||||
|
Loading…
Reference in New Issue
Block a user