mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEADEV-40832
This commit is contained in:
+4
-35
@@ -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<PsiFile,Editor> place = ShowIntentionActionsHandler.availableFor(psiFile, editor, action, psiElement);
|
||||
if (place != null) {
|
||||
List<IntentionAction> enableDisableIntentionAction = new ArrayList<IntentionAction>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
+39
-34
@@ -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<IntentionActionWithTextCaching>
|
||||
|
||||
private boolean wrapActionsTo(final List<HighlightInfo.IntentionActionDescriptor> descriptors, final Set<IntentionActionWithTextCaching> 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<IntentionAction> 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<IntentionAction> 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<IntentionActionWithTextCaching> cachedActions) {
|
||||
private boolean removeInvalidActions(final Collection<IntentionActionWithTextCaching> cachedActions, final PsiElement element) {
|
||||
boolean result = true;
|
||||
Iterator<IntentionActionWithTextCaching> iterator = cachedActions.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
IntentionActionWithTextCaching cachedAction = iterator.next();
|
||||
IntentionAction action = cachedAction.getAction();
|
||||
if (!myFile.isValid() || !action.isAvailable(myProject, myEditor, myFile)) {
|
||||
Pair<PsiFile,Editor> place = ShowIntentionActionsHandler.availableFor(myFile, myEditor, action, element);
|
||||
if (place == null) {
|
||||
iterator.remove();
|
||||
result = false;
|
||||
}
|
||||
|
||||
+40
-6
@@ -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<PsiFile, Editor> 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<PsiFile, Editor> 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() {
|
||||
|
||||
Reference in New Issue
Block a user