diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTests.java index dea52796a42..11e61f6e2bf 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTests.java @@ -28,6 +28,7 @@ import org.eclipse.ui.part.FileEditorInput; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.ui.testplugin.EditorTestHelper; @@ -39,6 +40,8 @@ import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction; +import org.eclipse.cdt.internal.ui.search.actions.SelectionParseAction; +import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction.ITargetDisambiguator; /** * Base class for all selection tests, using the indexer or not. @@ -62,10 +65,44 @@ public abstract class BaseSelectionTests extends BaseUITestCase { } protected IASTNode testF3(IFile file, int offset) throws ParserException, CoreException { - return testF3(file, offset, 0); + return testF3(file, offset, 0, null); } - protected IASTNode testF3(IFile file, int offset, int length) throws ParserException, CoreException { + private static class TargetChooser implements ITargetDisambiguator { + private int fIndex; + private boolean fDisambiguationRequested = false; + + public TargetChooser(int index) { + fIndex = index; + } + + @Override + public ICElement disambiguateTargets(ICElement[] targets, SelectionParseAction action) { + fDisambiguationRequested = true; + return targets[fIndex]; + } + + public boolean disambiguationRequested() { + return fDisambiguationRequested; + } + } + + protected IASTNode testF3(IFile file, int offset, int length) throws ParserException, CoreException { + return testF3(file, offset, length, null); + } + + protected IASTNode testF3WithAmbiguity(IFile file, int offset, int targetChoiceIndex) + throws ParserException, CoreException { + TargetChooser chooser = new TargetChooser(targetChoiceIndex); + OpenDeclarationsAction.sDisallowAmbiguousInput = false; + IASTNode result = testF3(file, offset, 0, chooser); + OpenDeclarationsAction.sDisallowAmbiguousInput = true; + assertTrue(chooser.disambiguationRequested()); // Make sure there actually was an ambiguity + return result; + } + + protected IASTNode testF3(IFile file, int offset, int length, ITargetDisambiguator disambiguator) + throws ParserException, CoreException { if (offset < 0) throw new ParserException("offset can not be less than 0 and was " + offset); //$NON-NLS-1$ @@ -83,7 +120,11 @@ public abstract class BaseSelectionTests extends BaseUITestCase { editor.getSelectionProvider().setSelection(new TextSelection(offset,length)); final OpenDeclarationsAction action = (OpenDeclarationsAction) editor.getAction("OpenDeclarations"); //$NON-NLS-1$ - action.runSync(); + if (disambiguator == null) { + action.runSync(); + } else { + action.runSync(disambiguator); + } if (shouldUpdateEditor()) { // update the file/part to point to the newly opened IFile/IEditorPart diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java index 0f5cedfbf1c..a00501bc784 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/BaseSelectionTestsIndexer.java @@ -66,7 +66,7 @@ public class BaseSelectionTestsIndexer extends BaseSelectionTests { @Override protected void setUp() throws Exception { super.setUp(); - OpenDeclarationsAction.sIsJUnitTest= true; + OpenDeclarationsAction.sDisallowAmbiguousInput= true; IWorkbenchPage page= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IViewReference[] refs= page.getViewReferences(); for (IViewReference viewReference : refs) { diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java index e9325d94efc..9387ce50bdd 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java @@ -130,7 +130,7 @@ public class CPPSelectionTestsNoIndexer extends BaseSelectionTests { protected void setUp() throws Exception { super.setUp(); initProject(); - OpenDeclarationsAction.sIsJUnitTest= true; + OpenDeclarationsAction.sDisallowAmbiguousInput= true; } @Override @@ -1191,5 +1191,4 @@ public class CPPSelectionTestsNoIndexer extends BaseSelectionTests { int offset = code.indexOf("obj.waldo") + 4; assertTrue(testF3(file, offset) instanceof IASTName); } - } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java index 9e54662844f..b433c17a6a7 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java @@ -100,7 +100,7 @@ public class CSelectionTestsNoIndexer extends BaseSelectionTests { @Override protected void setUp() throws Exception { super.setUp(); - OpenDeclarationsAction.sIsJUnitTest= true; + OpenDeclarationsAction.sDisallowAmbiguousInput= true; initProject(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java index 24277fa5168..b762d731ea3 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java @@ -25,15 +25,17 @@ import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.ui.actions.OpenActionUtil; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.CEditorMessages; import org.eclipse.cdt.internal.ui.text.CWordFinder; +import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; /** * Navigates to the definition of a name, or to the declaration if invoked on the definition. */ public class OpenDeclarationsAction extends SelectionParseAction { - public static boolean sIsJUnitTest = false; + public static boolean sDisallowAmbiguousInput = false; ITextSelection fTextSelection; @@ -49,7 +51,7 @@ public class OpenDeclarationsAction extends SelectionParseAction { @Override public void run() { - OpenDeclarationsJob job = createJob(); + OpenDeclarationsJob job = createJob(sDefaultDisambiguator); if (job != null) job.schedule(); } @@ -58,17 +60,23 @@ public class OpenDeclarationsAction extends SelectionParseAction { * For the purpose of regression testing. */ public void runSync() throws CoreException { - OpenDeclarationsJob job = createJob(); + OpenDeclarationsJob job = createJob(sDefaultDisambiguator); + if (job != null) + job.performNavigation(new NullProgressMonitor()); + } + public void runSync(ITargetDisambiguator targetDisambiguator) throws CoreException { + OpenDeclarationsJob job = createJob(targetDisambiguator); if (job != null) job.performNavigation(new NullProgressMonitor()); } - private OpenDeclarationsJob createJob() { + private OpenDeclarationsJob createJob(ITargetDisambiguator targetDisambiguator) { String text= computeSelectedWord(); OpenDeclarationsJob job= null; ICElement elem= fEditor.getInputCElement(); if (elem instanceof ITranslationUnit && fTextSelection != null) { - job= new OpenDeclarationsJob(this, (ITranslationUnit) elem, fTextSelection, text); + job= new OpenDeclarationsJob(this, (ITranslationUnit) elem, fTextSelection, text, + targetDisambiguator); } return job; } @@ -93,4 +101,25 @@ public class OpenDeclarationsAction extends SelectionParseAction { } return text; } + + /** + * Used to diambiguate between multiple candidate targets for this action. + */ + public static interface ITargetDisambiguator { + ICElement disambiguateTargets(ICElement[] targets, SelectionParseAction action); + } + + /** + * Disambiguates by showing the user a dialog to choose. + */ + private static class DialogTargetDisambiguator implements ITargetDisambiguator { + @Override + public ICElement disambiguateTargets(ICElement[] targets, SelectionParseAction action) { + return OpenActionUtil.selectCElement(targets, action.getSite().getShell(), + CEditorMessages.OpenDeclarationsAction_dialog_title, CEditorMessages.OpenDeclarationsAction_selectMessage, + CElementLabels.ALL_DEFAULT | CElementLabels.ALL_FULLY_QUALIFIED | CElementLabels.MF_POST_FILE_QUALIFIED, 0); + } + } + + private static final ITargetDisambiguator sDefaultDisambiguator = new DialogTargetDisambiguator(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java index a3d1ca5f520..5a9b4c72949 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java @@ -97,10 +97,9 @@ import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory; import org.eclipse.cdt.internal.core.model.ext.ICElementHandle; -import org.eclipse.cdt.internal.ui.actions.OpenActionUtil; import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.CEditorMessages; -import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; +import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction.ITargetDisambiguator; import org.eclipse.cdt.internal.ui.viewsupport.IndexUI; class OpenDeclarationsJob extends Job implements ASTRunnable { @@ -112,13 +111,16 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { private IIndex fIndex; private final ITextSelection fTextSelection; private final String fSelectedText; + private final ITargetDisambiguator fTargetDisambiguator; - OpenDeclarationsJob(SelectionParseAction action, ITranslationUnit editorInput, ITextSelection textSelection, String text) { + OpenDeclarationsJob(SelectionParseAction action, ITranslationUnit editorInput, + ITextSelection textSelection, String text, ITargetDisambiguator targetDisambiguator) { super(CEditorMessages.OpenDeclarations_dialog_title); fAction= action; fTranslationUnit= editorInput; fTextSelection= textSelection; fSelectedText= text; + fTargetDisambiguator= targetDisambiguator; } @Override @@ -533,13 +535,11 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { } } if (target == null) { - if (OpenDeclarationsAction.sIsJUnitTest) { + if (OpenDeclarationsAction.sDisallowAmbiguousInput) { throw new RuntimeException("ambiguous input: " + uniqueElements.size()); //$NON-NLS-1$ } ICElement[] elemArray= uniqueElements.toArray(new ICElement[uniqueElements.size()]); - target = (ISourceReference) OpenActionUtil.selectCElement(elemArray, fAction.getSite().getShell(), - CEditorMessages.OpenDeclarationsAction_dialog_title, CEditorMessages.OpenDeclarationsAction_selectMessage, - CElementLabels.ALL_DEFAULT | CElementLabels.ALL_FULLY_QUALIFIED | CElementLabels.MF_POST_FILE_QUALIFIED, 0); + target = (ISourceReference) fTargetDisambiguator.disambiguateTargets(elemArray, fAction); } } if (target != null) {