1
0
Fork 0
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:
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>.
*/
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;

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.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()));
}

View file

@ -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()));
}

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 {
if( project == null || !project.exists() )
return;

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}

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
* 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;
}

View file

@ -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 ?

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.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;