mirror of
https://github.com/ilyakooo0/intellij-haskell.git
synced 2024-09-11 14:56:19 +03:00
Varous improvements.
This commit is contained in:
parent
990a07c112
commit
b9d7f259ff
@ -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 = {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 _ => ()
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user