1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-29 20:05:35 +02:00

Fix for 187792, handling ambiguities during 'Open Declaration'

This commit is contained in:
Markus Schorn 2007-05-21 13:40:24 +00:00
parent 9fb29e5239
commit 2bd73d2db8
11 changed files with 139 additions and 68 deletions

View file

@ -610,7 +610,7 @@ public class CoreModelUtil {
* Returns the translation unit for the file given or <code>null</code>. * Returns the translation unit for the file given or <code>null</code>.
*/ */
public static ITranslationUnit findTranslationUnit(IFile file) { public static ITranslationUnit findTranslationUnit(IFile file) {
if (CoreModel.isTranslationUnit(file)) { if (CoreModel.isTranslationUnit(file) && file.exists()) {
ICProject cp= CoreModel.getDefault().getCModel().getCProject(file.getProject().getName()); ICProject cp= CoreModel.getDefault().getCModel().getCProject(file.getProject().getName());
if (cp != null) { if (cp != null) {
ICElement tu; ICElement tu;

View file

@ -19,10 +19,12 @@ import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -67,6 +69,9 @@ public class CElementHandleFactory {
element= new FieldHandle(parentElement, (IField) binding); element= new FieldHandle(parentElement, (IField) binding);
} }
else if (binding instanceof IVariable) { else if (binding instanceof IVariable) {
if (binding instanceof IParameter) {
return null;
}
element= new VariableHandle(parentElement, (IVariable) binding); element= new VariableHandle(parentElement, (IVariable) binding);
} }
else if (binding instanceof IEnumeration) { else if (binding instanceof IEnumeration) {
@ -125,6 +130,9 @@ public class CElementHandleFactory {
ICompositeType type= ((ICCompositeTypeScope) scope).getCompositeType(); ICompositeType type= ((ICCompositeTypeScope) scope).getCompositeType();
element= new StructureHandle(parentElement, type); element= new StructureHandle(parentElement, type);
} }
else if (scope instanceof ICPPBlockScope) {
return null;
}
else if (scope instanceof ICPPNamespaceScope) { else if (scope instanceof ICPPNamespaceScope) {
element= new NamespaceHandle(parentElement, new String(scopeName.toCharArray())); element= new NamespaceHandle(parentElement, new String(scopeName.toCharArray()));
} }

View file

@ -70,6 +70,11 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
super(name); super(name);
} }
protected void setUp() throws Exception {
super.setUp();
OpenDeclarationsAction.sIsJUnitTest= true;
}
public void waitForIndex(int maxSec) throws Exception { public void waitForIndex(int maxSec) throws Exception {
assertTrue(CCorePlugin.getIndexManager().joinIndexer(maxSec*1000, new NullProgressMonitor())); assertTrue(CCorePlugin.getIndexManager().joinIndexer(maxSec*1000, new NullProgressMonitor()));
} }

View file

@ -125,6 +125,11 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
} }
} }
protected void setUp() throws Exception {
super.setUp();
OpenDeclarationsAction.sIsJUnitTest= true;
}
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
if( project == null || !project.exists() ) if( project == null || !project.exists() )
return; return;

View file

@ -106,6 +106,11 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase {
return suite; return suite;
} }
protected void setUp() throws Exception {
super.setUp();
OpenDeclarationsAction.sIsJUnitTest= true;
}
public void cleanupProject() throws Exception { public void cleanupProject() throws Exception {
closeAllEditors(); closeAllEditors();
CProjectHelper.delete(cPrj); CProjectHelper.delete(cPrj);

View file

@ -11,21 +11,15 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.corext.util; package org.eclipse.cdt.internal.corext.util;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ICContainer; import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.util.EditorUtility; import org.eclipse.cdt.internal.ui.util.EditorUtility;
@ -120,33 +114,4 @@ public class CModelUtil {
} }
return null; return null;
} }
/**
* Returns the translation unit for the file given or <code>null</code>.
*/
public static ITranslationUnit findTranslationUnit(IFile file) {
if (CoreModel.isTranslationUnit(file)) {
ICProject cp= CoreModel.getDefault().getCModel().getCProject(file.getProject().getName());
if (cp != null) {
ICElement tu;
try {
tu = cp.findElement(file.getProjectRelativePath());
if (tu instanceof ITranslationUnit) {
return (ITranslationUnit) tu;
}
} catch (CModelException e) {
CUIPlugin.getDefault().log(e);
}
}
}
return null;
}
/**
* Returns the translation unit for the location given or <code>null</code>.
* @throws CModelException
*/
public static ITranslationUnit findTranslationUnitForLocation(IPath location, ICProject preferredProject) throws CModelException {
return CoreModelUtil.findTranslationUnitForLocation(location, preferredProject);
}
} }

View file

@ -9,6 +9,7 @@
# IBM Corporation - initial API and implementation # IBM Corporation - initial API and implementation
# QNX Software System # QNX Software System
# Anton Leherbauer (Wind River Systems) # Anton Leherbauer (Wind River Systems)
# Markus Schorn (Wind River Systems)
######################################### #########################################
AddIncludeOnSelection.description=Add include statement on selection AddIncludeOnSelection.description=Add include statement on selection
@ -33,6 +34,8 @@ OpenHierarchy.tooltip=Show the type hierarchy of the selected element
OpenDeclarations.description=Open an editor on the selected element's declaration OpenDeclarations.description=Open an editor on the selected element's declaration
OpenDeclarations.dialog.message=&Select or enter the element to open: OpenDeclarations.dialog.message=&Select or enter the element to open:
OpenDeclarationsAction.dialog.title=Open Declaration
OpenDeclarationsAction.selectMessage=Select one element from the list
OpenDeclarations.dialog.title=Open Declaration OpenDeclarations.dialog.title=Open Declaration
OpenDeclarations.label=&Open Declaration OpenDeclarations.label=&Open Declaration
OpenDeclarations.tooltip=Open an editor on the selected element's declaration OpenDeclarations.tooltip=Open an editor on the selected element's declaration

View file

@ -21,11 +21,10 @@ import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.editors.text.ILocationProvider; import org.eclipse.ui.editors.text.ILocationProvider;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
public class IBConversions { public class IBConversions {
public static IBNode selectionToNode(ISelection sel) { public static IBNode selectionToNode(ISelection sel) {
@ -60,7 +59,7 @@ public class IBConversions {
return (ITranslationUnit) object; return (ITranslationUnit) object;
} }
if (object instanceof IFile) { if (object instanceof IFile) {
return CModelUtil.findTranslationUnit((IFile) object); return CoreModelUtil.findTranslationUnit((IFile) object);
} }
if (object instanceof IAdaptable) { if (object instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) object; IAdaptable adaptable = (IAdaptable) object;
@ -70,7 +69,7 @@ public class IBConversions {
} }
IFile file= (IFile) adaptable.getAdapter(IFile.class); IFile file= (IFile) adaptable.getAdapter(IFile.class);
if (file != null) { if (file != null) {
return CModelUtil.findTranslationUnit(file); return CoreModelUtil.findTranslationUnit(file);
} }
ILocationProvider locProvider= (ILocationProvider) adaptable.getAdapter(ILocationProvider.class); ILocationProvider locProvider= (ILocationProvider) adaptable.getAdapter(ILocationProvider.class);
@ -78,7 +77,7 @@ public class IBConversions {
IPath path= locProvider.getPath(locProvider); IPath path= locProvider.getPath(locProvider);
if (path != null) { if (path != null) {
try { try {
return CModelUtil.findTranslationUnitForLocation(path, null); return CoreModelUtil.findTranslationUnitForLocation(path, null);
} catch (CModelException e) { } catch (CModelException e) {
CUIPlugin.getDefault().log(e); CUIPlugin.getDefault().log(e);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others. * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -30,10 +30,9 @@ import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ResourceTransfer; import org.eclipse.ui.part.ResourceTransfer;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
public class IBDropTargetListener implements DropTargetListener { public class IBDropTargetListener implements DropTargetListener {
private IBViewPart fIncludeBrowser; private IBViewPart fIncludeBrowser;
@ -140,7 +139,7 @@ public class IBDropTargetListener implements DropTargetListener {
for (int i = 0; i < files.length; i++) { for (int i = 0; i < files.length; i++) {
IResource resource = files[i]; IResource resource = files[i];
if (resource.getType() == IResource.FILE) { if (resource.getType() == IResource.FILE) {
ITranslationUnit tu= CModelUtil.findTranslationUnit((IFile) resource); ITranslationUnit tu= CoreModelUtil.findTranslationUnit((IFile) resource);
if (tu != null) { if (tu != null) {
return tu; return tu;
} }

View file

@ -13,6 +13,8 @@
package org.eclipse.cdt.internal.ui.search.actions; package org.eclipse.cdt.internal.ui.search.actions;
import java.util.ArrayList;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -37,15 +39,24 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.model.util.CElementBaseLabels;
import org.eclipse.cdt.core.parser.util.ArrayUtil; 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.ui.actions.OpenActionUtil;
import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.ASTProvider;
import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.CEditorMessages; import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
public class OpenDeclarationsAction extends SelectionParseAction { public class OpenDeclarationsAction extends SelectionParseAction {
public static boolean sIsJUnitTest = false;
public static final IASTName[] BLANK_NAME_ARRAY = new IASTName[0]; public static final IASTName[] BLANK_NAME_ARRAY = new IASTName[0];
ITextSelection selNode; ITextSelection selNode;
@ -114,26 +125,13 @@ public class OpenDeclarationsAction extends SelectionParseAction {
} }
} }
} }
for (int i = 0; i < declNames.length; i++) { if (navigateViaCElements(workingCopy.getCProject(), index, declNames)) {
IASTFileLocation fileloc = declNames[i].getFileLocation(); found= true;
if (fileloc != null) { }
found = true; else {
// leave old method as fallback for local variables, parameters and
final IPath path = new Path(fileloc.getFileName()); // everything else not covered by ICElementHandle.
final int offset = fileloc.getNodeOffset(); found = navigateOneLocation(declNames);
final int length = fileloc.getNodeLength();
runInUIThread(new Runnable() {
public void run() {
try {
open(path, offset, length);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
});
break;
}
} }
} }
if (!found) { if (!found) {
@ -191,6 +189,80 @@ public class OpenDeclarationsAction extends SelectionParseAction {
} }
} }
private boolean navigateOneLocation(IName[] declNames) {
for (int i = 0; i < declNames.length; i++) {
IASTFileLocation fileloc = declNames[i].getFileLocation();
if (fileloc != null) {
final IPath path = new Path(fileloc.getFileName());
final int offset = fileloc.getNodeOffset();
final int length = fileloc.getNodeLength();
runInUIThread(new Runnable() {
public void run() {
try {
open(path, offset, length);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
});
return true;
}
}
return false;
}
private boolean navigateViaCElements(ICProject project, IIndex index, IName[] declNames) {
final ArrayList elements= new ArrayList();
for (int i = 0; i < declNames.length; i++) {
try {
ICElement elem = IndexUI.getCElementForName(project, index, declNames[i]);
if (elem instanceof ISourceReference) {
elements.add(elem);
}
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
} catch (DOMException e) {
CUIPlugin.getDefault().log(e);
}
}
if (elements.isEmpty()) {
return false;
}
runInUIThread(new Runnable() {
public void run() {
ISourceReference target= null;
if (elements.size() == 1) {
target= (ISourceReference) elements.get(0);
}
else {
if (sIsJUnitTest) {
throw new RuntimeException("ambiguous input"); //$NON-NLS-1$
}
ICElement[] elemArray= (ICElement[]) elements.toArray(new ICElement[elements.size()]);
target = (ISourceReference) OpenActionUtil.selectCElement(elemArray, getSite().getShell(),
CEditorMessages.getString("OpenDeclarationsAction.dialog.title"), CEditorMessages.getString("OpenDeclarationsAction.selectMessage"), //$NON-NLS-1$ //$NON-NLS-2$
CElementBaseLabels.ALL_DEFAULT | CElementBaseLabels.MF_POST_FILE_QUALIFIED, 0);
}
if (target != null) {
ITranslationUnit tu= target.getTranslationUnit();
ISourceRange sourceRange;
try {
sourceRange = target.getSourceRange();
if (tu != null && sourceRange != null) {
open(tu.getLocation(), sourceRange.getIdStartPos(), sourceRange.getIdLength());
}
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
}
}
}
});
return true;
}
private IName[] findNames(IIndex index, IASTTranslationUnit ast, private IName[] findNames(IIndex index, IASTTranslationUnit ast,
boolean isDefinition, IBinding binding) throws CoreException { boolean isDefinition, IBinding binding) throws CoreException {
IName[] declNames= isDefinition ? IName[] declNames= isDefinition ?

View file

@ -45,6 +45,7 @@ import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceRange;
@ -55,7 +56,6 @@ import org.eclipse.cdt.ui.CUIPlugin;
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;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.ASTProvider;
@ -168,7 +168,17 @@ public class IndexUI {
} }
return EMPTY_ELEMENTS; return EMPTY_ELEMENTS;
} }
public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IName declName) throws CoreException, DOMException {
if (declName instanceof IASTName) {
return getCElementForName(preferProject, index, (IASTName) declName);
}
else if (declName instanceof IIndexName) {
return getCElementForName(preferProject, index, (IIndexName) declName);
}
return null;
}
public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IASTName declName) throws CoreException, DOMException { public static ICElementHandle getCElementForName(ICProject preferProject, IIndex index, IASTName declName) throws CoreException, DOMException {
assert !declName.isReference(); assert !declName.isReference();
IBinding binding= declName.resolveBinding(); IBinding binding= declName.resolveBinding();
@ -192,7 +202,7 @@ public class IndexUI {
private static ITranslationUnit getTranslationUnit(ICProject cproject, IName name) { private static ITranslationUnit getTranslationUnit(ICProject cproject, IName name) {
IPath path= Path.fromOSString(name.getFileLocation().getFileName()); IPath path= Path.fromOSString(name.getFileLocation().getFileName());
try { try {
return CModelUtil.findTranslationUnitForLocation(path, cproject); return CoreModelUtil.findTranslationUnitForLocation(path, cproject);
} catch (CModelException e) { } catch (CModelException e) {
CUIPlugin.getDefault().log(e); CUIPlugin.getDefault().log(e);
return null; return null;