diff --git a/src/main/scala/intellij/haskell/annotator/HaskellAnnotator.scala b/src/main/scala/intellij/haskell/annotator/HaskellAnnotator.scala index ade51c60..b26f5f01 100644 --- a/src/main/scala/intellij/haskell/annotator/HaskellAnnotator.scala +++ b/src/main/scala/intellij/haskell/annotator/HaskellAnnotator.scala @@ -66,22 +66,12 @@ class HaskellAnnotator extends ExternalAnnotator[PsiFile, CompilationResult] { } } - // 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) - 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 - } + HaskellFileUtil.saveFileInDispatchThread(psiFile.getProject, virtualFile) + HaskellComponentsManager.loadHaskellFile(psiFile, fileChanged).orNull case None => CompilationResult(Iterable(), Iterable(), failed = false) } } @@ -345,18 +335,21 @@ class LanguageExtensionIntentionAction(languageExtension: String) extends Haskel override def getFamilyName: String = "Add language extension" override def invoke(project: Project, editor: Editor, file: PsiFile): Unit = { - val languagePragmaElement = HaskellElementFactory.createLanguagePragma(project, s"{-# LANGUAGE $languageExtension #-}\n") - Option(PsiTreeUtil.findChildOfType(file, classOf[HaskellFileHeader])) match { - case Some(fh) => - val lastPragmaElement = PsiTreeUtil.findChildrenOfType(fh, classOf[HaskellPragma]).asScala.lastOption.orNull - if (lastPragmaElement == null) { - val p = fh.add(languagePragmaElement) - fh.addAfter(HaskellElementFactory.createNewLine(project), p) - } else { - val nl = fh.addAfter(HaskellElementFactory.createNewLine(project), lastPragmaElement) - fh.addAfter(languagePragmaElement, nl) + HaskellElementFactory.createLanguagePragma(project, s"{-# LANGUAGE $languageExtension #-}\n") match { + case Some(languagePragmaElement) => + Option(PsiTreeUtil.findChildOfType(file, classOf[HaskellFileHeader])) match { + case Some(fh) => + PsiTreeUtil.findChildrenOfType(fh, classOf[HaskellPragma]).asScala.lastOption match { + case Some(lastPragmaElement) => + val nl = fh.addAfter(HaskellElementFactory.createNewLine(project), lastPragmaElement) + fh.addAfter(languagePragmaElement, nl) + case None => + val p = fh.add(languagePragmaElement) + fh.addAfter(HaskellElementFactory.createNewLine(project), p) + } + case None => () // File header should always be there } - case None => () // File header should always be there + case None => () } } } @@ -387,11 +380,11 @@ private object IntentionHelper { Option(file.findElementAt(offset)).flatMap(HaskellPsiUtil.findQualifiedName) match { case Some(e) => if (e.getText.startsWith("`") && e.getText.endsWith("`")) { - e.replace(HaskellElementFactory.createQualifiedNameElement(project, s"`$newName`")) + HaskellElementFactory.createQualifiedNameElement(project, s"`$newName`").foreach(e.replace) } else if (StringUtil.isWithinParens(e.getText)) { - e.replace(HaskellElementFactory.createQualifiedNameElement(project, s"($newName)")) + HaskellElementFactory.createQualifiedNameElement(project, s"($newName)").foreach(e.replace) } else { - e.replace(HaskellElementFactory.createQualifiedNameElement(project, newName)) + HaskellElementFactory.createQualifiedNameElement(project, newName).foreach(e.replace) } case None => () } @@ -441,7 +434,7 @@ class NotInScopeIntentionAction(identifier: String, moduleName: String, psiFile: val commaElement = importIdsSpec.addAfter(HaskellElementFactory.createComma(project), importId) HaskellElementFactory.createImportId(project, identifier).foreach { ii => val iiElement = importIdsSpec.addAfter(ii, commaElement) - importIdsSpec.addBefore(HaskellElementFactory.createWhiteSpace(project), iiElement) + HaskellElementFactory.createWhiteSpace(project).foreach(importIdsSpec.addBefore(_, iiElement)) } }) case None => createImportDeclaration(importDeclarationElement, ids, project) diff --git a/src/main/scala/intellij/haskell/external/component/DefinitionLocationComponent.scala b/src/main/scala/intellij/haskell/external/component/DefinitionLocationComponent.scala index f12a99ee..426e6a6a 100644 --- a/src/main/scala/intellij/haskell/external/component/DefinitionLocationComponent.scala +++ b/src/main/scala/intellij/haskell/external/component/DefinitionLocationComponent.scala @@ -70,12 +70,6 @@ private[component] object DefinitionLocationComponent { Cache.asMap().find { case (k, _) => k.psiFile == psiFile && k.qualifiedNameElement == qualifiedNameElement }.flatMap(_._2.toOption) } - def invalidateOtherFiles(currentFile: PsiFile, name: String): Unit = { - val synchronousCache = Cache - val keys = synchronousCache.asMap().filter { case (k, v) => k.qualifiedNameElement.getIdentifierElement.getName == name && k.psiFile != currentFile }.keys - keys.foreach(synchronousCache.invalidate) - } - def invalidateAll(project: Project): Unit = { val synchronousCache = Cache synchronousCache.asMap().filter(_._1.psiFile.getProject == project).keys.foreach(synchronousCache.invalidate) @@ -109,7 +103,9 @@ private[component] object DefinitionLocationComponent { } private def checkValidName(key: Key, definitionLocation: DefinitionLocation): Boolean = { - ApplicationUtil.runReadAction(Option(key.qualifiedNameElement.getIdentifierElement.getName)).contains(ApplicationUtil.runReadAction(definitionLocation.namedElement.getName)) + val keyName = ApplicationUtil.runReadAction(Option(key.qualifiedNameElement.getIdentifierElement.getName)) + keyName == ApplicationUtil.runReadAction(Option(definitionLocation.namedElement.getName)) && + keyName.contains(definitionLocation.originalName) } private def findDefinitionLocationResult(key: Key): DefinitionLocationResult = { diff --git a/src/main/scala/intellij/haskell/external/component/HaskellComponentsManager.scala b/src/main/scala/intellij/haskell/external/component/HaskellComponentsManager.scala index dab6b197..a38aba3f 100644 --- a/src/main/scala/intellij/haskell/external/component/HaskellComponentsManager.scala +++ b/src/main/scala/intellij/haskell/external/component/HaskellComponentsManager.scala @@ -131,8 +131,8 @@ object HaskellComponentsManager { StackReplsManager.getReplsManager(project).map(_.moduleCabalInfos.map { case (_, ci) => ci }).getOrElse(Iterable()) } - def loadHaskellFile(psiFile: PsiFile): Option[CompilationResult] = { - LoadComponent.load(psiFile) + def loadHaskellFile(psiFile: PsiFile, fileChanged: Boolean): Option[CompilationResult] = { + LoadComponent.load(psiFile, fileChanged) } def invalidateFileInfos(psiFile: PsiFile): Unit = { @@ -147,8 +147,8 @@ object HaskellComponentsManager { findStackComponentInfos(project).map(info => (info.module, info.packageName)).distinct } - def invalidateOtherFilesLocations(currentFile: PsiFile, name: String): Unit = { - DefinitionLocationComponent.invalidateOtherFiles(currentFile, name) + def invalidateDefinitionLocations(psiFile: PsiFile): Unit = { + DefinitionLocationComponent.invalidate(psiFile) } def findLibraryPackageInfos(project: Project): Seq[PackageInfo] = { diff --git a/src/main/scala/intellij/haskell/external/component/LoadComponent.scala b/src/main/scala/intellij/haskell/external/component/LoadComponent.scala index 161bf2c1..3a805b98 100644 --- a/src/main/scala/intellij/haskell/external/component/LoadComponent.scala +++ b/src/main/scala/intellij/haskell/external/component/LoadComponent.scala @@ -37,7 +37,7 @@ private[component] object LoadComponent { }.contains(true) } - def load(psiFile: PsiFile): Option[CompilationResult] = { + def load(psiFile: PsiFile, fileChanged: Boolean): 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) match { + projectRepl.load(psiFile, fileChanged) match { case Some((loadOutput, loadFailed)) => ApplicationManager.getApplication.executeOnPooledThread(ScalaUtil.runnable { diff --git a/src/main/scala/intellij/haskell/external/component/ProjectLibraryFileWatcher.scala b/src/main/scala/intellij/haskell/external/component/ProjectLibraryFileWatcher.scala index d53d3945..0e74e6d2 100644 --- a/src/main/scala/intellij/haskell/external/component/ProjectLibraryFileWatcher.scala +++ b/src/main/scala/intellij/haskell/external/component/ProjectLibraryFileWatcher.scala @@ -34,6 +34,7 @@ import intellij.haskell.external.repl.StackRepl.LibType import intellij.haskell.external.repl.StackReplsManager import intellij.haskell.util.{ApplicationUtil, HaskellFileUtil, HaskellProjectUtil} +import scala.annotation.tailrec import scala.collection.JavaConverters._ import scala.collection.concurrent @@ -77,6 +78,7 @@ object ProjectLibraryFileWatcher { ProgressManager.getInstance().run(new Task.Backgroundable(project, "Building project", false, PerformInBackgroundOption.ALWAYS_BACKGROUND) { + @tailrec def run(progressIndicator: ProgressIndicator) { val buildMessage = s"Building project" HaskellNotificationGroup.logInfoEvent(project, buildMessage) diff --git a/src/main/scala/intellij/haskell/external/repl/ProjectStackRepl.scala b/src/main/scala/intellij/haskell/external/repl/ProjectStackRepl.scala index 47f5052d..d64f840f 100644 --- a/src/main/scala/intellij/haskell/external/repl/ProjectStackRepl.scala +++ b/src/main/scala/intellij/haskell/external/repl/ProjectStackRepl.scala @@ -136,13 +136,13 @@ case class ProjectStackRepl(project: Project, stackComponentInfo: StackComponent loadedModuleNames.foreach(mn => everLoadedDependentModules.put(mn, DependentModuleInfo())) } - def load(psiFile: PsiFile, mustBeByteCode: Boolean = false): Option[(StackReplOutput, Boolean)] = synchronized { + def load(psiFile: PsiFile, fileChanged: Boolean, mustBeByteCode: Boolean = false): Option[(StackReplOutput, Boolean)] = synchronized { val forceBytecodeLoad = if (mustBeByteCode) objectCodeEnabled else false - val reload = if (!forceBytecodeLoad) { + val reload = if (forceBytecodeLoad || !fileChanged) { + false + } else { val loaded = isFileLoaded(psiFile) loaded == Loaded || loaded == Failed - } else { - false } val output = if (reload) { @@ -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).exists(_._2 == false))) { + if (psiFile.isEmpty || isBrowseModuleLoaded(moduleName) || psiFile.exists(pf => load(pf, fileChanged = false).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") diff --git a/src/main/scala/intellij/haskell/psi/HaskellElementFactory.scala b/src/main/scala/intellij/haskell/psi/HaskellElementFactory.scala index 5171383b..7ea58350 100644 --- a/src/main/scala/intellij/haskell/psi/HaskellElementFactory.scala +++ b/src/main/scala/intellij/haskell/psi/HaskellElementFactory.scala @@ -18,60 +18,55 @@ package intellij.haskell.psi import java.util -import com.intellij.application.options.CodeStyle import com.intellij.openapi.project.Project -import com.intellij.psi.impl.PsiFileFactoryImpl import com.intellij.psi.impl.source.tree.LeafPsiElement -import com.intellij.psi.tree.IElementType import com.intellij.psi.util.PsiTreeUtil -import com.intellij.psi.{PsiElement, PsiFileFactory, PsiManager, PsiWhiteSpace} +import com.intellij.psi.{PsiElement, PsiFileFactory, PsiWhiteSpace} import intellij.haskell.psi.HaskellTypes._ -import intellij.haskell.{HaskellFile, HaskellFileType, HaskellLanguage} +import intellij.haskell.{HaskellFile, HaskellLanguage} import scala.collection.JavaConverters._ object HaskellElementFactory { def createUnderscore(project: Project): Option[PsiElement] = { - createElementFromText(project, "_", HS_RESERVED_ID) + createElement(project, "_", classOf[HaskellReservedId]) } def createVarid(project: Project, name: String): Option[HaskellVarid] = { - createElementFromText(project, name, HS_VARID).map(_.asInstanceOf[HaskellVarid]).filter(_.getChildren.length == 0) + createElement(project, name, classOf[HaskellVarid]) } def createConid(project: Project, name: String): Option[HaskellConid] = { - createElementFromText(project, name, HS_CONID).map(_.asInstanceOf[HaskellConid]).filter(_.getChildren.length == 0) + createElement(project, name, classOf[HaskellConid]) } def createVarsym(project: Project, name: String): Option[HaskellVarsym] = { - createElementFromText(project, name, HS_VARSYM).map(_.asInstanceOf[HaskellVarsym]) + createElement(project, name, classOf[HaskellVarsym]) } def createConsym(project: Project, name: String): Option[HaskellConsym] = { - createElementFromText(project, name, HS_CONSYM).map(_.asInstanceOf[HaskellConsym]).filter(_.getChildren.length == 0) + createElement(project, name, classOf[HaskellConsym]) } def createImportId(project: Project, identifier: String): Option[HaskellImportId] = { - createElementFromText(project, surroundWithParensIfSymbol(project, identifier), HS_IMPORT_ID).map(_.asInstanceOf[HaskellImportId]) + createElement(project, surroundWithParensIfSymbol(project, identifier), classOf[HaskellImportId]) } - def createQualifiedNameElement(project: Project, name: String): HaskellQualifiedNameElement = { - val haskellFile = createFileFromText(project, name) - PsiTreeUtil.findChildOfType(haskellFile, classOf[HaskellQualifiedNameElement]) + def createQualifiedNameElement(project: Project, name: String): Option[HaskellQualifiedNameElement] = { + createElement(project, name, classOf[HaskellQualifiedNameElement]) } def createBody(project: Project, body: String): Option[HaskellModuleBody] = { - createElementFromText(project, body, HS_MODULE_BODY).map(_.asInstanceOf[HaskellModuleBody]) + createElement(project, body, classOf[HaskellModuleBody]) } def createTopDeclarationLine(project: Project, declaration: String): Option[HaskellTopDeclarationLine] = { - createElementFromText(project, declaration, HS_TOP_DECLARATION_LINE).map(_.asInstanceOf[HaskellTopDeclarationLine]) + createElement(project, declaration, classOf[HaskellTopDeclarationLine]) } - def createLanguagePragma(project: Project, languagePragma: String): HaskellPragma = { - val haskellFile = createFileFromText(project, languagePragma) - PsiTreeUtil.findChildOfType(haskellFile, classOf[HaskellPragma]) + def createLanguagePragma(project: Project, languagePragma: String): Option[HaskellPragma] = { + createElement(project, languagePragma, classOf[HaskellPragma]) } def createLeafPsiElements(project: Project, code: String): util.Collection[LeafPsiElement] = { @@ -87,9 +82,8 @@ object HaskellElementFactory { createLeafPsiElements(project, "add = (1 + 2)").asScala.find(_.getNode.getElementType == HS_RIGHT_PAREN) } - def createWhiteSpace(project: Project, space: String = " "): PsiWhiteSpace = { - val haskellFile = createFileFromText(project, space) - PsiTreeUtil.findChildOfType(haskellFile, classOf[PsiWhiteSpace]) + def createWhiteSpace(project: Project, space: String = " "): Option[PsiWhiteSpace] = { + createElement(project, space, classOf[PsiWhiteSpace]) } def createComma(project: Project): PsiElement = { @@ -97,34 +91,28 @@ object HaskellElementFactory { haskellFile.getLastChild } - def createTab(project: Project): PsiWhiteSpace = { - val tabSize = CodeStyle.getSettings(project).getTabSize(HaskellFileType.Instance) - createWhiteSpace(project, " " * tabSize) - } - def createNewLine(project: Project): PsiElement = { createFileFromText(project, "\n").getFirstChild } def createQualifier(project: Project, qualifier: String): Option[HaskellQualifier] = { - createElementFromText(project, qualifier, HS_QUALIFIER).map(_.asInstanceOf[HaskellQualifier]) + createElement(project, "test = " + qualifier + ".bla", classOf[HaskellQualifier]) } def createQConQualifier(project: Project, qConQualifier: String): Option[HaskellQConQualifier] = { - createElementFromText(project, qConQualifier, HS_Q_CON_QUALIFIER).map(_.asInstanceOf[HaskellQConQualifier]) + createElement(project, qConQualifier, classOf[HaskellQConQualifier]) } def createModid(project: Project, moduleName: String): Option[HaskellModid] = { - val haskellModuleDeclaration = createElementFromText(project, s"module $moduleName where", HS_MODULE_DECLARATION) - haskellModuleDeclaration.map(_.asInstanceOf[HaskellModuleDeclaration]).map(_.getModid) + val haskellModuleDeclaration = createElement(project, s"module $moduleName where", classOf[HaskellModuleDeclaration]) + haskellModuleDeclaration.map(_.getModid) } def createImportDeclaration(project: Project, moduleName: String, identifier: String): Option[HaskellImportDeclaration] = { - val haskellImportDeclaration = createElementFromText(project, s"import $moduleName (${surroundWithParensIfSymbol(project, identifier)})", HS_IMPORT_DECLARATION) - haskellImportDeclaration.map(_.asInstanceOf[HaskellImportDeclaration]) + createElement(project, s"import $moduleName (${surroundWithParensIfSymbol(project, identifier)})", classOf[HaskellImportDeclaration]) } - private def surroundWithParensIfSymbol(project: Project, identifier: String) = { + private def surroundWithParensIfSymbol(project: Project, identifier: String): String = { if (createVarid(project, identifier).isDefined || createConid(project, identifier).isDefined) { identifier } else { @@ -133,15 +121,15 @@ object HaskellElementFactory { } def createImportDeclaration(project: Project, importDecl: String): Option[HaskellImportDeclaration] = { - val haskellImportDeclaration = createElementFromText(project, s"$importDecl \n", HS_IMPORT_DECLARATION) - haskellImportDeclaration.map(_.asInstanceOf[HaskellImportDeclaration]) + createElement(project, s"$importDecl \n", classOf[HaskellImportDeclaration]) + } + + private def createElement[C <: PsiElement](project: Project, newName: String, namedElementClass: Class[C]): Option[C] = { + val file = createFileFromText(project, newName) + Option(PsiTreeUtil.findChildOfType(file, namedElementClass)) } private def createFileFromText(project: Project, text: String): HaskellFile = { PsiFileFactory.getInstance(project).createFileFromText("a.hs", HaskellLanguage.Instance, text).asInstanceOf[HaskellFile] } - - def createElementFromText(project: Project, text: String, elementType: IElementType): Option[PsiElement] = { - Option(new PsiFileFactoryImpl(PsiManager.getInstance(project)).createElementFromText(text, HaskellLanguage.Instance, elementType, null)).filter(_.isValid) - } } diff --git a/src/main/scala/intellij/haskell/psi/impl/HaskellPsiImplUtil.scala b/src/main/scala/intellij/haskell/psi/impl/HaskellPsiImplUtil.scala index 03904559..c55dadab 100644 --- a/src/main/scala/intellij/haskell/psi/impl/HaskellPsiImplUtil.scala +++ b/src/main/scala/intellij/haskell/psi/impl/HaskellPsiImplUtil.scala @@ -101,7 +101,7 @@ object HaskellPsiImplUtil { def setName(modid: HaskellModid, newName: String): PsiElement = { if (newName.endsWith("." + HaskellFileType.Instance.getDefaultExtension)) { val newModid = HaskellElementFactory.createModid(modid.getProject, HaskellRenameFileProcessor.createNewModuleName(modid.getName, newName)) - newModid.foreach(mi => modid.getNode.getTreeParent.replaceChild(modid.getNode, mi.getNode)) + newModid.foreach(modid.replace) modid } else { modid @@ -118,7 +118,7 @@ object HaskellPsiImplUtil { def setName(varid: HaskellVarid, newName: String): PsiElement = { val newVarid = HaskellElementFactory.createVarid(varid.getProject, newName) - newVarid.foreach(vid => varid.getNode.getTreeParent.replaceChild(varid.getNode, vid.getNode)) + newVarid.foreach(varid.replace) varid } @@ -131,16 +131,9 @@ object HaskellPsiImplUtil { } def setName(varsym: HaskellVarsym, newName: String): PsiElement = { - if (varsym.getNode.getChildren(null).length == 1) { - val newVarsym = HaskellElementFactory.createVarsym(varsym.getProject, newName) - newVarsym.foreach(vs => varsym.getNode.getTreeParent.replaceChild(varsym.getNode, vs.getNode)) - varsym - } else { - HaskellElementFactory.createVarsym(varsym.getProject, newName).foreach { newVarsym => - varsym.getNode.replaceAllChildrenToChildrenOf(newVarsym.getNode) - } - varsym - } + val newVarsym = HaskellElementFactory.createVarsym(varsym.getProject, newName) + newVarsym.foreach(varsym.replace) + varsym } def getName(conid: HaskellConid): String = { @@ -153,7 +146,7 @@ object HaskellPsiImplUtil { def setName(conid: HaskellConid, newName: String): PsiElement = { val newConid = HaskellElementFactory.createConid(conid.getProject, newName) - newConid.foreach(ci => conid.getNode.getTreeParent.replaceChild(conid.getNode, ci.getNode)) + newConid.foreach(conid.replace) conid } @@ -167,7 +160,7 @@ object HaskellPsiImplUtil { def setName(consym: HaskellConsym, newName: String): PsiElement = { val newConsym = HaskellElementFactory.createConsym(consym.getProject, newName) - newConsym.foreach(cs => consym.getNode.getTreeParent.replaceChild(consym.getNode, cs.getNode)) + newConsym.foreach(consym.replace) consym } @@ -181,7 +174,7 @@ object HaskellPsiImplUtil { def setName(qualifier: HaskellQualifier, newName: String): PsiElement = { val newQualifier = HaskellElementFactory.createQualifier(qualifier.getProject, removeFileExtension(newName)) - newQualifier.foreach(q => qualifier.getNode.getTreeParent.replaceChild(qualifier.getNode, q.getNode)) + newQualifier.foreach(qualifier.replace) qualifier } @@ -195,7 +188,7 @@ object HaskellPsiImplUtil { def setName(qualifier: HaskellQualifierElement, newName: String): PsiElement = { val newQualifier = HaskellElementFactory.createQConQualifier(qualifier.getProject, newName) - newQualifier.foreach(q => qualifier.getNode.getTreeParent.replaceChild(qualifier.getNode, q.getNode)) + newQualifier.foreach(qualifier.replace) qualifier } diff --git a/src/main/scala/intellij/haskell/refactor/HaskellRenameVariableProcessor.scala b/src/main/scala/intellij/haskell/refactor/HaskellRenameVariableProcessor.scala index 4a000fc8..10f752f5 100644 --- a/src/main/scala/intellij/haskell/refactor/HaskellRenameVariableProcessor.scala +++ b/src/main/scala/intellij/haskell/refactor/HaskellRenameVariableProcessor.scala @@ -25,7 +25,6 @@ import com.intellij.refactoring.listeners.RefactoringElementListener import com.intellij.refactoring.rename.RenamePsiElementProcessor import intellij.haskell.external.component.{HaskellComponentsManager, ProjectLibraryFileWatcher} import intellij.haskell.external.repl.StackRepl.LibType -import intellij.haskell.psi.HaskellPsiUtil import intellij.haskell.util.{HaskellFileUtil, HaskellProjectUtil, ScalaUtil} class HaskellRenameVariableProcessor extends RenamePsiElementProcessor { @@ -33,19 +32,15 @@ class HaskellRenameVariableProcessor extends RenamePsiElementProcessor { // Target element is element of the definition // Invalidate cache is necessary because during (inline) renaming the id of psi element is changed override def prepareRenaming(targetElement: PsiElement, newName: String, allRenames: util.Map[PsiElement, String]): Unit = { - val oldName = HaskellPsiUtil.findNamedElement(targetElement).map(_.getName) - oldName match { - case Some(n) => - val project = targetElement.getProject - for { - f <- getCurrentFile(project) - _ = HaskellComponentsManager.invalidateOtherFilesLocations(f, n) - tf <- Option(targetElement.getContainingFile).map(_.getOriginalFile) - tInfo <- if (tf != f) HaskellComponentsManager.findStackComponentInfo(tf) else None - _ = if (tInfo.stanzaType == LibType) ProjectLibraryFileWatcher.addBuild(project, Set(tInfo)) else () - } yield () - case None => () - } + val project = targetElement.getProject + for { + cf <- getCurrentFile(project) + () = HaskellComponentsManager.invalidateDefinitionLocations(cf) + tf <- Option(targetElement.getContainingFile).map(_.getOriginalFile) + targetInfo <- HaskellComponentsManager.findStackComponentInfo(tf) + currentInfo <- HaskellComponentsManager.findStackComponentInfo(cf) + } yield if (targetInfo != currentInfo && targetInfo.stanzaType == LibType) + ProjectLibraryFileWatcher.addBuild(project, Set(targetInfo)) else () } override def canProcessElement(psiElement: PsiElement): Boolean = { @@ -63,16 +58,10 @@ class HaskellRenameVariableProcessor extends RenamePsiElementProcessor { } } - override def getPostRenameCallback(element: PsiElement, newName: String, elementListener: RefactoringElementListener): Runnable = { + override def getPostRenameCallback(targetElement: PsiElement, newName: String, elementListener: RefactoringElementListener): Runnable = { ScalaUtil.runnable { - val project = element.getProject - + val project = targetElement.getProject HaskellFileUtil.saveAllFiles(project) - - getCurrentFile(project).foreach { f => - val componentInfo = HaskellComponentsManager.findStackComponentInfo(f) - componentInfo.foreach(ci => ProjectLibraryFileWatcher.checkLibraryBuild(project, ci)) - } } }