From 2b18c7283f37cfa0aa84db99eb991eaca141ed47 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Fri, 26 Apr 2019 18:24:14 +0300 Subject: [PATCH] extract separate "Go To Declaration" action which knows nothing about "Show Usages" (IDEA-207052) GitOrigin-RevId: d9b07b4d4f5b7a68e2a610c9d56f52ad7178d85d --- .../actions/GotoDeclarationAction.java | 2 +- .../actions/GotoDeclarationOnlyAction.kt | 9 ++ .../actions/GotoDeclarationOnlyHandler.kt | 94 +++++++++++++++++++ .../src/messages/ActionsBundle.properties | 6 +- .../src/idea/LangActions.xml | 1 + 5 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyAction.kt create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyHandler.kt diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java index e34d7f847bc2..9768030bad63 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationAction.java @@ -178,7 +178,7 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code return false; } - private static void gotoTargetElement(@NotNull PsiElement element, @NotNull Editor currentEditor, @NotNull PsiFile currentFile) { + static void gotoTargetElement(@NotNull PsiElement element, @NotNull Editor currentEditor, @NotNull PsiFile currentFile) { if (navigateInCurrentEditor(element, currentFile, currentEditor)) return; Navigatable navigatable = element instanceof Navigatable ? (Navigatable)element : EditSourceUtil.getDescriptor(element); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyAction.kt b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyAction.kt new file mode 100644 index 000000000000..83ff7354b6f7 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyAction.kt @@ -0,0 +1,9 @@ +// 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 + +class GotoDeclarationOnlyAction : GotoDeclarationAction() { + + override fun getHandler(): CodeInsightActionHandler = GotoDeclarationOnlyHandler +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyHandler.kt b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyHandler.kt new file mode 100644 index 000000000000..0b08fe3efd05 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/actions/GotoDeclarationOnlyHandler.kt @@ -0,0 +1,94 @@ +// 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.codeInsight.CodeInsightBundle +import com.intellij.codeInsight.TargetElementUtil +import com.intellij.codeInsight.hint.HintManager +import com.intellij.codeInsight.navigation.NavigationUtil +import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction.* +import com.intellij.featureStatistics.FeatureUsageTracker +import com.intellij.ide.util.DefaultPsiElementCellRenderer +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.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.search.PsiElementProcessor +import com.intellij.util.containers.toArray + +/** + * Go To Declaration Handler which doesn't invoke Show Usages if there are no declarations to go + */ +object GotoDeclarationOnlyHandler : CodeInsightActionHandler { + + override fun startInWriteAction(): Boolean = false + + override fun invoke(project: Project, editor: Editor, file: PsiFile) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.declaration.only") + val dumbService = DumbService.getInstance(project) + try { + dumbService.isAlternativeResolveEnabled = true + val offset = editor.caretModel.offset + val elements = underModalProgress(project, "Resolving Reference...") { + findAllTargetElements(project, editor, offset) + } + if (elements.size == 1) { + // simplest case + val element = elements[0] + val navElement = TargetElementUtil.getInstance().getGotoDeclarationTarget(element, element.navigationElement) + if (navElement != null) { + gotoTargetElement(navElement, editor, file) + } + } + else if (elements.isEmpty()) { + // this means either there is really nowhere to go or weird TargetElementUtil didn't return anything + val reference = TargetElementUtil.findReference(editor, offset) + if (reference != null) { + val targets = underModalProgress(project, "Resolving Reference...") { + TargetElementUtil.getInstance().getTargetCandidates(reference) + } + if (targets.isNotEmpty()) { + chooseAmbiguousTarget(editor, file, targets.toArray(PsiElement.EMPTY_ARRAY)) + return + } + } + //disable 'no declaration found' notification for keywords + if (!isKeywordUnderCaret(project, file, offset)) { + HintManager.getInstance().showErrorHint(editor, "Cannot find declaration to go to") + } + } + else { + chooseAmbiguousTarget(editor, file, elements) + } + } + catch (e: IndexNotReadyException) { + dumbService.showDumbModeNotification("Navigation is not available here during index update") + } + finally { + dumbService.isAlternativeResolveEnabled = false + } + } + + private fun chooseAmbiguousTarget(editor: Editor, file: PsiFile, elements: Array) { + if (!editor.component.isShowing) return + chooseAmbiguousTarget(editor, CodeInsightBundle.message("declaration.navigation.title"), elements) { element -> + gotoTargetElement(element, editor, file) + } + } + + private fun chooseAmbiguousTarget(editor: Editor, title: String, elements: Array, processor: (PsiElement) -> Unit) { + require(elements.isNotEmpty()) + if (elements.size == 1) { + val element = elements[0] + processor(element) + return + } + val psiElementProcessor = PsiElementProcessor { + processor(it) + true + } + NavigationUtil.getPsiElementPopup(elements, DefaultPsiElementCellRenderer(), title, psiElementProcessor).showInBestPositionFor(editor) + } +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index a608214d6e2d..d10104a916cf 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -514,8 +514,10 @@ action.GotoAction.text=_Find Action... action.GotoAction.description=Quickly navigate to action by name action.GotoLine.text=_Line/Column... action.GotoLine.description=Navigate to a line (and/or column) in editor by its number -action.GotoDeclaration.text=_Declaration -action.GotoDeclaration.description=Navigate to the declaration of the symbol at caret +action.GotoDeclarationOnly.text=Declaration +action.GotoDeclarationOnly.description=Navigate to the declaration of the symbol at caret +action.GotoDeclaration.text=_Declaration or Usages +action.GotoDeclaration.description=Navigate to the declaration of the symbol at caret or show its usages action.GotoImplementation.text=I_mplementation(s) action.GotoImplementation.description=Navigate to the implementation(s) of the selected class or method action.GotoNextElementUnderCaretUsage.text=Go to next highlighted element usage diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 035fbc515e06..4176c38f72a9 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -144,6 +144,7 @@ +