mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
GotoDeclarationHandler now can return multiple targets
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class GotoBreakContinueHandler implements GotoDeclarationHandler {
|
||||
public class GotoBreakContinueHandler extends GotoDeclarationHandlerBase {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.navigation.actions.GotoBreakContinueHandler");
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -353,6 +353,23 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
}
|
||||
}
|
||||
else if (browseMode == BrowseMode.Declaration) {
|
||||
final PsiElement[] targetElements = GotoDeclarationAction.findTargetElementsNoVS(myProject, editor, offset);
|
||||
final PsiElement elementAtPointer = file.findElementAt(offset);
|
||||
|
||||
if (targetElements != null) {
|
||||
if (targetElements.length == 0) {
|
||||
return null;
|
||||
}
|
||||
else if (targetElements.length == 1) {
|
||||
if (elementAtPointer != null && targetElements[0].isPhysical()) {
|
||||
return new InfoSingle(elementAtPointer, targetElements[0]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return elementAtPointer != null ? new InfoMultiple(elementAtPointer) : null;
|
||||
}
|
||||
}
|
||||
|
||||
PsiReference ref = TargetElementUtilBase.findReference(editor, offset);
|
||||
if (ref != null) {
|
||||
PsiElement resolvedElement = resolve(ref);
|
||||
@@ -360,7 +377,6 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
|
||||
return new InfoSingle(ref, resolvedElement);
|
||||
}
|
||||
}
|
||||
targetElement = GotoDeclarationAction.findTargetElementNoVS(myProject, editor, offset);
|
||||
}
|
||||
else if (browseMode == BrowseMode.Implementation) {
|
||||
final PsiElement element = TargetElementUtilBase.getInstance().findTargetElement(editor, ImplementationSearcher.getFlags(), offset);
|
||||
|
||||
+38
-17
@@ -76,13 +76,16 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
|
||||
try {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = findTargetElement(project, editor, offset);
|
||||
PsiElement[] elements = findAllTargetElements(project, editor, offset);
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.declaration");
|
||||
if (element == null) {
|
||||
chooseAmbiguousTarget(editor, offset);
|
||||
|
||||
if (elements.length != 1) {
|
||||
chooseAmbiguousTarget(editor, offset, elements);
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiElement element = elements[0];
|
||||
|
||||
PsiElement navElement = element.getNavigationElement();
|
||||
navElement = TargetElementUtilBase.getInstance().getGotoDeclarationTarget(element, navElement);
|
||||
|
||||
@@ -104,7 +107,7 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
}
|
||||
}
|
||||
|
||||
private static void chooseAmbiguousTarget(final Editor editor, int offset) {
|
||||
private static void chooseAmbiguousTarget(final Editor editor, int offset, PsiElement[] elements) {
|
||||
PsiElementProcessor<PsiElement> navigateProcessor = new PsiElementProcessor<PsiElement>() {
|
||||
public boolean execute(final PsiElement element) {
|
||||
Navigatable navigatable = EditSourceUtil.getDescriptor(element);
|
||||
@@ -114,28 +117,37 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
return true;
|
||||
}
|
||||
};
|
||||
boolean found = chooseAmbiguousTarget(editor, offset, navigateProcessor, CodeInsightBundle.message("declaration.navigation.title"));
|
||||
boolean found =
|
||||
chooseAmbiguousTarget(editor, offset, navigateProcessor, CodeInsightBundle.message("declaration.navigation.title"), elements);
|
||||
if (!found) {
|
||||
HintManager.getInstance().showErrorHint(editor, "Cannot find declaration to go to");
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if processor is run or is going to be run after showing popup
|
||||
public static boolean chooseAmbiguousTarget(final Editor editor, int offset, PsiElementProcessor<PsiElement> processor, String titlePattern) {
|
||||
public static boolean chooseAmbiguousTarget(final Editor editor,
|
||||
int offset,
|
||||
PsiElementProcessor<PsiElement> processor,
|
||||
String titlePattern,
|
||||
PsiElement[] elements) {
|
||||
if (TargetElementUtilBase.inVirtualSpace(editor, offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiReference reference = TargetElementUtilBase.findReference(editor, offset);
|
||||
final Collection<PsiElement> candidates = suggestCandidates(reference);
|
||||
if (candidates.size() == 1) {
|
||||
PsiElement element = candidates.iterator().next();
|
||||
|
||||
if (elements == null) {
|
||||
final Collection<PsiElement> candidates = suggestCandidates(reference);
|
||||
elements = PsiUtilBase.toPsiElementArray(candidates);
|
||||
}
|
||||
|
||||
if (elements.length == 1) {
|
||||
PsiElement element = elements[0];
|
||||
LOG.assertTrue(element != null);
|
||||
processor.execute(element);
|
||||
return true;
|
||||
}
|
||||
if (candidates.size() > 1) {
|
||||
PsiElement[] elements = PsiUtilBase.toPsiElementArray(candidates);
|
||||
if (elements.length > 1) {
|
||||
final TextRange range = reference.getRangeInElement();
|
||||
final String refText = range.substring(reference.getElement().getText());
|
||||
String title = MessageFormat.format(titlePattern, refText);
|
||||
@@ -158,15 +170,22 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
|
||||
@Nullable
|
||||
public static PsiElement findTargetElement(Project project, Editor editor, int offset) {
|
||||
final PsiElement[] targets = findAllTargetElements(project, editor, offset);
|
||||
return targets.length == 1 ? targets[0] : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiElement[] findAllTargetElements(Project project, Editor editor, int offset) {
|
||||
if (TargetElementUtilBase.inVirtualSpace(editor, offset)) {
|
||||
return null;
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
return findTargetElementNoVS(project, editor, offset);
|
||||
final PsiElement[] targets = findTargetElementsNoVS(project, editor, offset);
|
||||
return targets != null ? targets : PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement findTargetElementNoVS(Project project, Editor editor, int offset) {
|
||||
public static PsiElement[] findTargetElementsNoVS(Project project, Editor editor, int offset) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (file == null) {
|
||||
return null;
|
||||
@@ -174,7 +193,7 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
PsiElement elementAt = file.findElementAt(offset);
|
||||
|
||||
for (GotoDeclarationHandler handler : Extensions.getExtensions(GotoDeclarationHandler.EP_NAME)) {
|
||||
PsiElement result = handler.getGotoDeclarationTarget(elementAt);
|
||||
PsiElement[] result = handler.getGotoDeclarationTargets(elementAt);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
@@ -182,12 +201,14 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
|
||||
|
||||
int flags = TargetElementUtilBase.getInstance().getAllAccepted() & ~TargetElementUtilBase.ELEMENT_NAME_ACCEPTED;
|
||||
PsiElement element = TargetElementUtilBase.getInstance().findTargetElement(editor, flags, offset);
|
||||
if (element != null) return element;
|
||||
if (element != null) {
|
||||
return new PsiElement[] {element};
|
||||
}
|
||||
|
||||
// if no references found in injected fragment, try outer document
|
||||
if (editor instanceof EditorWindow) {
|
||||
EditorWindow window = (EditorWindow)editor;
|
||||
return findTargetElementNoVS(project, window.getDelegate(), window.getDocument().injectedToHost(offset));
|
||||
return findTargetElementsNoVS(project, window.getDelegate(), window.getDocument().injectedToHost(offset));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,5 +27,5 @@ public interface GotoDeclarationHandler {
|
||||
ExtensionPointName<GotoDeclarationHandler> EP_NAME = ExtensionPointName.create("com.intellij.gotoDeclarationHandler");
|
||||
|
||||
@Nullable
|
||||
PsiElement getGotoDeclarationTarget(PsiElement sourceElement);
|
||||
PsiElement[] getGotoDeclarationTargets(PsiElement sourceElement);
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.navigation.actions;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public abstract class GotoDeclarationHandlerBase implements GotoDeclarationHandler {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement[] getGotoDeclarationTargets(PsiElement sourceElement) {
|
||||
final PsiElement target = getGotoDeclarationTarget(sourceElement);
|
||||
return target != null ? new PsiElement[] {target} : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract PsiElement getGotoDeclarationTarget(PsiElement sourceElement);
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public class FindUsagesAction extends AnAction {
|
||||
}
|
||||
else {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
boolean chosen = GotoDeclarationAction.chooseAmbiguousTarget(editor, offset, processor, FindBundle.message("find.usages.ambiguous.title"));
|
||||
boolean chosen = GotoDeclarationAction.chooseAmbiguousTarget(editor, offset, processor, FindBundle.message("find.usages.ambiguous.title"), null);
|
||||
if (!chosen) {
|
||||
HintManager.getInstance().showErrorHint(editor, FindBundle.message("find.no.usages.at.cursor.error"));
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,10 +16,10 @@
|
||||
package com.intellij.codeInspection.i18n.folding;
|
||||
|
||||
import com.intellij.codeInsight.folding.impl.EditorFoldingInfo;
|
||||
import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler;
|
||||
import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandlerBase;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.CompositeFoldingBuilder;
|
||||
import com.intellij.lang.folding.FoldingBuilder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.FoldRegion;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class I18nMessageGotoDeclarationHandler implements GotoDeclarationHandler {
|
||||
public class I18nMessageGotoDeclarationHandler extends GotoDeclarationHandlerBase {
|
||||
private static final Key<FoldingBuilder> KEY = CompositeFoldingBuilder.FOLDING_BUILDER;
|
||||
|
||||
public PsiElement getGotoDeclarationTarget(PsiElement element) {
|
||||
|
||||
Reference in New Issue
Block a user