mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Fix for 187792, handling ambiguities during 'Open Declaration'
This commit is contained in:
parent
9fb29e5239
commit
2bd73d2db8
11 changed files with 139 additions and 68 deletions
|
@ -610,7 +610,7 @@ public class CoreModelUtil {
|
|||
* Returns the translation unit for the file given or <code>null</code>.
|
||||
*/
|
||||
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());
|
||||
if (cp != null) {
|
||||
ICElement tu;
|
||||
|
|
|
@ -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.IField;
|
||||
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.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
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.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
|
@ -67,6 +69,9 @@ public class CElementHandleFactory {
|
|||
element= new FieldHandle(parentElement, (IField) binding);
|
||||
}
|
||||
else if (binding instanceof IVariable) {
|
||||
if (binding instanceof IParameter) {
|
||||
return null;
|
||||
}
|
||||
element= new VariableHandle(parentElement, (IVariable) binding);
|
||||
}
|
||||
else if (binding instanceof IEnumeration) {
|
||||
|
@ -125,6 +130,9 @@ public class CElementHandleFactory {
|
|||
ICompositeType type= ((ICCompositeTypeScope) scope).getCompositeType();
|
||||
element= new StructureHandle(parentElement, type);
|
||||
}
|
||||
else if (scope instanceof ICPPBlockScope) {
|
||||
return null;
|
||||
}
|
||||
else if (scope instanceof ICPPNamespaceScope) {
|
||||
element= new NamespaceHandle(parentElement, new String(scopeName.toCharArray()));
|
||||
}
|
||||
|
|
|
@ -70,6 +70,11 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
|
|||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
OpenDeclarationsAction.sIsJUnitTest= true;
|
||||
}
|
||||
|
||||
public void waitForIndex(int maxSec) throws Exception {
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(maxSec*1000, new NullProgressMonitor()));
|
||||
}
|
||||
|
|
|
@ -125,6 +125,11 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
|
|||
}
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
OpenDeclarationsAction.sIsJUnitTest= true;
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
if( project == null || !project.exists() )
|
||||
return;
|
||||
|
|
|
@ -106,6 +106,11 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase {
|
|||
return suite;
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
OpenDeclarationsAction.sIsJUnitTest= true;
|
||||
}
|
||||
|
||||
public void cleanupProject() throws Exception {
|
||||
closeAllEditors();
|
||||
CProjectHelper.delete(cPrj);
|
||||
|
|
|
@ -11,21 +11,15 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.corext.util;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
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.ICElement;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ISourceRoot;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||
|
||||
|
@ -120,33 +114,4 @@ public class CModelUtil {
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
# IBM Corporation - initial API and implementation
|
||||
# QNX Software System
|
||||
# Anton Leherbauer (Wind River Systems)
|
||||
# Markus Schorn (Wind River Systems)
|
||||
#########################################
|
||||
|
||||
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.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.label=&Open Declaration
|
||||
OpenDeclarations.tooltip=Open an editor on the selected element's declaration
|
||||
|
|
|
@ -21,11 +21,10 @@ import org.eclipse.jface.viewers.IStructuredSelection;
|
|||
import org.eclipse.ui.editors.text.ILocationProvider;
|
||||
|
||||
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.ui.CUIPlugin;
|
||||
|
||||
import org.eclipse.cdt.internal.corext.util.CModelUtil;
|
||||
|
||||
public class IBConversions {
|
||||
|
||||
public static IBNode selectionToNode(ISelection sel) {
|
||||
|
@ -60,7 +59,7 @@ public class IBConversions {
|
|||
return (ITranslationUnit) object;
|
||||
}
|
||||
if (object instanceof IFile) {
|
||||
return CModelUtil.findTranslationUnit((IFile) object);
|
||||
return CoreModelUtil.findTranslationUnit((IFile) object);
|
||||
}
|
||||
if (object instanceof IAdaptable) {
|
||||
IAdaptable adaptable = (IAdaptable) object;
|
||||
|
@ -70,7 +69,7 @@ public class IBConversions {
|
|||
}
|
||||
IFile file= (IFile) adaptable.getAdapter(IFile.class);
|
||||
if (file != null) {
|
||||
return CModelUtil.findTranslationUnit(file);
|
||||
return CoreModelUtil.findTranslationUnit(file);
|
||||
}
|
||||
|
||||
ILocationProvider locProvider= (ILocationProvider) adaptable.getAdapter(ILocationProvider.class);
|
||||
|
@ -78,7 +77,7 @@ public class IBConversions {
|
|||
IPath path= locProvider.getPath(locProvider);
|
||||
if (path != null) {
|
||||
try {
|
||||
return CModelUtil.findTranslationUnitForLocation(path, null);
|
||||
return CoreModelUtil.findTranslationUnitForLocation(path, null);
|
||||
} catch (CModelException e) {
|
||||
CUIPlugin.getDefault().log(e);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* 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.ui.part.ResourceTransfer;
|
||||
|
||||
import org.eclipse.cdt.core.model.CoreModelUtil;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
|
||||
import org.eclipse.cdt.internal.corext.util.CModelUtil;
|
||||
|
||||
public class IBDropTargetListener implements DropTargetListener {
|
||||
|
||||
private IBViewPart fIncludeBrowser;
|
||||
|
@ -140,7 +139,7 @@ public class IBDropTargetListener implements DropTargetListener {
|
|||
for (int i = 0; i < files.length; i++) {
|
||||
IResource resource = files[i];
|
||||
if (resource.getType() == IResource.FILE) {
|
||||
ITranslationUnit tu= CModelUtil.findTranslationUnit((IFile) resource);
|
||||
ITranslationUnit tu= CoreModelUtil.findTranslationUnit((IFile) resource);
|
||||
if (tu != null) {
|
||||
return tu;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
package org.eclipse.cdt.internal.ui.search.actions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
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.index.IIndex;
|
||||
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.util.CElementBaseLabels;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
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.CEditor;
|
||||
import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
|
||||
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
|
||||
|
||||
public class OpenDeclarationsAction extends SelectionParseAction {
|
||||
public static boolean sIsJUnitTest = false;
|
||||
public static final IASTName[] BLANK_NAME_ARRAY = new IASTName[0];
|
||||
ITextSelection selNode;
|
||||
|
||||
|
@ -114,26 +125,13 @@ public class OpenDeclarationsAction extends SelectionParseAction {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < declNames.length; i++) {
|
||||
IASTFileLocation fileloc = declNames[i].getFileLocation();
|
||||
if (fileloc != null) {
|
||||
found = true;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
if (navigateViaCElements(workingCopy.getCProject(), index, declNames)) {
|
||||
found= true;
|
||||
}
|
||||
else {
|
||||
// leave old method as fallback for local variables, parameters and
|
||||
// everything else not covered by ICElementHandle.
|
||||
found = navigateOneLocation(declNames);
|
||||
}
|
||||
}
|
||||
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,
|
||||
boolean isDefinition, IBinding binding) throws CoreException {
|
||||
IName[] declNames= isDefinition ?
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.cdt.core.index.IIndexName;
|
|||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
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.ICProject;
|
||||
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.ICElementHandle;
|
||||
import org.eclipse.cdt.internal.corext.util.CModelUtil;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
|
||||
|
||||
|
@ -168,7 +168,17 @@ public class IndexUI {
|
|||
}
|
||||
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 {
|
||||
assert !declName.isReference();
|
||||
IBinding binding= declName.resolveBinding();
|
||||
|
@ -192,7 +202,7 @@ public class IndexUI {
|
|||
private static ITranslationUnit getTranslationUnit(ICProject cproject, IName name) {
|
||||
IPath path= Path.fromOSString(name.getFileLocation().getFileName());
|
||||
try {
|
||||
return CModelUtil.findTranslationUnitForLocation(path, cproject);
|
||||
return CoreModelUtil.findTranslationUnitForLocation(path, cproject);
|
||||
} catch (CModelException e) {
|
||||
CUIPlugin.getDefault().log(e);
|
||||
return null;
|
||||
|
|
Loading…
Add table
Reference in a new issue