1
/*******************************************************************************
2
* Copyright (c) 2006, 2008 QNX Software Systems and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* QNX - Initial API and implementation
10
* Markus Schorn (Wind River Systems)
11
*******************************************************************************/
12
package org.eclipse.cdt.internal.pdom.tests;
15
import java.util.regex.Pattern;
17
import junit.framework.AssertionFailedError;
18
import junit.framework.Test;
20
import org.eclipse.cdt.core.dom.ILinkage;
21
import org.eclipse.cdt.core.dom.IName;
22
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
23
import org.eclipse.cdt.core.dom.ast.IBinding;
24
import org.eclipse.cdt.core.dom.ast.ICompositeType;
25
import org.eclipse.cdt.core.dom.ast.ITypedef;
26
import org.eclipse.cdt.core.index.IIndex;
27
import org.eclipse.cdt.core.index.IIndexBinding;
28
import org.eclipse.cdt.core.index.IIndexFile;
29
import org.eclipse.cdt.core.index.IIndexFileLocation;
30
import org.eclipse.cdt.core.index.IIndexName;
31
import org.eclipse.cdt.core.index.IndexFilter;
32
import org.eclipse.cdt.core.index.IndexLocationFactory;
33
import org.eclipse.cdt.core.model.ICProject;
34
import org.eclipse.cdt.core.model.ITranslationUnit;
35
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
36
import org.eclipse.cdt.internal.core.CCoreInternals;
37
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
38
import org.eclipse.cdt.internal.core.pdom.PDOM;
39
import org.eclipse.core.resources.IResource;
40
import org.eclipse.core.runtime.CoreException;
41
import org.eclipse.core.runtime.NullProgressMonitor;
42
import org.eclipse.core.runtime.Path;
43
import org.eclipse.jface.text.BadLocationException;
46
* Test that PDOM correctly track declarations, definitions and references of
49
* @author ELaskavaia@qnx.com
52
public class DefDeclTests extends PDOMTestBase {
53
private String projectName = null;
56
protected ICProject cproject;
58
public static Test suite() {
59
return suite(DefDeclTests.class);
62
protected void setUp() throws Exception {
63
String requiredName = "defDeclTests";
64
cproject = createProject(requiredName);
65
this.projectName = cproject.getElementName();
66
pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
67
pdom.acquireReadLock();
70
protected void tearDown() throws Exception {
71
pdom.releaseReadLock();
72
if (cproject != null) {
73
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
77
private IBinding findSingleBinding(String elName) throws CoreException {
78
IBinding[] binds = pdom.findBindings(Pattern.compile(elName), true,
79
IndexFilter.ALL, new NullProgressMonitor());
80
assertEquals(1, binds.length);
81
assertEquals(elName, binds[0].getName());
82
IBinding element = binds[0];
86
private void checkReference(IBinding element, String mark, int checkCount)
88
checkUsage(element, mark, checkCount, IIndex.FIND_REFERENCES);
91
private void checkDeclaration(IBinding element, String mark, int num)
93
checkUsage(element, mark, num, IIndex.FIND_DECLARATIONS);
96
private void checkDefinition(IBinding element, String mark, int countNum)
98
checkUsage(element, mark, countNum, IIndex.FIND_DEFINITIONS);
101
private void checkUsage(IBinding element, String mark, int countNum,
102
int flags) throws Exception {
103
if (mark == null || countNum == 0) {
104
getFirstUsage(element, 0, flags);
106
IName[] usage = pdom.findNames(element, flags);
108
assertEquals(countNum, usage.length);
110
boolean found = false;
111
for (int i = 0; i < usage.length; i++) {
112
IName name = usage[i];
113
IASTFileLocation loc = name.getFileLocation();
114
String fileName = new File(loc.getFileName()).getName();
117
markLine = getMarkLine(mark, fileName);
118
} catch (AssertionFailedError e) {
119
fail = e.getMessage();
122
int nodeLine = getLineNumber(loc.getNodeOffset(), fileName);
123
if (markLine != nodeLine) {
124
fail = "Marker at line " + markLine + ", actual at line "
136
* Get references defined by flags. If k>0 check that there are k of them.
140
* number of references, if k==-1 no check
141
* @return first references or null of non
142
* @throws CoreException
144
private IName getFirstUsage(IBinding binding, int k, int flags)
145
throws CoreException {
146
IName[] decls = pdom.findNames(binding, flags);
148
assertEquals(k, decls.length);
149
if (decls.length > 0) {
150
IName ref = decls[0];
157
protected void assertAtMark(IASTFileLocation loc, String mark)
159
String fileName = new File(loc.getFileName()).getName();
160
int markLine = getMarkLine(mark, fileName);
161
int nodeLine = getLineNumber(loc.getNodeOffset(), fileName);
162
assertEquals(markLine, nodeLine);
165
private int getMarkLine(String mark, String fileName) throws Exception,
166
BadLocationException {
167
int markLine = getLineNumber(offset(fileName, mark), fileName);
171
protected int getLineNumber(int position, String projectRelativePath)
173
Path fullPath = new Path(projectName + "/" + projectRelativePath);
174
return TestSourceReader.getLineNumber(position, fullPath);
177
public void assertDefDeclRef(String name, String testNum, int def,
178
int decl, int ref) throws Exception {
179
String elName = name + testNum;
180
IBinding binding = findSingleBinding(elName);
181
checkDefinition(binding, "def" + testNum, def);
182
checkDeclaration(binding, "decl" + testNum, decl);
183
checkReference(binding, "ref" + testNum, ref);
186
/* ------------------ Tests Started Here ------------------------ */
187
public void testInit() {
188
// will fail if setUp fails, maybe timelimit is too small for warm-up
191
public void testSimpleDeclUsage_f01() throws Exception {
192
assertDefDeclRef("foo", "01", 0, 1, 1);
195
public void testKRDeclUsage_f02() throws Exception {
196
assertDefDeclRef("foo", "02", 0, 1, 1);
199
public void testImplicitDeclPostDecl_f03() throws Exception {
200
assertDefDeclRef("foo", "03", 0, 1, 1);
203
public void testImplicitDeclPostDef_f04() throws Exception {
204
assertDefDeclRef("foo", "04", 1, 0, 1);
207
public void testImplicitDeclNone_f05() throws Exception {
208
assertDefDeclRef("foo", "05", 0, 0, 1);
211
public void testNonLocalDefintion_f06() throws Exception {
212
assertDefDeclRef("foo", "06", 1, 1, 1);
215
public void testWrongMatchedStaticDefinition() throws Exception {
216
String elName = "foo" + "07";
217
IIndexBinding[] binds = pdom.findBindings(Pattern.compile(elName), true, IndexFilter.ALL, new NullProgressMonitor());
218
assertEquals(2, binds.length);
219
assertTrue(binds[0].isFileLocal() != binds[1].isFileLocal());
220
if (binds[0].isFileLocal()) {
221
IIndexBinding b= binds[0]; binds[0]= binds[1]; binds[1]= b;
224
assertEquals(elName, binds[0].getName());
225
checkDefinition(binds[0], "def" + "07", 0);
226
checkDeclaration(binds[0], "decl" + "07", 1);
227
checkReference(binds[0], "ref" + "07", 1);
229
assertEquals(elName, binds[1].getName());
230
assertTrue(binds[1].getLocalToFile().getLocation().getFullPath().endsWith("second.c"));
231
checkDefinition(binds[1], "def" + "07", 1);
232
checkDeclaration(binds[1], "decl" + "07", 0);
233
checkReference(binds[1], "ref" + "07", 0);
236
public void testStaticBindings_f08() throws Exception {
237
String elName = "foo" + "08";
239
IIndexFileLocation ifl= IndexLocationFactory.getIFL((ITranslationUnit) cproject.findElement(new Path("func.c")));
240
IIndexFile file= pdom.getFile(ILinkage.C_LINKAGE_ID, ifl);
241
int offset= TestSourceReader.indexOfInFile("foo08();", new Path(ifl.getFullPath()));
242
IIndexName[] names= file.findNames(offset, 5);
243
assertEquals(1, names.length);
245
IBinding element = pdom.findBinding((IIndexFragmentName)names[0]);
246
assertEquals(elName, element.getName());
247
checkDefinition(element, "def" + "08", 1);
248
checkReference(element, "ref" + "08", 1);
250
// check the other file
251
ifl= IndexLocationFactory.getIFL((ITranslationUnit) cproject.findElement(new Path("second.c")));
252
file= pdom.getFile(ILinkage.C_LINKAGE_ID, ifl);
253
offset= TestSourceReader.indexOfInFile("foo08();", new Path(ifl.getFullPath()));
254
names= file.findNames(offset, 5);
255
assertEquals(1, names.length);
257
element = pdom.findBinding((IIndexFragmentName)names[0]);
258
assertEquals(elName, element.getName());
259
checkDefinition(element, "defS" + "08", 1);
260
checkReference(element, "refS" + "08", 1);
263
public void testSimpleGlobalWrite_v09() throws Exception {
264
assertDefDeclRef("var", "_v09", 1, 0, 1);
267
public void testGlobalInitRead_v10() throws Exception {
268
assertDefDeclRef("var", "_v10", 1, 0, 1);
271
public void testGlobalInitRead2_v11() throws Exception {
272
assertDefDeclRef("var", "_v11", 1, 0, 1);
275
public void testDeclUseDef_v12() throws Exception {
276
assertDefDeclRef("var", "_v12", 1, 1, 1);
279
public void testDeclDefUse_v13() throws Exception {
280
assertDefDeclRef("var", "_v13", 1, 1, 1);
283
public void testDefDeclUse_v14() throws Exception {
284
// Hmm. This test seems to work, but Find Declaration in the UI does not
286
assertDefDeclRef("var", "_v14", 1, 1, 1);
289
public void testNamedStruct_t01() throws Exception {
290
assertDefDeclRef("type", "_t01", 1, 0, 1);
293
public void testStructPreDefintion_t02() throws Exception {
294
assertDefDeclRef("type", "_t02", 0, 1, 1);
297
public void testStructRecursive_t03() throws Exception {
298
assertDefDeclRef("type", "_t03", 1, 1, 1);
301
public void testStructAndTypedef_t04() throws Exception {
303
String elName = "type" + num;
305
IBinding[] bindings = pdom.findBindings(Pattern.compile(elName), false, IndexFilter.ALL, new NullProgressMonitor());
306
assertEquals(2,bindings.length);
308
IBinding typedef = bindings[0] instanceof ITypedef ? bindings[0] : bindings[1];
309
IBinding struct = bindings[0] instanceof ICompositeType ? bindings[0] : bindings[1];
311
checkReference(typedef, "ref" + num, 1);
312
checkDefinition(typedef, "def" + num, 1);
314
checkReference(struct, "refS" + num, 1);
315
checkDefinition(struct, "defS" + num, 1);
318
public void testTypedefAndAnonymousStruct_t05() throws Exception {
319
assertDefDeclRef("type", "_t05", 1, 0, 1);