blob: b78a540e9f8673e33210d3ed9826a128b8d25435 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2015 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text.selection;
import java.io.IOException;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import junit.framework.Test;
public class CSelectionIndexerTests extends BaseSelectionTestsIndexer {
private String sourceIndexerID;
private IIndex index;
public CSelectionIndexerTests(String name) {
super(name);
sourceIndexerID = IPDOMManager.ID_FAST_INDEXER;
}
public static Test suite() {
return suite(CSelectionIndexerTests.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
//Create temp project
fCProject = createProject("CSelectionTestsDOMIndexerProject"); //$NON-NLS-1$
assertNotNull("Unable to create project", fCProject);
CCorePlugin.getIndexManager().setIndexerId(fCProject, sourceIndexerID);
index = CCorePlugin.getIndexManager().getIndex(fCProject);
}
@Override
protected void tearDown() throws Exception {
closeAllEditors();
CProjectHelper.delete(fCProject);
super.tearDown();
}
private ICProject createProject(String projectName) throws CoreException {
ICProject cPrj = CProjectHelper.createCProject(projectName, "bin", IPDOMManager.ID_NO_INDEXER); //$NON-NLS-1$
return cPrj;
}
protected StringBuilder[] getContents(int sections) throws IOException {
return TestSourceReader.getContentsForTest(CTestPlugin.getDefault().getBundle(), "ui",
CSelectionIndexerTests.class, getName(), sections);
}
private void assertNode(String name, int offset, IASTNode node) {
assertNotNull(node);
assertEquals(node.toString(), name);
IASTFileLocation loc = node.getFileLocation();
assertEquals(offset, loc.getNodeOffset());
assertEquals(name.length(), loc.getNodeLength());
}
// // the header
// extern int MyInt; // MyInt is in another file
// extern const int MyConst; // MyConst is in another file
// void MyFunc(int); // often used in header files
// typedef int NewInt; // a normal typedef statement
// struct MyStruct { int Member1; int Member2; };
// #include "basicDefinition.h"
// int MyInt;
// extern const int MyConst = 42;
// void MyFunc(int a) { cout << a << endl; }
// struct MyStruct;
public void testBasicDefinition() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("basicDefinition.h", hcode);
IFile file = importFile("testBasicDefinition.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
int hoffset = hcode.indexOf("MyInt");
int soffset = scode.indexOf("MyInt");
IASTNode decl = testF3(file, soffset + 2);
IASTNode def = testF3(hfile, hoffset + 2);
assertTrue(def instanceof IASTName);
assertTrue(decl instanceof IASTName);
assertEquals("MyInt", ((IASTName) decl).toString()); //$NON-NLS-1$
assertEquals(hoffset, ((ASTNode) decl).getOffset());
assertEquals(5, ((ASTNode) decl).getLength());
assertEquals("MyInt", ((IASTName) def).toString()); //$NON-NLS-1$
assertEquals(soffset, def.getFileLocation().getNodeOffset());
assertEquals(5, ((ASTNode) def).getLength());
hoffset = hcode.indexOf("MyConst");
soffset = scode.indexOf("MyConst");
decl = testF3(file, soffset + 2);
def = testF3(hfile, hoffset + 2);
assertTrue(def instanceof IASTName);
assertTrue(decl instanceof IASTName);
assertEquals("MyConst", ((IASTName) decl).toString()); //$NON-NLS-1$
assertEquals(hoffset, ((ASTNode) decl).getOffset());
assertEquals(7, ((ASTNode) decl).getLength());
assertEquals("MyConst", ((IASTName) def).toString()); //$NON-NLS-1$
assertEquals(soffset, def.getFileLocation().getNodeOffset());
assertEquals(7, ((ASTNode) def).getLength());
hoffset = hcode.indexOf("MyFunc");
soffset = scode.indexOf("MyFunc");
decl = testF3(file, soffset + 2);
def = testF3(hfile, hoffset + 2);
assertTrue(def instanceof IASTName);
assertTrue(decl instanceof IASTName);
assertEquals("MyFunc", ((IASTName) decl).toString()); //$NON-NLS-1$
assertEquals(hoffset, ((ASTNode) decl).getOffset());
assertEquals(6, ((ASTNode) decl).getLength());
assertEquals("MyFunc", ((IASTName) def).toString()); //$NON-NLS-1$
assertEquals(soffset, def.getFileLocation().getNodeOffset());
assertEquals(6, ((ASTNode) def).getLength());
hoffset = hcode.indexOf("MyStruct");
soffset = scode.indexOf("MyStruct");
decl = testF3(file, soffset + 2);
def = testF3(hfile, hoffset + 2);
assertTrue(def instanceof IASTName);
assertTrue(decl instanceof IASTName);
assertEquals("MyStruct", ((IASTName) decl).toString()); //$NON-NLS-1$
assertEquals(hoffset, ((ASTNode) decl).getOffset());
assertEquals(8, ((ASTNode) decl).getLength());
assertEquals("MyStruct", ((IASTName) def).toString()); //$NON-NLS-1$
assertEquals(hoffset, def.getFileLocation().getNodeOffset());
assertEquals(8, ((ASTNode) def).getLength());
}
// // the header
// extern int a; // declares
// extern const int c = 1; // defines
// struct S {int a; int b;}; // defines
// struct X { // defines
// int x; // defines nonstatic data member
// };
// enum E {up, down}; // defines
// int f(int); // declares
// extern struct X anotherX; // declares
// #include "testCPPSpecDeclsDefs.h"
// int a; // defines
// struct X anX; // defines
// extern const int c; // declares
// int f(int x) {return x+a;} // defines
// struct S; // declares
// typedef int Int; // declares
// struct S s;
// Int lhs= s.a+s.b+up+down+anX+0;
public void testCPPSpecDeclsDefs() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("testCPPSpecDeclsDefs.h", hcode);
IFile file = importFile("testCPPSpecDeclsDefs.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
int offset0 = hcode.indexOf("a;");
int offset1 = scode.indexOf("a;");
IASTNode decl = testF3(hfile, offset0);
assertNode("a", offset1, decl);
decl = testF3(file, offset1);
assertNode("a", offset0, decl);
offset0 = hcode.indexOf("int c") + 4;
offset1 = scode.indexOf("int c") + 4;
decl = testF3(hfile, offset0);
assertNode("c", offset1, decl);
decl = testF3(file, offset1);
assertNode("c", offset0, decl);
offset0 = hcode.indexOf("f(int");
offset1 = scode.indexOf("f(int");
decl = testF3(hfile, offset0);
assertNode("f", offset1, decl);
decl = testF3(file, offset1);
assertNode("f", offset0, decl);
offset0 = scode.indexOf("x)");
decl = testF3(file, offset0);
assertNode("x", offset0, decl);
offset1 = scode.indexOf("x+a");
decl = testF3(file, offset1);
assertNode("x", offset0, decl);
offset0 = scode.indexOf("a;");
offset1 = scode.indexOf("a;}");
decl = testF3(file, offset1);
assertNode("a", offset0, decl);
offset0 = hcode.indexOf("S");
offset1 = scode.indexOf("S;");
int offset2 = scode.indexOf("S", offset1);
decl = testF3(hfile, offset0);
assertNode("S", offset0, decl);
decl = testF3(file, offset1);
assertNode("S", offset0, decl);
decl = testF3(file, offset2);
assertNode("S", offset0, decl);
offset0 = hcode.indexOf("a; int b;};");
offset1 = scode.indexOf("a+s.b");
decl = testF3(hfile, offset0);
assertNode("a", offset0, decl);
decl = testF3(file, offset1);
assertNode("a", offset0, decl);
offset0 = hcode.indexOf("b;};");
offset1 = scode.indexOf("s.b") + 2;
decl = testF3(hfile, offset0);
assertNode("b", offset0, decl);
decl = testF3(file, offset1);
assertNode("b", offset0, decl);
offset0 = hcode.indexOf("X");
offset1 = scode.indexOf("X");
decl = testF3(hfile, offset0);
assertNode("X", offset0, decl);
decl = testF3(file, offset1);
assertNode("X", offset0, decl);
offset0 = hcode.indexOf("x;");
decl = testF3(hfile, offset0);
assertNode("x", offset0, decl);
offset0 = hcode.indexOf("up");
offset1 = scode.indexOf("up");
decl = testF3(hfile, offset0);
assertNode("up", offset0, decl);
decl = testF3(file, offset1);
assertNode("up", offset0, decl);
offset0 = hcode.indexOf("down");
offset1 = scode.indexOf("down");
decl = testF3(hfile, offset0);
assertNode("down", offset0, decl);
decl = testF3(file, offset1);
assertNode("down", offset0, decl);
offset0 = scode.indexOf("anX");
offset1 = scode.indexOf("anX", offset0 + 1);
decl = testF3(file, offset0);
assertNode("anX", offset0, decl);
decl = testF3(file, offset1);
assertNode("anX", offset0, decl);
offset0 = scode.indexOf("Int");
offset1 = scode.indexOf("Int", offset0 + 1);
decl = testF3(file, offset0);
assertNode("Int", offset0, decl);
decl = testF3(file, offset1);
assertNode("Int", offset0, decl);
}
// extern int abc;
// #include "testBug101287.h"
// int main(int argc, char **argv) {
// abc;
// }
public void testBug101287() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("testBug101287.h", hcode);
IFile file = importFile("testBug101287.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("abc");
offset1 = scode.indexOf("abc");
decl = testF3(hfile, offset0);
assertNode("abc", offset0, decl);
decl = testF3(file, offset1);
assertNode("abc", offset0, decl);
}
// int x;
// #include "testBug103697.h"
// int foo() {
// return x;
// }
public void testBug103697() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFileWithLink("testBug103697.h", hcode);
IFile file = importFileWithLink("testBug103697.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("x");
offset1 = scode.indexOf("x");
decl = testF3(hfile, offset0);
assertNode("x", offset0, decl);
decl = testF3(file, offset1);
assertNode("x", offset0, decl);
}
// typedef int TestTypeOne;
// typedef int TestTypeTwo;
// #include "testBug78354.h"
// main()
// {
// TestTypeOne myFirstLink = 5;
// TestTypeTwo mySecondLink = 6;
// return 0;
// }
public void testBug78354() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("testBug78354.h", hcode);
IFile file = importFile("testBug78354.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("TestTypeOne");
offset1 = scode.indexOf("TestTypeOne");
decl = testF3(hfile, offset0);
assertNode("TestTypeOne", offset0, decl);
decl = testF3(file, offset1);
assertNode("TestTypeOne", offset0, decl);
offset0 = hcode.indexOf("TestTypeTwo");
offset1 = scode.indexOf("TestTypeTwo");
decl = testF3(hfile, offset0);
assertNode("TestTypeTwo", offset0, decl);
decl = testF3(file, offset1);
assertNode("TestTypeTwo", offset0, decl);
}
// typedef struct {
// int a;
// } usertype;
// void func(usertype t);
// #include "testBug190730.h"
// void func(usertype t) {
// }
public void testFuncWithTypedefForAnonymousStruct_190730() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("testBug190730.h", hcode);
IFile file = importFile("testBug190730.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("func");
offset1 = scode.indexOf("func");
decl = testF3(hfile, offset0);
assertNode("func", offset1, decl);
decl = testF3(file, offset1);
assertNode("func", offset0, decl);
}
// typedef enum {
// int eitem
// } userEnum;
// void func(userEnum t);
// #include "testBug190730_2.h"
// void func(userEnum t) {
// }
public void testFuncWithTypedefForAnonymousEnum_190730() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("testBug190730_2.h", hcode);
IFile file = importFile("testBug190730_2.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("func");
offset1 = scode.indexOf("func");
decl = testF3(hfile, offset0);
assertNode("func", offset1, decl);
decl = testF3(file, offset1);
assertNode("func", offset0, decl);
}
// #define MY_MACRO 0xDEADBEEF
// #define MY_FUNC() 00
// #define MY_PAR( aRef );
// #include "macrodef.h"
// int basictest(void){
// int tester = MY_MACRO; //OK: F3 works
// int xx= MY_FUNC();
// MY_PAR(0);
// }
public void testMacroNavigation() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("macrodef.h", hcode);
IFile file = importFile("macronavi.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("MY_MACRO");
offset1 = scode.indexOf("MY_MACRO");
decl = testF3(file, offset1);
assertNode("MY_MACRO", offset0, decl);
offset0 = hcode.indexOf("MY_FUNC");
offset1 = scode.indexOf("MY_FUNC");
decl = testF3(file, offset1);
assertNode("MY_FUNC", offset0, decl);
offset0 = hcode.indexOf("MY_PAR");
offset1 = scode.indexOf("MY_PAR");
decl = testF3(file, offset1);
assertNode("MY_PAR", offset0, decl);
}
// #define MY_MACRO 0xDEADBEEF
// #define MY_PAR( aRef ) aRef
// #include "macrodef.h"
// int basictest(void){
// int tester = MY_PAR(MY_MACRO);
// }
public void testMacroNavigation_Bug208300() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("macrodef.h", hcode);
IFile file = importFile("macronavi.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("MY_PAR");
offset1 = scode.indexOf("MY_PAR");
decl = testF3(file, offset1);
assertNode("MY_PAR", offset0, decl);
offset0 = hcode.indexOf("MY_MACRO");
offset1 = scode.indexOf("MY_MACRO");
decl = testF3(file, offset1);
assertNode("MY_MACRO", offset0, decl);
}
// int wurscht;
// #include "aheader.h"
public void testIncludeNavigation() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("aheader.h", hcode);
IFile file = importFile("includenavi.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset1 = scode.indexOf("aheader.h");
testF3(file, offset1);
IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
IEditorInput input = part.getEditorInput();
assertEquals("aheader.h", ((FileEditorInput) input).getFile().getName());
}
// #define DR_NUM_DIMENSIONS(DR) VEC_length (tree, DR_ACCESS_FNS (DR))
// #define DR_ACCESS_FNS(DR)
public void testNavigationInMacroDefinition_Bug102643() throws Exception {
StringBuilder[] buffers = getContents(2);
String hcode = buffers[0].toString();
String scode = buffers[1].toString();
IFile hfile = importFile("aheader.h", hcode);
IFile file = importFile("source.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl;
int offset0, offset1;
offset1 = hcode.indexOf("DR_ACC");
testF3(hfile, offset1);
IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
IEditorInput input = part.getEditorInput();
assertEquals("source.c", ((FileEditorInput) input).getFile().getName());
}
// int myFunc();
// int myFunc(var)
// int var;
// {
// return var;
// }
//
// int main(void)
// {
// return myFunc(0);
// }
public void testKRstyleFunctions_Bug221635() throws Exception {
final StringBuilder[] contents = getContentsForTest(2);
String hcode = contents[0].toString();
String code = contents[1].toString();
IFile hfile = importFile("aheader.h", hcode);
IFile file = importFile("source.c", code);
int offset = code.indexOf("myFunc(0)");
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
IASTNode decl = testF3(file, offset);
assertTrue(decl instanceof IASTName);
final IASTName name = (IASTName) decl;
assertTrue(name.isDefinition());
assertEquals("myFunc", name.toString());
}
// int x= __LINE__;
public void testBuiltinMacro_Bug293864() throws Exception {
final StringBuilder[] contents = getContentsForTest(1);
String code = contents[0].toString();
IFile file = importFile("source.c", code);
int offset = code.indexOf("__LINE__");
TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000);
// Just make sure that no NPE is thrown.
testF3(file, offset);
}
}