From 9e06f0c46f440425f6570245ed174fb653fb6d6e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 16 Oct 2009 17:34:32 +0400 Subject: [PATCH] IDEADEV-40832 --- .../daemon/impl/ShowIntentionsPass.java | 39 ++---------- .../intention/impl/IntentionListStep.java | 73 ++++++++++++---------- .../impl/ShowIntentionActionsHandler.java | 46 ++++++++++++-- 3 files changed, 83 insertions(+), 75 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java index b69e1672cb..82aeb3423a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java @@ -23,15 +23,14 @@ import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.intention.AbstractIntentionAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.IntentionManager; -import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction; import com.intellij.codeInsight.intention.impl.IntentionHintComponent; +import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler; import com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.ide.DataManager; import com.intellij.lang.annotation.HighlightSeverity; -import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -44,14 +43,13 @@ import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Pair; import com.intellij.psi.IntentionFilterOwner; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; @@ -188,27 +186,13 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { public static void getActionsToShow(@NotNull final Editor editor, @NotNull final PsiFile psiFile, @NotNull IntentionsInfo intentions, int passIdToShowIntentionsFor) { final PsiElement psiElement = psiFile.findElementAt(editor.getCaretModel().getOffset()); LOG.assertTrue(psiElement == null || psiElement.isValid(), psiElement); - final boolean isInProject = psiFile.getManager().isInProject(psiFile); int offset = editor.getCaretModel().getOffset(); Project project = psiFile.getProject(); - PsiElement injected = InjectedLanguageManager.getInstance(project).findInjectedElementAt(psiFile, offset); - PsiFile injectedFile; - Editor injectedEditor; - if (injected != null) { - injectedFile = injected.getContainingFile(); - injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile); - } - else { - injectedFile = null; - injectedEditor = null; - } - for (IntentionAction action : IntentionManager.getInstance().getIntentionActions()) { - if (injectedFile != null && isAvailableHere(injectedEditor, injectedFile, injected, isInProject, project, action) || - isAvailableHere(editor, psiFile, psiElement, isInProject, project, action) - ) { + Pair place = ShowIntentionActionsHandler.availableFor(psiFile, editor, action, psiElement); + if (place != null) { List enableDisableIntentionAction = new ArrayList(); enableDisableIntentionAction.add(new IntentionHintComponent.EnableDisableIntentionAction(action)); intentions.intentionsToShow.add(new HighlightInfo.IntentionActionDescriptor(action, enableDisableIntentionAction, null)); @@ -256,19 +240,4 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { } } - private static boolean isAvailableHere(Editor editor, PsiFile psiFile, PsiElement psiElement, boolean inProject, Project project, - IntentionAction action) { - try { - if (action instanceof PsiElementBaseIntentionAction) { - if (!inProject || !((PsiElementBaseIntentionAction)action).isAvailable(project, editor, psiElement)) return false; - } - else if (!action.isAvailable(project, editor, psiFile)) { - return false; - } - } - catch (IndexNotReadyException e) { - return false; - } - return true; - } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java index 73ac167c64..7d25cc3b1d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java @@ -29,6 +29,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.*; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiUtilBase; @@ -83,52 +84,56 @@ class IntentionListStep implements ListPopupStep private boolean wrapActionsTo(final List descriptors, final Set cachedActions) { boolean result = true; - for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) { - IntentionAction action = descriptor.getAction(); - IntentionActionWithTextCaching cachedAction = new IntentionActionWithTextCaching(action, descriptor.getDisplayName(), descriptor.getIcon()); - result &= !cachedActions.add(cachedAction); - final int caretOffset = myEditor.getCaretModel().getOffset(); - final int fileOffset = caretOffset > 0 && caretOffset == myFile.getTextLength() ? caretOffset - 1 : caretOffset; - PsiElement element; - if (myFile instanceof PsiCompiledElement) { - element = myFile; - } - else if (PsiDocumentManager.getInstance(myProject).isUncommited(myEditor.getDocument())) { - //??? - FileViewProvider viewProvider = myFile.getViewProvider(); - element = viewProvider.findElementAt(fileOffset, viewProvider.getBaseLanguage()); - } - else { - element = InjectedLanguageUtil.findElementAtNoCommit(myFile, fileOffset); - } - final List options; - if (element != null && (options = descriptor.getOptions(element)) != null) { - for (IntentionAction option : options) { - boolean isErrorFix = myCachedErrorFixes.contains(new IntentionActionWithTextCaching(option, option.getText())); - if (isErrorFix) { - cachedAction.addErrorFix(option); - } - boolean isInspectionFix = myCachedInspectionFixes.contains(new IntentionActionWithTextCaching(option, option.getText())); - if (isInspectionFix) { - cachedAction.addInspectionFix(option); - } - else { - cachedAction.addIntention(option); + final int caretOffset = myEditor.getCaretModel().getOffset(); + final int fileOffset = caretOffset > 0 && caretOffset == myFile.getTextLength() ? caretOffset - 1 : caretOffset; + PsiElement element; + if (myFile instanceof PsiCompiledElement) { + element = myFile; + } + else if (PsiDocumentManager.getInstance(myProject).isUncommited(myEditor.getDocument())) { + //??? + FileViewProvider viewProvider = myFile.getViewProvider(); + element = viewProvider.findElementAt(fileOffset, viewProvider.getBaseLanguage()); + } + else { + element = InjectedLanguageUtil.findElementAtNoCommit(myFile, fileOffset); + } + if (!descriptors.isEmpty()) { + + for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) { + IntentionAction action = descriptor.getAction(); + IntentionActionWithTextCaching cachedAction = new IntentionActionWithTextCaching(action, descriptor.getDisplayName(), descriptor.getIcon()); + result &= !cachedActions.add(cachedAction); + final List options; + if (element != null && (options = descriptor.getOptions(element)) != null) { + for (IntentionAction option : options) { + boolean isErrorFix = myCachedErrorFixes.contains(new IntentionActionWithTextCaching(option, option.getText())); + if (isErrorFix) { + cachedAction.addErrorFix(option); + } + boolean isInspectionFix = myCachedInspectionFixes.contains(new IntentionActionWithTextCaching(option, option.getText())); + if (isInspectionFix) { + cachedAction.addInspectionFix(option); + } + else { + cachedAction.addIntention(option); + } } } } } - result &= removeInvalidActions(cachedActions); + result &= removeInvalidActions(cachedActions, element); return result; } - private boolean removeInvalidActions(final Collection cachedActions) { + private boolean removeInvalidActions(final Collection cachedActions, final PsiElement element) { boolean result = true; Iterator iterator = cachedActions.iterator(); while (iterator.hasNext()) { IntentionActionWithTextCaching cachedAction = iterator.next(); IntentionAction action = cachedAction.getAction(); - if (!myFile.isValid() || !action.isAvailable(myProject, myEditor, myFile)) { + Pair place = ShowIntentionActionsHandler.availableFor(myFile, myEditor, action, element); + if (place == null) { iterator.remove(); result = false; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java index df1c94197e..f20747b27c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java @@ -39,6 +39,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; @@ -50,6 +51,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -142,7 +144,10 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { return false; } - public static void chooseActionAndInvoke(PsiFile file, final Editor editor, final IntentionAction action, final String text) { + // returns editor,file where the action is available or null if there are none + @Nullable + public static Pair availableFor(PsiFile file, final Editor editor, final IntentionAction action, final PsiElement element) { + if (!file.isValid()) return null; final Project project = file.getProject(); final Editor editorToApply; @@ -150,29 +155,58 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { int offset = editor.getCaretModel().getOffset(); PsiElement injected = InjectedLanguageManager.getInstance(project).findInjectedElementAt(file, offset); + boolean inProject = file.getManager().isInProject(file); if (injected != null) { PsiFile injectedFile = injected.getContainingFile(); Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile); - if (action.isAvailable(project, injectedEditor, injectedFile)) { + if (isAvailableHere(injectedEditor, injectedFile, injected, inProject, action)) { editorToApply = injectedEditor; fileToApply = injectedFile; } - else if (!action.isAvailable(project, editor, file)) { - return; + else if (!isAvailableHere(editor, file, element, inProject, action)) { + return null; } else { editorToApply = editor; fileToApply = file; } } - else if (!action.isAvailable(project, editor, file)) { - return; + else if (!isAvailableHere(editor, file, element, inProject, action)) { + return null; } else { editorToApply = editor; fileToApply = file; } + return Pair.create(fileToApply, editorToApply); + } + + private static boolean isAvailableHere(Editor editor, PsiFile psiFile, PsiElement psiElement, boolean inProject, IntentionAction action) { + try { + Project project = psiFile.getProject(); + if (action instanceof PsiElementBaseIntentionAction) { + if (!inProject || !((PsiElementBaseIntentionAction)action).isAvailable(project, editor, psiElement)) return false; + } + else if (!action.isAvailable(project, editor, psiFile)) { + return false; + } + } + catch (IndexNotReadyException e) { + return false; + } + return true; + } + + public static void chooseActionAndInvoke(PsiFile file, final Editor editor, final IntentionAction action, final String text) { + final Project project = file.getProject(); + + int offset = editor.getCaretModel().getOffset(); + PsiElement element = file.findElementAt(offset); + Pair pair = availableFor(file, editor, action, element); + if (pair == null) return; + final Editor editorToApply = pair.second; + final PsiFile fileToApply = pair.first; Runnable runnable = new Runnable() { public void run() { -- 2.11.4.GIT