1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 01:45:33 +02:00

partial fix for 113063 from Janees and Vivian

This commit is contained in:
Chris Recoskie 2006-08-31 12:42:23 +00:00
parent 778c379f88
commit 1eceeb0258
2 changed files with 280 additions and 2 deletions

View file

@ -63,7 +63,7 @@ public class AddIncludesOperation implements IWorkspaceRunnable {
fTranslationUnit = tu;
}
public void executeInludes(IProgressMonitor monitor) throws CoreException {
public void executeIncludes(IProgressMonitor monitor) throws CoreException {
// Sanity
if (fIncludes == null || fIncludes.length == 0) {
return;
@ -199,7 +199,7 @@ public class AddIncludesOperation implements IWorkspaceRunnable {
}
try {
executeUsings(monitor);
executeInludes(monitor);
executeIncludes(monitor);
} finally {
monitor.done();
}

View file

@ -13,8 +13,31 @@ package org.eclipse.cdt.internal.ui.editor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.browser.IQualifiedTypeName;
import org.eclipse.cdt.core.browser.PathUtil;
import org.eclipse.cdt.core.browser.QualifiedTypeName;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.ui.CHelpProviderManager;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.actions.WorkbenchRunnableAdapter;
@ -24,9 +47,14 @@ import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IFunctionSummary;
import org.eclipse.cdt.ui.IRequiredInclude;
import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoLabelProvider;
import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
@ -35,9 +63,11 @@ import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.IUpdate;
@ -123,6 +153,42 @@ public class AddIncludeOnSelectionAction extends Action implements IUpdate {
fUsings = null;
fRequiredIncludes = null;
}
/**
* To be used by ElementListSelectionDialog for user to choose which declarations/
* definitions for "add include" when there are more than one to choose from.
*/
private class DisplayName extends Object
{
private PDOMName name;
public DisplayName(PDOMName name) {
this.name = name;
}
public String toString()
{
try {
PDOMBinding binding = (PDOMBinding) name.resolveBinding();
if (binding != null)
{
return getBindingQualifiedName(binding) + " - " + name.getFileName(); //$NON-NLS-1$
}
else
return null;
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
}
}
public PDOMName getPDOMName()
{
return name;
}
}
/**
* Extract the includes for the given selection. This can be both used to perform
@ -162,6 +228,144 @@ public class AddIncludeOnSelectionAction extends Action implements IUpdate {
}
}
IPDOMManager pdomManager = CCorePlugin.getPDOMManager();
try {
ITranslationUnit unit = getTranslationUnit();
//get all referenced projects
if (unit != null)
{
ICProject cProj = unit.getCProject();
if (cProj != null)
{
IProject proj = cProj.getProject();
if (proj != null)
{
IProjectDescription projectDescription = proj.getDescription();
if (projectDescription != null)
{
IProject[] projects = projectDescription.getReferencedProjects();
List cProjectsToSearch = new ArrayList();
//get all the ICProjects for the referenced projects
for(int i = 0; i < projects.length; i++)
{
IProject project = projects[i];
try {
ICProject[] cProjects = CoreModel.getDefault().getCModel().getCProjects();
if (cProjects != null) {
for (int j = 0; j < cProjects.length; j++) {
ICProject cProject = cProjects[j];
if (project.equals(cProjects[j].getProject()))
cProjectsToSearch.add(cProject);
}
}
} catch (CModelException e) {
}
}
cProjectsToSearch.add(cProj); //current project
Pattern pattern = Pattern.compile(name);
List pdomBindings = new ArrayList();
//search the projects and get name matching bindings
for (int n = 0; n < cProjectsToSearch.size(); n++)
{
PDOM pdom = (PDOM)pdomManager.getPDOM((ICProject) cProjectsToSearch.get(n));
IBinding[] bindings = pdom.findBindings(pattern);
for (int i = 0; i < bindings.length; ++i) {
PDOMBinding binding = (PDOMBinding)bindings[i];
PDOMBinding pdomBinding = pdom.getLinkage(getTranslationUnit().getLanguage()).adaptBinding(binding);
pdomBindings.add(pdomBinding);
}
}
List pdomNames = new ArrayList();
//get all the declarations/definitions of the pdomBindings found
for (int i = 0; i < pdomBindings.size(); ++i)
{
PDOMBinding pdomBinding = (PDOMBinding) pdomBindings.get(i);
if (pdomBinding instanceof PDOMMemberOwner //class or struct
|| pdomBinding instanceof IEnumeration)
{
PDOMName currentDef = pdomBinding.getFirstDefinition();
while(currentDef != null) //get all the definitions of the file to include
{
pdomNames.add(new DisplayName(currentDef));
currentDef = currentDef.getNextInBinding();
}
}
if (pdomBinding instanceof ITypedef || pdomBinding instanceof IFunction)
{
PDOMName currentDec = pdomBinding.getFirstDeclaration();
while(currentDec != null) //get all the declarations of the file to include
{
pdomNames.add(new DisplayName(currentDec));
currentDec = currentDec.getNextInBinding();
}
}
}
if (pdomNames.size() > 1)
{
ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY));
dialog.setElements(pdomNames.toArray());
dialog.setTitle(CEditorMessages.getString("AddIncludeOnSelection.label")); //$NON-NLS-1$
dialog.setMessage(CEditorMessages.getString("AddIncludeOnSelection.description")); //$NON-NLS-1$
if (dialog.open() == Window.OK) {
//get selection
Object[] selects = dialog.getResult();
fRequiredIncludes = new IRequiredInclude[selects.length];
List usings = new ArrayList(selects.length);
for (int i = 0; i < fRequiredIncludes.length; i++) {
IRequiredInclude include = getRequiredInclude(((DisplayName)selects[i]).getPDOMName().getFileName(), getTranslationUnit());
if (include != null) {
fRequiredIncludes[i] = include;
PDOMBinding pdomBinding = ((PDOMBinding)(((DisplayName)selects[i]).getPDOMName().resolveBinding()));
if (pdomBinding instanceof ICPPBinding)
{
//find the enclosing namespace, if there's one
IQualifiedTypeName qualifiedName = new QualifiedTypeName(getBindingQualifiedName(pdomBinding));
String qualifiedEnclosingName = (new QualifiedTypeName(qualifiedName.getEnclosingNames())).getFullyQualifiedName();
if (!qualifiedEnclosingName.equals("")) //$NON-NLS-1$
usings.add(qualifiedEnclosingName);
}
}
}
if(usings.size() > 0)
{
fUsings = new String[usings.size()];
for (int i = 0; i < usings.size(); i++)
{
fUsings[i] = (String) usings.get(i);
}
}
}
}
else if (pdomNames.size() == 1)
{
String fileName = ((DisplayName)pdomNames.get(0)).getPDOMName().getFileName();
fRequiredIncludes = new IRequiredInclude[] {getRequiredInclude(fileName, getTranslationUnit())};
PDOMBinding pdomBinding = (PDOMBinding) ((DisplayName)pdomNames.get(0)).getPDOMName().resolveBinding();
if (pdomBinding instanceof ICPPBinding)
{
//find the enclosing namespace, if there's one
IQualifiedTypeName qualifiedName = new QualifiedTypeName(getBindingQualifiedName(pdomBinding));
String qualifiedEnclosingName = new QualifiedTypeName(qualifiedName.getEnclosingNames()).getFullyQualifiedName();
if (!qualifiedEnclosingName.equals("")) //$NON-NLS-1$
fUsings = new String[] {qualifiedEnclosingName};
}
}
}
}
}
}
} catch (CoreException e) {
e.printStackTrace();
}
// Try the type caching.
if (fRequiredIncludes == null && fUsings == null) {
}
@ -214,6 +418,80 @@ public class AddIncludeOnSelectionAction extends Action implements IUpdate {
public void update() {
setEnabled(true);
}
/**
* Returns the RequiredInclude object to be added to the include list
* @param path - the full path of the file to include
* @param tu - the translation unit which requires the include
* @return the required include
*/
private IRequiredInclude getRequiredInclude(String path, ITranslationUnit tu) {
if (path != null) {
IPath typeLocation = new Path(path);
IProject project = tu.getCProject().getProject();
IPath projectLocation = project.getLocation();
IPath workspaceLocation = project.getWorkspace().getRoot().getLocation();
IPath headerLocation = tu.getResource().getLocation();
boolean isSystemIncludePath = false;
IPath includePath = makeRelativePathToProjectIncludes(typeLocation, tu);
if (includePath != null && !projectLocation.isPrefixOf(typeLocation)) {
isSystemIncludePath = true;
}
//create a relative path - the include file is in the same project as the file we're currently at
else if (projectLocation.isPrefixOf(typeLocation)
&& projectLocation.isPrefixOf(headerLocation)) {
includePath = PathUtil.makeRelativePath(typeLocation, headerLocation.removeLastSegments(1));
}
//create a relative path - the include file is in the same workspace as the file we're currently at
else if (workspaceLocation.isPrefixOf(typeLocation))
{
includePath = PathUtil.makeRelativePath(typeLocation, projectLocation);
}
if (includePath == null)
includePath = typeLocation; //the full path
return new RequiredIncludes(includePath.toString(), isSystemIncludePath);
}
return null;
}
/**
* Create a relative path to the project includes.
* @param fullPath the full path to the project
* @param tu a translation unit in the project
* @return IPath corresponding to a relative path to the project includes
*/
private static IPath makeRelativePathToProjectIncludes(IPath fullPath, ITranslationUnit tu) {
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(tu.getCProject().getProject());
if (provider != null) {
IScannerInfo info = provider.getScannerInformation(tu.getResource());
if (info != null) {
return PathUtil.makeRelativePathToIncludes(fullPath, info.getIncludePaths());
}
}
return null;
}
/**
* Get the fully qualified name for a given PDOMBinding
* @param pdomBinding
* @return binding's fully qualified name
* @throws CoreException
*/
private String getBindingQualifiedName(PDOMBinding pdomBinding) throws CoreException
{
StringBuffer buf = new StringBuffer(pdomBinding.getName());
PDOMNode parent = pdomBinding.getParentNode();
while (parent != null)
{
if (parent instanceof PDOMBinding)
{
buf.insert(0, ((PDOMBinding)parent).getName() + "::"); //$NON-NLS-1$
}
parent = parent.getParentNode();
}
return buf.toString();
}
}