Varous improvements.

This commit is contained in:
Rik van der Kleij 2019-01-29 20:34:07 +01:00
parent 990a07c112
commit b9d7f259ff
7 changed files with 62 additions and 50 deletions

View File

@ -72,13 +72,15 @@ class HaskellAnnotator extends ExternalAnnotator[(PsiFile, Option[PsiElement]),
override def doAnnotate(psiFileElement: (PsiFile, Option[PsiElement])): CompilationResult = {
val psiFile = psiFileElement._1
val fileChanged = HaskellFileUtil.findVirtualFile(psiFile).exists(FileDocumentManager.getInstance().isFileModified)
if (fileChanged) {
HaskellFileUtil.saveFileInDispatchThread(psiFile)
HaskellFileUtil.findVirtualFile(psiFile) match {
case Some(virtualFile) =>
val fileChanged = FileDocumentManager.getInstance().isFileModified(virtualFile)
if (fileChanged) {
HaskellFileUtil.saveFileInDispatchThread(psiFile.getProject, virtualFile)
}
HaskellComponentsManager.loadHaskellFile(psiFile, fileChanged, psiFileElement._2).orNull
case None => CompilationResult(Iterable(), Iterable(), failed = false)
}
HaskellComponentsManager.loadHaskellFile(psiFile, fileChanged, psiFileElement._2).orNull
}
override def apply(psiFile: PsiFile, loadResult: CompilationResult, holder: AnnotationHolder): Unit = {

View File

@ -254,10 +254,14 @@ private[component] object DefinitionLocationComponent {
} else if (!repl.available) {
Left(ReplNotAvailable)
} else {
f(repl) match {
case Some(o) if o.stderrLines.isEmpty && o.stdoutLines.nonEmpty => Right(o)
case None => Left(ReplNotAvailable)
case _ => Left(NoInfoAvailable(name, psiFile.getName))
if (ApplicationManager.getApplication.isDispatchThread && !LoadComponent.isModuleLoaded(moduleName, psiFile)) {
Left(ModuleNotLoaded(moduleName.getOrElse(psiFile.getName)))
} else {
f(repl) match {
case Some(o) if o.stderrLines.isEmpty && o.stdoutLines.nonEmpty => Right(o)
case None => Left(ReplNotAvailable)
case _ => Left(NoInfoAvailable(name, psiFile.getName))
}
}
}
case None => Left(ReplNotAvailable)

View File

@ -16,8 +16,6 @@
package intellij.haskell.external.component
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import intellij.haskell.external.execution.CommandLine
@ -41,28 +39,18 @@ object HLintComponent {
val hlintOptions = if (HaskellSettingsState.getHlintOptions.trim.isEmpty) Array[String]() else HaskellSettingsState.getHlintOptions.split("""\s+""")
HaskellFileUtil.getAbsolutePath(psiFile) match {
case Some(path) =>
val fileUnsaved = HaskellFileUtil.findDocument(psiFile) match {
case None => true
case Some(d) =>
val deadline = Timeout.fromNow
val deadline = Timeout.fromNow
while (isFileUnsaved(d) && deadline.hasTimeLeft() && !project.isDisposed) {
Thread.sleep(1)
}
isFileUnsaved(d)
while (deadline.hasTimeLeft() && !project.isDisposed) {
Thread.sleep(1)
}
if (fileUnsaved) {
val output = runHLint(project, hlintOptions.toSeq ++ Seq("--json", path), ignoreExitCode = true)
if (output.getExitCode > 0 && output.getStderr.nonEmpty) {
HaskellNotificationGroup.logErrorBalloonEvent(project, s"Error while calling $HLintName: ${output.getStderr}")
Seq()
} else {
val output = runHLint(project, hlintOptions.toSeq ++ Seq("--json", path), ignoreExitCode = true)
if (output.getExitCode > 0 && output.getStderr.nonEmpty) {
HaskellNotificationGroup.logErrorBalloonEvent(project, s"Error while calling $HLintName: ${output.getStderr}")
Seq()
} else {
deserializeHLintInfo(project, output.getStdout)
}
deserializeHLintInfo(project, output.getStdout)
}
case None => ()
HaskellNotificationGroup.logWarningBalloonEvent(psiFile.getProject, s"Can not display HLint suggestions because can not determine path for file `${psiFile.getName}`. File exists only in memory")
@ -74,10 +62,6 @@ object HLintComponent {
}
}
def isFileUnsaved(document: Document): Boolean = {
FileDocumentManager.getInstance().isDocumentUnsaved(document)
}
def versionInfo(project: Project): String = {
if (StackProjectManager.isHlintAvailable(project)) {
runHLint(project, Seq("--version"), ignoreExitCode = false).getStdout

View File

@ -93,6 +93,7 @@ private[component] object NameInfoComponent {
def findNameInfo(qualifiedNameElement: HaskellQualifiedNameElement, importQualifier: Option[String]): NameInfoResult = {
ProgressManager.checkCanceled()
val isReadAccessAllowed = ApplicationManager.getApplication.isReadAccessAllowed
val isDispatchThread = ApplicationManager.getApplication.isDispatchThread
val psiFile = qualifiedNameElement.getContainingFile.getOriginalFile
val qName1 = qualifiedNameElement.getName.replaceAll("""\s+""", "")
@ -114,17 +115,22 @@ private[component] object NameInfoComponent {
case _ => result
}
case None =>
if (isReadAccessAllowed && LoadComponent.isFileLoaded(psiFile)) {
val result = findNameInfos(key)
result match {
case Right(_) =>
Cache.put(key, result)
result
case Left(ReplIsBusy) | Left(ReadActionTimeout(_)) | Left(IndexNotReady) | Left(ReplNotAvailable) | Left(ModuleNotLoaded(_)) =>
result
case Left(_) =>
Cache.put(key, result)
result
if (isReadAccessAllowed) {
ProgressManager.checkCanceled()
if (isDispatchThread && !LoadComponent.isFileLoaded(psiFile)) {
Left(ModuleNotLoaded(psiFile.getName))
} else {
val result = findNameInfos(key)
result match {
case Right(_) =>
Cache.put(key, result)
result
case Left(ReplIsBusy) | Left(ReadActionTimeout(_)) | Left(IndexNotReady) | Left(ReplNotAvailable) | Left(ModuleNotLoaded(_)) =>
result
case Left(_) =>
Cache.put(key, result)
result
}
}
} else {
val result = Cache.get(key)

View File

@ -60,6 +60,7 @@ class HLintInspectionTool extends LocalInspectionTool {
val result = if (hlintCheckFuture.isDone) {
hlintCheckFuture.get()
} else {
ProgressManager.checkCanceled()
Seq()
}
@ -81,7 +82,6 @@ class HLintInspectionTool extends LocalInspectionTool {
case Some(to) if se.isValid && ee.isValid =>
problemsHolder.registerProblem(new ProblemDescriptorBase(se, ee, hi.hint, Array(createQuickfix(hi, se, ee, sl, el, to)), problemType, false, null, true, isOnTheFly))
case None =>
ProgressManager.checkCanceled()
problemsHolder.registerProblem(new ProblemDescriptorBase(se, ee, hi.hint, Array(), problemType, false, null, true, isOnTheFly))
case _ => ()
}

View File

@ -79,8 +79,8 @@ class HaskellReference(element: HaskellNamedElement, textRange: TextRange) exten
case Some(ts) =>
def find(e: PsiElement): Option[HaskellNamedElement] = {
Option(PsiTreeUtil.findSiblingForward(e, HaskellTypes.HS_TOP_DECLARATION, null)) match {
case Some(d) if Option(d.getFirstChild).exists(_.isInstanceOf[HaskellExpression]) => HaskellPsiUtil.findNamedElements(d).headOption.find(_.getName == ne.getName)
Option(PsiTreeUtil.findSiblingForward(e, HaskellTypes.HS_TOP_DECLARATION_LINE, null)) match {
case Some(d) if Option(d.getFirstChild).flatMap(c => Option(c.getFirstChild)).exists(_.isInstanceOf[HaskellExpression]) => HaskellPsiUtil.findNamedElements(d).headOption.find(_.getName == ne.getName)
case _ => None
}
}
@ -88,8 +88,15 @@ class HaskellReference(element: HaskellNamedElement, textRange: TextRange) exten
ProgressManager.checkCanceled()
// Work around Intero bug.
find(ts.getParent) match {
case Some(ee) => Some(HaskellNamedElementResolveResult(ee))
Option(ts.getParent).flatMap(p => Option(p.getParent)) match {
case Some(p) =>
find(p) match {
case Some(ee) => Some(HaskellNamedElementResolveResult(ee))
case None => resolveReference(ne, psiFile, project, None) match {
case Right(r) => Some(HaskellNamedElementResolveResult(r))
case Left(noInfo) => Some(NoResolveResult(noInfo))
}
}
case None => resolveReference(ne, psiFile, project, None) match {
case Right(r) => Some(HaskellNamedElementResolveResult(r))
case Left(noInfo) => Some(NoResolveResult(noInfo))

View File

@ -53,7 +53,16 @@ object HaskellFileUtil {
findDocument(psiFile).foreach(d => {
PsiDocumentManager.getInstance(psiFile.getProject).doPostponedOperationsAndUnblockDocument(d)
ApplicationManager.getApplication.invokeAndWait(() => {
HaskellFileUtil.saveFile(psiFile)
FileDocumentManager.getInstance.saveDocument(d)
})
})
}
def saveFileInDispatchThread(project: Project, virtualFile: VirtualFile): Unit = {
findDocument(virtualFile).foreach(d => {
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(d)
ApplicationManager.getApplication.invokeAndWait(() => {
FileDocumentManager.getInstance.saveDocument(d)
})
})
}