mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
New patch from Chris Wiebe to boost the performance
of the TypeInfo, a separation is done via the Core and UI to provide more flexibility for clients using this service.
This commit is contained in:
parent
b937c683b4
commit
f6a9f8da22
31 changed files with 2822 additions and 1244 deletions
|
@ -7,6 +7,7 @@
|
||||||
<classpathentry kind="src" path="search"/>
|
<classpathentry kind="src" path="search"/>
|
||||||
<classpathentry kind="src" path="dependency"/>
|
<classpathentry kind="src" path="dependency"/>
|
||||||
<classpathentry kind="src" path="parser"/>
|
<classpathentry kind="src" path="parser"/>
|
||||||
|
<classpathentry kind="src" path="browser"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
2004-04-06 Alain Magloire
|
||||||
|
|
||||||
|
Patch from Chris Wiebe.
|
||||||
|
This patch provides some improvements to the Open Type action, such as
|
||||||
|
per-file type caching (much faster now) and extra filtering options in
|
||||||
|
the dialog. The non-ui code has also been isolated and moved to
|
||||||
|
org.eclipse.cdt.core.browser.
|
||||||
|
|
||||||
|
* browser/*
|
||||||
|
|
||||||
2004-04-06 Alain Magloire
|
2004-04-06 Alain Magloire
|
||||||
|
|
||||||
Patch from Sam Robb covering part of PR #52864
|
Patch from Sam Robb covering part of PR #52864
|
||||||
|
|
2
core/org.eclipse.cdt.core/browser/ChangeLog
Normal file
2
core/org.eclipse.cdt.core/browser/ChangeLog
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
2004-04-06 Chris Wiebe
|
||||||
|
initial placement of non-ui code into org.eclipse.cdt.core.browser
|
|
@ -0,0 +1,295 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.browser;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
|
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.ICElementDelta;
|
||||||
|
import org.eclipse.cdt.core.model.IElementChangedListener;
|
||||||
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
|
import org.eclipse.cdt.core.search.ICSearchScope;
|
||||||
|
import org.eclipse.cdt.core.search.SearchEngine;
|
||||||
|
import org.eclipse.cdt.internal.core.browser.cache.TypeCache;
|
||||||
|
import org.eclipse.cdt.internal.core.browser.cache.TypeCacherJob;
|
||||||
|
import org.eclipse.cdt.internal.core.browser.util.ArrayUtil;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages a search cache for types in the workspace. Instead of returning objects of type <code>ICElement</code>
|
||||||
|
* the methods of this class returns a list of the lightweight objects <code>TypeInfo</code>.
|
||||||
|
* <P>
|
||||||
|
* AllTypesCache runs asynchronously using a background job to rebuild the cache as needed.
|
||||||
|
* If the cache becomes dirty again while the background job is running, the job is restarted.
|
||||||
|
* <P>
|
||||||
|
* If <code>getTypes</code> is called in response to a user action, a progress dialog is shown.
|
||||||
|
* If called before the background job has finished, getTypes waits
|
||||||
|
* for the completion of the background job.
|
||||||
|
*/
|
||||||
|
public class AllTypesCache {
|
||||||
|
|
||||||
|
private static final int INITIAL_DELAY= 5000;
|
||||||
|
private static TypeCache fgCache;
|
||||||
|
private static TypeCacherJob fgJob;
|
||||||
|
private static TypeCacheDeltaListener fgDeltaListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a simple interface in order to provide
|
||||||
|
* a level of abstraction between the Core and UI
|
||||||
|
* code.
|
||||||
|
*/
|
||||||
|
public static interface IWorkingCopyProvider {
|
||||||
|
public IWorkingCopy[] getWorkingCopies();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the AllTypesCache service.
|
||||||
|
*
|
||||||
|
* @param provider A working copy provider.
|
||||||
|
*/
|
||||||
|
public static void initialize(IWorkingCopyProvider provider) {
|
||||||
|
fgCache= new TypeCache();
|
||||||
|
fgJob= new TypeCacherJob(fgCache, provider);
|
||||||
|
fgDeltaListener= new TypeCacheDeltaListener(fgCache, fgJob);
|
||||||
|
|
||||||
|
// add delta listener
|
||||||
|
CoreModel.getDefault().addElementChangedListener(fgDeltaListener);
|
||||||
|
|
||||||
|
// schedule job to run after INITIAL_DELAY
|
||||||
|
if (fgJob.getState() != Job.RUNNING) {
|
||||||
|
fgJob.setSearchPaths(null);
|
||||||
|
fgJob.setPriority(Job.BUILD);
|
||||||
|
fgJob.schedule(INITIAL_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates the service provided by AllTypesCache.
|
||||||
|
*/
|
||||||
|
public static void terminate() {
|
||||||
|
// remove delta listener
|
||||||
|
CoreModel.getDefault().removeElementChangedListener(fgDeltaListener);
|
||||||
|
|
||||||
|
// terminate background job
|
||||||
|
fgJob.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the actual type cache.
|
||||||
|
*/
|
||||||
|
public static TypeCache getCache() {
|
||||||
|
return fgCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the type cache is up to date.
|
||||||
|
*/
|
||||||
|
public static boolean isCacheUpToDate() {
|
||||||
|
return !fgCache.isDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all types in the given scope.
|
||||||
|
* @param scope The search scope
|
||||||
|
* @param kinds Array containing CElement types:
|
||||||
|
* C_NAMESPACE, C_CLASS, C_UNION, C_ENUMERATION, C_TYPEDEF
|
||||||
|
* @param monitor Progress monitor to display search progress
|
||||||
|
* @param typesFound The resulting <code>TypeInfo</code> elements are added to this collection
|
||||||
|
*/
|
||||||
|
public static void getTypes(ICSearchScope scope, int[] kinds, IProgressMonitor monitor, Collection typesFound) {
|
||||||
|
if (!isCacheUpToDate()) {
|
||||||
|
// start job if not already running
|
||||||
|
if (fgJob.getState() != Job.RUNNING) {
|
||||||
|
// boost priority since action was user-initiated
|
||||||
|
fgJob.setSearchPaths(null);
|
||||||
|
fgJob.setPriority(Job.SHORT);
|
||||||
|
fgJob.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for job to finish
|
||||||
|
try {
|
||||||
|
fgJob.join(monitor);
|
||||||
|
if (monitor != null)
|
||||||
|
monitor.done();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isWorkspaceScope= scope.equals(SearchEngine.createWorkspaceScope());
|
||||||
|
for (Iterator typesIter= fgCache.getAllTypes().iterator(); typesIter.hasNext(); ) {
|
||||||
|
ITypeInfo info= (ITypeInfo) typesIter.next();
|
||||||
|
if ( ArrayUtil.contains(kinds, info.getType()) &&
|
||||||
|
(isWorkspaceScope || info.isEnclosed(scope)) ) {
|
||||||
|
typesFound.add(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener for changes to CModel.
|
||||||
|
* @see org.eclipse.cdt.core.model.IElementChangedListener
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
private static class TypeCacheDeltaListener implements IElementChangedListener {
|
||||||
|
|
||||||
|
private TypeCache fTypeCache;
|
||||||
|
private TypeCacherJob fTypeCacherJob;
|
||||||
|
private Set fPaths= new HashSet(5);
|
||||||
|
private Set fPrefixes= new HashSet(5);
|
||||||
|
private boolean fFlushAll= false;
|
||||||
|
|
||||||
|
public TypeCacheDeltaListener(TypeCache cache, TypeCacherJob job) {
|
||||||
|
fTypeCache= cache;
|
||||||
|
fTypeCacherJob= job;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IElementChangedListener#elementChanged
|
||||||
|
*/
|
||||||
|
public void elementChanged(ElementChangedEvent event) {
|
||||||
|
fPaths.clear();
|
||||||
|
fPrefixes.clear();
|
||||||
|
fFlushAll= false;
|
||||||
|
|
||||||
|
boolean needsFlushing= processDelta(event.getDelta());
|
||||||
|
if (needsFlushing) {
|
||||||
|
// cancel background job
|
||||||
|
if (fTypeCacherJob.getState() == Job.RUNNING) {
|
||||||
|
// wait for job to finish?
|
||||||
|
try {
|
||||||
|
fTypeCacherJob.cancel();
|
||||||
|
fTypeCacherJob.join();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fFlushAll) {
|
||||||
|
// flush the entire cache
|
||||||
|
fTypeCacherJob.setSearchPaths(null);
|
||||||
|
fTypeCache.flushAll();
|
||||||
|
} else {
|
||||||
|
// flush affected files from cache
|
||||||
|
Set searchPaths= new HashSet(10);
|
||||||
|
getPrefixMatches(fPrefixes, searchPaths);
|
||||||
|
searchPaths.addAll(fPaths);
|
||||||
|
fTypeCacherJob.setSearchPaths(searchPaths);
|
||||||
|
fTypeCache.flush(searchPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restart the background job
|
||||||
|
fTypeCacherJob.setPriority(Job.BUILD);
|
||||||
|
fTypeCacherJob.schedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returns true if the cache needs to be flushed
|
||||||
|
*/
|
||||||
|
private boolean processDelta(ICElementDelta delta) {
|
||||||
|
ICElement elem= delta.getElement();
|
||||||
|
int pathEntryChanged= ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE |
|
||||||
|
ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE | ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
|
||||||
|
boolean isAddedOrRemoved= (delta.getKind() != ICElementDelta.CHANGED)
|
||||||
|
|| ((delta.getFlags() & pathEntryChanged) != 0);
|
||||||
|
|
||||||
|
switch (elem.getElementType()) {
|
||||||
|
case ICElement.C_MODEL:
|
||||||
|
{
|
||||||
|
if (isAddedOrRemoved) {
|
||||||
|
// CModel has changed
|
||||||
|
// flush the entire cache
|
||||||
|
fFlushAll= true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return processDeltaChildren(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ICElement.C_PROJECT:
|
||||||
|
case ICElement.C_CCONTAINER:
|
||||||
|
{
|
||||||
|
if (isAddedOrRemoved) {
|
||||||
|
// project or folder has changed
|
||||||
|
// flush all files with matching prefix
|
||||||
|
IPath path= elem.getPath();
|
||||||
|
if (path != null)
|
||||||
|
fPrefixes.add(path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return processDeltaChildren(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ICElement.C_NAMESPACE:
|
||||||
|
case ICElement.C_TEMPLATE_CLASS:
|
||||||
|
case ICElement.C_CLASS:
|
||||||
|
case ICElement.C_STRUCT:
|
||||||
|
case ICElement.C_UNION:
|
||||||
|
case ICElement.C_ENUMERATION:
|
||||||
|
case ICElement.C_TYPEDEF:
|
||||||
|
case ICElement.C_INCLUDE:
|
||||||
|
case ICElement.C_UNIT:
|
||||||
|
{
|
||||||
|
if (isAddedOrRemoved) {
|
||||||
|
// CElement has changed
|
||||||
|
// flush file from cache
|
||||||
|
IPath path= elem.getPath();
|
||||||
|
if (path != null)
|
||||||
|
fPaths.add(path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return processDeltaChildren(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// fields, methods, imports ect
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean processDeltaChildren(ICElementDelta delta) {
|
||||||
|
ICElementDelta[] children= delta.getAffectedChildren();
|
||||||
|
for (int i= 0; i < children.length; i++) {
|
||||||
|
if (processDelta(children[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getPrefixMatches(Set prefixes, Set results) {
|
||||||
|
Set pathSet= fTypeCache.getAllFiles();
|
||||||
|
if (pathSet.isEmpty() || prefixes == null || prefixes.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (Iterator pathIter= pathSet.iterator(); pathIter.hasNext(); ) {
|
||||||
|
IPath path= (IPath) pathIter.next();
|
||||||
|
|
||||||
|
// find paths which match prefix
|
||||||
|
for (Iterator prefixIter= prefixes.iterator(); prefixIter.hasNext(); ) {
|
||||||
|
IPath prefix= (IPath) prefixIter.next();
|
||||||
|
if (prefix.isPrefixOf(path)) {
|
||||||
|
results.add(path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !results.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,47 +8,74 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - initial API and implementation
|
* QNX Software Systems - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui.browser.typeinfo;
|
package org.eclipse.cdt.core.browser;
|
||||||
|
|
||||||
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.search.ICSearchScope;
|
import org.eclipse.cdt.core.search.ICSearchScope;
|
||||||
import org.eclipse.cdt.core.search.IMatch;
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type information.
|
* Type information.
|
||||||
*/
|
*/
|
||||||
public interface ITypeInfo extends IMatch {
|
public interface ITypeInfo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if type is enclosed in the given scope
|
* Gets the CElement type.
|
||||||
*/
|
*/
|
||||||
public boolean isEnclosed(ICSearchScope scope);
|
public int getType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the type is a low-level system type.
|
* Gets the type name.
|
||||||
* e.g. __FILE
|
|
||||||
*/
|
*/
|
||||||
public boolean isSystemType();
|
public String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the enclosing type names.
|
* Gets the enclosing type names.
|
||||||
*/
|
*/
|
||||||
public String[] getEnclosingNames();
|
public String[] getEnclosingNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the resource where type is located.
|
||||||
|
*/
|
||||||
|
public IResource getResource();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the relative path where type is located.
|
||||||
|
*/
|
||||||
|
public IPath getPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the absolute path where type is located.
|
||||||
|
*/
|
||||||
|
public IPath getLocation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the start offset of type position.
|
||||||
|
*/
|
||||||
|
public int getStartOffset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the end offset of type position.
|
||||||
|
*/
|
||||||
|
public int getEndOffset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if type is enclosed in the given scope
|
||||||
|
*/
|
||||||
|
public boolean isEnclosed(ICSearchScope scope);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the filename where this type is located.
|
* Gets the filename where this type is located.
|
||||||
*/
|
*/
|
||||||
public String getFileName();
|
public String getFileName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the file path where this type is located.
|
* Gets the fully qualified type container name: Includes enclosing type names, but
|
||||||
|
* not filename. Identifiers are separated by colons.
|
||||||
*/
|
*/
|
||||||
public String getFilePath();
|
public String getParentName();
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the extension of the file where this type is located.
|
|
||||||
*/
|
|
||||||
public String getFileExtension();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type qualified name: Includes enclosing type names, but
|
* Gets the type qualified name: Includes enclosing type names, but
|
||||||
|
@ -73,4 +100,13 @@ public interface ITypeInfo extends IMatch {
|
||||||
* Gets the CElement which corresponds to this type.
|
* Gets the CElement which corresponds to this type.
|
||||||
*/
|
*/
|
||||||
public ICElement getCElement();
|
public ICElement getCElement();
|
||||||
|
|
||||||
|
/** Gets the include path for this type.
|
||||||
|
*
|
||||||
|
* @param cProject the C Project to use as a reference.
|
||||||
|
* @return The path to this type, relative to the longest
|
||||||
|
* matching include path in the given project, or
|
||||||
|
* <code>null</code> if not found.
|
||||||
|
*/
|
||||||
|
public IPath resolveIncludePath(ICProject cProject);
|
||||||
}
|
}
|
|
@ -0,0 +1,430 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.browser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
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.IParent;
|
||||||
|
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||||
|
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||||
|
import org.eclipse.cdt.core.search.ICSearchScope;
|
||||||
|
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.core.runtime.Path;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To change the template for this generated type comment go to
|
||||||
|
* Window>Preferences>Java>Code Generation>Code and Comments
|
||||||
|
*/
|
||||||
|
public class TypeInfo implements ITypeInfo, Comparable
|
||||||
|
{
|
||||||
|
protected final static String scopeResolutionOperator= "::"; //$NON-NLS-1$
|
||||||
|
protected final static String fileScopeSeparator= " : "; //$NON-NLS-1$
|
||||||
|
private String hashString= null;
|
||||||
|
private int hashCode= 0;
|
||||||
|
private String name= null;
|
||||||
|
private int type= 0;
|
||||||
|
private String[] enclosingNames= null;
|
||||||
|
private IResource resource= null;
|
||||||
|
private IPath path= null;
|
||||||
|
private int startOffset= 0;
|
||||||
|
private int endOffset= 0;
|
||||||
|
private ICElement cElement= null;
|
||||||
|
|
||||||
|
public TypeInfo(String name, int type, String[] enclosingNames, IResource resource, IPath path, int startOffset, int endOffset) {
|
||||||
|
init(name, type, enclosingNames, resource, path, startOffset, endOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeInfo(String fullName, int type, IPath path, int startOffset, int endOffset) {
|
||||||
|
String name= fullName;
|
||||||
|
String parentName= null;
|
||||||
|
int qualifierIndex= fullName.lastIndexOf(scopeResolutionOperator);
|
||||||
|
if (qualifierIndex >= 0) {
|
||||||
|
parentName= fullName.substring(0, qualifierIndex);
|
||||||
|
name= fullName.substring(qualifierIndex+2);
|
||||||
|
}
|
||||||
|
String[] enclosingNames= null;
|
||||||
|
if (parentName != null)
|
||||||
|
enclosingNames= parseScopedName(parentName);
|
||||||
|
|
||||||
|
init(name, type, enclosingNames, null, path, startOffset, endOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeInfo(TypeInfo info) {
|
||||||
|
init(info.name, info.type, info.enclosingNames, info.resource, info.path, info.startOffset, info.endOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(String name, int type, String[] enclosingNames, IResource resource, IPath path, int startOffset, int endOffset) {
|
||||||
|
this.name= name;
|
||||||
|
this.type= type;
|
||||||
|
if (enclosingNames != null) {
|
||||||
|
this.enclosingNames= new String[enclosingNames.length];
|
||||||
|
System.arraycopy(enclosingNames, 0, this.enclosingNames, 0, enclosingNames.length);
|
||||||
|
}
|
||||||
|
this.resource= resource;
|
||||||
|
if (path == null && resource != null)
|
||||||
|
path= resource.getFullPath();
|
||||||
|
this.path= path;
|
||||||
|
this.startOffset= startOffset;
|
||||||
|
this.endOffset= endOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getEnclosingNames() {
|
||||||
|
return enclosingNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IResource getResource() {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPath getPath() {
|
||||||
|
if (resource != null)
|
||||||
|
return resource.getFullPath();
|
||||||
|
else
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPath getLocation() {
|
||||||
|
if (resource != null)
|
||||||
|
return resource.getLocation();
|
||||||
|
else
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStartOffset() {
|
||||||
|
return startOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndOffset() {
|
||||||
|
return endOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
if (resource != null)
|
||||||
|
return resource.getName();
|
||||||
|
else if (path != null)
|
||||||
|
return path.lastSegment();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentName() {
|
||||||
|
if (enclosingNames != null) {
|
||||||
|
StringBuffer buf= new StringBuffer();
|
||||||
|
for (int i= 0; i < enclosingNames.length; ++i) {
|
||||||
|
if (i > 0)
|
||||||
|
buf.append(scopeResolutionOperator);
|
||||||
|
buf.append(enclosingNames[i]);
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQualifiedParentName() {
|
||||||
|
StringBuffer buf= new StringBuffer();
|
||||||
|
String fileName = getFileName();
|
||||||
|
if (fileName != null)
|
||||||
|
buf.append(fileName);
|
||||||
|
String parentName = getParentName();
|
||||||
|
if (parentName != null) {
|
||||||
|
if (fileName != null)
|
||||||
|
buf.append(fileScopeSeparator);
|
||||||
|
buf.append(parentName);
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQualifiedName() {
|
||||||
|
StringBuffer buf= new StringBuffer();
|
||||||
|
String parentName = getParentName();
|
||||||
|
if (parentName != null)
|
||||||
|
buf.append(parentName);
|
||||||
|
String name = getName();
|
||||||
|
if (name != null) {
|
||||||
|
if (parentName != null)
|
||||||
|
buf.append(scopeResolutionOperator);
|
||||||
|
buf.append(name);
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullyQualifiedName() {
|
||||||
|
StringBuffer buf= new StringBuffer();
|
||||||
|
String fileName = getFileName();
|
||||||
|
if (fileName != null)
|
||||||
|
buf.append(fileName);
|
||||||
|
String parentName = getParentName();
|
||||||
|
if (parentName != null) {
|
||||||
|
if (fileName != null)
|
||||||
|
buf.append(fileScopeSeparator);
|
||||||
|
buf.append(parentName);
|
||||||
|
}
|
||||||
|
String name = getName();
|
||||||
|
if (name != null)
|
||||||
|
if (parentName != null)
|
||||||
|
buf.append(scopeResolutionOperator);
|
||||||
|
else if (fileName != null)
|
||||||
|
buf.append(fileScopeSeparator);
|
||||||
|
buf.append(name);
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return getFullyQualifiedName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICElement getCElement() {
|
||||||
|
if (cElement == null)
|
||||||
|
cElement= resolveCElement();
|
||||||
|
return cElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICElement resolveCElement() {
|
||||||
|
if (resource != null && resource.getType() == IResource.FILE) {
|
||||||
|
ICElement parentElement= CoreModel.getDefault().create((IFile)resource);
|
||||||
|
if (parentElement instanceof IParent) {
|
||||||
|
if (enclosingNames != null) {
|
||||||
|
for (int i= 0; i < enclosingNames.length; ++i) {
|
||||||
|
parentElement= findCElement(parentElement, enclosingNames[i]);
|
||||||
|
if (parentElement == null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parentElement != null)
|
||||||
|
return findCElement(parentElement, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICElement findCElement(ICElement celement, String name) {
|
||||||
|
if (isValidType(celement.getElementType()) && celement.getElementName().equals(name))
|
||||||
|
return celement;
|
||||||
|
|
||||||
|
if (celement instanceof IParent) {
|
||||||
|
ICElement[] children = ((IParent)celement).getChildren();
|
||||||
|
for (int i = 0; i < children.length; i++) {
|
||||||
|
ICElement child= children[i];
|
||||||
|
if (isValidType(child.getElementType()) && child.getElementName().equals(name))
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPath resolveIncludePath(ICProject cProject) {
|
||||||
|
IPath fullPath= getLocation();
|
||||||
|
if (cProject == null || fullPath == null)
|
||||||
|
return null;
|
||||||
|
IProject project= cProject.getProject();
|
||||||
|
IScannerInfoProvider provider= CCorePlugin.getDefault().getScannerInfoProvider(project);
|
||||||
|
if (provider != null) {
|
||||||
|
IScannerInfo info= provider.getScannerInformation(project);
|
||||||
|
if (info != null) {
|
||||||
|
String[] includePaths= info.getIncludePaths();
|
||||||
|
IPath relativePath= null;
|
||||||
|
int mostSegments= 0;
|
||||||
|
for (int i= 0; i < includePaths.length; ++i) {
|
||||||
|
IPath includePath= new Path(includePaths[i]);
|
||||||
|
if (includePath.isPrefixOf(fullPath)) {
|
||||||
|
int segments= includePath.matchingFirstSegments(fullPath);
|
||||||
|
if (segments > mostSegments) {
|
||||||
|
relativePath= fullPath.removeFirstSegments(segments).setDevice(null);
|
||||||
|
mostSegments= segments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return relativePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnclosed(ICSearchScope scope) {
|
||||||
|
if (scope == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check if path is in scope
|
||||||
|
IPath path= getPath();
|
||||||
|
if (path != null && scope.encloses(path.toString()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// check include paths of enclosing projects
|
||||||
|
IPath[] projectPaths= scope.enclosingProjects();
|
||||||
|
if (projectPaths != null) {
|
||||||
|
for (int i= 0; i < projectPaths.length; ++i) {
|
||||||
|
IPath projPath= projectPaths[i];
|
||||||
|
ICElement elem= CoreModel.getDefault().create(projPath);
|
||||||
|
if (elem != null && elem instanceof ICProject) {
|
||||||
|
ICProject proj= (ICProject) elem;
|
||||||
|
if (resolveIncludePath(proj) != null)
|
||||||
|
return true;
|
||||||
|
// TODO search referenced projects too?
|
||||||
|
// IProject[] refs= proj.getProject().getReferencedProjects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
if (hashString == null) {
|
||||||
|
hashCode= getHashString().hashCode();
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getHashString() {
|
||||||
|
if (hashString == null) {
|
||||||
|
StringBuffer buf= new StringBuffer(64);
|
||||||
|
|
||||||
|
IPath path= getLocation();
|
||||||
|
if (path != null)
|
||||||
|
buf.append(path.toString());
|
||||||
|
|
||||||
|
buf.append(" ["); //$NON-NLS-1$
|
||||||
|
buf.append(startOffset);
|
||||||
|
buf.append("-"); //$NON-NLS-1$
|
||||||
|
buf.append(endOffset);
|
||||||
|
buf.append("] "); //$NON-NLS-1$
|
||||||
|
|
||||||
|
String parentName= getParentName();
|
||||||
|
if (parentName != null && parentName.length() > 0) {
|
||||||
|
buf.append(parentName);
|
||||||
|
buf.append(scopeResolutionOperator);
|
||||||
|
}
|
||||||
|
String name= getName();
|
||||||
|
if (name != null && name.length() > 0)
|
||||||
|
buf.append(name);
|
||||||
|
|
||||||
|
buf.append(":"); //$NON-NLS-1$
|
||||||
|
buf.append(type);
|
||||||
|
|
||||||
|
hashString= buf.toString();
|
||||||
|
}
|
||||||
|
return hashString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof TypeInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TypeInfo info= (TypeInfo)obj;
|
||||||
|
if (hashCode() != info.hashCode())
|
||||||
|
return false;
|
||||||
|
return getHashString().equals(info.getHashString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( !(obj instanceof TypeInfo)) {
|
||||||
|
throw new ClassCastException();
|
||||||
|
}
|
||||||
|
TypeInfo info= (TypeInfo)obj;
|
||||||
|
return getHashString().compareTo(info.getHashString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isValidType(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case ICElement.C_NAMESPACE:
|
||||||
|
case ICElement.C_CLASS:
|
||||||
|
case ICElement.C_STRUCT:
|
||||||
|
case ICElement.C_UNION:
|
||||||
|
case ICElement.C_ENUMERATION:
|
||||||
|
case ICElement.C_TYPEDEF:
|
||||||
|
// case ICElement.C_TEMPLATE_CLASS:
|
||||||
|
// case ICElement.C_TEMPLATE_STRUCT:
|
||||||
|
// case ICElement.C_TEMPLATE_UNION:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] parseScopedName(String scopedName) {
|
||||||
|
ArrayList names= new ArrayList(5);
|
||||||
|
int lastIndex= 0;
|
||||||
|
String nextName;
|
||||||
|
int qualifierIndex= scopedName.indexOf(scopeResolutionOperator, 0);
|
||||||
|
while (qualifierIndex >= 0) {
|
||||||
|
nextName= scopedName.substring(lastIndex, qualifierIndex);
|
||||||
|
lastIndex= qualifierIndex + scopeResolutionOperator.length();
|
||||||
|
names.add(nextName);
|
||||||
|
qualifierIndex= scopedName.indexOf(scopeResolutionOperator, lastIndex);
|
||||||
|
}
|
||||||
|
nextName= scopedName.substring(lastIndex);
|
||||||
|
names.add(nextName);
|
||||||
|
return (String[]) names.toArray(new String[names.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
final static private Comparator TYPE_NAME_COMPARATOR= new Comparator() {
|
||||||
|
public int compare(Object o1, Object o2) {
|
||||||
|
return ((ITypeInfo)o1).getName().compareTo(((ITypeInfo)o2).getName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static ITypeInfo findType(String name, IPath path, ITypeInfo[] elements) {
|
||||||
|
if (elements == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ITypeInfo key= new TypeInfo(name, 0, path, 0, 0);
|
||||||
|
|
||||||
|
int index= Arrays.binarySearch(elements, key, TYPE_NAME_COMPARATOR);
|
||||||
|
if (index >= 0 && index < elements.length) {
|
||||||
|
for (int i= index - 1; i >= 0; i--) {
|
||||||
|
ITypeInfo curr= elements[i];
|
||||||
|
if (key.getName().equals(curr.getName())) {
|
||||||
|
if (key.getQualifiedName().equals(curr.getQualifiedName())) {
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i= index; i < elements.length; i++) {
|
||||||
|
ITypeInfo curr= elements[i];
|
||||||
|
if (key.getName().equals(curr.getName())) {
|
||||||
|
if (key.getQualifiedName().equals(curr.getQualifiedName())) {
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
152
core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
vendored
Normal file
152
core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
vendored
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.cache;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.browser.TypeInfo;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
|
public class TypeCache {
|
||||||
|
|
||||||
|
private static final int INITIAL_FILE_COUNT= 100;
|
||||||
|
private static final int INITIAL_TYPE_COUNT= INITIAL_FILE_COUNT*20;
|
||||||
|
private final Map fFileMap= new HashMap(INITIAL_FILE_COUNT);
|
||||||
|
private final Map fTypeMap= new HashMap(INITIAL_TYPE_COUNT);
|
||||||
|
private boolean fIsDirty= true;
|
||||||
|
|
||||||
|
private static final class TypeReference {
|
||||||
|
private TypeInfo fRealInfo= null;
|
||||||
|
private Set fPaths= new HashSet(1);
|
||||||
|
|
||||||
|
public TypeReference(TypeInfo info, IPath path) {
|
||||||
|
fRealInfo= info;
|
||||||
|
fPaths.add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeInfo getInfo() {
|
||||||
|
return fRealInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPath(IPath path) {
|
||||||
|
fPaths.add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePath(IPath path) {
|
||||||
|
fPaths.remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection getPaths() {
|
||||||
|
return fPaths;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public TypeCache() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void markAsDirty(boolean dirty) {
|
||||||
|
fIsDirty= dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isDirty() {
|
||||||
|
return fIsDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Set getAllFiles() {
|
||||||
|
return fFileMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Set getAllTypes() {
|
||||||
|
return fTypeMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TypeInfo addTypeReference(TypeInfo info, IPath path) {
|
||||||
|
// we use info as a key here. the actual value found in
|
||||||
|
// the map corresponds to the 'real' TypeInfo object with
|
||||||
|
// the same hashCode
|
||||||
|
TypeReference typeRef= (TypeReference) fTypeMap.get(info);
|
||||||
|
if (typeRef == null) {
|
||||||
|
// add this type to cache
|
||||||
|
typeRef= new TypeReference(info, path);
|
||||||
|
fTypeMap.put(info, typeRef);
|
||||||
|
} else if (typeRef.getInfo() != info) {
|
||||||
|
typeRef.addPath(path);
|
||||||
|
}
|
||||||
|
return typeRef.getInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeTypeReference(TypeInfo info, IPath path) {
|
||||||
|
// we use info as a key here. the actual value found in
|
||||||
|
// the map corresponds to the 'real' TypeInfo object with
|
||||||
|
// the same hashCode
|
||||||
|
TypeReference typeRef= (TypeReference) fTypeMap.get(info);
|
||||||
|
if (typeRef == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
typeRef.removePath(path);
|
||||||
|
for (Iterator i= typeRef.getPaths().iterator(); i.hasNext(); ) {
|
||||||
|
IPath p= (IPath) i.next();
|
||||||
|
fFileMap.remove(p);
|
||||||
|
}
|
||||||
|
fTypeMap.remove(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void insert(IPath path, Collection types) {
|
||||||
|
Collection typeSet= (Collection) fFileMap.get(path);
|
||||||
|
if (typeSet == null)
|
||||||
|
typeSet= new ArrayList(types.size());
|
||||||
|
for (Iterator typesIter= types.iterator(); typesIter.hasNext(); ) {
|
||||||
|
TypeInfo info= (TypeInfo)typesIter.next();
|
||||||
|
TypeInfo newType= addTypeReference(info, path);
|
||||||
|
typeSet.add(newType);
|
||||||
|
}
|
||||||
|
fFileMap.put(path, typeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean contains(IPath path) {
|
||||||
|
return fFileMap.containsKey(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void flush(IPath path) {
|
||||||
|
Collection typeSet= (Collection) fFileMap.get(path);
|
||||||
|
if (typeSet != null) {
|
||||||
|
for (Iterator typesIter= typeSet.iterator(); typesIter.hasNext(); ) {
|
||||||
|
TypeInfo info= (TypeInfo)typesIter.next();
|
||||||
|
removeTypeReference(info, path);
|
||||||
|
}
|
||||||
|
fFileMap.remove(path);
|
||||||
|
}
|
||||||
|
fIsDirty= true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void flush(Set paths) {
|
||||||
|
if (paths != null) {
|
||||||
|
// flush paths from cache
|
||||||
|
for (Iterator i= paths.iterator(); i.hasNext(); ) {
|
||||||
|
IPath path= (IPath) i.next();
|
||||||
|
flush(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void flushAll() {
|
||||||
|
// flush the entire cache
|
||||||
|
fFileMap.clear();
|
||||||
|
fTypeMap.clear();
|
||||||
|
fIsDirty= true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.cache;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
public class TypeCacheMessages {
|
||||||
|
|
||||||
|
private static final String RESOURCE_BUNDLE= TypeCacheMessages.class.getName();
|
||||||
|
|
||||||
|
private static ResourceBundle fgResourceBundle;
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
fgResourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
|
||||||
|
} catch (MissingResourceException x) {
|
||||||
|
fgResourceBundle = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TypeCacheMessages() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getString(String key) {
|
||||||
|
try {
|
||||||
|
return fgResourceBundle.getString(key);
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
return '!' + key + '!';
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFormattedString(String key, String arg) {
|
||||||
|
return getFormattedString(key, new String[] { arg });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFormattedString(String key, String[] args) {
|
||||||
|
return MessageFormat.format(getString(key), args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
###############################################################################
|
||||||
|
# Copyright (c) 2004 QNX Software Systems Ltd. and others.
|
||||||
|
# All rights reserved. This program and the accompanying materials
|
||||||
|
# are made available under the terms of the Common Public License v0.5
|
||||||
|
# which accompanies this distribution, and is available at
|
||||||
|
# http://www.eclipse.org/legal/cpl-v05.html
|
||||||
|
#
|
||||||
|
# Contributors:
|
||||||
|
# QNX Software Systems - Initial API and implementation
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
TypeCacherJob.jobName=TypeCache
|
||||||
|
TypeCacherJob.taskName=Updating Type Info...
|
204
core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java
vendored
Normal file
204
core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java
vendored
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.cache;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.browser.AllTypesCache.IWorkingCopyProvider;
|
||||||
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
|
import org.eclipse.cdt.core.search.ICSearchConstants;
|
||||||
|
import org.eclipse.cdt.core.search.ICSearchScope;
|
||||||
|
import org.eclipse.cdt.internal.core.browser.util.DelegatedProgressMonitor;
|
||||||
|
import org.eclipse.cdt.internal.core.model.CModelManager;
|
||||||
|
import org.eclipse.cdt.internal.core.search.CWorkspaceScope;
|
||||||
|
import org.eclipse.cdt.internal.core.search.PatternSearchJob;
|
||||||
|
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.OperationCanceledException;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Background job for filling the type cache.
|
||||||
|
* @see org.eclipse.core.runtime.jobs.Job
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public class TypeCacherJob extends Job {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An "identity rule" that forces jobs to be queued.
|
||||||
|
* @see org.eclipse.core.runtime.jobs.ISchedulingRule
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
final static ISchedulingRule MUTEX_RULE= new ISchedulingRule() {
|
||||||
|
public boolean contains(ISchedulingRule rule) {
|
||||||
|
return rule == this;
|
||||||
|
}
|
||||||
|
public boolean isConflicting(ISchedulingRule rule) {
|
||||||
|
return rule == this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant identifying the job family identifier for the background job.
|
||||||
|
* @see IJobManager#join(Object, IProgressMonitor)
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
private static final Object FAMILY= new Object();
|
||||||
|
|
||||||
|
private DelegatedProgressMonitor fProgressMonitor;
|
||||||
|
private Set fSearchPaths= new HashSet(50);
|
||||||
|
private TypeCache fTypeCache;
|
||||||
|
private IWorkingCopyProvider fWorkingCopyProvider;
|
||||||
|
|
||||||
|
public TypeCacherJob(TypeCache cache, IWorkingCopyProvider provider) {
|
||||||
|
super(TypeCacheMessages.getString("TypeCacherJob.jobName")); //$NON-NLS-1$
|
||||||
|
setPriority(BUILD);
|
||||||
|
setSystem(true);
|
||||||
|
//setRule(MUTEX_RULE);
|
||||||
|
fTypeCache= cache;
|
||||||
|
fWorkingCopyProvider= provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.core.internal.jobs.InternalJob#belongsTo(java.lang.Object)
|
||||||
|
*/
|
||||||
|
public boolean belongsTo(Object family) {
|
||||||
|
return family == FAMILY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchPaths(Set paths) {
|
||||||
|
fSearchPaths.clear();
|
||||||
|
if (paths != null)
|
||||||
|
fSearchPaths.addAll(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.core.runtime.jobs.Job#run(IProgressMonitor)
|
||||||
|
*/
|
||||||
|
public IStatus run(IProgressMonitor monitor) {
|
||||||
|
fProgressMonitor= new DelegatedProgressMonitor(monitor);
|
||||||
|
|
||||||
|
try {
|
||||||
|
search(fProgressMonitor);
|
||||||
|
fProgressMonitor.done();
|
||||||
|
} catch(InterruptedException ex) {
|
||||||
|
return Status.CANCEL_STATUS;
|
||||||
|
} catch (OperationCanceledException ex) {
|
||||||
|
return Status.CANCEL_STATUS;
|
||||||
|
} finally {
|
||||||
|
fProgressMonitor= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forwards progress info to the progress monitor and
|
||||||
|
* blocks until the job is finished.
|
||||||
|
*
|
||||||
|
* @param monitor Optional progress monitor.
|
||||||
|
* @throws InterruptedException
|
||||||
|
*
|
||||||
|
* @see Job#join
|
||||||
|
*/
|
||||||
|
public void join(IProgressMonitor monitor) throws InterruptedException {
|
||||||
|
if (fProgressMonitor != null)
|
||||||
|
fProgressMonitor.addDelegate(monitor);
|
||||||
|
super.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void search(IProgressMonitor monitor) throws InterruptedException {
|
||||||
|
|
||||||
|
monitor.beginTask(TypeCacheMessages.getString("TypeCacherJob.taskName"), 100); //$NON-NLS-1$
|
||||||
|
|
||||||
|
IWorkspace workspace= CCorePlugin.getWorkspace();
|
||||||
|
if (workspace == null)
|
||||||
|
throw new InterruptedException();
|
||||||
|
|
||||||
|
ICSearchScope scope= new CWorkspaceScope();
|
||||||
|
|
||||||
|
// search for types and #include references
|
||||||
|
TypeSearchPattern pattern= new TypeSearchPattern();
|
||||||
|
for (Iterator pathIter= fSearchPaths.iterator(); pathIter.hasNext(); ) {
|
||||||
|
IPath path= (IPath) pathIter.next();
|
||||||
|
pattern.addDependencySearch(path);
|
||||||
|
}
|
||||||
|
TypeSearchPathCollector pathCollector= new TypeSearchPathCollector();
|
||||||
|
|
||||||
|
CModelManager modelManager= CModelManager.getDefault();
|
||||||
|
IndexManager indexManager= modelManager.getIndexManager();
|
||||||
|
|
||||||
|
if (monitor.isCanceled())
|
||||||
|
throw new InterruptedException();
|
||||||
|
|
||||||
|
SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, 5);
|
||||||
|
|
||||||
|
/* index search */
|
||||||
|
indexManager.performConcurrentJob(
|
||||||
|
new PatternSearchJob(
|
||||||
|
pattern,
|
||||||
|
scope,
|
||||||
|
pathCollector,
|
||||||
|
indexManager
|
||||||
|
),
|
||||||
|
ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
|
||||||
|
subMonitor,
|
||||||
|
null );
|
||||||
|
|
||||||
|
if (monitor.isCanceled())
|
||||||
|
throw new InterruptedException();
|
||||||
|
|
||||||
|
if (!fSearchPaths.isEmpty()) {
|
||||||
|
// flush all affected files from cache
|
||||||
|
fTypeCache.flush(fSearchPaths);
|
||||||
|
Set dependencyPaths= pathCollector.getDependencyPaths();
|
||||||
|
if (dependencyPaths != null && !dependencyPaths.isEmpty()) {
|
||||||
|
fTypeCache.flush(dependencyPaths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set allSearchPaths= pathCollector.getPaths();
|
||||||
|
if (allSearchPaths == null)
|
||||||
|
allSearchPaths= new HashSet();
|
||||||
|
|
||||||
|
// remove cached files
|
||||||
|
allSearchPaths.removeAll(fTypeCache.getAllFiles());
|
||||||
|
|
||||||
|
if (monitor.isCanceled())
|
||||||
|
throw new InterruptedException();
|
||||||
|
|
||||||
|
subMonitor= new SubProgressMonitor(monitor, 95);
|
||||||
|
|
||||||
|
IWorkingCopy[] workingCopies= null;
|
||||||
|
if (fWorkingCopyProvider != null)
|
||||||
|
workingCopies= fWorkingCopyProvider.getWorkingCopies();
|
||||||
|
|
||||||
|
TypeMatchCollector collector= new TypeMatchCollector(fTypeCache, subMonitor);
|
||||||
|
TypeMatchLocator matchLocator= new TypeMatchLocator(collector);
|
||||||
|
matchLocator.locateMatches(allSearchPaths, workspace, workingCopies);
|
||||||
|
|
||||||
|
if (monitor.isCanceled())
|
||||||
|
throw new InterruptedException();
|
||||||
|
|
||||||
|
fTypeCache.markAsDirty(false);
|
||||||
|
monitor.done();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.cache;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.browser.TypeInfo;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
|
||||||
|
public class TypeMatchCollector {
|
||||||
|
private ArrayList results= new ArrayList();
|
||||||
|
private TypeCache typeCache;
|
||||||
|
private IProgressMonitor progressMonitor;
|
||||||
|
|
||||||
|
public TypeMatchCollector(TypeCache cache, IProgressMonitor monitor) {
|
||||||
|
progressMonitor= monitor;
|
||||||
|
typeCache= cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IProgressMonitor getProgressMonitor() {
|
||||||
|
return progressMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean beginParsing(IPath path) {
|
||||||
|
// check if path is in the cache already
|
||||||
|
if (typeCache.contains(path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
results.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doneParsing(IPath path) {
|
||||||
|
if (!results.isEmpty()) {
|
||||||
|
// add types to cache
|
||||||
|
typeCache.insert(path, results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptType(String name, int type, String[] enclosingNames, IResource resource, IPath path, int startOffset, int endOffset) {
|
||||||
|
// create new type info
|
||||||
|
TypeInfo info= new TypeInfo(name, type, enclosingNames, resource, path, startOffset, endOffset);
|
||||||
|
results.add(info);
|
||||||
|
}
|
||||||
|
}
|
561
core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchLocator.java
vendored
Normal file
561
core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchLocator.java
vendored
Normal file
|
@ -0,0 +1,561 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corp. - Rational Software - initial implementation
|
||||||
|
* QNX Software Systems - adapted for type search
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.cache;
|
||||||
|
|
||||||
|
import java.io.CharArrayReader;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
|
import org.eclipse.cdt.core.parser.DefaultProblemHandler;
|
||||||
|
import org.eclipse.cdt.core.parser.IParser;
|
||||||
|
import org.eclipse.cdt.core.parser.IProblem;
|
||||||
|
import org.eclipse.cdt.core.parser.IScanner;
|
||||||
|
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||||
|
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||||
|
import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
|
||||||
|
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
|
||||||
|
import org.eclipse.cdt.core.parser.ParserFactory;
|
||||||
|
import org.eclipse.cdt.core.parser.ParserFactoryError;
|
||||||
|
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||||
|
import org.eclipse.cdt.core.parser.ParserMode;
|
||||||
|
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||||
|
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.ASTClassKind;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTClassReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTEnumerationReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTEnumeratorReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTField;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTFieldReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTFunction;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTFunctionReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTMacro;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTMethod;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTMethodReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTNamespaceReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTParameterReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTQualifiedNameElement;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTScope;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTTemplateParameterReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTTypedefReference;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTVariable;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
|
||||||
|
import org.eclipse.cdt.core.search.ICSearchConstants;
|
||||||
|
import org.eclipse.cdt.core.search.ICSearchPattern;
|
||||||
|
import org.eclipse.cdt.internal.core.browser.util.PathUtil;
|
||||||
|
import org.eclipse.cdt.internal.core.browser.util.SimpleStack;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.OperationCanceledException;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
|
public class TypeMatchLocator implements ISourceElementRequestor, ICSearchConstants {
|
||||||
|
private ISourceElementCallbackDelegate lastDeclaration;
|
||||||
|
private ICSearchPattern searchPattern;
|
||||||
|
private TypeMatchCollector resultCollector;
|
||||||
|
private IProgressMonitor progressMonitor;
|
||||||
|
private IWorkspaceRoot workspaceRoot= null;
|
||||||
|
private SimpleStack scopeStack= new SimpleStack();
|
||||||
|
private SimpleStack resourceStack= new SimpleStack();
|
||||||
|
private static boolean VERBOSE= false;
|
||||||
|
|
||||||
|
public TypeMatchLocator(TypeMatchCollector collector) {
|
||||||
|
super();
|
||||||
|
searchPattern= new TypeSearchPattern();
|
||||||
|
resultCollector= collector;
|
||||||
|
progressMonitor= collector.getProgressMonitor();
|
||||||
|
if (progressMonitor == null)
|
||||||
|
progressMonitor= new NullProgressMonitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean acceptProblem(IProblem problem) {
|
||||||
|
return DefaultProblemHandler.ruleOnProblem(problem, ParserMode.COMPLETE_PARSE );
|
||||||
|
}
|
||||||
|
public void acceptUsingDirective(IASTUsingDirective usageDirective) { }
|
||||||
|
public void acceptUsingDeclaration(IASTUsingDeclaration usageDeclaration) { }
|
||||||
|
public void acceptASMDefinition(IASTASMDefinition asmDefinition) { }
|
||||||
|
public void acceptAbstractTypeSpecDeclaration(IASTAbstractTypeSpecifierDeclaration abstractDeclaration) { }
|
||||||
|
public void enterTemplateDeclaration(IASTTemplateDeclaration declaration) { }
|
||||||
|
public void enterTemplateSpecialization(IASTTemplateSpecialization specialization) { }
|
||||||
|
public void enterTemplateInstantiation(IASTTemplateInstantiation instantiation) { }
|
||||||
|
public void exitTemplateDeclaration(IASTTemplateDeclaration declaration) { }
|
||||||
|
public void exitTemplateSpecialization(IASTTemplateSpecialization specialization) { }
|
||||||
|
public void exitTemplateExplicitInstantiation(IASTTemplateInstantiation instantiation) { }
|
||||||
|
public void acceptParameterReference(IASTParameterReference reference) { }
|
||||||
|
public void acceptTemplateParameterReference(IASTTemplateParameterReference reference) { }
|
||||||
|
public void acceptTypedefReference( IASTTypedefReference reference ) { }
|
||||||
|
public void acceptEnumeratorReference(IASTEnumeratorReference reference) { }
|
||||||
|
public void acceptClassReference(IASTClassReference reference) { }
|
||||||
|
public void acceptNamespaceReference( IASTNamespaceReference reference ) { }
|
||||||
|
public void acceptVariableReference( IASTVariableReference reference ) { }
|
||||||
|
public void acceptFieldReference( IASTFieldReference reference ) { }
|
||||||
|
public void acceptEnumerationReference( IASTEnumerationReference reference ) { }
|
||||||
|
public void acceptFunctionReference( IASTFunctionReference reference ) { }
|
||||||
|
public void acceptMethodReference( IASTMethodReference reference ) { }
|
||||||
|
public void acceptField(IASTField field) { }
|
||||||
|
public void acceptMacro(IASTMacro macro) { }
|
||||||
|
public void acceptVariable(IASTVariable variable) { }
|
||||||
|
public void acceptFunctionDeclaration(IASTFunction function) { }
|
||||||
|
public void acceptMethodDeclaration(IASTMethod method) { }
|
||||||
|
public void enterCodeBlock(IASTCodeScope scope) { }
|
||||||
|
public void exitCodeBlock(IASTCodeScope scope) { }
|
||||||
|
|
||||||
|
public void acceptTypedefDeclaration(IASTTypedefDeclaration typedef){
|
||||||
|
lastDeclaration = typedef;
|
||||||
|
check( DECLARATIONS, typedef );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptEnumerationSpecifier(IASTEnumerationSpecifier enumeration){
|
||||||
|
lastDeclaration = enumeration;
|
||||||
|
check( DECLARATIONS, enumeration );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptElaboratedForewardDeclaration(IASTElaboratedTypeSpecifier elaboratedType){
|
||||||
|
check( DECLARATIONS, elaboratedType );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterLinkageSpecification(IASTLinkageSpecification linkageSpec){
|
||||||
|
pushScope( linkageSpec );
|
||||||
|
}
|
||||||
|
public void exitLinkageSpecification(IASTLinkageSpecification linkageSpec){
|
||||||
|
popScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterCompilationUnit(IASTCompilationUnit compilationUnit) {
|
||||||
|
pushScope( compilationUnit );
|
||||||
|
}
|
||||||
|
public void exitCompilationUnit(IASTCompilationUnit compilationUnit){
|
||||||
|
popScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterFunctionBody(IASTFunction function){
|
||||||
|
pushScope( function );
|
||||||
|
}
|
||||||
|
public void exitFunctionBody(IASTFunction function) {
|
||||||
|
popScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterMethodBody(IASTMethod method) {
|
||||||
|
pushScope( method );
|
||||||
|
}
|
||||||
|
public void exitMethodBody(IASTMethod method) {
|
||||||
|
popScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
|
||||||
|
lastDeclaration = namespaceDefinition;
|
||||||
|
check( DECLARATIONS, namespaceDefinition );
|
||||||
|
check( DEFINITIONS, namespaceDefinition );
|
||||||
|
pushScope( namespaceDefinition );
|
||||||
|
}
|
||||||
|
public void exitNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
|
||||||
|
popScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterClassSpecifier(IASTClassSpecifier classSpecification) {
|
||||||
|
lastDeclaration = classSpecification;
|
||||||
|
check( DECLARATIONS, classSpecification );
|
||||||
|
pushScope( classSpecification );
|
||||||
|
}
|
||||||
|
public void exitClassSpecifier(IASTClassSpecifier classSpecification) {
|
||||||
|
popScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterInclusion(IASTInclusion inclusion) {
|
||||||
|
String includePath = inclusion.getFullFileName();
|
||||||
|
|
||||||
|
IPath path = new Path( includePath );
|
||||||
|
IResource resource = null;
|
||||||
|
|
||||||
|
if (workspaceRoot != null)
|
||||||
|
resource = workspaceRoot.getFileForLocation( path );
|
||||||
|
|
||||||
|
if (resource == null) {
|
||||||
|
// we need to standardize the paths for external headers
|
||||||
|
path = PathUtil.getCanonicalPath(includePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource != null)
|
||||||
|
resourceStack.push(resource);
|
||||||
|
else
|
||||||
|
resourceStack.push(path);
|
||||||
|
|
||||||
|
if (progressMonitor.isCanceled())
|
||||||
|
throw new OperationCanceledException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exitInclusion(IASTInclusion inclusion) {
|
||||||
|
resourceStack.pop();
|
||||||
|
|
||||||
|
if (progressMonitor.isCanceled())
|
||||||
|
throw new OperationCanceledException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void report( ISourceElementCallbackDelegate node, int accuracyLevel ){
|
||||||
|
int offset = 0;
|
||||||
|
int end = 0;
|
||||||
|
IASTOffsetableNamedElement offsetable = null;
|
||||||
|
String name = null;
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
if( node instanceof IASTReference ){
|
||||||
|
IASTReference reference = (IASTReference) node;
|
||||||
|
offset = reference.getOffset();
|
||||||
|
end = offset + reference.getName().length();
|
||||||
|
if (VERBOSE)
|
||||||
|
verbose("Report Match: " + reference.getName()); //$NON-NLS-1$
|
||||||
|
} else if( node instanceof IASTOffsetableNamedElement ){
|
||||||
|
offsetable= (IASTOffsetableNamedElement) node;
|
||||||
|
offset = offsetable.getNameOffset() != 0 ? offsetable.getNameOffset()
|
||||||
|
: offsetable.getStartingOffset();
|
||||||
|
end = offsetable.getNameEndOffset();
|
||||||
|
if( end == 0 ){
|
||||||
|
end = offset + offsetable.getName().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VERBOSE)
|
||||||
|
verbose("Report Match: " + offsetable.getName()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node instanceof IASTReference)
|
||||||
|
node = lastDeclaration;
|
||||||
|
|
||||||
|
if (node instanceof IASTReference) {
|
||||||
|
offsetable = (IASTOffsetableNamedElement) ((IASTReference)node).getReferencedElement();
|
||||||
|
name = ((IASTReference)node).getName();
|
||||||
|
} else if (node instanceof IASTOffsetableNamedElement) {
|
||||||
|
offsetable = (IASTOffsetableNamedElement)node;
|
||||||
|
name = offsetable.getName();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip unnamed structs
|
||||||
|
if (name == null || name.length() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// skip unused types
|
||||||
|
type= getElementType(offsetable);
|
||||||
|
if (type == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect enclosing names
|
||||||
|
String[] enclosingNames = null;
|
||||||
|
if (offsetable instanceof IASTQualifiedNameElement) {
|
||||||
|
String[] names = ((IASTQualifiedNameElement) offsetable).getFullyQualifiedName();
|
||||||
|
if (names != null && names.length > 1) {
|
||||||
|
enclosingNames = new String[names.length-1];
|
||||||
|
System.arraycopy(names, 0, enclosingNames, 0, names.length-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// // collect enclosing files
|
||||||
|
// IPath[] enclosingPaths= null;
|
||||||
|
// Object[] sourceRefs= resourceStack.toArray();
|
||||||
|
// // assert(sourceRefs.length > 0)
|
||||||
|
//
|
||||||
|
// // walk through resource stack and
|
||||||
|
// // collect enclosing paths
|
||||||
|
// enclosingPaths= new IPath[sourceRefs.length-1];
|
||||||
|
// for (int i= 0; i < sourceRefs.length-1; ++i) {
|
||||||
|
// Object obj= sourceRefs[i];
|
||||||
|
// IPath sourcePath= null;
|
||||||
|
// if (obj instanceof IResource) {
|
||||||
|
// IResource res= (IResource) obj;
|
||||||
|
// enclosingPaths[i]= res.getFullPath();
|
||||||
|
// } else {
|
||||||
|
// enclosingPaths[i]= (IPath) obj;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
IResource resource= null;
|
||||||
|
IPath path= null;
|
||||||
|
Object obj= (Object) resourceStack.top();
|
||||||
|
if (obj instanceof IResource)
|
||||||
|
resource= (IResource) obj;
|
||||||
|
else
|
||||||
|
path= (IPath) obj;
|
||||||
|
|
||||||
|
resultCollector.acceptType(name, type, enclosingNames, resource, path, offset, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void check( LimitTo limit, ISourceElementCallbackDelegate node ){
|
||||||
|
|
||||||
|
if (progressMonitor.isCanceled())
|
||||||
|
throw new OperationCanceledException();
|
||||||
|
|
||||||
|
// skip local declarations
|
||||||
|
IASTScope currentScope= (IASTScope)scopeStack.top();
|
||||||
|
if (currentScope instanceof IASTFunction || currentScope instanceof IASTMethod) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// always limit == DECLARATIONS
|
||||||
|
//
|
||||||
|
// if( !searchPattern.canAccept( limit ) )
|
||||||
|
// return;
|
||||||
|
|
||||||
|
int level = ICSearchPattern.IMPOSSIBLE_MATCH;
|
||||||
|
|
||||||
|
if( node instanceof IASTReference ){
|
||||||
|
level = searchPattern.matchLevel( ((IASTReference)node).getReferencedElement(), limit );
|
||||||
|
} else {
|
||||||
|
level = searchPattern.matchLevel( node, limit );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( level != ICSearchPattern.IMPOSSIBLE_MATCH )
|
||||||
|
{
|
||||||
|
report( node, level );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushScope( IASTScope scope ){
|
||||||
|
scopeStack.push(scope);
|
||||||
|
|
||||||
|
if (progressMonitor.isCanceled())
|
||||||
|
throw new OperationCanceledException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTScope popScope(){
|
||||||
|
IASTScope oldScope= (IASTScope) scopeStack.pop();
|
||||||
|
|
||||||
|
if (progressMonitor.isCanceled())
|
||||||
|
throw new OperationCanceledException();
|
||||||
|
|
||||||
|
return oldScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verbose(String log) {
|
||||||
|
System.out.println("(" + Thread.currentThread() + ") " + log); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#createReader(java.lang.String)
|
||||||
|
*/
|
||||||
|
public Reader createReader(String finalPath) {
|
||||||
|
return ParserUtil.createReader(finalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#parserTimeout()
|
||||||
|
*/
|
||||||
|
public boolean parserTimeout() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void locateMatches(Set searchPaths, IWorkspace workspace, IWorkingCopy[] workingCopies) throws InterruptedException {
|
||||||
|
workspaceRoot= (workspace != null) ? workspace.getRoot() : null;
|
||||||
|
|
||||||
|
Set searchablePaths= new HashSet(searchPaths);
|
||||||
|
Map workingCopyMap= null;
|
||||||
|
|
||||||
|
if (workingCopies != null && workingCopies.length > 0) {
|
||||||
|
workingCopyMap= new HashMap(workingCopies.length);
|
||||||
|
for (int i= 0; i < workingCopies.length; ++i) {
|
||||||
|
IWorkingCopy workingCopy= workingCopies[i];
|
||||||
|
IPath wcPath= workingCopy.getOriginalElement().getPath();
|
||||||
|
workingCopyMap.put(wcPath, workingCopy);
|
||||||
|
searchablePaths.add(wcPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
progressMonitor.beginTask("", searchablePaths.size()); //$NON-NLS-1$
|
||||||
|
|
||||||
|
for (Iterator i= searchablePaths.iterator(); i.hasNext(); ) {
|
||||||
|
|
||||||
|
if (progressMonitor.isCanceled())
|
||||||
|
throw new InterruptedException();
|
||||||
|
|
||||||
|
IPath path= (IPath) i.next();
|
||||||
|
|
||||||
|
if (!resultCollector.beginParsing(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Reader reader= null;
|
||||||
|
IPath realPath= null;
|
||||||
|
IProject project= null;
|
||||||
|
IResource currentResource= null;
|
||||||
|
IPath currentPath= null;
|
||||||
|
|
||||||
|
progressMonitor.worked(1);
|
||||||
|
|
||||||
|
if (workspaceRoot != null) {
|
||||||
|
IWorkingCopy workingCopy= null;
|
||||||
|
if (workingCopyMap != null)
|
||||||
|
workingCopy= (IWorkingCopy) workingCopyMap.get(path);
|
||||||
|
if (workingCopy != null) {
|
||||||
|
currentResource= workingCopy.getResource();
|
||||||
|
reader= new CharArrayReader(workingCopy.getContents());
|
||||||
|
} else {
|
||||||
|
currentResource= workspaceRoot.findMember(path, true);
|
||||||
|
if (currentResource != null && currentResource instanceof IFile) {
|
||||||
|
IFile file= (IFile) currentResource;
|
||||||
|
try {
|
||||||
|
reader= new InputStreamReader(file.getContents());
|
||||||
|
} catch (CoreException ex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentResource == null) {
|
||||||
|
try {
|
||||||
|
reader= new FileReader(path.toFile());
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentPath= path;
|
||||||
|
realPath= currentPath;
|
||||||
|
project= null;
|
||||||
|
} else {
|
||||||
|
currentPath= null;
|
||||||
|
realPath= currentResource.getLocation();
|
||||||
|
project= currentResource.getProject();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentResource != null)
|
||||||
|
resourceStack.push(currentResource);
|
||||||
|
else
|
||||||
|
resourceStack.push(currentPath);
|
||||||
|
|
||||||
|
parseMatches(path, reader, realPath, project);
|
||||||
|
|
||||||
|
resourceStack.pop();
|
||||||
|
|
||||||
|
resultCollector.doneParsing(path);
|
||||||
|
|
||||||
|
if (progressMonitor.isCanceled())
|
||||||
|
throw new InterruptedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
progressMonitor.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseMatches(IPath path, Reader reader, IPath realPath, IProject project) throws InterruptedException {
|
||||||
|
//Get the scanner info
|
||||||
|
IScannerInfo scanInfo = new ScannerInfo();
|
||||||
|
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
|
||||||
|
if (provider != null){
|
||||||
|
IScannerInfo buildScanInfo = provider.getScannerInformation(project);
|
||||||
|
if( buildScanInfo != null )
|
||||||
|
scanInfo = new ScannerInfo(buildScanInfo.getDefinedSymbols(), buildScanInfo.getIncludePaths());
|
||||||
|
}
|
||||||
|
|
||||||
|
ParserLanguage language = null;
|
||||||
|
if( project != null ){
|
||||||
|
language = CoreModel.getDefault().hasCCNature( project ) ? ParserLanguage.CPP : ParserLanguage.C;
|
||||||
|
} else {
|
||||||
|
//TODO no project, what language do we use?
|
||||||
|
language = ParserLanguage.CPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
IParser parser = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IScanner scanner = ParserFactory.createScanner( reader, realPath.toOSString(), scanInfo, ParserMode.COMPLETE_PARSE, language, this, ParserUtil.getScannerLogService() );
|
||||||
|
parser = ParserFactory.createParser( scanner, this, ParserMode.COMPLETE_PARSE, language, ParserUtil.getParserLogService() );
|
||||||
|
}
|
||||||
|
catch( ParserFactoryError pfe )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VERBOSE)
|
||||||
|
verbose("*** New Search for path: " + path); //$NON-NLS-1$
|
||||||
|
|
||||||
|
try {
|
||||||
|
parser.parse();
|
||||||
|
}
|
||||||
|
catch(OperationCanceledException ex) {
|
||||||
|
throw new InterruptedException();
|
||||||
|
}
|
||||||
|
catch(Exception ex) {
|
||||||
|
if (VERBOSE){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(VirtualMachineError vmErr){
|
||||||
|
if (VERBOSE){
|
||||||
|
verbose("TypeMatchLocator VM Error: "); //$NON-NLS-1$
|
||||||
|
vmErr.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getElementType(IASTOffsetableNamedElement offsetable) {
|
||||||
|
if (offsetable instanceof IASTClassSpecifier ||
|
||||||
|
offsetable instanceof IASTElaboratedTypeSpecifier) {
|
||||||
|
|
||||||
|
ASTClassKind kind = null;
|
||||||
|
if (offsetable instanceof IASTClassSpecifier) {
|
||||||
|
kind= ((IASTClassSpecifier)offsetable).getClassKind();
|
||||||
|
} else {
|
||||||
|
kind= ((IASTElaboratedTypeSpecifier)offsetable).getClassKind();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kind == ASTClassKind.CLASS) {
|
||||||
|
return ICElement.C_CLASS;
|
||||||
|
} else if (kind == ASTClassKind.STRUCT) {
|
||||||
|
return ICElement.C_STRUCT;
|
||||||
|
} else if (kind == ASTClassKind.UNION) {
|
||||||
|
return ICElement.C_UNION;
|
||||||
|
}
|
||||||
|
} else if ( offsetable instanceof IASTNamespaceDefinition ){
|
||||||
|
return ICElement.C_NAMESPACE;
|
||||||
|
} else if ( offsetable instanceof IASTEnumerationSpecifier ){
|
||||||
|
return ICElement.C_ENUMERATION;
|
||||||
|
} else if ( offsetable instanceof IASTTypedefDeclaration ){
|
||||||
|
return ICElement.C_TYPEDEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.cache;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.search.IIndexSearchRequestor;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects type and dependency paths from search results.
|
||||||
|
*/
|
||||||
|
public class TypeSearchPathCollector implements IIndexSearchRequestor {
|
||||||
|
|
||||||
|
public Set typePaths= new HashSet(5);
|
||||||
|
public Set dependencyPaths= new HashSet(5);
|
||||||
|
|
||||||
|
public void acceptClassDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames) {
|
||||||
|
typePaths.add(resourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptNamespaceDeclaration(String resourcePath, char[] typeName, char[][] enclosingTypeNames) {
|
||||||
|
typePaths.add(resourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptIncludeDeclaration(String resourcePath, char[] decodedSimpleName) {
|
||||||
|
dependencyPaths.add(resourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptConstructorDeclaration(String resourcePath, char[] typeName, int parameterCount) { }
|
||||||
|
public void acceptConstructorReference(String resourcePath, char[] typeName, int parameterCount) { }
|
||||||
|
public void acceptFieldDeclaration(String resourcePath, char[] fieldName) { }
|
||||||
|
public void acceptFieldReference(String resourcePath, char[] fieldName) { }
|
||||||
|
public void acceptInterfaceDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames, char[] packageName) { }
|
||||||
|
public void acceptFunctionDeclaration(String resourcePath, char[] methodName, int parameterCount) { }
|
||||||
|
public void acceptMethodDeclaration(String resourcePath, char[] methodName, int parameterCount, char[][] enclosingTypeNames) { }
|
||||||
|
public void acceptMethodReference(String resourcePath, char[] methodName, int parameterCount) { }
|
||||||
|
public void acceptPackageReference(String resourcePath, char[] packageName) { }
|
||||||
|
public void acceptVariableDeclaration(String resourcePath, char[] simpleTypeName) { }
|
||||||
|
public void acceptFieldDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames) { }
|
||||||
|
public void acceptMacroDeclaration(String resourcePath, char[] decodedSimpleName) { }
|
||||||
|
public void acceptSuperTypeReference(String resourcePath, char[] qualification, char[] typeName, char[] enclosingTypeName, char classOrInterface, char[] superQualification, char[] superTypeName, char superClassOrInterface, int modifiers) { }
|
||||||
|
public void acceptSuperTypeReference(String resourcePath, char[] qualification, char[] typeName, char classOrInterface, char[] superQualification, char[] superTypeName, char superClassOrInterface, int modifiers) { }
|
||||||
|
public void acceptTypeReference(String resourcePath, char[] typeName) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the paths that have been collected.
|
||||||
|
*/
|
||||||
|
public Set getPaths() {
|
||||||
|
Set pathSet= new HashSet(typePaths.size());
|
||||||
|
for (Iterator i= typePaths.iterator(); i.hasNext(); ) {
|
||||||
|
String path= (String) i.next();
|
||||||
|
pathSet.add(new Path(path));
|
||||||
|
}
|
||||||
|
return pathSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dependency paths that have been collected.
|
||||||
|
*/
|
||||||
|
public Set getDependencyPaths() {
|
||||||
|
Set pathSet= new HashSet(dependencyPaths.size());
|
||||||
|
for (Iterator i= dependencyPaths.iterator(); i.hasNext(); ) {
|
||||||
|
String path= (String) i.next();
|
||||||
|
pathSet.add(new Path(path));
|
||||||
|
}
|
||||||
|
return pathSet;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.cache;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.search.ICSearchConstants;
|
||||||
|
import org.eclipse.cdt.core.search.OrPattern;
|
||||||
|
import org.eclipse.cdt.core.search.SearchEngine;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
|
|
||||||
|
public final class TypeSearchPattern extends OrPattern {
|
||||||
|
public TypeSearchPattern() {
|
||||||
|
super();
|
||||||
|
addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
||||||
|
addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
||||||
|
addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.STRUCT, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
||||||
|
addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.UNION, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
||||||
|
addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
||||||
|
addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDependencySearch(IPath path) {
|
||||||
|
// convert path to absolute or the search will fail
|
||||||
|
IResource res= CCorePlugin.getWorkspace().getRoot().findMember(path);
|
||||||
|
if (res != null)
|
||||||
|
path= res.getRawLocation();
|
||||||
|
if (path != null)
|
||||||
|
addPattern(createPattern(path.toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true));
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - initial API and implementation
|
* QNX Software Systems - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.browser.util;
|
package org.eclipse.cdt.internal.core.browser.util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper class which allows you to perform some
|
* A helper class which allows you to perform some
|
||||||
|
@ -20,6 +20,8 @@ public class ArrayUtil {
|
||||||
|
|
||||||
// returns true if set contains elem
|
// returns true if set contains elem
|
||||||
public static boolean contains(int[] set, int elem) {
|
public static boolean contains(int[] set, int elem) {
|
||||||
|
if (set == null)
|
||||||
|
return false;
|
||||||
for (int i= 0; i < set.length; ++i) {
|
for (int i= 0; i < set.length; ++i) {
|
||||||
if (set[i] == elem)
|
if (set[i] == elem)
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,6 +31,8 @@ public class ArrayUtil {
|
||||||
|
|
||||||
// returns true if set contains all of subset
|
// returns true if set contains all of subset
|
||||||
public static boolean containsAll(int[] set, int[] subset) {
|
public static boolean containsAll(int[] set, int[] subset) {
|
||||||
|
if (set == null || subset == null)
|
||||||
|
return false;
|
||||||
for (int i= 0; i < subset.length; ++i) {
|
for (int i= 0; i < subset.length; ++i) {
|
||||||
if (!contains(set, subset[i]))
|
if (!contains(set, subset[i]))
|
||||||
return false;
|
return false;
|
||||||
|
@ -38,9 +42,11 @@ public class ArrayUtil {
|
||||||
|
|
||||||
// return a copy of fromSet
|
// return a copy of fromSet
|
||||||
public static int[] clone(int[] fromSet) {
|
public static int[] clone(int[] fromSet) {
|
||||||
|
if (fromSet == null)
|
||||||
|
return null;
|
||||||
int[] newSet= new int[fromSet.length];
|
int[] newSet= new int[fromSet.length];
|
||||||
for (int i= 0; i < fromSet.length; ++i) {
|
for (int i= 0; i < fromSet.length; ++i) {
|
||||||
newSet[i]= newSet[i];
|
newSet[i]= fromSet[i];
|
||||||
}
|
}
|
||||||
return newSet;
|
return newSet;
|
||||||
}
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper around one or more progress monitors. Forwards
|
||||||
|
* <code>IProgressMonitor</code> and <code>IProgressMonitorWithBlocking</code>
|
||||||
|
* methods to the delegate monitors.
|
||||||
|
*/
|
||||||
|
public class DelegatedProgressMonitor implements IProgressMonitor, IProgressMonitorWithBlocking {
|
||||||
|
|
||||||
|
private static int INITIAL_DELEGATE_COUNT = 2;
|
||||||
|
private final ArrayList fDelegateList = new ArrayList(INITIAL_DELEGATE_COUNT);
|
||||||
|
private String fTaskName;
|
||||||
|
private String fSubTask;
|
||||||
|
private int fTotalWork = IProgressMonitor.UNKNOWN;
|
||||||
|
private double fWorked;
|
||||||
|
private boolean fIsBlocked = false;
|
||||||
|
private boolean fIsCanceled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new delegated monitor.
|
||||||
|
*/
|
||||||
|
public DelegatedProgressMonitor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new delegated monitor, and adds a delegate.
|
||||||
|
*/
|
||||||
|
public DelegatedProgressMonitor(IProgressMonitor delegate) {
|
||||||
|
addDelegate(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#beginTask
|
||||||
|
*/
|
||||||
|
public synchronized void beginTask(String name, int totalWork) {
|
||||||
|
fTaskName = name;
|
||||||
|
fTotalWork = totalWork;
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
delegate.beginTask(fTaskName, fTotalWork);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#done
|
||||||
|
*/
|
||||||
|
public synchronized void done() {
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
delegate.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#setTaskName
|
||||||
|
*/
|
||||||
|
public synchronized void setTaskName(String name) {
|
||||||
|
fTaskName = name;
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
delegate.setTaskName(fTaskName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#subTask
|
||||||
|
*/
|
||||||
|
public synchronized void subTask(String name) {
|
||||||
|
fSubTask = name;
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
delegate.subTask(fSubTask);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#worked
|
||||||
|
*/
|
||||||
|
public void worked(int work) {
|
||||||
|
internalWorked(work);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#internalWorked
|
||||||
|
*/
|
||||||
|
public synchronized void internalWorked(double internalWork) {
|
||||||
|
fWorked += internalWork;
|
||||||
|
final double fInternalWork = internalWork;
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
delegate.internalWorked(fInternalWork);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#isCanceled
|
||||||
|
*/
|
||||||
|
public synchronized boolean isCanceled() {
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
fIsCanceled |= delegate.isCanceled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return fIsCanceled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#setCanceled
|
||||||
|
*/
|
||||||
|
public synchronized void setCanceled(boolean canceled) {
|
||||||
|
fIsCanceled = canceled;
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
delegate.setCanceled(fIsCanceled);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#setBlocked
|
||||||
|
*/
|
||||||
|
public synchronized void setBlocked(IStatus reason) {
|
||||||
|
fIsBlocked = true;
|
||||||
|
final IStatus fReason = reason;
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
if (delegate instanceof IProgressMonitorWithBlocking)
|
||||||
|
((IProgressMonitorWithBlocking) delegate).setBlocked(fReason);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IProgressMonitor#clearBlocked
|
||||||
|
*/
|
||||||
|
public synchronized void clearBlocked() {
|
||||||
|
fIsBlocked = false;
|
||||||
|
visitDelegates(new IDelegateVisitor() {
|
||||||
|
public void visit(IProgressMonitor delegate) {
|
||||||
|
if (delegate instanceof IProgressMonitorWithBlocking)
|
||||||
|
((IProgressMonitorWithBlocking) delegate).clearBlocked();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a delegate.
|
||||||
|
*/
|
||||||
|
public synchronized void addDelegate(IProgressMonitor delegate) {
|
||||||
|
if (fDelegateList.indexOf(delegate) == -1) {
|
||||||
|
if (fTaskName != null)
|
||||||
|
syncUp(delegate);
|
||||||
|
fDelegateList.add(delegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Brings delegate in sync with current progress.
|
||||||
|
*/
|
||||||
|
private void syncUp(IProgressMonitor delegate) {
|
||||||
|
delegate.beginTask(fTaskName, fTotalWork);
|
||||||
|
delegate.internalWorked(fWorked);
|
||||||
|
if (fSubTask != null && fSubTask.length() > 0)
|
||||||
|
delegate.subTask(fSubTask);
|
||||||
|
if (fIsBlocked && delegate instanceof IProgressMonitorWithBlocking)
|
||||||
|
((IProgressMonitorWithBlocking) delegate).setBlocked(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a delegate.
|
||||||
|
*/
|
||||||
|
public synchronized void removeDelegate(IProgressMonitor delegate) {
|
||||||
|
int index = fDelegateList.indexOf(delegate);
|
||||||
|
if (index != -1) {
|
||||||
|
fDelegateList.remove(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the delegate list.
|
||||||
|
*
|
||||||
|
* @return An array of progress monitors added using <code>addDelegate()</code>.
|
||||||
|
*/
|
||||||
|
public synchronized IProgressMonitor[] getDelegates() {
|
||||||
|
return (IProgressMonitor[]) fDelegateList.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a delegate visitor.
|
||||||
|
*/
|
||||||
|
private static interface IDelegateVisitor {
|
||||||
|
public void visit(IProgressMonitor delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits each delegate in the delegates list.
|
||||||
|
*/
|
||||||
|
private void visitDelegates(IDelegateVisitor visitor) {
|
||||||
|
// Clone the delegates since they could remove themselves when called
|
||||||
|
ArrayList delegatesList = (ArrayList) fDelegateList.clone();
|
||||||
|
for (Iterator i = delegatesList.iterator(); i.hasNext(); ) {
|
||||||
|
IProgressMonitor delegate = (IProgressMonitor) i.next();
|
||||||
|
visitor.visit(delegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
|
public class PathUtil {
|
||||||
|
|
||||||
|
private static boolean fWindows = false;
|
||||||
|
static {
|
||||||
|
String os = System.getProperty("os.name"); //$NON-NLS-1$
|
||||||
|
if (os != null && os.startsWith("Win")) { //$NON-NLS-1$
|
||||||
|
fWindows= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static boolean isWindowsSystem() {
|
||||||
|
return fWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Path getCanonicalPath(String fullPath) {
|
||||||
|
File file = new File(fullPath);
|
||||||
|
try {
|
||||||
|
String canonPath = file.getCanonicalPath();
|
||||||
|
return new Path(canonPath);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
return new Path(fullPath);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.browser.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper class which allows you to perform some simple
|
||||||
|
* stack operations. Avoids the extra overhead of
|
||||||
|
* synchronization in Java.Util.Stack.
|
||||||
|
*/
|
||||||
|
public class SimpleStack {
|
||||||
|
|
||||||
|
private static int INITIAL_STACK_SIZE = 10;
|
||||||
|
private ArrayList items;
|
||||||
|
private static boolean VERBOSE = false;
|
||||||
|
|
||||||
|
public SimpleStack() {
|
||||||
|
items = new ArrayList(INITIAL_STACK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleStack(int initialSize) {
|
||||||
|
items = new ArrayList(initialSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object push(Object item) {
|
||||||
|
items.add(item);
|
||||||
|
if (VERBOSE)
|
||||||
|
trace("push on stack: " + item); //$NON-NLS-1$
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object pop() {
|
||||||
|
int top = items.size()-1;
|
||||||
|
if (top < 0)
|
||||||
|
return null;
|
||||||
|
Object item = items.get(top);
|
||||||
|
items.remove(top);
|
||||||
|
if (VERBOSE)
|
||||||
|
trace("pop from stack: " + item); //$NON-NLS-1$
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object top() {
|
||||||
|
int top = items.size()-1;
|
||||||
|
if (top < 0)
|
||||||
|
return null;
|
||||||
|
return items.get(top);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return (items.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray() {
|
||||||
|
return items.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray(Object a[]) {
|
||||||
|
return items.toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void trace(String msg) {
|
||||||
|
System.out.println("(" + Thread.currentThread() + ") " + msg); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ src.includes = about.html,\
|
||||||
index/,\
|
index/,\
|
||||||
doc/,\
|
doc/,\
|
||||||
dependency/,\
|
dependency/,\
|
||||||
|
browser/,\
|
||||||
.options
|
.options
|
||||||
javadoc.packages = org.eclipse.cdt.core.*,\
|
javadoc.packages = org.eclipse.cdt.core.*,\
|
||||||
org.eclipse.cdt.core.index.*,\
|
org.eclipse.cdt.core.index.*,\
|
||||||
|
@ -33,5 +34,6 @@ source.cdtcore.jar = index/,\
|
||||||
src/,\
|
src/,\
|
||||||
utils/,\
|
utils/,\
|
||||||
search/,\
|
search/,\
|
||||||
dependency/
|
dependency/,\
|
||||||
|
browser/
|
||||||
source.cdtparser.jar = parser/
|
source.cdtparser.jar = parser/
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
2004-04-06 Alain Magloire
|
||||||
|
|
||||||
|
This patch provides some improvements to the Open Type action, such as
|
||||||
|
per-file type caching (much faster now) and extra filtering options in
|
||||||
|
the dialog. The non-ui code has also been isolated and moved to
|
||||||
|
org.eclipse.cdt.core.browser.
|
||||||
|
|
||||||
|
* browser/*
|
||||||
|
|
||||||
2004-04-06 Alain Magloire
|
2004-04-06 Alain Magloire
|
||||||
|
|
||||||
Reorder the sorter.
|
Reorder the sorter.
|
||||||
|
|
|
@ -12,16 +12,16 @@ package org.eclipse.cdt.internal.ui.browser.opentype;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.browser.AllTypesCache;
|
||||||
|
import org.eclipse.cdt.core.browser.ITypeInfo;
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.resources.FileStorage;
|
import org.eclipse.cdt.core.resources.FileStorage;
|
||||||
import org.eclipse.cdt.core.search.ICSearchScope;
|
import org.eclipse.cdt.core.search.ICSearchScope;
|
||||||
import org.eclipse.cdt.core.search.SearchEngine;
|
import org.eclipse.cdt.core.search.SearchEngine;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||||
import org.eclipse.cdt.ui.browser.typeinfo.AllTypesCache;
|
|
||||||
import org.eclipse.cdt.ui.browser.typeinfo.ITypeInfo;
|
|
||||||
import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoFilter;
|
|
||||||
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||||
import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
|
import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
@ -58,26 +58,26 @@ public class OpenTypeAction implements IWorkbenchWindowActionDelegate {
|
||||||
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
|
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
|
||||||
*/
|
*/
|
||||||
public void run(IAction action) {
|
public void run(IAction action) {
|
||||||
|
|
||||||
final ICSearchScope scope= SearchEngine.createWorkspaceScope();
|
final ICSearchScope scope= SearchEngine.createWorkspaceScope();
|
||||||
Shell shell= CUIPlugin.getDefault().getActiveWorkbenchShell();
|
final int[] kinds= { ICElement.C_NAMESPACE, ICElement.C_CLASS, ICElement.C_STRUCT,
|
||||||
|
ICElement.C_UNION, ICElement.C_ENUMERATION, ICElement.C_TYPEDEF };
|
||||||
|
final Collection typeList= new ArrayList();
|
||||||
|
|
||||||
final ArrayList typeList= new ArrayList();
|
if (AllTypesCache.isCacheUpToDate()) {
|
||||||
final TypeInfoFilter filter= new TypeInfoFilter();
|
|
||||||
|
|
||||||
if (AllTypesCache.isCacheUpToDate(filter)) {
|
|
||||||
// run without progress monitor
|
// run without progress monitor
|
||||||
AllTypesCache.getTypes(scope, filter, null, typeList);
|
AllTypesCache.getTypes(scope, kinds, null, typeList);
|
||||||
} else {
|
} else {
|
||||||
IRunnableContext runnableContext= new ProgressMonitorDialog(shell);
|
|
||||||
IRunnableWithProgress runnable= new IRunnableWithProgress() {
|
IRunnableWithProgress runnable= new IRunnableWithProgress() {
|
||||||
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
|
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
|
||||||
AllTypesCache.getTypes(scope, filter, monitor, typeList);
|
AllTypesCache.getTypes(scope, kinds, monitor, typeList);
|
||||||
if (monitor.isCanceled()) {
|
if (monitor.isCanceled()) {
|
||||||
throw new InterruptedException();
|
throw new InterruptedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IRunnableContext runnableContext= new ProgressMonitorDialog(getShell());
|
||||||
try {
|
try {
|
||||||
runnableContext.run(true, true, runnable);
|
runnableContext.run(true, true, runnable);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
|
@ -94,13 +94,14 @@ public class OpenTypeAction implements IWorkbenchWindowActionDelegate {
|
||||||
if (typeList.isEmpty()) {
|
if (typeList.isEmpty()) {
|
||||||
String title= OpenTypeMessages.getString("OpenTypeAction.notypes.title"); //$NON-NLS-1$
|
String title= OpenTypeMessages.getString("OpenTypeAction.notypes.title"); //$NON-NLS-1$
|
||||||
String message= OpenTypeMessages.getString("OpenTypeAction.notypes.message"); //$NON-NLS-1$
|
String message= OpenTypeMessages.getString("OpenTypeAction.notypes.message"); //$NON-NLS-1$
|
||||||
MessageDialog.openInformation(shell, title, message);
|
MessageDialog.openInformation(getShell(), title, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ITypeInfo[] typeRefs= (ITypeInfo[])typeList.toArray(new ITypeInfo[typeList.size()]);
|
|
||||||
|
|
||||||
OpenTypeDialog dialog= new OpenTypeDialog(shell);
|
ITypeInfo[] elements= (ITypeInfo[])typeList.toArray(new ITypeInfo[typeList.size()]);
|
||||||
dialog.setElements(typeRefs);
|
|
||||||
|
OpenTypeDialog dialog= new OpenTypeDialog(getShell());
|
||||||
|
dialog.setElements(elements);
|
||||||
|
|
||||||
int result= dialog.open();
|
int result= dialog.open();
|
||||||
if (result != IDialogConstants.OK_ID)
|
if (result != IDialogConstants.OK_ID)
|
||||||
|
@ -110,28 +111,34 @@ public class OpenTypeAction implements IWorkbenchWindowActionDelegate {
|
||||||
if (info == null)
|
if (info == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!openTypeInEditor(shell, info))
|
if (!openTypeInEditor(info))
|
||||||
{
|
{
|
||||||
// could not find definition
|
// could not find definition
|
||||||
String path= info.getFilePath();
|
String pathString= null;
|
||||||
if (path == null || path.length() == 0)
|
IPath path= info.getLocation();
|
||||||
path= OpenTypeMessages.getString("OpenTypeAction.errorNoPath"); //$NON-NLS-1$
|
if (path != null)
|
||||||
|
pathString= path.toString();
|
||||||
|
else
|
||||||
|
pathString= OpenTypeMessages.getString("OpenTypeAction.errorNoPath"); //$NON-NLS-1$
|
||||||
String title= OpenTypeMessages.getString("OpenTypeAction.errorTitle"); //$NON-NLS-1$
|
String title= OpenTypeMessages.getString("OpenTypeAction.errorTitle"); //$NON-NLS-1$
|
||||||
String message= OpenTypeMessages.getFormattedString("OpenTypeAction.errorMessage", path); //$NON-NLS-1$
|
String message= OpenTypeMessages.getFormattedString("OpenTypeAction.errorMessage", pathString); //$NON-NLS-1$
|
||||||
MessageDialog.openError(shell, title, message);
|
MessageDialog.openError(getShell(), title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Shell getShell() {
|
||||||
|
return CUIPlugin.getDefault().getActiveWorkbenchShell();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens an editor and displays the selected type.
|
* Opens an editor and displays the selected type.
|
||||||
* @param shell Workbench shell.
|
|
||||||
* @param info Type to display.
|
* @param info Type to display.
|
||||||
* @return true if succesfully displayed.
|
* @return true if succesfully displayed.
|
||||||
*/
|
*/
|
||||||
private boolean openTypeInEditor(Shell shell, ITypeInfo info) {
|
private boolean openTypeInEditor(ITypeInfo info) {
|
||||||
IResource res= null;
|
IResource res= null;
|
||||||
IEditorPart editorPart= null;
|
IEditorPart editorPart= null;
|
||||||
IPath path= info.getLocation();
|
IPath path= info.getPath();
|
||||||
ICElement celement= info.getCElement();
|
ICElement celement= info.getCElement();
|
||||||
|
|
||||||
// attempt to locate the resource
|
// attempt to locate the resource
|
||||||
|
|
|
@ -12,12 +12,6 @@
|
||||||
package org.eclipse.cdt.internal.ui.browser.opentype;
|
package org.eclipse.cdt.internal.ui.browser.opentype;
|
||||||
|
|
||||||
import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog;
|
import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
|
||||||
import org.eclipse.jface.dialogs.IDialogSettings;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,128 +20,17 @@ import org.eclipse.swt.widgets.Shell;
|
||||||
*/
|
*/
|
||||||
public class OpenTypeDialog extends TypeSelectionDialog {
|
public class OpenTypeDialog extends TypeSelectionDialog {
|
||||||
|
|
||||||
/** The dialog location. */
|
private static final String DIALOG_SETTINGS= OpenTypeDialog.class.getName();
|
||||||
private Point fLocation;
|
|
||||||
/** The dialog size. */
|
|
||||||
private Point fSize;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance of <code>OpenTypeDialog</code>.
|
* Constructs an instance of <code>OpenTypeDialog</code>.
|
||||||
* @param parent the parent shell.
|
* @param parent the parent shell.
|
||||||
* @param context the context.
|
|
||||||
*/
|
*/
|
||||||
public OpenTypeDialog(Shell parent) {
|
public OpenTypeDialog(Shell parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
setTitle(OpenTypeMessages.getString("OpenTypeDialog.title")); //$NON-NLS-1$
|
setTitle(OpenTypeMessages.getString("OpenTypeDialog.title")); //$NON-NLS-1$
|
||||||
setMessage(OpenTypeMessages.getString("OpenTypeDialog.message")); //$NON-NLS-1$
|
setMessage(OpenTypeMessages.getString("OpenTypeDialog.message")); //$NON-NLS-1$
|
||||||
//setFilter(OpenTypeMessages.getString("OpenTypeDialog.filter")); //$NON-NLS-1$
|
|
||||||
setMatchEmptyString(true);
|
setMatchEmptyString(true);
|
||||||
}
|
setDialogSettings(DIALOG_SETTINGS);
|
||||||
|
|
||||||
/*
|
|
||||||
* @see org.eclipse.jface.window.Window#configureShell(Shell)
|
|
||||||
*/
|
|
||||||
protected void configureShell(Shell newShell) {
|
|
||||||
super.configureShell(newShell);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see Window#close()
|
|
||||||
*/
|
|
||||||
public boolean close() {
|
|
||||||
writeSettings();
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
|
|
||||||
*/
|
|
||||||
protected Control createContents(Composite parent) {
|
|
||||||
Control control= super.createContents(parent);
|
|
||||||
readSettings();
|
|
||||||
return control;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.window.Window#getInitialSize()
|
|
||||||
*/
|
|
||||||
protected Point getInitialSize() {
|
|
||||||
Point result= super.getInitialSize();
|
|
||||||
if (fSize != null) {
|
|
||||||
result.x= Math.max(result.x, fSize.x);
|
|
||||||
result.y= Math.max(result.y, fSize.y);
|
|
||||||
Rectangle display= getShell().getDisplay().getClientArea();
|
|
||||||
result.x= Math.min(result.x, display.width);
|
|
||||||
result.y= Math.min(result.y, display.height);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point)
|
|
||||||
*/
|
|
||||||
protected Point getInitialLocation(Point initialSize) {
|
|
||||||
Point result= super.getInitialLocation(initialSize);
|
|
||||||
if (fLocation != null) {
|
|
||||||
result.x= fLocation.x;
|
|
||||||
result.y= fLocation.y;
|
|
||||||
Rectangle display= getShell().getDisplay().getClientArea();
|
|
||||||
int xe= result.x + initialSize.x;
|
|
||||||
if (xe > display.width) {
|
|
||||||
result.x-= xe - display.width;
|
|
||||||
}
|
|
||||||
int ye= result.y + initialSize.y;
|
|
||||||
if (ye > display.height) {
|
|
||||||
result.y-= ye - display.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes itself from the dialog settings with the same state
|
|
||||||
* as at the previous invocation.
|
|
||||||
*/
|
|
||||||
private void readSettings() {
|
|
||||||
IDialogSettings s= getDialogSettings();
|
|
||||||
try {
|
|
||||||
int x= s.getInt("x"); //$NON-NLS-1$
|
|
||||||
int y= s.getInt("y"); //$NON-NLS-1$
|
|
||||||
fLocation= new Point(x, y);
|
|
||||||
int width= s.getInt("width"); //$NON-NLS-1$
|
|
||||||
int height= s.getInt("height"); //$NON-NLS-1$
|
|
||||||
fSize= new Point(width, height);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
fLocation= null;
|
|
||||||
fSize= null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores it current configuration in the dialog store.
|
|
||||||
*/
|
|
||||||
private void writeSettings() {
|
|
||||||
IDialogSettings s= getDialogSettings();
|
|
||||||
Point location= getShell().getLocation();
|
|
||||||
s.put("x", location.x); //$NON-NLS-1$
|
|
||||||
s.put("y", location.y); //$NON-NLS-1$
|
|
||||||
Point size= getShell().getSize();
|
|
||||||
s.put("width", size.x); //$NON-NLS-1$
|
|
||||||
s.put("height", size.y); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the dialog settings object used to share state
|
|
||||||
* between several find/replace dialogs.
|
|
||||||
*
|
|
||||||
* @return the dialog settings to be used
|
|
||||||
*/
|
|
||||||
private IDialogSettings getDialogSettings() {
|
|
||||||
IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings();
|
|
||||||
String sectionName= getClass().getName();
|
|
||||||
IDialogSettings subSettings= settings.getSection(sectionName);
|
|
||||||
if (subSettings == null)
|
|
||||||
subSettings= settings.addNewSection(sectionName);
|
|
||||||
return subSettings;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,233 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2004 QNX Software Systems and others.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Common Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/cpl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* QNX Software Systems - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.internal.ui.browser.util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A wrapper around multiple progress monitors which forwards
|
|
||||||
* <code>IProgressMonitor</code> and <code>IProgressMonitorWithBlocking</code>
|
|
||||||
* methods to the wrapped progress monitors.
|
|
||||||
*/
|
|
||||||
public class ProgressMonitorMultiWrapper implements IProgressMonitor, IProgressMonitorWithBlocking {
|
|
||||||
|
|
||||||
private double internalWork;
|
|
||||||
private int totalWork;
|
|
||||||
private int work;
|
|
||||||
private String taskName;
|
|
||||||
private String subtaskName;
|
|
||||||
private boolean isCanceled= false;
|
|
||||||
private boolean blocked= false;
|
|
||||||
|
|
||||||
/** The wrapped progress monitors. */
|
|
||||||
private final ArrayList fProgressMonitors= new ArrayList(2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new monitor wrapper.
|
|
||||||
*/
|
|
||||||
public ProgressMonitorMultiWrapper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new monitor wrapper around the given monitor.
|
|
||||||
*/
|
|
||||||
public ProgressMonitorMultiWrapper(IProgressMonitor monitor) {
|
|
||||||
addProgressMonitor(monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#beginTask
|
|
||||||
*/
|
|
||||||
public void beginTask(String name, int totalWork) {
|
|
||||||
taskName= name;
|
|
||||||
this.totalWork= totalWork;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
monitor.beginTask(name, totalWork);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#setTaskName
|
|
||||||
*/
|
|
||||||
public void setTaskName(String name) {
|
|
||||||
taskName= name;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
monitor.setTaskName(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#subTask
|
|
||||||
*/
|
|
||||||
public void subTask(String name) {
|
|
||||||
subtaskName= name;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
monitor.subTask(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#worked
|
|
||||||
*/
|
|
||||||
public void worked(int work) {
|
|
||||||
this.work= work;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
monitor.worked(work);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#internalWorked
|
|
||||||
*/
|
|
||||||
public void internalWorked(double work) {
|
|
||||||
internalWork= work;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
monitor.internalWorked(work);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#done
|
|
||||||
*/
|
|
||||||
public void done() {
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
monitor.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#setCanceled
|
|
||||||
*/
|
|
||||||
public void setCanceled(boolean canceled) {
|
|
||||||
isCanceled= canceled;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
monitor.setCanceled(canceled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#isCanceled
|
|
||||||
*/
|
|
||||||
public boolean isCanceled() {
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
isCanceled |= monitor.isCanceled();
|
|
||||||
}
|
|
||||||
return isCanceled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#setBlocked
|
|
||||||
*/
|
|
||||||
public void setBlocked(IStatus reason) {
|
|
||||||
blocked= true;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
if (monitor instanceof IProgressMonitorWithBlocking)
|
|
||||||
((IProgressMonitorWithBlocking) monitor).setBlocked(reason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see IProgressMonitor#clearBlocked
|
|
||||||
*/
|
|
||||||
public void clearBlocked() {
|
|
||||||
blocked= false;
|
|
||||||
|
|
||||||
// Clone the monitors since they could remove themselves when called
|
|
||||||
ArrayList monitors= (ArrayList) fProgressMonitors.clone();
|
|
||||||
for (int i= 0; i < monitors.size(); i++) {
|
|
||||||
IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
|
|
||||||
if (monitor instanceof IProgressMonitorWithBlocking)
|
|
||||||
((IProgressMonitorWithBlocking) monitor).clearBlocked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* brings monitor up to date
|
|
||||||
*/
|
|
||||||
private void syncUpMonitor(IProgressMonitor monitor) {
|
|
||||||
if (totalWork > 0) {
|
|
||||||
monitor.beginTask(taskName, totalWork);
|
|
||||||
monitor.worked(work);
|
|
||||||
monitor.internalWorked(internalWork);
|
|
||||||
if (subtaskName != null && subtaskName.length() > 0)
|
|
||||||
monitor.subTask(subtaskName);
|
|
||||||
if (blocked && monitor instanceof IProgressMonitorWithBlocking)
|
|
||||||
((IProgressMonitorWithBlocking) monitor).setBlocked(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a monitor to the list of wrapped monitors.
|
|
||||||
*/
|
|
||||||
public synchronized void addProgressMonitor(IProgressMonitor monitor) {
|
|
||||||
if (fProgressMonitors.indexOf(monitor) == -1) {
|
|
||||||
syncUpMonitor(monitor);
|
|
||||||
fProgressMonitors.add(monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a monitor from the list of wrapped monitors.
|
|
||||||
*/
|
|
||||||
public synchronized void removeProgressMonitor(IProgressMonitor monitor) {
|
|
||||||
int index = fProgressMonitors.indexOf(monitor);
|
|
||||||
if (index != -1) {
|
|
||||||
fProgressMonitors.remove(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the wrapped progress monitors.
|
|
||||||
*
|
|
||||||
* @return the wrapped progress monitors
|
|
||||||
*/
|
|
||||||
public IProgressMonitor[] getWrappedProgressMonitors() {
|
|
||||||
return (IProgressMonitor[]) fProgressMonitors.toArray();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,483 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2004 IBM Corporation and others.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Common Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/cpl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IBM Corporation - initial API and implementation
|
|
||||||
* QNX Software Systems - adapted for use in CDT
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.ui.browser.typeinfo;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
|
||||||
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
|
||||||
import org.eclipse.cdt.core.model.ICElementDelta;
|
|
||||||
import org.eclipse.cdt.core.model.IElementChangedListener;
|
|
||||||
import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
|
|
||||||
import org.eclipse.cdt.core.search.BasicSearchResultCollector;
|
|
||||||
import org.eclipse.cdt.core.search.ICSearchConstants;
|
|
||||||
import org.eclipse.cdt.core.search.ICSearchPattern;
|
|
||||||
import org.eclipse.cdt.core.search.ICSearchScope;
|
|
||||||
import org.eclipse.cdt.core.search.IMatch;
|
|
||||||
import org.eclipse.cdt.core.search.OrPattern;
|
|
||||||
import org.eclipse.cdt.core.search.SearchEngine;
|
|
||||||
import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
|
|
||||||
import org.eclipse.cdt.internal.ui.browser.util.ProgressMonitorMultiWrapper;
|
|
||||||
import org.eclipse.core.resources.IWorkspace;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
|
||||||
import org.eclipse.core.runtime.IPath;
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
|
||||||
import org.eclipse.core.runtime.Status;
|
|
||||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
|
||||||
import org.eclipse.core.runtime.jobs.Job;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manages a search cache for types in the workspace. Instead of returning objects of type <code>ICElement</code>
|
|
||||||
* the methods of this class returns a list of the lightweight objects <code>TypeInfo</code>.
|
|
||||||
* <P>
|
|
||||||
* AllTypesCache runs asynchronously using a background job to rebuild the cache as needed.
|
|
||||||
* If the cache becomes dirty again while the background job is running, the job is restarted.
|
|
||||||
* <P>
|
|
||||||
* If <code>getAllTypes</code> is called in response to a user action, a progress dialog is shown.
|
|
||||||
* If called before the background job has finished, getAllTypes waits
|
|
||||||
* for the completion of the background job.
|
|
||||||
*/
|
|
||||||
public class AllTypesCache {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Background job for filling the type cache.
|
|
||||||
* @see org.eclipse.core.runtime.jobs.Job
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
|
||||||
private static class TypeCacherJob extends Job {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An "identity rule" that forces jobs to be queued.
|
|
||||||
* @see org.eclipse.core.runtime.jobs.ISchedulingRule
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
|
||||||
final static ISchedulingRule MUTEX_RULE= new ISchedulingRule() {
|
|
||||||
public boolean contains(ISchedulingRule rule) {
|
|
||||||
return rule == this;
|
|
||||||
}
|
|
||||||
public boolean isConflicting(ISchedulingRule rule) {
|
|
||||||
return rule == this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A comparator for simple type names
|
|
||||||
*/
|
|
||||||
private static class TypeNameComparator implements Comparator {
|
|
||||||
public int compare(Object o1, Object o2) {
|
|
||||||
return ((TypeInfo)o1).getName().compareTo(((TypeInfo)o2).getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A search result collector for type info.
|
|
||||||
* @see org.eclipse.cdt.core.search.ICSearchResultCollector
|
|
||||||
*/
|
|
||||||
private static class TypeSearchResultCollector extends BasicSearchResultCollector {
|
|
||||||
|
|
||||||
public TypeSearchResultCollector() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeSearchResultCollector(IProgressMonitor monitor) {
|
|
||||||
super(monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMatch createMatch(Object fileResource, int start, int end, ISourceElementCallbackDelegate node, IPath realPath )
|
|
||||||
{
|
|
||||||
TypeInfo result= new TypeInfo();
|
|
||||||
return super.createMatch( result, fileResource, start, end, node, realPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean acceptMatch(IMatch match) throws CoreException {
|
|
||||||
// filter out unnamed structs
|
|
||||||
TypeInfo result= (TypeInfo) match;
|
|
||||||
String name= result.getName();
|
|
||||||
if (name == null || name.length() == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// make sure we've got a valid type
|
|
||||||
if (!TypeInfo.isValidCElementType(result.getElementType()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return super.acceptMatch(match);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constant identifying the job family identifier for the background job.
|
|
||||||
* @see IJobManager#join(Object, IProgressMonitor)
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
|
||||||
public static final Object FAMILY= new Object();
|
|
||||||
|
|
||||||
final static Comparator TYPE_COMPARATOR= new TypeNameComparator();
|
|
||||||
|
|
||||||
private ProgressMonitorMultiWrapper progressMonitor;
|
|
||||||
|
|
||||||
public TypeCacherJob() {
|
|
||||||
super(TypeInfoMessages.getString("TypeCacherJob.jobName")); //$NON-NLS-1$
|
|
||||||
setPriority(BUILD);
|
|
||||||
setSystem(true);
|
|
||||||
//setRule(MUTEX_RULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.core.internal.jobs.InternalJob#belongsTo(java.lang.Object)
|
|
||||||
*/
|
|
||||||
public boolean belongsTo(Object family) {
|
|
||||||
return family == FAMILY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.core.runtime.jobs.Job#shouldRun()
|
|
||||||
*/
|
|
||||||
public boolean shouldRun() {
|
|
||||||
return isCacheDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.core.runtime.jobs.Job#run(IProgressMonitor)
|
|
||||||
*/
|
|
||||||
public IStatus run(IProgressMonitor monitor) {
|
|
||||||
progressMonitor= new ProgressMonitorMultiWrapper(monitor);
|
|
||||||
progressMonitor.beginTask(TypeInfoMessages.getString("TypeCacherJob.taskName"), 100); //$NON-NLS-1$
|
|
||||||
|
|
||||||
SubProgressMonitor subMonitor= new SubProgressMonitor(progressMonitor, 100);
|
|
||||||
TypeSearchResultCollector collector= new TypeSearchResultCollector(subMonitor);
|
|
||||||
|
|
||||||
IWorkspace workspace= CCorePlugin.getWorkspace();
|
|
||||||
if (workspace == null) {
|
|
||||||
return Status.CANCEL_STATUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
ICSearchScope scope= SearchEngine.createWorkspaceScope();
|
|
||||||
SearchEngine engine= new SearchEngine();
|
|
||||||
|
|
||||||
ICSearchPattern pattern= createSearchPattern();
|
|
||||||
try {
|
|
||||||
flushCache();
|
|
||||||
// start the search engine
|
|
||||||
if (progressMonitor.isCanceled())
|
|
||||||
throw new InterruptedException();
|
|
||||||
engine.search(workspace, pattern, scope, collector, true);
|
|
||||||
if (progressMonitor.isCanceled())
|
|
||||||
throw new InterruptedException();
|
|
||||||
progressMonitor.done();
|
|
||||||
} catch(InterruptedException ex) {
|
|
||||||
return Status.CANCEL_STATUS;
|
|
||||||
} finally {
|
|
||||||
progressMonitor= null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set searchResults= collector.getSearchResults();
|
|
||||||
|
|
||||||
if (searchResults != null) {
|
|
||||||
TypeInfo[] result= (TypeInfo[]) searchResults.toArray(new TypeInfo[searchResults.size()]);
|
|
||||||
Arrays.sort(result, TYPE_COMPARATOR);
|
|
||||||
setCache(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TypeInfo[] result= new TypeInfo[0];
|
|
||||||
setCache(result);
|
|
||||||
}
|
|
||||||
return Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* creates a search pattern based on the cache types
|
|
||||||
*/
|
|
||||||
private ICSearchPattern createSearchPattern() {
|
|
||||||
OrPattern pattern= new OrPattern();
|
|
||||||
int[] types= getCacheTypes();
|
|
||||||
for (int i= 0; i < types.length; ++i) {
|
|
||||||
switch (types[i]) {
|
|
||||||
case ICElement.C_NAMESPACE:
|
|
||||||
pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICElement.C_CLASS: // fall through
|
|
||||||
case ICElement.C_TEMPLATE_CLASS:
|
|
||||||
pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICElement.C_STRUCT: // fall through
|
|
||||||
case ICElement.C_TEMPLATE_STRUCT:
|
|
||||||
pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.STRUCT, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICElement.C_UNION: // fall through
|
|
||||||
case ICElement.C_TEMPLATE_UNION:
|
|
||||||
pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.UNION, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICElement.C_ENUMERATION:
|
|
||||||
pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICElement.C_TYPEDEF:
|
|
||||||
pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forwards progress info to the progress monitor and
|
|
||||||
* blocks until the job is finished.
|
|
||||||
*
|
|
||||||
* @param monitor Optional progress monitor.
|
|
||||||
* @throws InterruptedException
|
|
||||||
*
|
|
||||||
* @see Job#join
|
|
||||||
*/
|
|
||||||
public void join(IProgressMonitor monitor) throws InterruptedException {
|
|
||||||
if (progressMonitor != null)
|
|
||||||
progressMonitor.addProgressMonitor(monitor);
|
|
||||||
super.join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener for changes to CModel.
|
|
||||||
* @see org.eclipse.cdt.core.model.IElementChangedListener
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
|
||||||
private static class TypeCacheDeltaListener implements IElementChangedListener {
|
|
||||||
/*
|
|
||||||
* @see IElementChangedListener#elementChanged
|
|
||||||
*/
|
|
||||||
public void elementChanged(ElementChangedEvent event) {
|
|
||||||
//TODO optimization: calculate deltas per file and
|
|
||||||
// update the cache selectively
|
|
||||||
boolean needsFlushing= processDelta(event.getDelta());
|
|
||||||
if (needsFlushing) {
|
|
||||||
// mark cache as dirty and reschedule the
|
|
||||||
// background job
|
|
||||||
setCacheDirty();
|
|
||||||
if (fgJob.getState() == Job.RUNNING)
|
|
||||||
fgJob.cancel();
|
|
||||||
fgJob.setPriority(Job.BUILD);
|
|
||||||
fgJob.schedule();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* returns true if the cache needs to be flushed
|
|
||||||
*/
|
|
||||||
private boolean processDelta(ICElementDelta delta) {
|
|
||||||
ICElement elem= delta.getElement();
|
|
||||||
int pathEntryChanged= ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE |
|
|
||||||
ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE | ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
|
|
||||||
boolean isAddedOrRemoved= (delta.getKind() != ICElementDelta.CHANGED)
|
|
||||||
|| ((delta.getFlags() & pathEntryChanged) != 0);
|
|
||||||
|
|
||||||
switch (elem.getElementType()) {
|
|
||||||
case ICElement.C_MODEL:
|
|
||||||
case ICElement.C_PROJECT:
|
|
||||||
case ICElement.C_CCONTAINER:
|
|
||||||
case ICElement.C_NAMESPACE:
|
|
||||||
case ICElement.C_TEMPLATE_CLASS:
|
|
||||||
case ICElement.C_CLASS:
|
|
||||||
case ICElement.C_STRUCT:
|
|
||||||
case ICElement.C_UNION:
|
|
||||||
case ICElement.C_ENUMERATION:
|
|
||||||
case ICElement.C_TYPEDEF:
|
|
||||||
case ICElement.C_INCLUDE:
|
|
||||||
case ICElement.C_UNIT:
|
|
||||||
if (isAddedOrRemoved) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return processChildrenDelta(delta);
|
|
||||||
default:
|
|
||||||
// fields, methods, imports ect
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPossibleStructuralChange(int flags) {
|
|
||||||
return (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean processChildrenDelta(ICElementDelta delta) {
|
|
||||||
ICElementDelta[] children= delta.getAffectedChildren();
|
|
||||||
for (int i= 0; i < children.length; i++) {
|
|
||||||
if (processDelta(children[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int INITIAL_DELAY= 5000;
|
|
||||||
private static final TypeCacherJob fgJob= new TypeCacherJob();
|
|
||||||
private static final TypeCacheDeltaListener fgDeltaListener= new TypeCacheDeltaListener();
|
|
||||||
private static int[] fgCacheTypes= TypeInfo.getAllCElementTypes();
|
|
||||||
private static TypeInfo[] fgCacheData;
|
|
||||||
private static int fgNumberOfCacheFlushes;
|
|
||||||
private static boolean cacheIsDirty= true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the AllTypesCache service.
|
|
||||||
*/
|
|
||||||
public static void initialize() {
|
|
||||||
// add delta listener
|
|
||||||
CoreModel.getDefault().addElementChangedListener(fgDeltaListener);
|
|
||||||
|
|
||||||
// schedule job to run after INITIAL_DELAY
|
|
||||||
if (fgJob.getState() != Job.RUNNING) {
|
|
||||||
fgJob.setPriority(Job.BUILD);
|
|
||||||
fgJob.schedule(INITIAL_DELAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Terminates the service provided by AllTypesCache.
|
|
||||||
*/
|
|
||||||
public static void terminate() {
|
|
||||||
// remove delta listener
|
|
||||||
CoreModel.getDefault().removeElementChangedListener(fgDeltaListener);
|
|
||||||
|
|
||||||
// terminate background job
|
|
||||||
fgJob.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets the cache contents.
|
|
||||||
*/
|
|
||||||
private static synchronized void setCache(TypeInfo[] cache) {
|
|
||||||
fgCacheData= cache;
|
|
||||||
cacheIsDirty= false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets the cache contents.
|
|
||||||
*/
|
|
||||||
private static synchronized TypeInfo[] getCache() {
|
|
||||||
return fgCacheData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clears the cache.
|
|
||||||
*/
|
|
||||||
private static synchronized void flushCache() {
|
|
||||||
fgCacheData= null;
|
|
||||||
++fgNumberOfCacheFlushes;
|
|
||||||
cacheIsDirty= true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Marks cache as dirty.
|
|
||||||
*/
|
|
||||||
private static synchronized void setCacheDirty() {
|
|
||||||
cacheIsDirty= true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tests if cache is dirty.
|
|
||||||
*/
|
|
||||||
private static synchronized boolean isCacheDirty() {
|
|
||||||
return cacheIsDirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets which types are stored in the cache.
|
|
||||||
*/
|
|
||||||
private static synchronized void setCacheTypes(int[] cElementTypes) {
|
|
||||||
fgCacheTypes= ArrayUtil.clone(cElementTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets types stored in the cache.
|
|
||||||
*/
|
|
||||||
private static synchronized int[] getCacheTypes() {
|
|
||||||
return fgCacheTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all types in the given scope, matching the given filter.
|
|
||||||
* @param filter Filter for the type info.
|
|
||||||
* @param monitor Progress monitor.
|
|
||||||
* @param typesFound The resulting <code>TypeInfo</code> elements are added to this collection
|
|
||||||
*/
|
|
||||||
public static void getTypes(ICSearchScope scope, ITypeInfoFilter filter, IProgressMonitor monitor, Collection typesFound) {
|
|
||||||
TypeInfo[] allTypes= getAllTypes(filter, monitor);
|
|
||||||
if (allTypes != null) {
|
|
||||||
boolean isWorkspaceScope= scope.equals(SearchEngine.createWorkspaceScope());
|
|
||||||
for (int i= 0; i < allTypes.length; i++) {
|
|
||||||
TypeInfo info= allTypes[i];
|
|
||||||
if (isWorkspaceScope || info.isEnclosed(scope)) {
|
|
||||||
if (filter.match(info))
|
|
||||||
typesFound.add(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all types in the workspace. The returned array must not be
|
|
||||||
* modified. The elements in the array are sorted by simple type name.
|
|
||||||
*/
|
|
||||||
public static TypeInfo[] getAllTypes(ITypeInfoFilter filter, IProgressMonitor monitor) {
|
|
||||||
|
|
||||||
// check if requested types are in cache
|
|
||||||
if (!ArrayUtil.containsAll(getCacheTypes(), filter.getCElementTypes()))
|
|
||||||
{
|
|
||||||
// mark cache dirty and cancel the running job
|
|
||||||
setCacheDirty();
|
|
||||||
if (fgJob.getState() == Job.RUNNING)
|
|
||||||
fgJob.cancel();
|
|
||||||
setCacheTypes(filter.getCElementTypes());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCacheDirty()) {
|
|
||||||
// start job if not already running
|
|
||||||
if (fgJob.getState() != Job.RUNNING) {
|
|
||||||
// boost priority since action was user-initiated
|
|
||||||
fgJob.setPriority(Job.SHORT);
|
|
||||||
fgJob.schedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for job to finish
|
|
||||||
try {
|
|
||||||
fgJob.join(monitor);
|
|
||||||
if (monitor != null)
|
|
||||||
monitor.done();
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the type cache is up to date.
|
|
||||||
*/
|
|
||||||
public static boolean isCacheUpToDate(ITypeInfoFilter filter) {
|
|
||||||
// check if requested types are in cache
|
|
||||||
if (!ArrayUtil.containsAll(getCacheTypes(), filter.getCElementTypes()))
|
|
||||||
return false;
|
|
||||||
return !isCacheDirty();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2004 QNX Software Systems and others.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Common Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/cpl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* QNX Software Systems - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.ui.browser.typeinfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter for type info.
|
|
||||||
*/
|
|
||||||
public interface ITypeInfoFilter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the C types handled by this filter.
|
|
||||||
*
|
|
||||||
* @return An array of ICElement types.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public int[] getCElementTypes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Matches type info against filter.
|
|
||||||
*
|
|
||||||
* @param info The object to filter.
|
|
||||||
* @return <code>true</code> if successful match.
|
|
||||||
*/
|
|
||||||
public boolean match(ITypeInfo info);
|
|
||||||
/**
|
|
||||||
* Returns <code>true</code> if <code>info</code> matches the filter.
|
|
||||||
*/
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2004 QNX Software Systems and others.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Common Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/cpl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* QNX Software Systems - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.ui.browser.typeinfo;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
|
||||||
import org.eclipse.cdt.core.model.IParent;
|
|
||||||
import org.eclipse.cdt.core.search.BasicSearchMatch;
|
|
||||||
import org.eclipse.cdt.core.search.ICSearchScope;
|
|
||||||
import org.eclipse.cdt.internal.core.index.StringMatcher;
|
|
||||||
import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
|
|
||||||
import org.eclipse.core.resources.IFile;
|
|
||||||
import org.eclipse.core.resources.IResource;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To change the template for this generated type comment go to
|
|
||||||
* Window>Preferences>Java>Code Generation>Code and Comments
|
|
||||||
*/
|
|
||||||
public class TypeInfo extends BasicSearchMatch implements ITypeInfo
|
|
||||||
{
|
|
||||||
private final static int[] cElementTypes= {
|
|
||||||
ICElement.C_NAMESPACE,
|
|
||||||
ICElement.C_CLASS,
|
|
||||||
ICElement.C_TEMPLATE_CLASS,
|
|
||||||
ICElement.C_STRUCT,
|
|
||||||
ICElement.C_TEMPLATE_STRUCT,
|
|
||||||
ICElement.C_UNION,
|
|
||||||
ICElement.C_TEMPLATE_UNION,
|
|
||||||
ICElement.C_ENUMERATION,
|
|
||||||
ICElement.C_TYPEDEF
|
|
||||||
};
|
|
||||||
|
|
||||||
public static int[] getAllCElementTypes() {
|
|
||||||
return cElementTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isValidCElementType(int type) {
|
|
||||||
return ArrayUtil.contains(cElementTypes, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static String scopeResolutionOperator= "::"; //$NON-NLS-1$
|
|
||||||
private final static String fileScopeSeparator= " : "; //$NON-NLS-1$
|
|
||||||
private static final StringMatcher fSystemTypeMatcher= new StringMatcher("_*", true, false); //$NON-NLS-1$
|
|
||||||
|
|
||||||
public TypeInfo() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnclosed(ICSearchScope scope) {
|
|
||||||
return scope.encloses(getFilePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSystemType() {
|
|
||||||
// recognized low-level system types eg __FILE
|
|
||||||
String[] names= getEnclosingNames();
|
|
||||||
if (names != null) {
|
|
||||||
for (int i= 0; i < names.length; ++i) {
|
|
||||||
if (fSystemTypeMatcher.match(names[i]))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fSystemTypeMatcher.match(getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
if (resource != null)
|
|
||||||
return resource.getName();
|
|
||||||
else if (path != null)
|
|
||||||
return path.lastSegment();
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilePath() {
|
|
||||||
if (resource != null)
|
|
||||||
return resource.getFullPath().toString();
|
|
||||||
else if (path != null)
|
|
||||||
return path.toString();
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileExtension() {
|
|
||||||
if (resource != null)
|
|
||||||
return resource.getFileExtension();
|
|
||||||
else if (path != null)
|
|
||||||
return path.getFileExtension();
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getQualifiedParentName() {
|
|
||||||
StringBuffer buf= new StringBuffer();
|
|
||||||
String fileName = getFileName();
|
|
||||||
if (fileName != null && fileName.length() > 0)
|
|
||||||
buf.append(fileName);
|
|
||||||
String parentName = getParentName();
|
|
||||||
if (parentName != null && parentName.length() > 0) {
|
|
||||||
buf.append(fileScopeSeparator); //$NON-NLS-1$
|
|
||||||
buf.append(parentName);
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFullyQualifiedName() {
|
|
||||||
StringBuffer buf= new StringBuffer();
|
|
||||||
String fileName = getFileName();
|
|
||||||
if (fileName != null && fileName.length() > 0)
|
|
||||||
buf.append(fileName);
|
|
||||||
String parentName = getParentName();
|
|
||||||
if (parentName != null && parentName.length() > 0) {
|
|
||||||
buf.append(fileScopeSeparator); //$NON-NLS-1$
|
|
||||||
buf.append(parentName);
|
|
||||||
buf.append(scopeResolutionOperator); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
String name = getName();
|
|
||||||
if (name != null && name.length() > 0)
|
|
||||||
buf.append(name);
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getQualifiedName() {
|
|
||||||
StringBuffer buf= new StringBuffer();
|
|
||||||
String parentName = getParentName();
|
|
||||||
if (parentName != null && parentName.length() > 0) {
|
|
||||||
buf.append(parentName);
|
|
||||||
buf.append(scopeResolutionOperator); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
String name = getName();
|
|
||||||
if (name != null && name.length() > 0)
|
|
||||||
buf.append(name);
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getEnclosingNames() {
|
|
||||||
//TODO pull up this method into BasicSearchMatch
|
|
||||||
//since it already has access to this info
|
|
||||||
String parentName= getParentName();
|
|
||||||
if (parentName == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ArrayList names= new ArrayList(5);
|
|
||||||
int lastIndex= 0;
|
|
||||||
String nextName;
|
|
||||||
int qualifierIndex= parentName.indexOf(scopeResolutionOperator, 0);
|
|
||||||
while (qualifierIndex >= 0) {
|
|
||||||
nextName= parentName.substring(lastIndex, qualifierIndex);
|
|
||||||
lastIndex= qualifierIndex + scopeResolutionOperator.length();
|
|
||||||
names.add(nextName);
|
|
||||||
qualifierIndex= parentName.indexOf(scopeResolutionOperator, lastIndex);
|
|
||||||
}
|
|
||||||
nextName= parentName.substring(lastIndex);
|
|
||||||
names.add(nextName);
|
|
||||||
|
|
||||||
return (String[]) names.toArray(new String[names.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return getFullyQualifiedName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean matchesCType(ICElement celement, String name) {
|
|
||||||
if (isValidCElementType(celement.getElementType()))
|
|
||||||
return celement.getElementName().equals(name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ICElement findCElement(ICElement celement, String name) {
|
|
||||||
if (matchesCType(celement, name))
|
|
||||||
return celement;
|
|
||||||
else if (celement instanceof IParent) {
|
|
||||||
ICElement[] children = ((IParent)celement).getChildren();
|
|
||||||
for (int i = 0; i < children.length; i++) {
|
|
||||||
if (matchesCType(children[i], name))
|
|
||||||
return children[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICElement getCElement() {
|
|
||||||
if (resource != null && resource.getType() == IResource.FILE) {
|
|
||||||
ICElement parentElement= CoreModel.getDefault().create((IFile)resource);
|
|
||||||
if (parentElement instanceof IParent) {
|
|
||||||
String[] names= getEnclosingNames();
|
|
||||||
if (names != null) {
|
|
||||||
for (int i= 0; i < names.length; ++i) {
|
|
||||||
parentElement= findCElement(parentElement, names[i]);
|
|
||||||
if (parentElement == null)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parentElement != null)
|
|
||||||
return findCElement(parentElement, getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2004 QNX Software Systems and others.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Common Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/cpl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* QNX Software Systems - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.ui.browser.typeinfo;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default type filter.
|
|
||||||
*/
|
|
||||||
public class TypeInfoFilter implements ITypeInfoFilter {
|
|
||||||
|
|
||||||
public int[] getCElementTypes() {
|
|
||||||
return TypeInfo.getAllCElementTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeInfoFilter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean hideSystemTypes() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean match(ITypeInfo info) {
|
|
||||||
// check if type is handled
|
|
||||||
if (!ArrayUtil.contains(getCElementTypes(), info.getElementType()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// filter out low-level system types eg __FILE
|
|
||||||
//TODO make this a preferences option
|
|
||||||
if (hideSystemTypes() && info.isSystemType())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,9 +11,11 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui.browser.typeinfo;
|
package org.eclipse.cdt.ui.browser.typeinfo;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.browser.ITypeInfo;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.internal.ui.CPluginImages;
|
import org.eclipse.cdt.internal.ui.CPluginImages;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.jface.viewers.LabelProvider;
|
import org.eclipse.jface.viewers.LabelProvider;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
|
||||||
|
@ -90,18 +92,42 @@ public class TypeInfoLabelProvider extends LabelProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSet(SHOW_ROOT_POSTFIX)) {
|
if (isSet(SHOW_ROOT_POSTFIX)) {
|
||||||
String path= typeRef.getFilePath();
|
IPath path= typeRef.getPath();
|
||||||
if (path != null && path.length() > 0) {
|
if (path != null) {
|
||||||
buf.append(TypeInfoMessages.getString("TypeInfoLabelProvider.dash"));//$NON-NLS-1$
|
buf.append(TypeInfoMessages.getString("TypeInfoLabelProvider.dash"));//$NON-NLS-1$
|
||||||
buf.append(path);
|
buf.append(path.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image getFileIcon(ITypeInfo typeRef)
|
/* non java-doc
|
||||||
|
* @see ILabelProvider#getImage
|
||||||
|
*/
|
||||||
|
public Image getImage(Object element) {
|
||||||
|
if (!(element instanceof ITypeInfo))
|
||||||
|
return super.getImage(element);
|
||||||
|
|
||||||
|
ITypeInfo typeRef= (ITypeInfo) element;
|
||||||
|
if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
|
||||||
|
return getContainerIcon(typeRef);
|
||||||
|
} else if (isSet(SHOW_FILENAME_ONLY)) {
|
||||||
|
return getFileIcon(typeRef.getPath());
|
||||||
|
} else {
|
||||||
|
return getTypeIcon(typeRef.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image getContainerIcon(ITypeInfo typeRef)
|
||||||
{
|
{
|
||||||
String ext = typeRef.getFileExtension();
|
//TODO get enclosing types and parent type icon
|
||||||
|
return getFileIcon(typeRef.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image getFileIcon(IPath path)
|
||||||
|
{
|
||||||
|
if (path != null) {
|
||||||
|
String ext= path.getFileExtension();
|
||||||
if (ext != null) {
|
if (ext != null) {
|
||||||
String[] exts = CoreModel.getDefault().getHeaderExtensions();
|
String[] exts = CoreModel.getDefault().getHeaderExtensions();
|
||||||
for (int i = 0; i < exts.length; i++) {
|
for (int i = 0; i < exts.length; i++) {
|
||||||
|
@ -110,12 +136,13 @@ public class TypeInfoLabelProvider extends LabelProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return SOURCE_ICON;
|
return SOURCE_ICON;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image getIcon(ITypeInfo typeRef)
|
public static Image getTypeIcon(int type)
|
||||||
{
|
{
|
||||||
switch (typeRef.getElementType())
|
switch (type)
|
||||||
{
|
{
|
||||||
case ICElement.C_NAMESPACE:
|
case ICElement.C_NAMESPACE:
|
||||||
return NAMESPACE_ICON;
|
return NAMESPACE_ICON;
|
||||||
|
@ -142,21 +169,4 @@ public class TypeInfoLabelProvider extends LabelProvider {
|
||||||
return CLASS_ICON;
|
return CLASS_ICON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non java-doc
|
|
||||||
* @see ILabelProvider#getImage
|
|
||||||
*/
|
|
||||||
public Image getImage(Object element) {
|
|
||||||
if (!(element instanceof ITypeInfo))
|
|
||||||
return super.getImage(element);
|
|
||||||
|
|
||||||
ITypeInfo typeRef= (ITypeInfo) element;
|
|
||||||
if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
|
|
||||||
return getFileIcon(typeRef);
|
|
||||||
} else if (isSet(SHOW_FILENAME_ONLY)) {
|
|
||||||
return getFileIcon(typeRef);
|
|
||||||
} else {
|
|
||||||
return getIcon(typeRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,16 @@
|
||||||
# QNX Software Systems - Initial API and implementation
|
# QNX Software Systems - Initial API and implementation
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
TypeCacherJob.jobName=TypeCache
|
|
||||||
TypeCacherJob.taskName=Updating Type Info...
|
|
||||||
|
|
||||||
TypeSelectionDialog.lowerLabel=&Qualifier:
|
TypeSelectionDialog.lowerLabel=&Qualifier:
|
||||||
TypeSelectionDialog.upperLabel=&Matching types:
|
TypeSelectionDialog.upperLabel=&Matching types:
|
||||||
|
TypeSelectionDialog.filterLabel=Visible types:
|
||||||
|
TypeSelectionDialog.filterNamespaces=namespace
|
||||||
|
TypeSelectionDialog.filterClasses=class
|
||||||
|
TypeSelectionDialog.filterStructs=struct
|
||||||
|
TypeSelectionDialog.filterTypedefs=typedef
|
||||||
|
TypeSelectionDialog.filterEnums=enum
|
||||||
|
TypeSelectionDialog.filterUnions=union
|
||||||
|
TypeSelectionDialog.filterLowLevelTypes=Show low-level types
|
||||||
|
|
||||||
TypeInfoLabelProvider.default_filename=default
|
TypeInfoLabelProvider.default_filename=default
|
||||||
TypeInfoLabelProvider.dash=\ -
|
TypeInfoLabelProvider.dash=\ -
|
||||||
|
|
|
@ -12,12 +12,29 @@
|
||||||
package org.eclipse.cdt.ui.browser.typeinfo;
|
package org.eclipse.cdt.ui.browser.typeinfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.browser.*;
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.internal.ui.util.StringMatcher;
|
import org.eclipse.cdt.internal.ui.util.StringMatcher;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.layout.RowLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
import org.eclipse.ui.dialogs.FilteredList;
|
import org.eclipse.ui.dialogs.FilteredList;
|
||||||
import org.eclipse.ui.dialogs.TwoPaneElementSelector;
|
import org.eclipse.ui.dialogs.TwoPaneElementSelector;
|
||||||
|
|
||||||
|
@ -36,34 +53,64 @@ public class TypeSelectionDialog extends TwoPaneElementSelector {
|
||||||
private StringMatcher fMatcher;
|
private StringMatcher fMatcher;
|
||||||
private StringMatcher fQualifierMatcher;
|
private StringMatcher fQualifierMatcher;
|
||||||
private StringMatcher fScopedQualifierMatcher;
|
private StringMatcher fScopedQualifierMatcher;
|
||||||
|
private Collection fVisibleTypes = new HashSet();
|
||||||
|
private boolean fShowLowLevelTypes = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see FilteredList.FilterMatcher#setFilter(String, boolean)
|
* @see FilteredList.FilterMatcher#setFilter(String, boolean)
|
||||||
*/
|
*/
|
||||||
public void setFilter(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
|
public void setFilter(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
|
||||||
int qualifierIndex= pattern.lastIndexOf(scopeResolutionOperator); //$NON-NLS-1$
|
int qualifierIndex = pattern.lastIndexOf(scopeResolutionOperator);
|
||||||
|
|
||||||
// type
|
// type
|
||||||
if (qualifierIndex == -1) {
|
if (qualifierIndex == -1) {
|
||||||
fQualifierMatcher = null;
|
fQualifierMatcher = null;
|
||||||
fScopedQualifierMatcher = null;
|
fScopedQualifierMatcher = null;
|
||||||
fMatcher = new StringMatcher(adjustPattern(pattern), ignoreCase, ignoreWildCards);
|
fMatcher = new StringMatcher(adjustPattern(pattern), ignoreCase, ignoreWildCards);
|
||||||
|
|
||||||
// qualified type
|
// qualified type
|
||||||
} else {
|
} else {
|
||||||
String pattern1 = pattern.substring(0, qualifierIndex + scopeResolutionOperator.length());
|
String prefixPattern = pattern.substring(0, qualifierIndex + scopeResolutionOperator.length());
|
||||||
fQualifierMatcher= new StringMatcher(adjustPattern(pattern1), ignoreCase, ignoreWildCards);
|
fQualifierMatcher = new StringMatcher(adjustPattern(prefixPattern), ignoreCase, ignoreWildCards);
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
buf.append(ANY_STRING);
|
buf.append(ANY_STRING);
|
||||||
buf.append(scopeResolutionOperator);
|
buf.append(scopeResolutionOperator);
|
||||||
buf.append(pattern1);
|
buf.append(prefixPattern);
|
||||||
String pattern2= buf.toString();
|
String scopedPattern = buf.toString();
|
||||||
fScopedQualifierMatcher= new StringMatcher(adjustPattern(pattern2), ignoreCase, ignoreWildCards);
|
fScopedQualifierMatcher = new StringMatcher(adjustPattern(scopedPattern), ignoreCase, ignoreWildCards);
|
||||||
String pattern3 = pattern.substring(qualifierIndex + scopeResolutionOperator.length());
|
String namePattern = pattern.substring(qualifierIndex + scopeResolutionOperator.length());
|
||||||
fMatcher= new StringMatcher(adjustPattern(pattern3), ignoreCase, ignoreWildCards);
|
fMatcher = new StringMatcher(adjustPattern(namePattern), ignoreCase, ignoreWildCards);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVisibleTypes(Collection visibleTypes) {
|
||||||
|
fVisibleTypes.clear();
|
||||||
|
fVisibleTypes.addAll(visibleTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection getVisibleTypes() {
|
||||||
|
return fVisibleTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShowLowLevelTypes(boolean show) {
|
||||||
|
fShowLowLevelTypes = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getShowLowLevelTypes() {
|
||||||
|
return fShowLowLevelTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLowLevelType(ITypeInfo info) {
|
||||||
|
String[] enclosingNames = info.getEnclosingNames();
|
||||||
|
// filter out low-level system types eg __FILE
|
||||||
|
if (enclosingNames != null) {
|
||||||
|
for (int i = 0; i < enclosingNames.length; ++i) {
|
||||||
|
if (enclosingNames[i].startsWith("_")) //$NON-NLS-1$
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info.getName().startsWith("_"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see FilteredList.FilterMatcher#match(Object)
|
* @see FilteredList.FilterMatcher#match(Object)
|
||||||
*/
|
*/
|
||||||
|
@ -71,18 +118,24 @@ public class TypeSelectionDialog extends TwoPaneElementSelector {
|
||||||
if (!(element instanceof ITypeInfo))
|
if (!(element instanceof ITypeInfo))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TypeInfo type= (TypeInfo) element;
|
TypeInfo info = (TypeInfo) element;
|
||||||
|
|
||||||
if (!fMatcher.match(type.getName()))
|
if (fVisibleTypes != null && !fVisibleTypes.contains(new Integer(info.getType())))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!fShowLowLevelTypes && isLowLevelType(info))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!fMatcher.match(info.getName()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fQualifierMatcher == null)
|
if (fQualifierMatcher == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (fQualifierMatcher.match(type.getQualifiedName()))
|
if (fQualifierMatcher.match(info.getQualifiedName()))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return fScopedQualifierMatcher.match(type.getQualifiedName());
|
return fScopedQualifierMatcher.match(info.getQualifiedName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String adjustPattern(String pattern) {
|
private String adjustPattern(String pattern) {
|
||||||
|
@ -115,29 +168,362 @@ public class TypeSelectionDialog extends TwoPaneElementSelector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String DIALOG_SETTINGS = TypeSelectionDialog.class.getName();
|
||||||
|
private static final String SETTINGS_X_POS = "x"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_Y_POS = "y"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_WIDTH = "width"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_HEIGHT = "height"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_SHOW_NAMESPACES = "show_namespaces"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_SHOW_CLASSES = "show_classes"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_SHOW_STRUCTS = "show_structs"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_SHOW_TYPEDEFS = "show_typedefs"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_SHOW_ENUMS = "show_enums"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_SHOW_UNIONS = "show_unions"; //$NON-NLS-1$
|
||||||
|
private static final String SETTINGS_SHOW_LOWLEVEL = "show_lowlevel"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static final TypeInfoLabelProvider fElementRenderer = new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY);
|
||||||
|
private static final TypeInfoLabelProvider fQualifierRenderer = new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeInfoLabelProvider.SHOW_ROOT_POSTFIX);
|
||||||
|
|
||||||
|
private static final TypeFilterMatcher fFilterMatcher = new TypeFilterMatcher();
|
||||||
|
private static final StringComparator fStringComparator = new StringComparator();
|
||||||
|
|
||||||
|
private static final int[] fAllTypes = { ICElement.C_NAMESPACE, ICElement.C_CLASS,
|
||||||
|
ICElement.C_STRUCT, ICElement.C_TYPEDEF, ICElement.C_ENUMERATION,
|
||||||
|
ICElement.C_UNION };
|
||||||
|
|
||||||
|
private Set fKnownTypes = new HashSet(fAllTypes.length);
|
||||||
|
private Text fTextWidget;
|
||||||
|
private boolean fSelectFilterText = false;
|
||||||
|
private FilteredList fNewFilteredList;
|
||||||
|
private String fDialogSection;
|
||||||
|
private Point fLocation;
|
||||||
|
private Point fSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a type selection dialog.
|
* Constructs a type selection dialog.
|
||||||
* @param parent the parent shell.
|
* @param parent the parent shell.
|
||||||
* @param context the runnable context.
|
|
||||||
* @param scope the C search scope.
|
|
||||||
*/
|
*/
|
||||||
public TypeSelectionDialog(Shell parent) {
|
public TypeSelectionDialog(Shell parent) {
|
||||||
super(parent, new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY),
|
super(parent, fElementRenderer, fQualifierRenderer);
|
||||||
new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeInfoLabelProvider.SHOW_ROOT_POSTFIX));
|
|
||||||
setUpperListLabel(TypeInfoMessages.getString("TypeSelectionDialog.upperLabel")); //$NON-NLS-1$
|
setUpperListLabel(TypeInfoMessages.getString("TypeSelectionDialog.upperLabel")); //$NON-NLS-1$
|
||||||
setLowerListLabel(TypeInfoMessages.getString("TypeSelectionDialog.lowerLabel")); //$NON-NLS-1$
|
setLowerListLabel(TypeInfoMessages.getString("TypeSelectionDialog.lowerLabel")); //$NON-NLS-1$
|
||||||
|
setVisibleTypes(fAllTypes);
|
||||||
|
setDialogSettings(DIALOG_SETTINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the filter pattern.
|
||||||
|
* @param filter the filter pattern.
|
||||||
|
* @param selectText <code>true</code> if filter text should be initially selected
|
||||||
|
* @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#setFilter(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void setFilter(String filter, boolean selectText) {
|
||||||
|
super.setFilter(filter);
|
||||||
|
fSelectFilterText = selectText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which CElement types are visible in the dialog.
|
||||||
|
*
|
||||||
|
* @param types Array of CElement types.
|
||||||
|
*/
|
||||||
|
public void setVisibleTypes(int[] types) {
|
||||||
|
fKnownTypes.clear();
|
||||||
|
for (int i = 0; i < types.length; ++i) {
|
||||||
|
fKnownTypes.add(new Integer(types[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets section name to use when storing the dialog settings.
|
||||||
|
*
|
||||||
|
* @param section Name of section.
|
||||||
|
*/
|
||||||
|
public void setDialogSettings(String section) {
|
||||||
|
fDialogSection = section + "Settings"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#createFilterText(org.eclipse.swt.widgets.Composite)
|
||||||
|
*/
|
||||||
|
protected Text createFilterText(Composite parent) {
|
||||||
|
fTextWidget = super.createFilterText(parent);
|
||||||
|
|
||||||
|
// create type checkboxes below filter text
|
||||||
|
createTypeFilterArea(parent);
|
||||||
|
|
||||||
|
return fTextWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#createFilteredList(org.eclipse.swt.widgets.Composite)
|
||||||
|
*/
|
||||||
|
protected FilteredList createFilteredList(Composite parent) {
|
||||||
|
fNewFilteredList = super.createFilteredList(parent);
|
||||||
|
fNewFilteredList.setFilterMatcher(fFilterMatcher);
|
||||||
|
fNewFilteredList.setComparator(fStringComparator);
|
||||||
|
return fNewFilteredList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.window.Window#create()
|
||||||
|
*/
|
||||||
|
public void create() {
|
||||||
|
super.create();
|
||||||
|
if (!fSelectFilterText)
|
||||||
|
fTextWidget.setSelection(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see AbstractElementListSelectionDialog#createFilteredList(Composite)
|
* @see Window#close()
|
||||||
*/
|
*/
|
||||||
protected FilteredList createFilteredList(Composite parent) {
|
public boolean close() {
|
||||||
FilteredList list= super.createFilteredList(parent);
|
writeSettings(getDialogSettings());
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
fFilteredList.setFilterMatcher(new TypeFilterMatcher());
|
/*
|
||||||
fFilteredList.setComparator(new StringComparator());
|
* @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
|
||||||
|
*/
|
||||||
|
protected Control createContents(Composite parent) {
|
||||||
|
readSettings(getDialogSettings());
|
||||||
|
return super.createContents(parent);
|
||||||
|
}
|
||||||
|
|
||||||
return list;
|
/**
|
||||||
|
* Creates a type filter checkbox.
|
||||||
|
*/
|
||||||
|
private Button createTypeCheckbox(Composite parent, Integer typeObject) {
|
||||||
|
String name;
|
||||||
|
int type = typeObject.intValue();
|
||||||
|
switch (type) {
|
||||||
|
case ICElement.C_NAMESPACE:
|
||||||
|
name = TypeInfoMessages.getString("TypeSelectionDialog.filterNamespaces"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case ICElement.C_CLASS:
|
||||||
|
name = TypeInfoMessages.getString("TypeSelectionDialog.filterClasses"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case ICElement.C_STRUCT:
|
||||||
|
name = TypeInfoMessages.getString("TypeSelectionDialog.filterStructs"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case ICElement.C_TYPEDEF:
|
||||||
|
name = TypeInfoMessages.getString("TypeSelectionDialog.filterTypedefs"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case ICElement.C_ENUMERATION:
|
||||||
|
name = TypeInfoMessages.getString("TypeSelectionDialog.filterEnums"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case ICElement.C_UNION:
|
||||||
|
name = TypeInfoMessages.getString("TypeSelectionDialog.filterUnions"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
Image icon = TypeInfoLabelProvider.getTypeIcon(type);
|
||||||
|
|
||||||
|
final Integer fTypeObject = typeObject;
|
||||||
|
Button checkbox = new Button(parent, SWT.CHECK);
|
||||||
|
checkbox.setFont(parent.getFont());
|
||||||
|
checkbox.setText(name);
|
||||||
|
checkbox.setImage(icon);
|
||||||
|
checkbox.setSelection(fFilterMatcher.getVisibleTypes().contains(fTypeObject));
|
||||||
|
checkbox.addSelectionListener(new SelectionAdapter() {
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
if (e.widget instanceof Button) {
|
||||||
|
Button checkbox = (Button) e.widget;
|
||||||
|
if (checkbox.getSelection())
|
||||||
|
fFilterMatcher.getVisibleTypes().add(fTypeObject);
|
||||||
|
else
|
||||||
|
fFilterMatcher.getVisibleTypes().remove(fTypeObject);
|
||||||
|
updateElements();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return checkbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an area to filter types.
|
||||||
|
*
|
||||||
|
* @param parent area to create controls in
|
||||||
|
*/
|
||||||
|
private void createTypeFilterArea(Composite parent) {
|
||||||
|
createLabel(parent, TypeInfoMessages.getString("TypeSelectionDialog.filterLabel")); //$NON-NLS-1$
|
||||||
|
|
||||||
|
Composite upperRow = new Composite(parent, SWT.NONE);
|
||||||
|
RowLayout layout = new RowLayout();
|
||||||
|
layout.spacing = 10;
|
||||||
|
layout.marginTop = 0;
|
||||||
|
layout.marginLeft = 0;
|
||||||
|
upperRow.setLayout(layout);
|
||||||
|
|
||||||
|
// the for loop is here to guarantee we always
|
||||||
|
// create the checkboxes in the same order
|
||||||
|
for (int i = 0; i < fAllTypes.length; ++i) {
|
||||||
|
Integer typeObject = new Integer(fAllTypes[i]);
|
||||||
|
if (fKnownTypes.contains(typeObject))
|
||||||
|
createTypeCheckbox(upperRow, typeObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
Composite lowerRow = new Composite(parent, SWT.NONE);
|
||||||
|
lowerRow.setLayout(layout);
|
||||||
|
|
||||||
|
String name = TypeInfoMessages.getString("TypeSelectionDialog.filterLowLevelTypes"); //$NON-NLS-1$
|
||||||
|
Button checkbox = new Button(lowerRow, SWT.CHECK);
|
||||||
|
checkbox.setFont(lowerRow.getFont());
|
||||||
|
checkbox.setText(name);
|
||||||
|
checkbox.setSelection(fFilterMatcher.getShowLowLevelTypes());
|
||||||
|
checkbox.addSelectionListener(new SelectionAdapter() {
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
if (e.widget instanceof Button) {
|
||||||
|
Button button = (Button) e.widget;
|
||||||
|
fFilterMatcher.setShowLowLevelTypes(button.getSelection());
|
||||||
|
updateElements();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces redraw of elements list.
|
||||||
|
*/
|
||||||
|
private void updateElements() {
|
||||||
|
fNewFilteredList.setFilter(fTextWidget.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dialog settings object used to save state
|
||||||
|
* for this dialog.
|
||||||
|
*
|
||||||
|
* @return the dialog settings to be used
|
||||||
|
*/
|
||||||
|
protected IDialogSettings getDialogSettings() {
|
||||||
|
IDialogSettings allSettings = CUIPlugin.getDefault().getDialogSettings();
|
||||||
|
IDialogSettings section = allSettings.getSection(fDialogSection);
|
||||||
|
if (section == null) {
|
||||||
|
section = allSettings.addNewSection(fDialogSection);
|
||||||
|
writeDefaultSettings(section);
|
||||||
|
}
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores current configuration in the dialog store.
|
||||||
|
*/
|
||||||
|
protected void writeSettings(IDialogSettings section) {
|
||||||
|
Point location = getShell().getLocation();
|
||||||
|
section.put(SETTINGS_X_POS, location.x);
|
||||||
|
section.put(SETTINGS_Y_POS, location.y);
|
||||||
|
|
||||||
|
Point size = getShell().getSize();
|
||||||
|
section.put(SETTINGS_WIDTH, size.x);
|
||||||
|
section.put(SETTINGS_HEIGHT, size.y);
|
||||||
|
|
||||||
|
section.put(SETTINGS_SHOW_NAMESPACES, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_NAMESPACE)));
|
||||||
|
section.put(SETTINGS_SHOW_CLASSES, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_CLASS)));
|
||||||
|
section.put(SETTINGS_SHOW_STRUCTS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_STRUCT)));
|
||||||
|
section.put(SETTINGS_SHOW_TYPEDEFS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_TYPEDEF)));
|
||||||
|
section.put(SETTINGS_SHOW_ENUMS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_ENUMERATION)));
|
||||||
|
section.put(SETTINGS_SHOW_UNIONS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_UNION)));
|
||||||
|
section.put(SETTINGS_SHOW_LOWLEVEL, fFilterMatcher.getShowLowLevelTypes());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores default dialog settings.
|
||||||
|
*/
|
||||||
|
protected void writeDefaultSettings(IDialogSettings section) {
|
||||||
|
section.put(SETTINGS_SHOW_NAMESPACES, true);
|
||||||
|
section.put(SETTINGS_SHOW_CLASSES, true);
|
||||||
|
section.put(SETTINGS_SHOW_STRUCTS, true);
|
||||||
|
section.put(SETTINGS_SHOW_TYPEDEFS, true);
|
||||||
|
section.put(SETTINGS_SHOW_ENUMS, true);
|
||||||
|
section.put(SETTINGS_SHOW_UNIONS, true);
|
||||||
|
section.put(SETTINGS_SHOW_LOWLEVEL, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes itself from the dialog settings with the same state
|
||||||
|
* as at the previous invocation.
|
||||||
|
*/
|
||||||
|
protected void readSettings(IDialogSettings section) {
|
||||||
|
try {
|
||||||
|
int x = section.getInt(SETTINGS_X_POS);
|
||||||
|
int y = section.getInt(SETTINGS_Y_POS);
|
||||||
|
fLocation = new Point(x, y);
|
||||||
|
int width = section.getInt(SETTINGS_WIDTH);
|
||||||
|
int height = section.getInt(SETTINGS_HEIGHT);
|
||||||
|
fSize = new Point(width, height);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
fLocation = null;
|
||||||
|
fSize = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section.getBoolean(SETTINGS_SHOW_NAMESPACES)) {
|
||||||
|
Integer typeObject = new Integer(ICElement.C_NAMESPACE);
|
||||||
|
if (fKnownTypes.contains(typeObject))
|
||||||
|
fFilterMatcher.getVisibleTypes().add(typeObject);
|
||||||
|
}
|
||||||
|
if (section.getBoolean(SETTINGS_SHOW_CLASSES)) {
|
||||||
|
Integer typeObject = new Integer(ICElement.C_CLASS);
|
||||||
|
if (fKnownTypes.contains(typeObject))
|
||||||
|
fFilterMatcher.getVisibleTypes().add(typeObject);
|
||||||
|
}
|
||||||
|
if (section.getBoolean(SETTINGS_SHOW_STRUCTS)) {
|
||||||
|
Integer typeObject = new Integer(ICElement.C_STRUCT);
|
||||||
|
if (fKnownTypes.contains(typeObject))
|
||||||
|
fFilterMatcher.getVisibleTypes().add(typeObject);
|
||||||
|
}
|
||||||
|
if (section.getBoolean(SETTINGS_SHOW_TYPEDEFS)) {
|
||||||
|
Integer typeObject = new Integer(ICElement.C_TYPEDEF);
|
||||||
|
if (fKnownTypes.contains(typeObject))
|
||||||
|
fFilterMatcher.getVisibleTypes().add(typeObject);
|
||||||
|
}
|
||||||
|
if (section.getBoolean(SETTINGS_SHOW_ENUMS)) {
|
||||||
|
Integer typeObject = new Integer(ICElement.C_ENUMERATION);
|
||||||
|
if (fKnownTypes.contains(typeObject))
|
||||||
|
fFilterMatcher.getVisibleTypes().add(typeObject);
|
||||||
|
}
|
||||||
|
if (section.getBoolean(SETTINGS_SHOW_UNIONS)) {
|
||||||
|
Integer typeObject = new Integer(ICElement.C_UNION);
|
||||||
|
if (fKnownTypes.contains(typeObject))
|
||||||
|
fFilterMatcher.getVisibleTypes().add(typeObject);
|
||||||
|
}
|
||||||
|
fFilterMatcher.setShowLowLevelTypes(section.getBoolean(SETTINGS_SHOW_LOWLEVEL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Cdoc)
|
||||||
|
* @see org.eclipse.jface.window.Window#getInitialSize()
|
||||||
|
*/
|
||||||
|
protected Point getInitialSize() {
|
||||||
|
Point result = super.getInitialSize();
|
||||||
|
if (fSize != null) {
|
||||||
|
result.x = Math.max(result.x, fSize.x);
|
||||||
|
result.y = Math.max(result.y, fSize.y);
|
||||||
|
Rectangle display = getShell().getDisplay().getClientArea();
|
||||||
|
result.x = Math.min(result.x, display.width);
|
||||||
|
result.y = Math.min(result.y, display.height);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Cdoc)
|
||||||
|
* @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point)
|
||||||
|
*/
|
||||||
|
protected Point getInitialLocation(Point initialSize) {
|
||||||
|
Point result = super.getInitialLocation(initialSize);
|
||||||
|
if (fLocation != null) {
|
||||||
|
result.x = fLocation.x;
|
||||||
|
result.y = fLocation.y;
|
||||||
|
Rectangle display = getShell().getDisplay().getClientArea();
|
||||||
|
int xe = result.x + initialSize.x;
|
||||||
|
if (xe > display.width) {
|
||||||
|
result.x -= xe - display.width;
|
||||||
|
}
|
||||||
|
int ye = result.y + initialSize.y;
|
||||||
|
if (ye > display.height) {
|
||||||
|
result.y -= ye - display.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.ResourceBundle;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.browser.AllTypesCache;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
|
@ -44,7 +45,6 @@ import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||||
import org.eclipse.cdt.internal.ui.util.ImageDescriptorRegistry;
|
import org.eclipse.cdt.internal.ui.util.ImageDescriptorRegistry;
|
||||||
import org.eclipse.cdt.internal.ui.util.ProblemMarkerManager;
|
import org.eclipse.cdt.internal.ui.util.ProblemMarkerManager;
|
||||||
import org.eclipse.cdt.internal.ui.util.Util;
|
import org.eclipse.cdt.internal.ui.util.Util;
|
||||||
import org.eclipse.cdt.ui.browser.typeinfo.AllTypesCache;
|
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.resources.IWorkspace;
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
@ -338,7 +338,12 @@ public class CUIPlugin extends AbstractUIPlugin {
|
||||||
public void run() {
|
public void run() {
|
||||||
registerAdapters();
|
registerAdapters();
|
||||||
CPluginImages.initialize();
|
CPluginImages.initialize();
|
||||||
AllTypesCache.initialize();
|
|
||||||
|
AllTypesCache.initialize(new AllTypesCache.IWorkingCopyProvider() {
|
||||||
|
public IWorkingCopy[] getWorkingCopies() {
|
||||||
|
return CUIPlugin.getSharedWorkingCopies();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue