1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

Bug 325135: Navigation of function and template parameters.

This commit is contained in:
Markus Schorn 2010-09-16 08:11:12 +00:00
parent 4720831a18
commit e18bd9cc26
2 changed files with 81 additions and 24 deletions

View file

@ -1153,4 +1153,55 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
node= testF3(file, index+4);
assertContents(code, node.getFileLocation().getNodeOffset(), "AAA");
}
// void bug(int var) {
// int foo = var;
// int foo2(var);
// }
public void testBug325135a() throws Exception {
String code = getAboveComment();
IFile file = importFile("testBug325135a.cpp", code); //$NON-NLS-1$
int parOffset= code.indexOf("var)");
int offset = code.indexOf("var;"); //$NON-NLS-1$
IASTNode decl = testF3(file, offset);
assertTrue(decl instanceof IASTName);
assertEquals("var", ((IASTName) decl).toString()); //$NON-NLS-1$
assertEquals(parOffset, ((ASTNode) decl).getOffset());
assertEquals(3, ((ASTNode) decl).getLength());
offset = code.indexOf("var);"); //$NON-NLS-1$
decl = testF3(file, offset);
assertTrue(decl instanceof IASTName);
assertEquals("var", ((IASTName) decl).toString()); //$NON-NLS-1$
assertEquals(parOffset, ((ASTNode) decl).getOffset());
assertEquals(3, ((ASTNode) decl).getLength());
}
// template<typename T> class C {
// template<typename V> void f(V v) {
// T t;
// V s;
// }
// };
public void testBug325135b() throws Exception {
String code = getAboveComment();
IFile file = importFile("testBug325135b.cpp", code); //$NON-NLS-1$
int offsetT= code.indexOf("T>");
int offsetV= code.indexOf("V>");
int offset = code.indexOf("T t;");
IASTNode decl = testF3(file, offset);
assertTrue(decl instanceof IASTName);
assertEquals("T", ((IASTName) decl).toString());
assertEquals(offsetT, ((ASTNode) decl).getOffset());
offset = code.indexOf("V s;");
decl = testF3(file, offset);
assertTrue(decl instanceof IASTName);
assertEquals("V", ((IASTName) decl).toString());
assertEquals(offsetV, ((ASTNode) decl).getOffset());
}
}

View file

@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.ASTNameCollector;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
@ -189,21 +190,23 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
if (binding != null && !(binding instanceof IProblemBinding)) {
IName[] names = findDeclNames(ast, kind, binding);
for (final IName name : names) {
if (name instanceof IIndexName &&
filename.equals(((IIndexName) name).getFileLocation().getFileName())) {
// Exclude index names from the current file.
} else if (areOverlappingNames(name, sourceName)) {
// Exclude the current location.
} else if (binding instanceof IParameter) {
if (isInSameFunction(sourceName, name)) {
if (name != null) {
if (name instanceof IIndexName &&
filename.equals(((IIndexName) name).getFileLocation().getFileName())) {
// Exclude index names from the current file.
} else if (areOverlappingNames(name, sourceName)) {
// Exclude the current location.
} else if (binding instanceof IParameter) {
if (isInSameFunction(sourceName, name)) {
targets = ArrayUtil.append(targets, name);
}
} else if (binding instanceof ICPPTemplateParameter) {
if (isInSameTemplate(sourceName, name)) {
targets = ArrayUtil.append(targets, name);
}
} else {
targets = ArrayUtil.append(targets, name);
}
} else if (binding instanceof ICPPTemplateParameter) {
if (isInSameTemplate(sourceName, name)) {
targets = ArrayUtil.append(targets, name);
}
} else if (name != null) {
targets = ArrayUtil.append(targets, name);
}
}
}
@ -388,24 +391,27 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
min(loc1.getNodeOffset() + loc1.getNodeLength(), loc2.getNodeOffset() + loc2.getNodeLength());
}
private static boolean isInSameFunction(IASTName name1, IName name2) {
IASTDeclaration decl1 = getEnclosingDeclaration(name1);
IASTDeclaration decl2 = name2 instanceof IASTName ? getEnclosingDeclaration((IASTName) name2) : null;
return decl1 != null && decl1.equals(decl2) || decl1 == null && decl2 == null;
private static boolean isInSameFunction(IASTName refName, IName funcDeclName) {
if (funcDeclName instanceof IASTName) {
IASTDeclaration fdef = getEnclosingFunctionDefinition((IASTNode) funcDeclName);
return fdef != null && fdef.contains(refName);
}
return false;
}
private static IASTDeclaration getEnclosingDeclaration(IASTNode node) {
while (node != null && !(node instanceof IASTDeclaration)) {
private static IASTDeclaration getEnclosingFunctionDefinition(IASTNode node) {
while (node != null && !(node instanceof IASTFunctionDefinition)) {
node= node.getParent();
}
return (IASTDeclaration) node;
}
private static boolean isInSameTemplate(IASTName name1, IName name2) {
IASTDeclaration decl1 = getEnclosingTemplateDeclaration(name1);
IASTDeclaration decl2 = name2 instanceof IASTName ?
getEnclosingTemplateDeclaration((IASTName) name2) : null;
return decl1 != null && decl1.equals(decl2) || decl1 == null && decl2 == null;
private static boolean isInSameTemplate(IASTName refName, IName templateDeclName) {
if (templateDeclName instanceof IASTName) {
IASTDeclaration template = getEnclosingTemplateDeclaration(refName);
return template != null && template.contains(refName);
}
return false;
}
private static IASTDeclaration getEnclosingTemplateDeclaration(IASTNode node) {