mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
make "Go To Declaration Or Usage" action choose between "Go To Declaration" or "Show Usages" (IDEA-206322)
This commit is contained in:
+5
-87
@@ -3,21 +3,18 @@ package com.intellij.codeInsight.navigation.actions;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
import com.intellij.codeInsight.actions.BaseCodeInsightAction;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.codeInsight.navigation.NavigationUtil;
|
||||
import com.intellij.diagnostic.PluginException;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.find.actions.ShowUsagesAction;
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
|
||||
import com.intellij.ide.util.EditSourceUtil;
|
||||
import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.lang.LanguageNamesValidation;
|
||||
import com.intellij.lang.refactoring.NamesValidator;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -30,9 +27,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.Navigatable;
|
||||
@@ -56,13 +51,13 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class GotoDeclarationAction extends BaseCodeInsightAction implements CodeInsightActionHandler, DumbAware {
|
||||
public class GotoDeclarationAction extends BaseCodeInsightAction implements DumbAware {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.navigation.actions.GotoDeclarationAction");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected CodeInsightActionHandler getHandler() {
|
||||
return this;
|
||||
return new GotoDeclarationActionHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,65 +65,6 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, @NotNull Editor editor, @NotNull PsiFile file) {
|
||||
|
||||
DumbService.getInstance(project).setAlternativeResolveEnabled(true);
|
||||
try {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement[] elements = underModalProgress(project, "Resolving Reference...", () -> findAllTargetElements(project, editor, offset));
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.declaration");
|
||||
|
||||
if (elements.length != 1) {
|
||||
if (elements.length == 0 && suggestCandidates(TargetElementUtil.findReference(editor, offset)).isEmpty()) {
|
||||
PsiElement element = findElementToShowUsagesOf(editor, editor.getCaretModel().getOffset());
|
||||
if (startFindUsages(editor, project, element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//disable 'no declaration found' notification for keywords
|
||||
if (isKeywordUnderCaret(project, file, offset)) return;
|
||||
}
|
||||
chooseAmbiguousTarget(editor, offset, elements, file);
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement element = elements[0];
|
||||
if (element == findElementToShowUsagesOf(editor, editor.getCaretModel().getOffset()) &&
|
||||
startFindUsages(editor, project, element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement navElement = element.getNavigationElement();
|
||||
navElement = TargetElementUtil.getInstance().getGotoDeclarationTarget(element, navElement);
|
||||
if (navElement != null) {
|
||||
gotoTargetElement(navElement, editor, file);
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
DumbService.getInstance(project).showDumbModeNotification("Navigation is not available here during index update");
|
||||
}
|
||||
finally {
|
||||
DumbService.getInstance(project).setAlternativeResolveEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean startFindUsages(@NotNull Editor editor, @NotNull Project project, PsiElement element) {
|
||||
if (element == null) {
|
||||
return false;
|
||||
}
|
||||
if (DumbService.getInstance(project).isDumb()) {
|
||||
AnAction action = ActionManager.getInstance().getAction(ShowUsagesAction.ID);
|
||||
String name = action.getTemplatePresentation().getText();
|
||||
DumbService.getInstance(project).showDumbModeNotification(ActionUtil.getUnavailableMessage(name, false));
|
||||
}
|
||||
else {
|
||||
RelativePoint popupPosition = JBPopupFactory.getInstance().guessBestPopupLocation(editor);
|
||||
new ShowUsagesAction().startFindUsages(element, popupPosition, editor, ShowUsagesAction.getUsagesPageSize());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static <T> T underModalProgress(@NotNull Project project,
|
||||
@NotNull @Nls(capitalization = Nls.Capitalization.Title) String progressTitle,
|
||||
@NotNull Computable<T> computable) throws ProcessCanceledException {
|
||||
@@ -147,19 +83,6 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
return TargetElementUtil.getInstance().findTargetElement(editor, TargetElementUtil.ELEMENT_NAME_ACCEPTED, offset);
|
||||
}
|
||||
|
||||
private static void chooseAmbiguousTarget(final Editor editor, int offset, PsiElement[] elements, PsiFile currentFile) {
|
||||
if (!editor.getComponent().isShowing()) return;
|
||||
PsiElementProcessor<PsiElement> navigateProcessor = element -> {
|
||||
gotoTargetElement(element, editor, currentFile);
|
||||
return true;
|
||||
};
|
||||
boolean found =
|
||||
chooseAmbiguousTarget(editor, offset, navigateProcessor, CodeInsightBundle.message("declaration.navigation.title"), elements);
|
||||
if (!found) {
|
||||
HintManager.getInstance().showErrorHint(editor, "Cannot find declaration to go to");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean navigateInCurrentEditor(@NotNull PsiElement element, @NotNull PsiFile currentFile, @NotNull Editor currentEditor) {
|
||||
if (element.getContainingFile() == currentFile && !currentEditor.isDisposed()) {
|
||||
int offset = element.getTextOffset();
|
||||
@@ -240,11 +163,6 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
return TargetElementUtil.getInstance().getTargetCandidates(reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@TestOnly
|
||||
public static PsiElement findTargetElement(Project project, Editor editor, int offset) {
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight.navigation.actions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.find.actions.ShowUsagesAction;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.codeInsight.navigation.actions.GotoDeclarationAction.findElementToShowUsagesOf;
|
||||
|
||||
public final class GotoDeclarationActionHandler implements CodeInsightActionHandler {
|
||||
|
||||
public static final GotoDeclarationActionHandler INSTANCE = new GotoDeclarationActionHandler();
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, @NotNull Editor editor, @NotNull PsiFile file) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.declaration");
|
||||
final PsiElement declarationElement = findDeclarationElement(project, editor);
|
||||
if (declarationElement == null) {
|
||||
GotoDeclarationOnlyHandler.INSTANCE.invoke(project, editor, file);
|
||||
}
|
||||
else {
|
||||
startFindUsages(editor, project, declarationElement);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement findDeclarationElement(@NotNull Project project, @NotNull Editor editor) {
|
||||
final DumbService dumbService = DumbService.getInstance(project);
|
||||
try {
|
||||
return dumbService.computeWithAlternativeResolveEnabled(() -> {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
return findElementToShowUsagesOf(editor, offset);
|
||||
});
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
dumbService.showDumbModeNotification("Navigation is not available here during index update");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void startFindUsages(@NotNull Editor editor, @NotNull Project project, @NotNull PsiElement element) {
|
||||
if (DumbService.getInstance(project).isDumb()) {
|
||||
AnAction action = ActionManager.getInstance().getAction(ShowUsagesAction.ID);
|
||||
String name = action.getTemplatePresentation().getText();
|
||||
DumbService.getInstance(project).showDumbModeNotification(ActionUtil.getUnavailableMessage(name, false));
|
||||
}
|
||||
else {
|
||||
RelativePoint popupPosition = JBPopupFactory.getInstance().guessBestPopupLocation(editor);
|
||||
new ShowUsagesAction().startFindUsages(element, popupPosition, editor, ShowUsagesAction.getUsagesPageSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user