1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-09 01:05:38 +02:00

Open Declaration improvements. Bug 232587.

This commit is contained in:
Sergey Prigogin 2009-05-16 06:27:13 +00:00
parent da854927c4
commit c5c0fc6d24
5 changed files with 173 additions and 103 deletions

View file

@ -80,7 +80,6 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
OpenDeclarationsAction.sIsJUnitTest= true; OpenDeclarationsAction.sIsJUnitTest= true;
OpenDeclarationsAction.sAllowFallback= false;
IWorkbenchPage page= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IWorkbenchPage page= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IViewReference[] refs= page.getViewReferences(); IViewReference[] refs= page.getViewReferences();
for (int i = 0; i < refs.length; i++) { for (int i = 0; i < refs.length; i++) {
@ -145,9 +144,9 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
if (file.getLocalTimeStamp() == timestamp) { if (file.getLocalTimeStamp() == timestamp) {
file.setLocalTimeStamp(timestamp+1000); file.setLocalTimeStamp(timestamp+1000);
} }
} } else {
else
file.create(stream, false, monitor); file.create(stream, false, monitor);
}
fileManager.addFile(file); fileManager.addFile(file);
@ -190,12 +189,10 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
return folder; return folder;
} }
protected String getEditorID() { protected String getEditorID() {
return "org.eclipse.cdt.ui.editor.CEditor"; return "org.eclipse.cdt.ui.editor.CEditor";
} }
protected IASTNode testF3(IFile file, int offset) throws ParserException, CoreException { protected IASTNode testF3(IFile file, int offset) throws ParserException, CoreException {
return testF3(file, offset, 0); return testF3(file, offset, 0);
} }

View file

@ -110,15 +110,15 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
//Create file manager //Create file manager
fileManager = new FileManager(); fileManager = new FileManager();
} }
public CPPSelectionTestsNoIndexer()
{ public CPPSelectionTestsNoIndexer() {
super(); super();
} }
/** /**
* @param name * @param name
*/ */
public CPPSelectionTestsNoIndexer(String name) public CPPSelectionTestsNoIndexer(String name) {
{
super(name); super(name);
} }
@ -147,7 +147,6 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
super.setUp(); super.setUp();
initProject(); initProject();
OpenDeclarationsAction.sIsJUnitTest= true; OpenDeclarationsAction.sIsJUnitTest= true;
OpenDeclarationsAction.sAllowFallback= false;
} }
@Override @Override
@ -326,7 +325,6 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
assertEquals(((IASTName)node).toString(), "operator ="); //$NON-NLS-1$ assertEquals(((IASTName)node).toString(), "operator ="); //$NON-NLS-1$
assertEquals(((ASTNode)node).getOffset(), 121); assertEquals(((ASTNode)node).getOffset(), 121);
assertEquals(((ASTNode)node).getLength(), 9); assertEquals(((ASTNode)node).getLength(), 9);
} }
public void testBasicDefinition() throws Exception { public void testBasicDefinition() throws Exception {
@ -1041,7 +1039,6 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
String code= getContentsForTest(1)[0].toString(); String code= getContentsForTest(1)[0].toString();
String[] filenames= {"testBug252549.c", "testBug252549.cpp"}; String[] filenames= {"testBug252549.c", "testBug252549.cpp"};
for (int i= 0; i < 2; i++) { for (int i= 0; i < 2; i++) {
OpenDeclarationsAction.sAllowFallback= true;
IFile file = importFile(filenames[i], code); IFile file = importFile(filenames[i], code);
int offset= code.indexOf("myFunc(x)"); int offset= code.indexOf("myFunc(x)");
IASTNode decl= testF3(file, offset); IASTNode decl= testF3(file, offset);
@ -1051,5 +1048,4 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
assertEquals("myFunc", name.toString()); assertEquals("myFunc", name.toString());
} }
} }
} }

View file

@ -32,8 +32,6 @@ import org.eclipse.cdt.ui.testplugin.CTestPlugin;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction;
public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexer { public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexer {
private static final int MAX_WAIT_TIME = 8000; private static final int MAX_WAIT_TIME = 8000;
@ -506,8 +504,6 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
// #define DR_ACCESS_FNS(DR) // #define DR_ACCESS_FNS(DR)
public void testNavigationInMacroDefinition_Bug102643() throws Exception { public void testNavigationInMacroDefinition_Bug102643() throws Exception {
OpenDeclarationsAction.sAllowFallback= true;
StringBuffer[] buffers= getContents(2); StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString(); String hcode= buffers[0].toString();
String scode= buffers[1].toString(); String scode= buffers[1].toString();

View file

@ -120,7 +120,6 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase {
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
OpenDeclarationsAction.sIsJUnitTest= true; OpenDeclarationsAction.sIsJUnitTest= true;
OpenDeclarationsAction.sAllowFallback= false;
initProject(); initProject();
} }

View file

@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Ed Swartz (Nokia) * Ed Swartz (Nokia)
* Mike Kucera (IBM) * Mike Kucera (IBM)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.search.actions; package org.eclipse.cdt.internal.ui.search.actions;
@ -39,6 +40,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTNameCollector; import org.eclipse.cdt.core.dom.ast.ASTNameCollector;
import org.eclipse.cdt.core.dom.ast.DOMException; 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.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
@ -48,9 +50,12 @@ import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
@ -69,6 +74,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory; import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle; import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
@ -82,7 +88,6 @@ import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
public class OpenDeclarationsAction extends SelectionParseAction implements ASTRunnable { public class OpenDeclarationsAction extends SelectionParseAction implements ASTRunnable {
public static boolean sIsJUnitTest = false; public static boolean sIsJUnitTest = false;
public static boolean sAllowFallback= true;
private static final int KIND_OTHER = 0; private static final int KIND_OTHER = 0;
private static final int KIND_USING_DECL = 1; private static final int KIND_USING_DECL = 1;
@ -181,7 +186,6 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
return Status.OK_STATUS; return Status.OK_STATUS;
} }
IBinding binding = searchName.resolveBinding(); IBinding binding = searchName.resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding)) {
int isKind= KIND_OTHER; int isKind= KIND_OTHER;
if (searchName.isDefinition()) { if (searchName.isDefinition()) {
if (binding instanceof ICPPUsingDeclaration) { if (binding instanceof ICPPUsingDeclaration) {
@ -190,16 +194,33 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
isKind= KIND_DEFINITION; isKind= KIND_DEFINITION;
} }
} }
if (binding != null && !(binding instanceof IProblemBinding)) {
IName[] declNames = findDeclNames(ast, isKind, binding); IName[] declNames = findDeclNames(ast, isKind, binding);
// Exclude the current location.
for (int i = 0; i < declNames.length; i++) {
if (isSameName(declNames[i], searchName)) {
declNames[i] = null;
} else if (binding instanceof IParameter) {
if (!isInSameFunction(searchName, declNames[i])) {
declNames[i] = null;
}
} else if (binding instanceof ICPPTemplateParameter) {
if (!isInSameTemplate(searchName, declNames[i])) {
declNames[i] = null;
}
}
}
declNames = (IName[]) ArrayUtil.removeNulls(IName.class, declNames);
if (navigateViaCElements(fWorkingCopy.getCProject(), fIndex, declNames)) { if (navigateViaCElements(fWorkingCopy.getCProject(), fIndex, declNames)) {
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(declNames);
} }
} }
if (!found && !navigationFallBack(ast)) { if (!found && !navigationFallBack(ast, searchName, isKind)) {
reportSymbolLookupFailure(new String(searchName.toCharArray())); reportSymbolLookupFailure(new String(searchName.toCharArray()));
} }
return Status.OK_STATUS; return Status.OK_STATUS;
@ -208,15 +229,42 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
// no enclosing name, check if we're in an include statement // no enclosing name, check if we're in an include statement
IASTNode node= nodeSelector.findEnclosingNode(selectionStart, selectionLength); IASTNode node= nodeSelector.findEnclosingNode(selectionStart, selectionLength);
if (node instanceof IASTPreprocessorIncludeStatement) { if (node instanceof IASTPreprocessorIncludeStatement) {
openInclude(((IASTPreprocessorIncludeStatement) node)); openInclude((IASTPreprocessorIncludeStatement) node);
return Status.OK_STATUS; return Status.OK_STATUS;
} }
if (!navigationFallBack(ast)) { if (!navigationFallBack(ast, null, KIND_OTHER)) {
reportSelectionMatchFailure(); reportSelectionMatchFailure();
} }
return Status.OK_STATUS; return Status.OK_STATUS;
} }
private 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 IASTDeclaration getEnclosingDeclaration(IASTNode node) {
while (node != null && !(node instanceof IASTDeclaration)) {
node= node.getParent();
}
return (IASTDeclaration) node;
}
private 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 IASTDeclaration getEnclosingTemplateDeclaration(IASTNode node) {
while (node != null && !(node instanceof ICPPASTTemplateDeclaration)) {
node= node.getParent();
}
return (IASTDeclaration) node;
}
private IName[] findDeclNames(IASTTranslationUnit ast, int isKind, IBinding binding) throws CoreException { private IName[] findDeclNames(IASTTranslationUnit ast, int isKind, IBinding binding) throws CoreException {
IName[] declNames = findNames(fIndex, ast, isKind, binding); IName[] declNames = findNames(fIndex, ast, isKind, binding);
if (declNames.length == 0) { if (declNames.length == 0) {
@ -244,9 +292,9 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
return declNames; return declNames;
} }
private boolean navigationFallBack(IASTTranslationUnit ast) { private boolean navigationFallBack(IASTTranslationUnit ast, IASTName sourceName, int isKind) {
// bug 102643, as a fall-back we look up the selected word in the index // bug 102643, as a fall-back we look up the selected word in the index
if (sAllowFallback && fSelectedText != null && fSelectedText.length() > 0) { if (fSelectedText != null && fSelectedText.length() > 0) {
try { try {
final ICProject project = fWorkingCopy.getCProject(); final ICProject project = fWorkingCopy.getCProject();
final char[] name = fSelectedText.toCharArray(); final char[] name = fSelectedText.toCharArray();
@ -289,12 +337,32 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
} }
} }
// convert bindings to CElements String[] sourceQualifiedName= sourceName != null ?
CPPVisitor.getQualifiedName(sourceName.resolveBinding()) :
new String[] { fSelectedText };
// Convert bindings to CElements
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
final IName[] names = findNames(fIndex, ast, KIND_OTHER, binding); String[] qualifiedName = CPPVisitor.getQualifiedName(binding);
if (!Arrays.equals(qualifiedName, sourceQualifiedName)) {
continue;
}
IName[] names = findNames(fIndex, ast, isKind, binding);
// Exclude the current location.
for (int i = 0; i < names.length; i++) {
if (sourceName != null && isSameName(names[i], sourceName)) {
names[i] = null;
}
}
names = (IName[]) ArrayUtil.removeNulls(IName.class, names);
convertToCElements(project, fIndex, names, elems); convertToCElements(project, fIndex, names, elems);
} }
return navigateCElements(elems); if (navigateCElements(elems)) {
return true;
}
if (sourceName != null && sourceName.isDeclaration()) {
// Select the name at the current location as the last resort.
return navigateToName(sourceName);
}
} catch (CoreException e) { } catch (CoreException e) {
CUIPlugin.log(e); CUIPlugin.log(e);
} }
@ -302,6 +370,14 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
return false; return false;
} }
private boolean isSameName(IName n1, IName n2) {
IASTFileLocation loc1 = n1.getFileLocation();
IASTFileLocation loc2 = n2.getFileLocation();
return loc1.getFileName().equals(loc2.getFileName()) &&
loc1.getNodeOffset() == loc2.getNodeOffset() &&
loc1.getNodeLength() == loc2.getNodeLength();
}
private void openInclude(IASTPreprocessorIncludeStatement incStmt) { private void openInclude(IASTPreprocessorIncludeStatement incStmt) {
String name = null; String name = null;
if (incStmt.isResolved()) if (incStmt.isResolved())
@ -323,11 +399,20 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
} }
} }
private boolean navigateOneLocation(IName[] declNames) { private boolean navigateOneLocation(IName[] names) {
for (IName declName : declNames) { for (IName name : names) {
IASTFileLocation fileloc = declName.getFileLocation(); if (navigateToName(name)) {
if (fileloc != null) { return true;
}
}
return false;
}
private boolean navigateToName(IName name) {
IASTFileLocation fileloc = name.getFileLocation();
if (fileloc == null) {
return false;
}
final IPath path = new Path(fileloc.getFileName()); final IPath path = new Path(fileloc.getFileName());
final int offset = fileloc.getNodeOffset(); final int offset = fileloc.getNodeOffset();
final int length = fileloc.getNodeLength(); final int length = fileloc.getNodeLength();
@ -343,9 +428,6 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
}); });
return true; return true;
} }
}
return false;
}
private boolean navigateViaCElements(ICProject project, IIndex index, IName[] declNames) { private boolean navigateViaCElements(ICProject project, IIndex index, IName[] declNames) {
final ArrayList<ICElement> elements= new ArrayList<ICElement>(); final ArrayList<ICElement> elements= new ArrayList<ICElement>();