mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
Navigation to implicitly called constructors. Bug 248855.
This commit is contained in:
parent
92e5bf17ea
commit
ebee62c7ca
4 changed files with 136 additions and 80 deletions
|
@ -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
|
||||||
|
|
|
@ -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,7 +399,7 @@ 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
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue