Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 1fcaceb245f70fef63d2976036c437431d32a0fa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*******************************************************************************
 * Copyright (c) 2015 Nathan Ridge and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Nathan Ridge - Initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.ui.tests.text.selection;

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.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.OpenDeclarationsAction.ITargetDisambiguator;
import org.eclipse.cdt.internal.ui.search.actions.SelectionParseAction;
import org.eclipse.cdt.ui.testplugin.EditorTestHelper;
import org.eclipse.cdt.ui.tests.BaseUITestCase;
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;

/**
 * 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;
	}
}

Back to the top