1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-03 14:25:37 +02:00

Additional test cases for Call Hierarchy

This commit is contained in:
Markus Schorn 2006-09-06 07:56:18 +00:00
parent b4c6a27239
commit de527bb7cd
6 changed files with 509 additions and 237 deletions

View file

@ -29,7 +29,14 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
public class BaseTestCase extends TestCase {
public BaseTestCase() {
super();
}
public BaseTestCase(String name) {
super(name);
}
/**
* Reads a section in comments form the source of the given class. The section
* is started with '// {tag}' and ends with the first line not started by '//'

View file

@ -0,0 +1,332 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.callhierarchy;
import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.cdt.internal.ui.editor.CEditor;
public class BasicCallHierarchyTest extends CallHierarchyBaseTest {
private static final int EVENT_QUEUE_MILLIS = 100;
public BasicCallHierarchyTest(String name) {
super(name);
}
public void testFunctionsC() throws Exception {
doTestFunctions("functions.c");
}
public void testFunctionsCpp() throws Exception {
doTestFunctions("functions.cpp");
}
// {testFunctions}
// void proto();
// void func() {
// };
// void main() {
// proto(); //ref
// func(); //ref
// };
private void doTestFunctions(String filename) throws IOException, Exception, PartInitException {
String content = readTaggedComment("testFunctions");
IFile file= createFile(getProject(), filename, content);
waitForIndexer(file, 1000);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
CEditor editor= (CEditor) IDE.openEditor(page, file);
editor.selectAndReveal(content.indexOf("proto"), 5);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
Tree tree = getCHTree(page);
checkTreeNode(tree, 0, "proto()");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("func"), 2);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "func()");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("proto(); //ref"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "proto()");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("func(); //ref"), 7);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "func()");
checkTreeNode(tree, 0, 0, "main()");
}
public void testVariablesC() throws Exception {
doTestVariables("variables.c");
}
public void testVariablesCpp() throws Exception {
doTestVariables("variables.cpp");
}
// {testVariables}
// extern int extern_var;
// int global_var= 0;
// void main() {
// int i= extern_var; //ref
// i= global_var; //ref
// };
private void doTestVariables(String filename) throws Exception {
String content = readTaggedComment("testVariables");
IFile file= createFile(getProject(), filename, content);
waitForIndexer(file, 1000);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
CEditor editor= (CEditor) IDE.openEditor(page, file);
editor.selectAndReveal(content.indexOf("extern_var"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
Tree tree = getCHTree(page);
checkTreeNode(tree, 0, "extern_var");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("global_var"), 2);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "global_var");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("extern_var; //ref"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "extern_var");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("global_var; //ref"), 7);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "global_var");
checkTreeNode(tree, 0, 0, "main()");
}
public void testEnumeratorC() throws Exception {
doTestEnumerator("enumerator.c", "testEnumerator");
}
public void testEnumeratorCpp() throws Exception {
doTestEnumerator("enumerator.cpp", "testEnumerator");
}
public void failing_testAnonymousEnumeratorC() throws Exception {
doTestEnumerator("enumerator.c", "testAnonymousEnumerator");
}
public void failing_testAnonymousEnumeratorCpp() throws Exception {
doTestEnumerator("enumerator.cpp", "testAnonymousEnumerator");
}
// {testEnumerator}
// enum Enum {enumerator=12};
// void main() {
// int i= enumerator; //ref
// };
// {testAnonymousEnumerator}
// enum {enumerator};
// void main() {
// int i= enumerator; //ref
// };
private void doTestEnumerator(String filename, String contentTag) throws Exception {
String content = readTaggedComment(contentTag);
IFile file= createFile(getProject(), filename, content);
waitForIndexer(file, 1000);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
CEditor editor= (CEditor) IDE.openEditor(page, file);
editor.selectAndReveal(content.indexOf("enumerator"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
Tree tree = getCHTree(page);
checkTreeNode(tree, 0, "enumerator");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("main"), 2);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "main()");
editor.selectAndReveal(content.indexOf("enumerator; //ref"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "enumerator");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("main"), 2);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "main()");
}
public void testStructMembersC() throws Exception {
doTestStructMembers("struct_member.c");
}
public void testStructMembersCpp() throws Exception {
doTestStructMembers("struct_member.cpp");
}
// {testStructMembers}
// struct s1 {
// int mem1;
// };
// typedef struct s2 {
// int mem2;
// } t2;
// typedef struct {
// int mem3;
// } t3;
// struct s4 {
// struct {
// int mem5;
// } mem4;
// };
//
// void main() {
// struct s1 vs1;
// struct s2 vs2;
// struct s4 vs4;
// t2 vt2;
// t3 vt3;
// int i;
// i= vs1.mem1; //ref
// i= vs2.mem2; //ref
// i= vs4.mem4.mem5; //ref
// i= vt2.mem2; //ref
// i= vt3.mem3; //ref
// };
private void doTestStructMembers(String filename) throws Exception {
String content = readTaggedComment("testStructMembers");
IFile file= createFile(getProject(), filename, content);
waitForIndexer(file, 1000);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
CEditor editor= (CEditor) IDE.openEditor(page, file);
editor.selectAndReveal(content.indexOf("mem1"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
Tree tree = getCHTree(page);
checkTreeNode(tree, 0, "s1::mem1");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem2"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "s2::mem2");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem3"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "(anon)::mem3");
editor.selectAndReveal(content.indexOf("mem4"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "s4::mem4");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem5"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "s4::(anon)::mem5");
editor.selectAndReveal(content.indexOf("mem1; //ref"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "s1::mem1");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem2; //ref"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "s2::mem2");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem4."), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "s4::mem4");
checkTreeNode(tree, 0, 0, "main()");
}
public void failing_testAnonymousStructMembersC() throws Exception {
doTestAnonymousStructMembers("anon_struct_member.c");
}
public void failing_testAnonymousStructMembersCpp() throws Exception {
doTestAnonymousStructMembers("anon_struct_member.cpp");
}
private void doTestAnonymousStructMembers(String filename) throws Exception {
String content = readTaggedComment("testStructMembers");
IFile file= createFile(getProject(), filename, content);
waitForIndexer(file, 1000);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
CEditor editor= (CEditor) IDE.openEditor(page, file);
editor.selectAndReveal(content.indexOf("mem3"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
Tree tree = getCHTree(page);
checkTreeNode(tree, 0, "(anon)::mem3");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem5"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
checkTreeNode(tree, 0, "s4::(anon)::mem5");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem3; //ref"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "(anon)::mem3");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("mem5; //ref"), 0);
openCallHierarchy(editor);
runEventQueue(EVENT_QUEUE_MILLIS);
tree = getCHTree(page);
checkTreeNode(tree, 0, "s4::(anon)::mem5");
checkTreeNode(tree, 0, 0, "main()");
}
}

View file

@ -39,10 +39,15 @@ public class CallHierarchyBaseTest extends BaseTestCase {
private ICProject fCProject;
private PDOM fPdom;
public CallHierarchyBaseTest(String name) {
super(name);
}
protected void setUp() throws CoreException {
fCProject= CProjectHelper.createCProject("__chTest__", "bin");
CCorePlugin.getPDOMManager().setIndexerId(fCProject, "org.eclipse.cdt.core.fastIndexer");
fPdom= (PDOM) CCorePlugin.getPDOMManager().getPDOM(fCProject);
fPdom.clear();
}
protected void tearDown() throws CoreException {
@ -100,7 +105,7 @@ public class CallHierarchyBaseTest extends BaseTestCase {
root= tree.getItem(i0);
}
catch (IllegalArgumentException e) {
assertTrue("Tree node " + i0 + " does not exist!", false);
assertTrue("Tree node " + label + "{" + i0 + "} does not exist!", false);
}
assertEquals(label, root.getText());
}
@ -112,7 +117,7 @@ public class CallHierarchyBaseTest extends BaseTestCase {
item= root.getItem(i1);
}
catch (IllegalArgumentException e) {
assertTrue("Tree node " + i0 + "," + i1 + " does not exist!", false);
assertTrue("Tree node " + label + "{" + i0 + "," + i1 + "} does not exist!", false);
}
assertEquals(label, item.getText());
}

View file

@ -13,6 +13,8 @@ package org.eclipse.cdt.ui.tests.callhierarchy;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.tests.FailingTest;
public class CallHierarchyTestSuite extends TestSuite {
public static TestSuite suite() {
@ -21,6 +23,10 @@ public class CallHierarchyTestSuite extends TestSuite {
public CallHierarchyTestSuite() {
super("Tests in package org.eclipse.cdt.ui.tests.callhierarchy");
addTestSuite(OpenCallHierarchyFromEditorTest.class);
addTestSuite(BasicCallHierarchyTest.class);
addTest(new FailingTest(new BasicCallHierarchyTest("failing_testAnonymousEnumeratorC")));;
addTest(new FailingTest(new BasicCallHierarchyTest("failing_testAnonymousEnumeratorCpp")));;
addTest(new FailingTest(new BasicCallHierarchyTest("failing_testAnonymousStructMembersC")));;
addTest(new FailingTest(new BasicCallHierarchyTest("failing_testAnonymousStructMembersCpp")));;
}
}

View file

@ -1,111 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.callhierarchy;
import org.eclipse.core.resources.IFile;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.cdt.internal.ui.editor.CEditor;
public class OpenCallHierarchyFromEditorTest extends CallHierarchyBaseTest {
// {testFunctions}
// void proto();
// void func() {
// };
// void main() {
// proto(); //ref
// func(); //ref
// };
public void testFunctions() throws Exception {
String content = readTaggedComment("testFunctions");
IFile file= createFile(getProject(), "functions.c", content);
waitForIndexer(file, 1000);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
CEditor editor= (CEditor) IDE.openEditor(page, file);
editor.selectAndReveal(content.indexOf("proto"), 5);
openCallHierarchy(editor);
runEventQueue(100);
Tree tree = getCHTree(page);
checkTreeNode(tree, 0, "proto()");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("func"), 2);
openCallHierarchy(editor);
runEventQueue(100);
checkTreeNode(tree, 0, "func()");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("proto(); //ref"), 0);
openCallHierarchy(editor);
runEventQueue(100);
tree = getCHTree(page);
checkTreeNode(tree, 0, "proto()");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("func(); //ref"), 7);
openCallHierarchy(editor);
runEventQueue(100);
tree = getCHTree(page);
checkTreeNode(tree, 0, "func()");
checkTreeNode(tree, 0, 0, "main()");
}
// {testVariables}
// extern int extern_var;
// int global_var= 0;
// void main() {
// int i= extern_var; //ref
// i= global_var; //ref
// };
public void testVariables() throws Exception {
String content = readTaggedComment("testVariables");
IFile file= createFile(getProject(), "variables.c", content);
waitForIndexer(file, 1000);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
CEditor editor= (CEditor) IDE.openEditor(page, file);
editor.selectAndReveal(content.indexOf("extern_var"), 0);
openCallHierarchy(editor);
runEventQueue(100);
Tree tree = getCHTree(page);
checkTreeNode(tree, 0, "extern_var");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("global_var"), 2);
openCallHierarchy(editor);
runEventQueue(100);
checkTreeNode(tree, 0, "global_var");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("extern_var; //ref"), 0);
openCallHierarchy(editor);
runEventQueue(100);
tree = getCHTree(page);
checkTreeNode(tree, 0, "extern_var");
checkTreeNode(tree, 0, 0, "main()");
editor.selectAndReveal(content.indexOf("global_var; //ref"), 7);
openCallHierarchy(editor);
runEventQueue(100);
tree = getCHTree(page);
checkTreeNode(tree, 0, "global_var");
checkTreeNode(tree, 0, 0, "main()");
}
}

View file

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
@ -26,6 +27,7 @@ import org.eclipse.jface.text.Region;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IPositionConverter;
import org.eclipse.cdt.core.dom.IPDOM;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -53,7 +55,8 @@ import org.eclipse.cdt.internal.corext.util.CModelUtil;
* @since 4.0
*/
public class CIndexQueries {
private static final ICElement[] EMPTY_ELEMENTS = new ICElement[0];
private static final int ASTTU_OPTIONS = ILanguage.AST_SKIP_ALL_HEADERS | ILanguage.AST_USE_INDEX;
private static final ICElement[] EMPTY_ELEMENTS = new ICElement[0];
private static final CIndexIncludeRelation[] EMPTY_INCLUDES = new CIndexIncludeRelation[0];
private static final CIndexQueries sInstance= new CIndexQueries();
@ -192,53 +195,52 @@ public class CIndexQueries {
* @since 4.0
*/
public CalledByResult findCalledBy(ICProject[] scope, ICElement callee, IProgressMonitor pm) {
IASTName name= astNameForElement(callee);
CalledByResult result= new CalledByResult();
if (name != null) {
// resolve the binding.
name.resolveBinding();
try {
findCalledBy(scope, callee, pm, result);
}
catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
catch (InterruptedException e) {
}
return result;
}
private void findCalledBy(ICProject[] scope, ICElement callee, IProgressMonitor pm, CalledByResult result)
throws CoreException, InterruptedException {
if (! (callee instanceof ISourceReference)) {
return;
}
ISourceReference sf= (ISourceReference) callee;
ISourceRange range;
range = sf.getSourceRange();
ITranslationUnit tu= sf.getTranslationUnit();
IPDOM pdom= CCorePlugin.getPDOMManager().getPDOM(tu.getCProject());
if (pdom != null) {
pdom.acquireReadLock();
}
try {
ILanguage language = tu.getLanguage();
IASTTranslationUnit ast= language.getASTTranslationUnit(tu, ASTTU_OPTIONS);
if (ast == null) {
return;
}
IASTName[] names = language.getSelectedNames(ast, range.getIdStartPos(), range.getIdLength());
if (names == null || names.length == 0) {
return;
}
IASTName name= names[names.length-1];
for (int i = 0; i < scope.length; i++) {
ICProject project = scope[i];
findCalledBy(name, project, result);
}
}
return result;
}
private IASTName astNameForElement(ICElement elem) {
try {
if (elem instanceof ISourceReference) {
ISourceReference sf= (ISourceReference) elem;
ISourceRange range= sf.getSourceRange();
ITranslationUnit tu= sf.getTranslationUnit();
IASTTranslationUnit ast= astUnitForTU(tu);
if (ast != null) {
ILanguage language = tu.getLanguage();
IASTName[] names = language.getSelectedNames(ast, range.getIdStartPos(), range.getIdLength());
if (names.length > 0) {
return names[names.length-1];
}
return null;
}
finally {
if (pdom != null) {
pdom.releaseReadLock();
}
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
return null;
}
private IASTTranslationUnit astUnitForTU(ITranslationUnit tu) {
try {
if (tu != null) {
ILanguage language = tu.getLanguage();
return language.getASTTranslationUnit(tu, ILanguage.AST_SKIP_ALL_HEADERS | ILanguage.AST_USE_INDEX);
}
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
return null;
}
private void findCalledBy(IASTName name, ICProject project, CalledByResult result) {
@ -252,7 +254,7 @@ public class CIndexQueries {
IASTName[] names= pdom.getReferences(binding);
for (int i = 0; i < names.length; i++) {
IASTName rname = names[i];
ITranslationUnit tu= toTranslationUnit(project, rname);
ITranslationUnit tu= getTranslationUnit(project, rname);
CIndexReference ref= new CIndexReference(tu, rname);
ICElement elem = findCalledBy(ref);
if (elem != null) {
@ -271,6 +273,20 @@ public class CIndexQueries {
}
}
private IBinding getPDOMBinding(PDOM pdom, IASTName name) {
IBinding binding= name.resolveBinding();
IASTTranslationUnit tu= name.getTranslationUnit();
ILanguage lang= tu.getLanguage();
PDOMLinkage linkage;
try {
linkage = pdom.getLinkage(lang);
return linkage.adaptBinding(binding);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
return null;
}
private ICElement findCalledBy(CIndexReference reference) {
ITranslationUnit tu= reference.getTranslationUnit();
long timestamp= reference.getTimestamp();
@ -306,41 +322,8 @@ public class CIndexQueries {
return null;
}
private ICElement findCElementForDeclaration(ICElement element, int offset, int length) {
int endoffset= offset+length;
if (element == null) {
return null;
}
try {
if (element instanceof IParent) {
ICElement[] children= ((IParent) element).getChildren();
for (int i = 0; i < children.length; i++) {
ICElement child = children[i];
if (child instanceof ISourceReference) {
ISourceRange sr= ((ISourceReference) child).getSourceRange();
int offset2= sr.getIdStartPos();
int endoffset2= offset2+sr.getIdLength();
if (offset <= offset2 && endoffset2 <= endoffset) {
return child;
}
offset2= sr.getStartPos();
endoffset2= offset2+sr.getLength();
if (offset2 <= offset && endoffset <= endoffset2) {
ICElement result= findCElementForDeclaration(child, offset, length);
if (result != null) {
return result;
}
}
}
}
}
} catch (CModelException e) {
CUIPlugin.getDefault().log(e);
}
return null;
}
private ITranslationUnit toTranslationUnit(ICProject cproject, IASTName name) {
private ITranslationUnit getTranslationUnit(ICProject cproject, IASTName name) {
IPath path= Path.fromOSString(name.getFileLocation().getFileName());
try {
return CModelUtil.findTranslationUnitForLocation(path, cproject);
@ -361,32 +344,55 @@ public class CIndexQueries {
*/
public CallsToResult findCallsInRange(ICProject[] scope, ITranslationUnit tu, IRegion range, IProgressMonitor pm) {
CallsToResult result= new CallsToResult();
IASTTranslationUnit astTU= astUnitForTU(tu);
if (astTU != null) {
ReferenceVisitor refVisitor= new ReferenceVisitor(astTU.getFilePath(), range.getOffset(), range.getLength());
astTU.accept(refVisitor);
IASTName[] refs = refVisitor.getReferences();
for (int i = 0; i < refs.length; i++) {
IASTName name = refs[i];
ICElement[] defs = findAllDefinitions(scope, name);
if (defs.length == 0) {
ICElement elem = findAnyDeclaration(scope, name);
if (elem != null) {
defs = new ICElement[] { elem };
}
}
if (defs != null && defs.length > 0) {
CIndexReference ref = new CIndexReference(tu, name);
result.add(defs, ref);
}
}
try {
findCallsInRange(scope, tu, range, pm, result);
}
catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
catch (InterruptedException e) {
}
return result;
}
private void findCallsInRange(ICProject[] scope, ITranslationUnit tu, IRegion range, IProgressMonitor pm, CallsToResult result)
throws CoreException, InterruptedException {
IPDOM pdom= CCorePlugin.getPDOMManager().getPDOM(tu.getCProject());
if (pdom != null) {
pdom.acquireReadLock();
}
try {
ILanguage language = tu.getLanguage();
IASTTranslationUnit astTU= language.getASTTranslationUnit(tu, ASTTU_OPTIONS);
if (astTU != null) {
ReferenceVisitor refVisitor= new ReferenceVisitor(astTU.getFilePath(), range.getOffset(), range.getLength());
astTU.accept(refVisitor);
IASTName[] refs = refVisitor.getReferences();
for (int i = 0; i < refs.length; i++) {
IASTName name = refs[i];
ICElement[] defs = findAllDefinitions(scope, name);
if (defs.length == 0) {
ICElement elem = findAnyDeclaration(scope, name);
if (elem != null) {
defs = new ICElement[] { elem };
}
}
if (defs != null && defs.length > 0) {
CIndexReference ref = new CIndexReference(tu, name);
result.add(defs, ref);
}
}
}
}
finally {
if (pdom != null) {
pdom.releaseReadLock();
}
}
}
public ICElement[] findAllDefinitions(ICProject[] projectsToSearch, IASTName name) {
name.resolveBinding();
ArrayList result= new ArrayList();
for (int i = 0; i < projectsToSearch.length; i++) {
ICProject project = projectsToSearch[i];
@ -407,7 +413,7 @@ public class CIndexQueries {
try {
IBinding binding= getPDOMBinding(pdom, name);
if (binding != null) {
return allEnclosingElements(project, pdom.getDefinitions(binding));
return getCElementsForNames(project, pdom.getDefinitions(binding));
}
}
finally {
@ -422,26 +428,13 @@ public class CIndexQueries {
return EMPTY_ELEMENTS;
}
private IBinding getPDOMBinding(PDOM pdom, IASTName name) {
IBinding binding= name.resolveBinding();
IASTTranslationUnit tu= name.getTranslationUnit();
ILanguage lang= tu.getLanguage();
PDOMLinkage linkage;
try {
linkage = pdom.getLinkage(lang);
return linkage.adaptBinding(binding);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
return null;
}
private ICElement[] allEnclosingElements(ICProject project, IASTName[] defs) {
private ICElement[] getCElementsForNames(ICProject project, IASTName[] defs) {
if (defs != null && defs.length > 0) {
ArrayList result= new ArrayList(defs.length);
HashSet result= new HashSet(defs.length);
for (int i = 0; i < defs.length; i++) {
IASTName defName = defs[i];
ICElement elem= findCElementForDeclaration(project, defName);
assert !defName.isReference();
ICElement elem= getCElementForName(project, defName);
if (elem != null) {
result.add(elem);
}
@ -451,8 +444,9 @@ public class CIndexQueries {
return EMPTY_ELEMENTS;
}
private ICElement findCElementForDeclaration(ICProject project, IASTName declName) {
ITranslationUnit tu= toTranslationUnit(project, declName);
private ICElement getCElementForName(ICProject project, IASTName declName) {
assert !declName.isReference();
ITranslationUnit tu= getTranslationUnit(project, declName);
if (tu != null) {
IRegion region= null;
if (declName instanceof PDOMName) {
@ -470,11 +464,50 @@ public class CIndexQueries {
IASTFileLocation loc= declName.getFileLocation();
region= new Region(loc.getNodeOffset(), loc.getNodeLength());
}
return findCElementForDeclaration(tu, region.getOffset(), region.getLength());
return getCElementWithRangeOfID(tu, region.getOffset(), region.getLength());
}
return null;
}
private ICElement getCElementWithRangeOfID(ICElement element, int offset, int length) {
if (element == null) {
return null;
}
try {
if (element instanceof IParent) {
ICElement[] children= ((IParent) element).getChildren();
for (int i = 0; i < children.length; i++) {
ICElement child = children[i];
if (child instanceof ISourceReference) {
ISourceRange sr= ((ISourceReference) child).getSourceRange();
if (surrounds(offset, length, sr.getIdStartPos(), sr.getIdLength())) {
return child;
}
int childOffset= sr.getStartPos();
if (childOffset > offset) {
return null;
}
if (surrounds(childOffset, sr.getLength(), offset, length)) {
ICElement result= getCElementWithRangeOfID(child, offset, length);
if (result != null) {
return result;
}
}
}
}
}
} catch (CModelException e) {
CUIPlugin.getDefault().log(e);
}
return null;
}
private boolean surrounds(int offset1, int length1, int offset2, int length2) {
int deltaOffset= offset2-offset1;
int deltaEndoffset= deltaOffset + length2 - length1;
return deltaOffset >= 0 && deltaEndoffset <= 0;
}
public ICElement findDefinition(ICProject[] projectsToSearch, IASTName name) {
name.resolveBinding();
@ -490,7 +523,7 @@ public class CIndexQueries {
public ICElement findDefinition(ICProject project, IASTName name) {
if (name.isDefinition()) {
return findCElementForDeclaration(project, name);
return getCElementForName(project, name);
}
PDOM pdom;
@ -501,7 +534,7 @@ public class CIndexQueries {
try {
IBinding binding= getPDOMBinding(pdom, name);
if (binding != null) {
ICElement elem= firstEnclosingElement(project, pdom.getDefinitions(binding));
ICElement elem= getFirstCElementForNames(project, pdom.getDefinitions(binding));
if (elem != null) {
return elem;
}
@ -519,11 +552,11 @@ public class CIndexQueries {
return null;
}
private ICElement firstEnclosingElement(ICProject project, IASTName[] defs) {
private ICElement getFirstCElementForNames(ICProject project, IASTName[] defs) {
if (defs != null) {
for (int i = 0; i < defs.length; i++) {
IASTName defName = defs[i];
ICElement elem= findCElementForDeclaration(project, defName);
ICElement elem= getCElementForName(project, defName);
if (elem != null) {
return elem;
}
@ -554,11 +587,11 @@ public class CIndexQueries {
try {
IBinding binding= getPDOMBinding(pdom, name);
if (binding != null) {
ICElement elem= firstEnclosingElement(project, pdom.getDefinitions(binding));
ICElement elem= getFirstCElementForNames(project, pdom.getDefinitions(binding));
if (elem != null) {
return elem;
}
elem= firstEnclosingElement(project, pdom.getDeclarations(binding));
elem= getFirstCElementForNames(project, pdom.getDeclarations(binding));
if (elem != null) {
return elem;
}