1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Navigation to implicitly called constructors. Bug 248855.

This commit is contained in:
Sergey Prigogin 2010-04-12 01:44:49 +00:00
parent 92e5bf17ea
commit ebee62c7ca
4 changed files with 136 additions and 80 deletions

View file

@ -21,6 +21,11 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
*/ */
public interface IName { public interface IName {
/**
* @since 5.2
*/
IName[] EMPTY_ARRAY= {};
/** /**
* Returns the name without qualification and without template arguments. * Returns the name without qualification and without template arguments.
* @since 5.1 * @since 5.1

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.ui.tests.text.selection; package org.eclipse.cdt.ui.tests.text.selection;
@ -398,14 +399,14 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
// #include "testCPPSpecDeclsDefs.h" // #include "testCPPSpecDeclsDefs.h"
// int a; // defines // int a; // defines
// int X::y = 1; // defines // int X::y = 1; // defines
// X anX; // defines // X anX; // defines variable, implicitly calls ctor
// extern const int c; // declares // extern const int c; // declares
// int f(int x) {return x+a;} // defines // int f(int x) {return x+a;} // defines
// struct S; // declares // struct S; // declares
// typedef int Int; // declares // typedef int Int; // declares
// using N::d; // declares // using N::d; // declares
// S s; // S s;
// Int lhs= s.a+s.b+up+down+anX+0; // Int lhs= s.a+s.b+up+down+anX+0;
public void testCPPSpecDeclsDefs() throws Exception { public void testCPPSpecDeclsDefs() throws Exception {
StringBuffer[] buffers= getContents(2); StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString(); String hcode= buffers[0].toString();
@ -474,7 +475,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
offset0= hcode.indexOf("X"); offset0= hcode.indexOf("X");
offset1= scode.indexOf("X"); offset1= scode.indexOf("X");
offset2= scode.indexOf("X", offset1+1); offset2= scode.indexOf("X", offset1 + 1);
decl= testF3(hfile, offset0); decl= testF3(hfile, offset0);
assertNode("X", offset0, decl); assertNode("X", offset0, decl);
decl= testF3(file, offset1); decl= testF3(file, offset1);
@ -483,7 +484,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
assertNode("X", offset0, decl); assertNode("X", offset0, decl);
offset0= hcode.indexOf("x;"); offset0= hcode.indexOf("x;");
offset1= hcode.indexOf("x", offset0+1); offset1= hcode.indexOf("x", offset0 + 1);
decl= testF3(hfile, offset0); decl= testF3(hfile, offset0);
assertNode("x", offset0, decl); assertNode("x", offset0, decl);
decl= testF3(hfile, offset1); decl= testF3(hfile, offset1);
@ -515,7 +516,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
assertNode("down", offset0, decl); assertNode("down", offset0, decl);
offset0= hcode.indexOf("N"); offset0= hcode.indexOf("N");
offset1= hcode.indexOf("N;", offset0+1); offset1= hcode.indexOf("N;", offset0 + 1);
offset2= scode.indexOf("N"); offset2= scode.indexOf("N");
decl= testF3(hfile, offset0); decl= testF3(hfile, offset0);
assertNode("N", offset0, decl); assertNode("N", offset0, decl);
@ -537,14 +538,14 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
assertNode("N1", offset0, decl); assertNode("N1", offset0, decl);
offset0= scode.indexOf("anX"); offset0= scode.indexOf("anX");
offset1= scode.indexOf("anX", offset0+1); offset1= scode.indexOf("anX", offset0 + 1);
decl= testF3(file, offset0); decl= testF3(file, offset0);
assertNode("anX", offset0, decl); assertNode("X", hcode.indexOf("X()"), decl);
decl= testF3(file, offset1); decl= testF3(file, offset1);
assertNode("anX", offset0, decl); assertNode("anX", offset0, decl);
offset0= scode.indexOf("Int"); offset0= scode.indexOf("Int");
offset1= scode.indexOf("Int", offset0+1); offset1= scode.indexOf("Int", offset0 + 1);
decl= testF3(file, offset0); decl= testF3(file, offset0);
assertNode("Int", offset0, decl); assertNode("Int", offset0, decl);
decl= testF3(file, offset1); decl= testF3(file, offset1);
@ -625,7 +626,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
assertNode("x", offset0, decl); assertNode("x", offset0, decl);
} }
// struct A { }; // implicitlydeclared A::operator= // struct A { }; // implicitly declared A::operator=
// struct B : A { // struct B : A {
// B& operator=(const B &); // B& operator=(const B &);
// }; // };
@ -646,7 +647,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
int offset0, offset1; int offset0, offset1;
offset0= scode.indexOf("s)"); offset0= scode.indexOf("s)");
offset1= scode.indexOf("s);", offset0+1); offset1= scode.indexOf("s);", offset0 + 1);
decl = testF3(file, offset0); decl = testF3(file, offset0);
assertNode("s", offset0, decl); assertNode("s", offset0, decl);
decl = testF3(file, offset1); decl = testF3(file, offset1);
@ -1023,7 +1024,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
int offset1, offset2; int offset1, offset2;
offset1 = scode.indexOf("cxcpp"); offset1 = scode.indexOf("cxcpp");
offset2 = scode.indexOf("cxcpp", offset1+1); offset2 = scode.indexOf("cxcpp", offset1 + 1);
testF3(cppfile, offset1); testF3(cppfile, offset1);
IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
IEditorInput input = part.getEditorInput(); IEditorInput input = part.getEditorInput();
@ -1061,7 +1062,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
int offset1, offset2; int offset1, offset2;
offset1 = ccode.indexOf("cxcpp"); offset1 = ccode.indexOf("cxcpp");
offset2 = ccode.indexOf("cxcpp", offset1+1); offset2 = ccode.indexOf("cxcpp", offset1 + 1);
testF3(cfile, offset1); testF3(cfile, offset1);
IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
IEditorInput input = part.getEditorInput(); IEditorInput input = part.getEditorInput();
@ -1094,12 +1095,12 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
int offset1, offset2; int offset1, offset2;
offset1 = code.indexOf("ADD_TEXT"); offset1 = code.indexOf("ADD_TEXT");
offset2 = code.indexOf("ADD_TEXT", offset1+1); offset2 = code.indexOf("ADD_TEXT", offset1 + 1);
decl= testF3(file, offset2); decl= testF3(file, offset2);
assertNode("ADD_TEXT", offset1, decl); assertNode("ADD_TEXT", offset1, decl);
offset1 = code.indexOf("ADD", offset1+1); offset1 = code.indexOf("ADD", offset1 + 1);
offset2 = code.indexOf("ADD", offset2+1); offset2 = code.indexOf("ADD", offset2 + 1);
decl= testF3(file, offset2); decl= testF3(file, offset2);
assertNode("ADD", offset1, decl); assertNode("ADD", offset1, decl);
} }
@ -1131,7 +1132,7 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
offset1 = code.indexOf("operator []"); offset1 = code.indexOf("operator []");
offset2 = code.indexOf("[6];"); offset2 = code.indexOf("[6];");
decl = testF3(file, offset2+1); decl = testF3(file, offset2 + 1);
assertNode("operator []", offset1, decl); assertNode("operator []", offset1, decl);
offset2 = code.indexOf("];"); offset2 = code.indexOf("];");
decl = testF3(file, offset2); decl = testF3(file, offset2);
@ -1186,4 +1187,46 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
IASTNode def = testF3(file, offset + 1); IASTNode def = testF3(file, offset + 1);
assertTrue(def instanceof IASTName); assertTrue(def instanceof IASTName);
} }
// struct A {
// A();
// A(int x);
// };
// #include "testImplicitConstructorCall_248855.h"
// void func() {
// A a1;
// A a2(5);
// }
// struct B {
// B() : a3(1) {}
// A a3;
// };
public void testImplicitConstructorCall_248855() throws Exception {
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
IFile hfile = importFile("testImplicitConstructorCall_248855.h", hcode);
IFile file = importFile("testImplicitConstructorCall_248855.cpp", scode);
waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode target = testF3(file, scode.indexOf("a1"));
assertTrue(target instanceof IASTName);
assertEquals("A", ((IASTName) target).toString());
assertEquals(hcode.indexOf("A()"), target.getFileLocation().getNodeOffset());
assertEquals("A".length(), ((ASTNode) target).getLength());
target = testF3(file, scode.indexOf("a2"));
assertTrue(target instanceof IASTName);
assertEquals("A", ((IASTName) target).toString());
assertEquals(hcode.indexOf("A(int x)"), target.getFileLocation().getNodeOffset());
assertEquals("A".length(), ((ASTNode) target).getLength());
try {
target = testF3(file, scode.indexOf("a3"));
fail("Didn't expect navigation to succeed due to multiple choices: B::a3, A::A(int x).");
} catch (RuntimeException e) {
assertEquals("ambiguous input: 2", e.getMessage());
}
}
} }

View file

@ -524,7 +524,7 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
enum { up, down }; // defines up and down enum { up, down }; // defines up and down
namespace N { int d; } // defines N and N::d namespace N { int d; } // defines N and N::d
namespace N1 = N; // defines N1 namespace N1 = N; // defines N1
X anX; // defines anX X anX; // defines anX, implicitly calls X()
// whereas these are just declarations: // whereas these are just declarations:
extern int a; // declares a extern int a; // declares a
extern const int c; // declares c extern const int c; // declares c
@ -732,9 +732,9 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$ offset = code.indexOf("anX; // defines anX"); //$NON-NLS-1$
decl = testF3(file, offset); decl = testF3(file, offset);
assertTrue(decl instanceof IASTName); assertTrue(decl instanceof IASTName);
assertEquals("anX", ((IASTName) decl).toString()); //$NON-NLS-1$ assertEquals("X", ((IASTName) decl).toString()); //$NON-NLS-1$
assertEquals(481, ((ASTNode) decl).getOffset()); assertEquals(code.indexOf("X()"), ((ASTNode) decl).getOffset());
assertEquals(3, ((ASTNode) decl).getLength()); assertEquals("X".length(), ((ASTNode) decl).getLength());
offset = code.indexOf("a; // declares a"); //$NON-NLS-1$ offset = code.indexOf("a; // declares a"); //$NON-NLS-1$
def = testF3(file, offset); def = testF3(file, offset);
@ -1000,7 +1000,7 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
for (int i= 0; i < 2; i++) { for (int i= 0; i < 2; i++) {
IFile file = importFile(filenames[i], code); IFile file = importFile(filenames[i], code);
int od1 = code.indexOf("functionPointer"); int od1 = code.indexOf("functionPointer");
int or1 = code.indexOf("functionPointer", od1+1); int or1 = code.indexOf("functionPointer", od1 + 1);
IASTNode decl = testF3(file, or1); IASTNode decl = testF3(file, or1);
assertTrue(decl instanceof IASTName); assertTrue(decl instanceof IASTName);
@ -1013,7 +1013,7 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
IDocument doc= ((ITextEditor) editor).getDocumentProvider().getDocument(editor.getEditorInput()); IDocument doc= ((ITextEditor) editor).getDocumentProvider().getDocument(editor.getEditorInput());
doc.replace(doc.getLength(), 0, appendCode); doc.replace(doc.getLength(), 0, appendCode);
int od2 = appendCode.indexOf("functionPointerArray"); int od2 = appendCode.indexOf("functionPointerArray");
int or2 = appendCode.indexOf("functionPointerArray", od2+1); int or2 = appendCode.indexOf("functionPointerArray", od2 + 1);
decl = testF3(file, code.length() + or2); decl = testF3(file, code.length() + or2);
assertTrue(decl instanceof IASTName); assertTrue(decl instanceof IASTName);
@ -1030,7 +1030,7 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
for (int i= 0; i < 2; i++) { for (int i= 0; i < 2; i++) {
IFile file = importFile(filenames[i], code); IFile file = importFile(filenames[i], code);
int od1 = code.indexOf("EMPTY"); int od1 = code.indexOf("EMPTY");
int or1 = code.indexOf("EMPTY", od1+1); int or1 = code.indexOf("EMPTY", od1 + 1);
IASTNode decl = testF3(file, or1); IASTNode decl = testF3(file, or1);
assertTrue(decl instanceof IASTName); assertTrue(decl instanceof IASTName);
@ -1104,11 +1104,10 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
int offset= code.indexOf("func();"); int offset= code.indexOf("func();");
try { try {
IASTNode node= testF3(file, offset); IASTNode node= testF3(file, offset);
fail("Didn't expect navigation to succeed due to multiple choices.");
} catch (RuntimeException e) { } catch (RuntimeException e) {
assertEquals("ambiguous input: 3", e.getMessage()); assertEquals("ambiguous input: 3", e.getMessage());
return;
} }
fail("Expected exception not caught");
} }
// namespace nm { // namespace nm {
@ -1126,13 +1125,13 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
assertContents(code, node.getFileLocation().getNodeOffset(), "func(T a, T b)"); assertContents(code, node.getFileLocation().getNodeOffset(), "func(T a, T b)");
} }
// template<typename T> void func(T a){} // template<typename T> void func(T a){}
// template<typename T> void func(T a, T b){} // template<typename T> void func(T a, T b){}
// //
// template<typename Tmp> void testFunc() { // template<typename Tmp> void testFunc() {
// Tmp val; // Tmp val;
// func(val, val); // F3 could know that 'func(T a)' cannot be a correct match. // func(val, val); // F3 could know that 'func(T a)' cannot be a correct match.
// } // }
public void testDependentNameTwoChoices_281736() throws Exception { public void testDependentNameTwoChoices_281736() throws Exception {
String code= getContentsForTest(1)[0].toString(); String code= getContentsForTest(1)[0].toString();
IFile file = importFile("testDependentNameTwoChoices_281736.cpp", code); IFile file = importFile("testDependentNameTwoChoices_281736.cpp", code);

View file

@ -7,9 +7,13 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ * Sergey Prigogin (Google)
******************************************************************************/
package org.eclipse.cdt.internal.ui.search.actions; package org.eclipse.cdt.internal.ui.search.actions;
import static java.lang.Math.max;
import static java.lang.Math.min;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -152,24 +156,11 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null); final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
IASTName sourceName= nodeSelector.findEnclosingName(selectionStart, selectionLength); IASTName sourceName= nodeSelector.findEnclosingName(selectionStart, selectionLength);
IName[] implicitTargets = findImplicitTargets(ast, nodeSelector, selectionStart, selectionLength);
if (sourceName == null) { if (sourceName == null) {
IASTName implicit = nodeSelector.findEnclosingImplicitName(selectionStart, selectionLength); if (implicitTargets.length > 0) {
if (implicit != null) { if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, implicitTargets))
IASTImplicitNameOwner owner = (IASTImplicitNameOwner) implicit.getParent(); return Status.OK_STATUS;
IASTImplicitName[] implicits = owner.getImplicitNames();
// There may be more than one name in the same spot.
if (implicits.length > 0) {
List<IName> allNames = new ArrayList<IName>();
for (IASTImplicitName name : implicits) {
if (((ASTNode) name).getOffset() == ((ASTNode) implicit).getOffset()) {
IBinding binding = name.resolveBinding(); // Guaranteed to resolve.
IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, binding);
allNames.addAll(Arrays.asList(declNames));
}
}
if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, allNames.toArray(new IName[0])))
return Status.OK_STATUS;
}
} }
} else { } else {
boolean found= false; boolean found= false;
@ -192,7 +183,7 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
navigateToName(sourceName); navigateToName(sourceName);
return Status.OK_STATUS; return Status.OK_STATUS;
} }
List<IName> nameList= new ArrayList<IName>(); IName[] targets = IName.EMPTY_ARRAY;
String filename = ast.getFilePath(); String filename = ast.getFilePath();
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
if (binding != null && !(binding instanceof IProblemBinding)) { if (binding != null && !(binding instanceof IProblemBinding)) {
@ -201,29 +192,29 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
if (name instanceof IIndexName && if (name instanceof IIndexName &&
filename.equals(((IIndexName) name).getFileLocation().getFileName())) { filename.equals(((IIndexName) name).getFileLocation().getFileName())) {
// Exclude index names from the current file. // Exclude index names from the current file.
} else if (isSameName(name, sourceName)) { } else if (areOverlappingNames(name, sourceName)) {
// Exclude the current location. // Exclude the current location.
} else if (binding instanceof IParameter) { } else if (binding instanceof IParameter) {
if (isInSameFunction(sourceName, name)) { if (isInSameFunction(sourceName, name)) {
nameList.add(name); targets = ArrayUtil.append(targets, name);
} }
} else if (binding instanceof ICPPTemplateParameter) { } else if (binding instanceof ICPPTemplateParameter) {
if (isInSameTemplate(sourceName, name)) { if (isInSameTemplate(sourceName, name)) {
nameList.add(name); targets = ArrayUtil.append(targets, name);
} }
} else if (name != null) { } else if (name != null) {
nameList.add(name); targets = ArrayUtil.append(targets, name);
} }
} }
} }
} }
IName[] declNames = nameList.toArray(new IName[nameList.size()]); targets = ArrayUtil.trim(ArrayUtil.addAll(targets, implicitTargets));
if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, declNames)) { if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, targets)) {
found= true; found= true;
} else { } else {
// Leave old method as fallback for local variables, parameters and // Leave old method as fallback for local variables, parameters and
// everything else not covered by ICElementHandle. // everything else not covered by ICElementHandle.
found = navigateOneLocation(declNames); found = navigateOneLocation(targets);
} }
if (!found && !navigationFallBack(ast, sourceName, kind)) { if (!found && !navigationFallBack(ast, sourceName, kind)) {
fAction.reportSymbolLookupFailure(new String(sourceName.toCharArray())); fAction.reportSymbolLookupFailure(new String(sourceName.toCharArray()));
@ -255,25 +246,24 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
private IName[] findDeclNames(IASTTranslationUnit ast, NameKind kind, IBinding binding) throws CoreException { private IName[] findDeclNames(IASTTranslationUnit ast, NameKind kind, IBinding binding) throws CoreException {
IName[] declNames = findNames(fIndex, ast, kind, binding); IName[] declNames = findNames(fIndex, ast, kind, binding);
if (declNames.length == 0) { // Bug 207320, handle template instances.
if (binding instanceof ICPPSpecialization) { while (declNames.length == 0 && binding instanceof ICPPSpecialization) {
// Bug 207320, handle template instances. binding = ((ICPPSpecialization) binding).getSpecializedBinding();
IBinding specialized= ((ICPPSpecialization) binding).getSpecializedBinding(); if (binding != null && !(binding instanceof IProblemBinding)) {
if (specialized != null && !(specialized instanceof IProblemBinding)) { declNames = findNames(fIndex, ast, NameKind.DEFINITION, binding);
declNames = findNames(fIndex, ast, NameKind.DEFINITION, specialized); }
} }
} else if (binding instanceof ICPPMethod) { if (declNames.length == 0 && binding instanceof ICPPMethod) {
// Bug 86829, handle implicit methods. // Bug 86829, handle implicit methods.
ICPPMethod method= (ICPPMethod) binding; ICPPMethod method= (ICPPMethod) binding;
if (method.isImplicit()) { if (method.isImplicit()) {
try { try {
IBinding clsBinding= method.getClassOwner(); IBinding clsBinding= method.getClassOwner();
if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) { if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) {
declNames= findNames(fIndex, ast, NameKind.REFERENCE, clsBinding); declNames= findNames(fIndex, ast, NameKind.REFERENCE, clsBinding);
}
} catch (DOMException e) {
// Don't log problem bindings.
} }
} catch (DOMException e) {
// Don't log problem bindings.
} }
} }
} }
@ -329,8 +319,7 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
return index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES); return index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
} }
private IName[] findDeclarations(IIndex index, IASTTranslationUnit ast, private IName[] findDeclarations(IIndex index, IASTTranslationUnit ast, IBinding binding) throws CoreException {
IBinding binding) throws CoreException {
IName[] declNames= ast.getDeclarationsInAST(binding); IName[] declNames= ast.getDeclarationsInAST(binding);
for (int i = 0; i < declNames.length; i++) { for (int i = 0; i < declNames.length; i++) {
IName name = declNames[i]; IName name = declNames[i];
@ -344,6 +333,26 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
return declNames; return declNames;
} }
/**
* Returns definitions of bindings referenced by implicit name at the given location.
*/
private IName[] findImplicitTargets(IASTTranslationUnit ast, IASTNodeSelector nodeSelector,
int offset, int length) throws CoreException {
IName[] definitions = IName.EMPTY_ARRAY;
IASTName firstName = nodeSelector.findEnclosingImplicitName(offset, length);
if (firstName != null) {
IASTImplicitNameOwner owner = (IASTImplicitNameOwner) firstName.getParent();
for (IASTImplicitName name : owner.getImplicitNames()) {
if (((ASTNode) name).getOffset() == ((ASTNode) firstName).getOffset()) {
IBinding binding = name.resolveBinding(); // Guaranteed to resolve.
IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, binding);
definitions = ArrayUtil.addAll(definitions, declNames);
}
}
}
return ArrayUtil.trim(definitions);
}
private static NameKind getNameKind(IName name) { private static NameKind getNameKind(IName name) {
if (name.isDefinition()) { if (name.isDefinition()) {
if (getBinding(name) instanceof ICPPUsingDeclaration) { if (getBinding(name) instanceof ICPPUsingDeclaration) {
@ -370,7 +379,7 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
return null; return null;
} }
private boolean isSameName(IName n1, IName n2) { private boolean areOverlappingNames(IName n1, IName n2) {
if (n1 == n2) if (n1 == n2)
return true; return true;
@ -379,8 +388,8 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
if (loc1 == null || loc2 == null) if (loc1 == null || loc2 == null)
return false; return false;
return loc1.getFileName().equals(loc2.getFileName()) && return loc1.getFileName().equals(loc2.getFileName()) &&
loc1.getNodeOffset() == loc2.getNodeOffset() && max(loc1.getNodeOffset(), loc2.getNodeOffset()) <
loc1.getNodeLength() == loc2.getNodeLength(); min(loc1.getNodeOffset() + loc1.getNodeLength(), loc2.getNodeOffset() + loc2.getNodeLength());
} }
private static boolean isInSameFunction(IASTName name1, IName name2) { private static boolean isInSameFunction(IASTName name1, IName name2) {