/******************************************************************************* * Copyright (c) 2015 Nathan Ridge and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nathan Ridge - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.selection; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; 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; import org.eclipse.cdt.ui.tests.BaseUITestCase; import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; 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. */ public abstract class BaseSelectionTests extends BaseUITestCase { private IProgressMonitor monitor = new NullProgressMonitor(); public BaseSelectionTests() { super(); } public BaseSelectionTests(String name) { super(name); } /** * Derived classes should override this to return 'true' if they run tests where the * OpenDeclarationsAction can open a different editor than the one from which the action was invoked. */ protected boolean shouldUpdateEditor() { return false; } protected IASTNode testF3(IFile file, int offset) throws ParserException, CoreException { return testF3(file, offset, 0, null); } 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$ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IEditorPart part = null; try { part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ } catch (PartInitException e) { assertFalse(true); } if (part instanceof CEditor) { CEditor editor= (CEditor) part; EditorTestHelper.joinReconciler(EditorTestHelper.getSourceViewer(editor), 100, 5000, 10); editor.getSelectionProvider().setSelection(new TextSelection(offset,length)); final OpenDeclarationsAction action = (OpenDeclarationsAction) editor.getAction("OpenDeclarations"); //$NON-NLS-1$ if (disambiguator == null) { action.runSync(); } else { action.runSync(disambiguator); } if (shouldUpdateEditor()) { // update the file/part to point to the newly opened IFile/IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); assertTrue (part instanceof CEditor); editor= (CEditor) part; EditorTestHelper.joinReconciler(EditorTestHelper.getSourceViewer(editor), 0, 5000, 10); } // the action above should highlight the declaration, so now retrieve it and use that selection to get the IASTName selected on the TU ISelection sel = editor.getSelectionProvider().getSelection(); final IASTName[] result= { null }; if (sel instanceof ITextSelection) { final ITextSelection textSel = (ITextSelection)sel; ITranslationUnit tu= (ITranslationUnit) editor.getInputCElement(); IStatus ok= ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_IF_OPEN, monitor, new ASTRunnable() { @Override public IStatus runOnAST(ILanguage language, IASTTranslationUnit ast) throws CoreException { result[0]= ast.getNodeSelector(null).findName(textSel.getOffset(), textSel.getLength()); return Status.OK_STATUS; } }); assertTrue(ok.isOK()); return result[0]; } } return null; } }