1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-30 21:55:31 +02:00

175151 (move OpenTypeDialog/Action, AllTypesCache to use the IIndex API): apply fix

This commit is contained in:
Andrew Ferguson 2007-02-23 17:16:25 +00:00
parent 8429b3fcd5
commit a7e92473df
7 changed files with 345 additions and 283 deletions

View file

@ -36,7 +36,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.core.settings.model.extension.impl,
org.eclipse.cdt.core.settings.model.util,
org.eclipse.cdt.internal.core;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.browser.util;x-internal:=true,
org.eclipse.cdt.internal.core.browser.util;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.dom;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.dom.parser;x-friends:="org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.dom.parser.c;x-friends:="org.eclipse.cdt.refactoring",

View file

@ -7,33 +7,24 @@
*
* Contributors:
* QNX Software Systems - initial API and implementation
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.core.browser;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCStructure;
import org.eclipse.cdt.internal.core.browser.util.IndexModelUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
/**
* Manages a search cache for types in the workspace. Instead of returning
@ -49,137 +40,69 @@ import org.eclipse.core.runtime.CoreException;
* waits for the completion of the background job.
*/
public class AllTypesCache {
private static final boolean DEBUG = false;
private static ITypeInfo[] getTypes(ICProject[] projects, final int[] kinds, IProgressMonitor monitor) throws CoreException {
IIndex index = CCorePlugin.getIndexManager().getIndex(projects);
try {
index.acquireReadLock();
long start = System.currentTimeMillis();
IIndexBinding[] all =
index.findBindings(Pattern.compile(".*"), false, new IndexFilter() { //$NON-NLS-1$
public boolean acceptBinding(IBinding binding) {
return IndexModelUtil.bindingHasCElementType(binding, kinds);
}},
monitor
);
if(DEBUG) {
System.out.println("Index search took "+(System.currentTimeMillis() - start)); //$NON-NLS-1$
start = System.currentTimeMillis();
}
ITypeInfo[] result = new ITypeInfo[all.length];
for(int i=0; i<all.length; i++) {
IIndexBinding ib = (IIndexBinding) all[i];
result[i] = new IndexTypeInfo(ib.getQualifiedName(), IndexModelUtil.getElementType(ib), index);
}
private abstract static class TypesCollector implements IPDOMVisitor {
private final int[] kinds;
protected final List types;
protected final ICProject project;
protected TypesCollector(int[] kinds, List types, ICProject project) {
this.kinds = kinds;
this.types = types;
this.project = project;
}
protected abstract void visitKind(IPDOMNode node, int kind);
public boolean visit(IPDOMNode node) throws CoreException {
for (int i = 0; i < kinds.length; ++i)
visitKind(node, kinds[i]);
return true;
}
public void leave(IPDOMNode node) throws CoreException {
}
public List getTypes() {
return types;
}
}
private static class CTypesCollector extends TypesCollector {
public CTypesCollector(int[] kinds, List types, ICProject project) {
super(kinds, types, project);
}
protected void visitKind(IPDOMNode node, int kind) {
switch (kind) {
case ICElement.C_NAMESPACE:
return;
case ICElement.C_CLASS:
return;
case ICElement.C_STRUCT:
if (node instanceof PDOMCStructure)
types.add(new PDOMTypeInfo((IBinding)node, kind, project));
return;
case ICElement.C_UNION:
return;
case ICElement.C_ENUMERATION:
return;
case ICElement.C_TYPEDEF:
return;
}
}
}
private static class CPPTypesCollector extends TypesCollector {
public CPPTypesCollector(int[] kinds, List types, ICProject project) {
super(kinds, types, project);
}
protected void visitKind(IPDOMNode node, int kind) {
try {
switch (kind) {
case ICElement.C_NAMESPACE:
if (node instanceof ICPPNamespace || node instanceof ICPPNamespaceAlias)
types.add(new PDOMTypeInfo((PDOMBinding)node, kind, project));
return;
case ICElement.C_CLASS:
if (node instanceof ICPPClassType
&& ((ICPPClassType)node).getKey() == ICPPClassType.k_class)
types.add(new PDOMTypeInfo((PDOMBinding)node, kind, project));
return;
case ICElement.C_STRUCT:
if (node instanceof ICPPClassType
&& ((ICPPClassType)node).getKey() == ICompositeType.k_struct)
types.add(new PDOMTypeInfo((PDOMBinding)node, kind, project));
return;
case ICElement.C_UNION:
if (node instanceof ICPPClassType
&& ((ICPPClassType)node).getKey() == ICompositeType.k_union)
types.add(new PDOMTypeInfo((PDOMBinding)node, kind, project));
return;
case ICElement.C_ENUMERATION:
if (node instanceof IEnumeration
/*&& node instanceof ICPPBinding*/)
types.add(new PDOMTypeInfo((IEnumeration)node, kind, project));
return;
case ICElement.C_TYPEDEF:
return;
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
}
private static ITypeInfo[] getTypes(ICProject[] projects, int[] kinds) throws CoreException {
List types = new ArrayList();
PDOMManager pdomManager = CCoreInternals.getPDOMManager();
for (int i = 0; i < projects.length; ++i) {
ICProject project = projects[i];
CTypesCollector cCollector = new CTypesCollector(kinds, types, project);
CPPTypesCollector cppCollector = new CPPTypesCollector(kinds, types, project);
PDOM pdom = (PDOM)pdomManager.getPDOM(project);
PDOMLinkage linkage= pdom.getLinkage(ILinkage.C_LINKAGE_ID);
if (linkage != null) {
linkage.accept(cCollector);
if(DEBUG) {
System.out.println("Wrapping as ITypeInfo took "+(System.currentTimeMillis() - start)); //$NON-NLS-1$
start = System.currentTimeMillis();
}
linkage= pdom.getLinkage(ILinkage.CPP_LINKAGE_ID);
if (linkage != null) {
linkage.accept(cppCollector);
}
return result;
} catch(InterruptedException ie) {
ie.printStackTrace();
} finally {
index.releaseReadLock();
}
return (ITypeInfo[])types.toArray(new ITypeInfo[types.size()]);
return new ITypeInfo[0];
}
/**
* Returns all types in the workspace.
*/
public static ITypeInfo[] getAllTypes() {
return getAllTypes(new NullProgressMonitor());
}
/**
* Returns all types in the workspace.
*/
public static ITypeInfo[] getAllTypes() {
public static ITypeInfo[] getAllTypes(IProgressMonitor monitor) {
try {
ICProject[] projects = CoreModel.getDefault().getCModel().getCProjects();
return getTypes(projects, ITypeInfo.KNOWN_TYPES);
return getTypes(projects, ITypeInfo.KNOWN_TYPES, monitor);
} catch (CoreException e) {
CCorePlugin.log(e);
return new ITypeInfo[0];
}
}
/**
* Returns all types in the given scope.
*
@ -189,13 +112,13 @@ public class AllTypesCache {
*/
public static ITypeInfo[] getTypes(ITypeSearchScope scope, int[] kinds) {
try {
return getTypes(scope.getEnclosingProjects(), kinds);
return getTypes(scope.getEnclosingProjects(), kinds, new NullProgressMonitor());
} catch (CoreException e) {
CCorePlugin.log(e);
return new ITypeInfo[0];
}
}
/**
* Returns all namespaces in the given scope.
*
@ -204,13 +127,13 @@ public class AllTypesCache {
*/
public static ITypeInfo[] getNamespaces(ITypeSearchScope scope, boolean includeGlobalNamespace) {
try {
return getTypes(scope.getEnclosingProjects(), new int[] {ICElement.C_NAMESPACE});
return getTypes(scope.getEnclosingProjects(), new int[] {ICElement.C_NAMESPACE}, new NullProgressMonitor());
} catch (CoreException e) {
CCorePlugin.log(e);
return new ITypeInfo[0];
}
}
/** Returns first type in the cache which matches the given
* type and name. If no type is found, <code>null</code>
* is returned.

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* Copyright (c) 2006, 2007 QNX Software Systems 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
@ -8,40 +8,46 @@
* Contributors:
* QNX - Initial API and implementation
* IBM Corporation
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.core.browser;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.browser.util.IndexModelUtil;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
/**
* @author Doug Schaefer
*
*/
public class PDOMTypeInfo implements ITypeInfo {
private final IBinding binding;
public class IndexTypeInfo implements ITypeInfo {
private final String[] fqn;
private final int elementType;
private final ICProject project;
public PDOMTypeInfo(IBinding binding, int elementType, ICProject project) {
this.binding = binding;
this.elementType = elementType;
this.project = project;
}
private final IIndex index;
private ITypeReference reference; // lazily constructed
public IndexTypeInfo(String[] fqn, int elementType, IIndex index) {
this.fqn = fqn;
this.elementType = elementType;
this.index = index;
}
public void addDerivedReference(ITypeReference location) {
throw new PDOMNotImplementedError();
}
@ -83,7 +89,13 @@ public class PDOMTypeInfo implements ITypeInfo {
}
public ICProject getEnclosingProject() {
return project;
if(getResolvedReference()!=null) {
IProject project = reference.getProject();
if(project!=null) {
return CCorePlugin.getDefault().getCoreModel().getCModel().getCProject(project.getName());
}
}
return null;
}
public ITypeInfo getEnclosingType() {
@ -96,23 +108,11 @@ public class PDOMTypeInfo implements ITypeInfo {
}
public String getName() {
return binding.getName();
return fqn[fqn.length-1];
}
public IQualifiedTypeName getQualifiedTypeName() {
String qn;
if(binding instanceof ICPPBinding) {
try {
qn = CPPVisitor.renderQualifiedName(((ICPPBinding)binding).getQualifiedName());
} catch(DOMException de) {
CCorePlugin.log(de); // can't happen when (binding instanceof PDOMBinding)
return null;
}
} else {
qn = binding.getName();
}
return new QualifiedTypeName(qn);
return new QualifiedTypeName(fqn);
}
public ITypeReference[] getReferences() {
@ -120,14 +120,50 @@ public class PDOMTypeInfo implements ITypeInfo {
}
public ITypeReference getResolvedReference() {
try {
PDOM pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(project);
IName[] names= pdom.findNames(binding, IIndex.FIND_DEFINITIONS);
return names != null && names.length > 0 ? new PDOMTypeReference(names[0], project) : null;
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
if(reference==null) {
try {
index.acquireReadLock();
char[][] cfqn = new char[fqn.length][];
for(int i=0; i<fqn.length; i++)
cfqn[i] = fqn[i].toCharArray();
IIndexBinding[] ibs = index.findBindings(cfqn, new IndexFilter() {
public boolean acceptBinding(IBinding binding) {
return IndexModelUtil.bindingHasCElementType(binding, new int[]{elementType});
}
}, new NullProgressMonitor());
if(ibs.length>0) {
IIndexName[] names = index.findNames(ibs[0], IIndex.FIND_DEFINITIONS);
if(names.length>0) {
IIndexFileLocation ifl = names[0].getFile().getLocation();
String fullPath = ifl.getFullPath();
if(fullPath!=null) {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fullPath));
if(file!=null) {
reference = new TypeReference(
file, file.getProject(), names[0].getNodeOffset(), names[0].getNodeLength()
);
}
} else {
IPath path = URIUtil.toPath(ifl.getURI());
if(path!=null) {
reference = new TypeReference(
path, null, names[0].getNodeOffset(), names[0].getNodeLength()
);
}
}
}
}
} catch(CoreException ce) {
CCorePlugin.log(ce);
} catch (InterruptedException ie) {
CCorePlugin.log(ie);
} finally {
index.releaseReadLock();
}
}
return reference;
}
public ITypeInfo getRootNamespace(boolean includeGlobalNamespace) {

View file

@ -1,94 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.browser;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* @author Doug Schaefer
*
*/
public class PDOMTypeReference implements ITypeReference {
private final IName name;
private final ICProject project;
private final IPath path;
public PDOMTypeReference(IName name, ICProject project) {
this.name = name;
this.project = project;
this.path = new Path(name.getFileLocation().getFileName());
}
public ICElement[] getCElements() {
throw new PDOMNotImplementedError();
}
public int getLength() {
return name.getFileLocation().getNodeLength();
}
public IPath getLocation() {
return path;
}
public int getOffset() {
return name.getFileLocation().getNodeOffset();
}
public IPath getPath() {
return path;
}
public IProject getProject() {
throw new PDOMNotImplementedError();
}
public IPath getRelativeIncludePath(IProject project) {
throw new PDOMNotImplementedError();
}
public IPath getRelativePath(IPath relativeToPath) {
throw new PDOMNotImplementedError();
}
public IResource getResource() {
throw new PDOMNotImplementedError();
}
public ITranslationUnit getTranslationUnit() {
ICElement element = CoreModel.getDefault().create(path);
if (element != null && element instanceof ITranslationUnit)
return (ITranslationUnit)element;
else
return CoreModel.getDefault().createTranslationUnitFrom(project, path);
}
public IWorkingCopy getWorkingCopy() {
throw new PDOMNotImplementedError();
}
public boolean isLineNumber() {
return name.getFileLocation().getNodeLength() == -1;
}
}

View file

@ -0,0 +1,109 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 QNX Software Systems 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* IBM Corporation
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.internal.core.browser.util;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.model.ICElement;
/**
* Convenience class for bridging the model gap between binding types and CModel types
*
* This is internal in case some IBinding's do not have ICElement constants in future
*/
public class IndexModelUtil {
/**
* Returns whether the binding is of any of the specified CElement type constants
* @param binding
* @param kinds
* @return whether the binding is of any of the specified CElement type constants
*/
public static boolean bindingHasCElementType(IBinding binding, int[] kinds) {
try {
for(int i=0; i<kinds.length; i++) {
switch(kinds[i]) {
case ICElement.C_STRUCT:
if (binding instanceof ICompositeType
&& ((ICompositeType)binding).getKey() == ICompositeType.k_struct)
return true;
break;
case ICElement.C_UNION:
if (binding instanceof ICompositeType
&& ((ICompositeType)binding).getKey() == ICompositeType.k_union)
return true;
break;
case ICElement.C_CLASS:
if (binding instanceof ICompositeType
&& ((ICompositeType)binding).getKey() == ICPPClassType.k_class)
return true;
break;
case ICElement.C_NAMESPACE:
if (binding instanceof ICPPNamespace || binding instanceof ICPPNamespaceAlias)
return true;
break;
case ICElement.C_ENUMERATION:
if (binding instanceof IEnumeration)
return true;
break;
case ICElement.C_TYPEDEF:
if(binding instanceof ITypedef)
return true;
break;
}
}
} catch(DOMException de) {
CCorePlugin.log(de);
}
return false;
}
/**
* Returns the CElement type constant for the specified binding
* @param binding
* @return the CElement type constant for the specified binding
*/
public static int getElementType(IBinding binding) {
int elementType = Integer.MIN_VALUE;
if (binding instanceof ICompositeType) {
ICompositeType classType = (ICompositeType) binding;
try {
if(classType.getKey() == ICPPClassType.k_class) {
elementType = ICElement.C_CLASS;
} else if(classType.getKey() == ICPPClassType.k_struct) {
elementType = ICElement.C_STRUCT;
} else if(classType.getKey() == ICPPClassType.k_union) {
elementType = ICElement.C_UNION;
}
} catch(DOMException de) {
CCorePlugin.log(de);
}
}
if (binding instanceof ICPPNamespace || binding instanceof ICPPNamespaceAlias) {
elementType = ICElement.C_NAMESPACE;
}
if (binding instanceof IEnumeration) {
elementType = ICElement.C_ENUMERATION;
}
return elementType;
}
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - initial API and implementation
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.browser.opentype;
@ -23,7 +24,6 @@ import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.cdt.core.browser.AllTypesCache;
import org.eclipse.cdt.core.browser.ITypeInfo;
import org.eclipse.cdt.core.browser.ITypeReference;
import org.eclipse.cdt.core.model.CModelException;
@ -44,16 +44,7 @@ public class OpenTypeAction implements IWorkbenchWindowActionDelegate {
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
public void run(IAction action) {
ITypeInfo[] elements = AllTypesCache.getAllTypes();
if (elements.length == 0) {
String title = OpenTypeMessages.getString("OpenTypeAction.notypes.title"); //$NON-NLS-1$
String message = OpenTypeMessages.getString("OpenTypeAction.notypes.message"); //$NON-NLS-1$
MessageDialog.openInformation(getShell(), title, message);
return;
}
OpenTypeDialog dialog = new OpenTypeDialog(getShell());
dialog.setElements(elements);
int result = dialog.open();
if (result != IDialogConstants.OK_ID)
return;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* Copyright (c) 2004, 2006, 2007 IBM Corporation 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
@ -8,11 +8,33 @@
* Contributors:
* IBM Corporation - initial API and implementation
* QNX Software Systems - adapted for use in CDT
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.browser.opentype;
import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.browser.ITypeInfo;
import org.eclipse.cdt.core.browser.IndexTypeInfo;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog;
import org.eclipse.cdt.internal.core.browser.util.IndexModelUtil;
/**
* A dialog to select a type from a list of types. The selected type will be
@ -31,5 +53,80 @@ public class OpenTypeDialog extends TypeSelectionDialog {
setTitle(OpenTypeMessages.getString("OpenTypeDialog.title")); //$NON-NLS-1$
setMessage(OpenTypeMessages.getString("OpenTypeDialog.message")); //$NON-NLS-1$
setDialogSettings(DIALOG_SETTINGS);
}
char[] toPrefix(String userFilter) {
userFilter= userFilter.trim().replaceAll("^(\\*)*", ""); //$NON-NLS-1$//$NON-NLS-2$
int asterix= userFilter.indexOf("*"); //$NON-NLS-1$
return (asterix==-1 ? userFilter : userFilter.substring(0, asterix)).toCharArray();
}
/**
* Update the list of elements in AbstractElementListSelectionDialog
*
* Filtering on wildcards and types is done by the superclass - we just provide
* a good starting point
* @param userFilter
*/
public void update(String userFilter) {
char[] prefix = toPrefix(userFilter);
List types = new ArrayList();
if(prefix.length>0)
try {
IIndex index = CCorePlugin.getIndexManager().getIndex(CoreModel.getDefault().getCModel().getCProjects());
try {
index.acquireReadLock();
IBinding[] bindings= index.findBindingsForPrefix(prefix, IndexFilter.ALL, false);
for(int i=0; i<bindings.length; i++) {
IBinding binding = bindings[i];
try {
String[] fqn;
if(binding instanceof ICPPBinding) {
fqn= ((ICPPBinding)binding).getQualifiedName();
} else {
fqn = new String[] {binding.getName()};
}
types.add(new IndexTypeInfo(fqn, IndexModelUtil.getElementType(binding), index));
} catch(DOMException de) {
}
}
} finally {
index.releaseReadLock();
}
} catch(CoreException ce) {
CCorePlugin.log(ce);
} catch(InterruptedException ie) {
CCorePlugin.log(ie);
}
setListElements(types.toArray(new ITypeInfo[types.size()]));
}
protected void setListElements(Object[] elements) {
super.setListElements(elements);
}
/**
* @deprecated
*/
public void setElements(Object[] elements) {
}
protected void handleEmptyList() {
// override super-class behaviour with no-op
}
protected Text createFilterText(Composite parent) {
final Text result = super.createFilterText(parent);
Listener listener = new Listener() {
public void handleEvent(Event e) {
update(result.getText());
}
};
result.addListener(SWT.Modify, listener);
return result;
}
}