extract separate "Go To Declaration" action which knows nothing about "Show Usages" (IDEA-206322)

This commit is contained in:
Daniil Ovchinnikov
2019-02-04 17:07:46 +03:00
parent e00ecc9156
commit 1a98569af9
5 changed files with 112 additions and 3 deletions
@@ -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);
@@ -0,0 +1,12 @@
// 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
/**
* Go To Declaration which doesn't invoke Show Usages if there are no declarations to go
*/
class GotoDeclarationOnlyAction : GotoDeclarationAction() {
override fun getHandler(): CodeInsightActionHandler = GotoDeclarationOnlyHandler
}
@@ -0,0 +1,93 @@
// 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.toArray
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<PsiElement>) {
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<PsiElement>, processor: (PsiElement) -> Unit) {
require(elements.isNotEmpty())
if (elements.size == 1) {
val element = elements[0]
processor(element)
return
}
val psiElementProcessor = PsiElementProcessor<PsiElement> {
processor(it)
true
}
NavigationUtil.getPsiElementPopup(elements, DefaultPsiElementCellRenderer(), title, psiElementProcessor).showInBestPositionFor(editor)
}
}
@@ -519,8 +519,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.GotoDeclaration.text=Declaration or Usages
action.GotoDeclaration.description=Navigate to the declaration of the symbol at caret or show its usages
action.GotoDeclarationOnly.text=_Declaration
action.GotoDeclarationOnly.description=Navigate to the declaration of the symbol at caret
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
@@ -139,6 +139,7 @@
<action id="SelectIn" class="com.intellij.ide.actions.SelectInAction"/>
<action id="ShowNavBar" class="com.intellij.ide.navigationToolbar.ShowNavBarAction"/>
<action id="GotoDeclaration" class="com.intellij.codeInsight.navigation.actions.GotoDeclarationAction"/>
<action id="GotoDeclarationOnly" class="com.intellij.codeInsight.navigation.actions.GotoDeclarationOnlyAction"/>
<action id="GotoImplementation" class="com.intellij.codeInsight.navigation.actions.GotoImplementationAction"/>
<action id="GotoTypeDeclaration" class="com.intellij.codeInsight.navigation.actions.GotoTypeDeclarationAction"/>
<action id="GotoSuperMethod" class="com.intellij.codeInsight.navigation.actions.GotoSuperAction"/>
@@ -625,6 +626,7 @@
<group id="EditorPopupMenu.GoTo" popup="true">
<reference ref="ShowNavBar"/>
<reference ref="GotoDeclaration"/>
<reference ref="GotoDeclarationOnly"/>
<reference ref="GotoImplementation"/>
<reference ref="GotoTypeDeclaration"/>
<reference ref="GotoSuperMethod"/>