mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
2004-08-31 Chris Wiebe
Fix for 68883 * browser/org/eclipse/cdt/core/browser/AllTypesCache.java * browser/org/eclipse/cdt/core/browser/ITypeCacheChangedListener.java * browser/org/eclipse/cdt/core/browser/ITypeInfo.java * browser/org/eclipse/cdt/core/browser/TypeInfo.java * browser/org/eclipse/cdt/core/browser/TypeUtil.java * browser/org/eclipse/cdt/core/browser/typehierarchy/TypeHierarchy.java * browser/org/eclipse/cdt/core/browser/cache/ITypeCache.java * browser/org/eclipse/cdt/core/browser/cache/TypeCache.java * browser/org/eclipse/cdt/core/browser/cache/TypeCacheManager.java
This commit is contained in:
parent
5aaece1941
commit
f5fbd76f3d
10 changed files with 320 additions and 134 deletions
|
@ -1,3 +1,16 @@
|
|||
2004-08-31 Chris Wiebe
|
||||
|
||||
Fix for 68883
|
||||
* browser/org/eclipse/cdt/core/browser/AllTypesCache.java
|
||||
* browser/org/eclipse/cdt/core/browser/ITypeCacheChangedListener.java
|
||||
* browser/org/eclipse/cdt/core/browser/ITypeInfo.java
|
||||
* browser/org/eclipse/cdt/core/browser/TypeInfo.java
|
||||
* browser/org/eclipse/cdt/core/browser/TypeUtil.java
|
||||
* browser/org/eclipse/cdt/core/browser/typehierarchy/TypeHierarchy.java
|
||||
* browser/org/eclipse/cdt/core/browser/cache/ITypeCache.java
|
||||
* browser/org/eclipse/cdt/core/browser/cache/TypeCache.java
|
||||
* browser/org/eclipse/cdt/core/browser/cache/TypeCacheManager.java
|
||||
|
||||
2004-08-26 Chris Wiebe
|
||||
|
||||
make QualifiedTypeName immutable class
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.eclipse.cdt.core.model.ICElement;
|
|||
import org.eclipse.cdt.core.model.IElementChangedListener;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.internal.core.browser.cache.ITypeCache;
|
||||
import org.eclipse.cdt.internal.core.browser.cache.TypeCacheMessages;
|
||||
import org.eclipse.cdt.internal.core.browser.cache.TypeCacheManager;
|
||||
import org.eclipse.cdt.internal.core.browser.util.ArrayUtil;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
@ -55,7 +54,7 @@ public class AllTypesCache {
|
|||
private static IPropertyChangeListener fgPropertyChangeListener;
|
||||
static boolean fgEnableIndexing = true;
|
||||
|
||||
/** Preference key for enabling background cache */
|
||||
/** Preference key for enabling background cache */
|
||||
public final static String ENABLE_BACKGROUND_TYPE_CACHE = "enableBackgroundTypeCache"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
|
@ -85,8 +84,7 @@ public class AllTypesCache {
|
|||
// add delta listener
|
||||
fgElementChangedListener = new IElementChangedListener() {
|
||||
public void elementChanged(ElementChangedEvent event) {
|
||||
TypeCacheManager.getInstance().processDelta(event.getDelta());
|
||||
TypeCacheManager.getInstance().reconcile(fgEnableIndexing, Job.BUILD, 0);
|
||||
TypeCacheManager.getInstance().processElementChanged(event, fgEnableIndexing);
|
||||
}
|
||||
};
|
||||
CoreModel.getDefault().addElementChangedListener(fgElementChangedListener);
|
||||
|
@ -282,15 +280,7 @@ public class AllTypesCache {
|
|||
* @param monitor the progress monitor
|
||||
*/
|
||||
public static void updateCache(ITypeSearchScope scope, IProgressMonitor monitor) {
|
||||
// schedule jobs to update cache
|
||||
IProject[] projects = scope.getEnclosingProjects();
|
||||
monitor.beginTask(TypeCacheMessages.getString("AllTypesCache.updateCache.taskName"), projects.length); //$NON-NLS-1$
|
||||
for (int i = 0; i < projects.length; ++i) {
|
||||
IProject project = projects[i];
|
||||
// wait for any running jobs to finish
|
||||
TypeCacheManager.getInstance().getCache(project).reconcileAndWait(true, Job.SHORT, monitor);
|
||||
}
|
||||
monitor.done();
|
||||
TypeCacheManager.getInstance().updateCache(scope, monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,26 +290,7 @@ public class AllTypesCache {
|
|||
* @param monitor the progress monitor
|
||||
*/
|
||||
public static ITypeReference resolveTypeLocation(ITypeInfo info, IProgressMonitor monitor) {
|
||||
ITypeReference location = info.getResolvedReference();
|
||||
if (location == null) {
|
||||
// cancel background jobs
|
||||
IProject project = info.getEnclosingProject();
|
||||
TypeCacheManager.getInstance().getCache(project).cancelJobs();
|
||||
|
||||
// start the search job
|
||||
TypeCacheManager.getInstance().getCache(project).locateTypeAndWait(info, Job.SHORT, monitor);
|
||||
|
||||
// get the newly parsed location
|
||||
location = info.getResolvedReference();
|
||||
|
||||
// resume background jobs
|
||||
TypeCacheManager.getInstance().reconcile(fgEnableIndexing, Job.BUILD, 0);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public static ITypeInfo getTypeForElement(ICElement elem) {
|
||||
return TypeUtil.getTypeForElement(elem);
|
||||
return TypeCacheManager.getInstance().resolveTypeLocation(info, monitor, fgEnableIndexing);
|
||||
}
|
||||
|
||||
/** Returns first type in the cache which matches the given
|
||||
|
@ -359,9 +330,25 @@ public class AllTypesCache {
|
|||
* @return a type hierarchy for the given type
|
||||
*/
|
||||
public static ITypeHierarchy createTypeHierarchy(ICElement type, IProgressMonitor monitor) throws CModelException {
|
||||
ITypeInfo info = TypeUtil.getTypeForElement(type);
|
||||
ITypeInfo info = TypeCacheManager.getInstance().getTypeForElement(type, true, true, fgEnableIndexing, monitor);
|
||||
if (info != null)
|
||||
return fgTypeHierarchyBuilder.createTypeHierarchy(info, fgEnableIndexing, monitor);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addTypeCacheChangedListener(ITypeCacheChangedListener listener) {
|
||||
TypeCacheManager.getInstance().addTypeCacheChangedListener(listener);
|
||||
}
|
||||
|
||||
public static void removeTypeCacheChangedListener(ITypeCacheChangedListener listener) {
|
||||
TypeCacheManager.getInstance().removeTypeCacheChangedListener(listener);
|
||||
}
|
||||
|
||||
public static ITypeInfo getTypeForElement(ICElement element, boolean forceUpdate, boolean forceResolve, IProgressMonitor monitor) {
|
||||
return TypeCacheManager.getInstance().getTypeForElement(element, forceUpdate, forceResolve, fgEnableIndexing, monitor);
|
||||
}
|
||||
|
||||
public static ICElement getElementForType(ITypeInfo type, boolean forceUpdate, boolean forceResolve, IProgressMonitor monitor) {
|
||||
return TypeCacheManager.getInstance().getElementForType(type, forceUpdate, forceResolve, fgEnableIndexing, monitor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* 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 org.eclipse.core.resources.IProject;
|
||||
|
||||
|
||||
/**
|
||||
* A listener which gets notified when the type cache changes.
|
||||
* <p>
|
||||
* This interface may be implemented by clients.
|
||||
* </p>
|
||||
*/
|
||||
public interface ITypeCacheChangedListener {
|
||||
|
||||
/**
|
||||
* Notifies that the type cache for the given project has changed in some way
|
||||
* and should be refreshed at some point to make it consistent with the current
|
||||
* state of the C model.
|
||||
*
|
||||
* @param project the given project
|
||||
*/
|
||||
void typeCacheChanged(IProject project);
|
||||
}
|
|
@ -75,7 +75,7 @@ public interface ITypeInfo extends Comparable {
|
|||
/** Gets the enclosing namespace for this type.
|
||||
* @return the enclosing namespace, or <code>null</code> if none exists.
|
||||
*/
|
||||
public ITypeInfo getEnclosingNamespace();
|
||||
public ITypeInfo getEnclosingNamespace(boolean includeGlobalNamespace);
|
||||
|
||||
/** Gets the first enclosing type which matches one of the given kinds.
|
||||
* @param kinds Array containing CElement types: C_NAMESPACE, C_CLASS, C_STRUCT
|
||||
|
|
|
@ -149,9 +149,9 @@ public class TypeInfo implements ITypeInfo
|
|||
return getEnclosingType(KNOWN_TYPES);
|
||||
}
|
||||
|
||||
public ITypeInfo getEnclosingNamespace() {
|
||||
public ITypeInfo getEnclosingNamespace(boolean includeGlobalNamespace) {
|
||||
if (fTypeCache != null) {
|
||||
return fTypeCache.getEnclosingNamespace(this);
|
||||
return fTypeCache.getEnclosingNamespace(this, includeGlobalNamespace);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -13,17 +13,14 @@ import org.eclipse.cdt.core.browser.typehierarchy.ITypeHierarchy;
|
|||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ICElementVisitor;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.IEnumeration;
|
||||
import org.eclipse.cdt.core.model.IMember;
|
||||
import org.eclipse.cdt.core.model.IMethodDeclaration;
|
||||
import org.eclipse.cdt.core.model.INamespace;
|
||||
import org.eclipse.cdt.core.model.IParent;
|
||||
import org.eclipse.cdt.core.model.IStructure;
|
||||
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
|
||||
import org.eclipse.cdt.internal.core.browser.cache.ITypeCache;
|
||||
import org.eclipse.cdt.internal.core.browser.cache.TypeCacheManager;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author CWiebe
|
||||
|
@ -33,7 +30,30 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
|||
*/
|
||||
public class TypeUtil {
|
||||
|
||||
public static ICElement getDeclaringType(ICElement type) {
|
||||
public static boolean isDeclaredType(ICElement elem) {
|
||||
int type = elem.getElementType();
|
||||
return (type == ICElement.C_CLASS
|
||||
|| type == ICElement.C_STRUCT
|
||||
|| type == ICElement.C_ENUMERATION
|
||||
|| type == ICElement.C_UNION
|
||||
|| type == ICElement.C_TYPEDEF
|
||||
|| type == ICElement.C_NAMESPACE);
|
||||
}
|
||||
|
||||
public static ICElement getDeclaringContainerType(ICElement elem) {
|
||||
while (elem != null) {
|
||||
if (elem instanceof IStructure
|
||||
|| elem instanceof INamespace
|
||||
|| elem instanceof IEnumeration) {
|
||||
return elem;
|
||||
}
|
||||
elem = elem.getParent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ICElement getDeclaringClass(ICElement type) {
|
||||
ICElement parentElement = type.getParent();
|
||||
if (parentElement != null && isClassOrStruct(parentElement)) {
|
||||
return parentElement;
|
||||
|
@ -97,64 +117,6 @@ public class TypeUtil {
|
|||
return qualifiedName;
|
||||
}
|
||||
|
||||
public static ITypeInfo getTypeForElement(ICElement elem, IProgressMonitor monitor) {
|
||||
if (elem != null) {
|
||||
ICProject cProject = elem.getCProject();
|
||||
IQualifiedTypeName qualifiedName = getFullyQualifiedName(elem);
|
||||
if (qualifiedName != null) {
|
||||
final ITypeSearchScope fScope = new TypeSearchScope(true);
|
||||
if (!AllTypesCache.isCacheUpToDate(fScope)) {
|
||||
AllTypesCache.updateCache(fScope, monitor);
|
||||
}
|
||||
|
||||
ITypeCache cache = TypeCacheManager.getInstance().getCache(cProject.getProject());
|
||||
ITypeInfo info = cache.getType(elem.getElementType(), qualifiedName);
|
||||
if (info != null) {
|
||||
ITypeReference ref = info.getResolvedReference();
|
||||
if (ref == null) {
|
||||
ref = AllTypesCache.resolveTypeLocation(info, monitor);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ITypeInfo getTypeForElement(ICElement elem) {
|
||||
return getTypeForElement(elem, new NullProgressMonitor());
|
||||
}
|
||||
|
||||
public static ICElement getElementForType(ITypeInfo type, IProgressMonitor monitor) {
|
||||
final ITypeSearchScope fScope = new TypeSearchScope(true);
|
||||
if (!AllTypesCache.isCacheUpToDate(fScope)) {
|
||||
AllTypesCache.updateCache(fScope, monitor);
|
||||
}
|
||||
ITypeReference ref = type.getResolvedReference();
|
||||
if (ref == null) {
|
||||
ref = AllTypesCache.resolveTypeLocation(type, monitor);
|
||||
}
|
||||
if (ref != null) {
|
||||
ICElement[] elems = ref.getCElements();
|
||||
if (elems != null && elems.length > 0) {
|
||||
if (elems.length == 1)
|
||||
return elems[0];
|
||||
|
||||
for (int i = 0; i < elems.length; ++i) {
|
||||
ICElement elem = elems[i];
|
||||
if (elem.getElementType() == type.getCElementType() && elem.getElementName().equals(type.getName())) {
|
||||
//TODO should check fully qualified name
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static ICElement getElementForType(ITypeInfo type) {
|
||||
return getElementForType(type, new NullProgressMonitor());
|
||||
}
|
||||
|
||||
public static IMethodDeclaration[] getMethods(ICElement elem) {
|
||||
if (elem instanceof IStructure) {
|
||||
try {
|
||||
|
@ -267,7 +229,7 @@ public class TypeUtil {
|
|||
IMethodDeclaration first= findMethod(name, paramTypes, isConstructor, isDestructor, superTypes[i]);
|
||||
if (first != null && first.getVisibility() != ASTAccessVisibility.PRIVATE) {
|
||||
// the order getAllSupertypes does make assumptions of the order of inner elements -> search recursivly
|
||||
IMethodDeclaration res= findMethodDeclarationInHierarchy(hierarchy, TypeUtil.getDeclaringType(first), name, paramTypes, isConstructor, isDestructor);
|
||||
IMethodDeclaration res= findMethodDeclarationInHierarchy(hierarchy, TypeUtil.getDeclaringClass(first), name, paramTypes, isConstructor, isDestructor);
|
||||
if (res != null) {
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.Map;
|
|||
import org.eclipse.cdt.core.ICLogConstants;
|
||||
import org.eclipse.cdt.core.browser.AllTypesCache;
|
||||
import org.eclipse.cdt.core.browser.ITypeInfo;
|
||||
import org.eclipse.cdt.core.browser.TypeUtil;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
||||
|
@ -33,7 +32,6 @@ import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
|
|||
import org.eclipse.cdt.core.search.ICSearchScope;
|
||||
import org.eclipse.cdt.internal.core.model.Util;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.ISafeRunnable;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
@ -314,7 +312,7 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
*/
|
||||
public boolean contains(ICElement type) {
|
||||
// classes
|
||||
ITypeInfo info = AllTypesCache.getTypeForElement(type);
|
||||
ITypeInfo info = AllTypesCache.getTypeForElement(type, true, true, null);
|
||||
|
||||
if (info == null)
|
||||
return false;
|
||||
|
@ -381,12 +379,12 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
*/
|
||||
public ICElement[] getSubtypes(ICElement type) {
|
||||
List list = new ArrayList();
|
||||
ITypeInfo info = TypeUtil.getTypeForElement(type);
|
||||
ITypeInfo info = AllTypesCache.getTypeForElement(type, true, true, null);
|
||||
Collection entries = (Collection) fTypeToSubTypes.get(info);
|
||||
if (entries != null) {
|
||||
for (Iterator i = entries.iterator(); i.hasNext(); ) {
|
||||
ITypeInfo subType = (ITypeInfo)i.next();
|
||||
ICElement elem = TypeUtil.getElementForType(subType);
|
||||
ICElement elem = AllTypesCache.getElementForType(subType, true, true, null);
|
||||
if (elem != null) {
|
||||
list.add(elem);
|
||||
}
|
||||
|
@ -400,14 +398,14 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
*/
|
||||
public ICElement[] getAllSubtypes(ICElement type) {
|
||||
List list = new ArrayList();
|
||||
ITypeInfo info = TypeUtil.getTypeForElement(type);
|
||||
ITypeInfo info = AllTypesCache.getTypeForElement(type, true, true, null);
|
||||
addSubs(info, list);
|
||||
//convert list to ICElements
|
||||
ICElement[] elems = new ICElement[list.size()];
|
||||
int count = 0;
|
||||
for (Iterator i = list.iterator(); i.hasNext(); ) {
|
||||
ITypeInfo subType = (ITypeInfo) i.next();
|
||||
elems[count++] = TypeUtil.getElementForType(subType);
|
||||
elems[count++] = AllTypesCache.getElementForType(subType, true, true, null);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
@ -430,13 +428,13 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
*/
|
||||
public ICElement[] getSupertypes(ICElement type) {
|
||||
List list = new ArrayList();
|
||||
ITypeInfo info = TypeUtil.getTypeForElement(type);
|
||||
ITypeInfo info = AllTypesCache.getTypeForElement(type, true, true, null);
|
||||
Collection entries = (Collection) fTypeToSuperTypes.get(info);
|
||||
if (entries != null) {
|
||||
for (Iterator i = entries.iterator(); i.hasNext(); ) {
|
||||
TypeEntry entry = (TypeEntry)i.next();
|
||||
ITypeInfo superType = entry.type;
|
||||
ICElement elem = TypeUtil.getElementForType(superType);
|
||||
ICElement elem = AllTypesCache.getElementForType(superType, true, true, null);
|
||||
if (elem != null) {
|
||||
list.add(elem);
|
||||
}
|
||||
|
@ -450,14 +448,14 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
*/
|
||||
public ICElement[] getAllSupertypes(ICElement type) {
|
||||
List list = new ArrayList();
|
||||
ITypeInfo info = TypeUtil.getTypeForElement(type);
|
||||
ITypeInfo info = AllTypesCache.getTypeForElement(type, true, true, null);
|
||||
addSupers(info, list);
|
||||
//convert list to ICElements
|
||||
ICElement[] elems = new ICElement[list.size()];
|
||||
int count = 0;
|
||||
for (Iterator i = list.iterator(); i.hasNext(); ) {
|
||||
ITypeInfo superType = (ITypeInfo) i.next();
|
||||
elems[count++] = TypeUtil.getElementForType(superType);
|
||||
elems[count++] = AllTypesCache.getElementForType(superType, true, true, null);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
@ -481,7 +479,7 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
*/
|
||||
public ICElement getType() {
|
||||
if (fFocusType != null)
|
||||
return TypeUtil.getElementForType(fFocusType);
|
||||
return AllTypesCache.getElementForType(fFocusType, true, true, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -526,10 +524,6 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
}
|
||||
System.out.println(this.toString());
|
||||
}
|
||||
} catch (CModelException e) {
|
||||
throw e;
|
||||
} catch (CoreException e) {
|
||||
throw new CModelException(e);
|
||||
} finally {
|
||||
if (monitor != null) {
|
||||
monitor.done();
|
||||
|
@ -541,7 +535,7 @@ public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
|
|||
/**
|
||||
* Compute this type hierarchy.
|
||||
*/
|
||||
protected void compute() throws CModelException, CoreException {
|
||||
protected void compute() {
|
||||
if (fFocusType != null) {
|
||||
// HierarchyBuilder builder =
|
||||
// new IndexBasedHierarchyBuilder(
|
||||
|
|
|
@ -132,9 +132,10 @@ public interface ITypeCache extends ISchedulingRule {
|
|||
* <code>null</code> if none exists.
|
||||
*
|
||||
* @param type the ICElement type
|
||||
* @return the namespace
|
||||
* @param includeGlobalNamespace <code>true</code> if the global (default) namespace should be returned
|
||||
* @return the enclosing namespace, or <code>null</code> if not found.
|
||||
*/
|
||||
public ITypeInfo getEnclosingNamespace(ITypeInfo info);
|
||||
public ITypeInfo getEnclosingNamespace(ITypeInfo info, boolean includeGlobalNamespace);
|
||||
|
||||
/** Gets the root namespace of which encloses the given type.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.browser.IQualifiedTypeName;
|
||||
import org.eclipse.cdt.core.browser.ITypeCacheChangedListener;
|
||||
import org.eclipse.cdt.core.browser.ITypeInfo;
|
||||
import org.eclipse.cdt.core.browser.ITypeInfoVisitor;
|
||||
import org.eclipse.cdt.core.browser.ITypeReference;
|
||||
|
@ -52,6 +53,7 @@ public class TypeCache implements ITypeCache {
|
|||
final ITypeInfo fGlobalNamespace;
|
||||
private final Map fTypeToSubTypes = new HashMap();
|
||||
private final Map fTypeToSuperTypes = new HashMap();
|
||||
private ITypeCacheChangedListener fChangeListener = null;
|
||||
|
||||
private static final class SuperTypeEntry {
|
||||
ITypeInfo superType;
|
||||
|
@ -105,6 +107,9 @@ public class TypeCache implements ITypeCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO finer-grained change deltas
|
||||
if (fChangeListener != null)
|
||||
fChangeListener.typeCacheChanged(fProject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,6 +304,11 @@ public class TypeCache implements ITypeCache {
|
|||
fGlobalNamespace.setCache(this);
|
||||
}
|
||||
|
||||
public TypeCache(IProject project, IWorkingCopyProvider workingCopyProvider, ITypeCacheChangedListener listener) {
|
||||
this(project, workingCopyProvider);
|
||||
fChangeListener = listener;
|
||||
}
|
||||
|
||||
public boolean contains(ISchedulingRule rule) {
|
||||
if (this == rule)
|
||||
return true;
|
||||
|
@ -554,7 +564,7 @@ public class TypeCache implements ITypeCache {
|
|||
return null;
|
||||
}
|
||||
|
||||
public synchronized ITypeInfo getEnclosingNamespace(ITypeInfo info) {
|
||||
public synchronized ITypeInfo getEnclosingNamespace(ITypeInfo info, boolean includeGlobalNamespace) {
|
||||
IQualifiedTypeName enclosingName = info.getQualifiedTypeName().getEnclosingTypeName();
|
||||
if (enclosingName != null) {
|
||||
// look for namespace
|
||||
|
@ -568,9 +578,11 @@ public class TypeCache implements ITypeCache {
|
|||
enclosingType = (ITypeInfo) fTypeKeyMap.get(new HashKey(enclosingName, kinds[i]));
|
||||
}
|
||||
if (enclosingType != null) {
|
||||
return getEnclosingNamespace(enclosingType);
|
||||
return getEnclosingNamespace(enclosingType, includeGlobalNamespace);
|
||||
}
|
||||
}
|
||||
if (includeGlobalNamespace)
|
||||
return fGlobalNamespace;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,27 +10,45 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.browser.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.browser.IQualifiedTypeName;
|
||||
import org.eclipse.cdt.core.browser.ITypeCacheChangedListener;
|
||||
import org.eclipse.cdt.core.browser.ITypeInfo;
|
||||
import org.eclipse.cdt.core.browser.ITypeReference;
|
||||
import org.eclipse.cdt.core.browser.ITypeSearchScope;
|
||||
import org.eclipse.cdt.core.browser.IWorkingCopyProvider;
|
||||
import org.eclipse.cdt.core.browser.TypeSearchScope;
|
||||
import org.eclipse.cdt.core.browser.TypeUtil;
|
||||
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.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.ISafeRunnable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.IJobManager;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
|
||||
public class TypeCacheManager {
|
||||
|
||||
public class TypeCacheManager implements ITypeCacheChangedListener {
|
||||
private static final TypeCacheManager fgInstance = new TypeCacheManager();
|
||||
private Map fCacheMap;
|
||||
private IWorkingCopyProvider fWorkingCopyProvider;
|
||||
private ArrayList fChangeListeners = new ArrayList();
|
||||
|
||||
private static final int INITIAL_TYPE_MAP_SIZE = 50;
|
||||
//TODO make this a WeakHashMap or LRUCache
|
||||
private Map fTypeToElementMap = new HashMap(INITIAL_TYPE_MAP_SIZE);
|
||||
private Map fElementToTypeMap = new HashMap(INITIAL_TYPE_MAP_SIZE);
|
||||
|
||||
private TypeCacheManager() {
|
||||
fCacheMap = new HashMap();
|
||||
|
@ -45,8 +63,7 @@ public class TypeCacheManager {
|
|||
}
|
||||
|
||||
public synchronized void updateProject(IProject project) {
|
||||
TypeCacheDelta cacheDelta = new TypeCacheDelta(project);
|
||||
getCache(project).addDelta(cacheDelta);
|
||||
addCacheDelta(project, null);
|
||||
}
|
||||
|
||||
private static final int PATH_ENTRY_FLAGS = ICElementDelta.F_ADDED_PATHENTRY_SOURCE
|
||||
|
@ -69,8 +86,7 @@ public class TypeCacheManager {
|
|||
ICProject cProject = elem.getCProject();
|
||||
IProject project = cProject.getProject();
|
||||
if (added || removed || pathEntryChanged) {
|
||||
TypeCacheDelta cacheDelta = new TypeCacheDelta(project, delta);
|
||||
getCache(project).addDelta(cacheDelta);
|
||||
addCacheDelta(project, delta);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -84,8 +100,7 @@ public class TypeCacheManager {
|
|||
return;
|
||||
} else {
|
||||
if (added || removed || pathEntryChanged || contentChanged) {
|
||||
TypeCacheDelta cacheDelta = new TypeCacheDelta(project, delta);
|
||||
getCache(project).addDelta(cacheDelta);
|
||||
addCacheDelta(project, delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,8 +118,7 @@ public class TypeCacheManager {
|
|||
ICProject cProject = elem.getCProject();
|
||||
IProject project = cProject.getProject();
|
||||
if (added || removed) {
|
||||
TypeCacheDelta cacheDelta = new TypeCacheDelta(project, delta);
|
||||
getCache(project).addDelta(cacheDelta);
|
||||
addCacheDelta(project, delta);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -120,6 +134,17 @@ public class TypeCacheManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void addCacheDelta(IProject project, ICElementDelta delta) {
|
||||
if (delta == null) {
|
||||
getCache(project).addDelta(new TypeCacheDelta(project));
|
||||
} else {
|
||||
getCache(project).addDelta(new TypeCacheDelta(project, delta));
|
||||
}
|
||||
// TODO finer-grained flush needed, for now just flush the whole map
|
||||
fTypeToElementMap.clear();
|
||||
fElementToTypeMap.clear();
|
||||
}
|
||||
|
||||
public synchronized void processWorkingCopyDelta(ICElementDelta delta) {
|
||||
// ignore workies copies for now
|
||||
return;
|
||||
|
@ -175,7 +200,7 @@ public class TypeCacheManager {
|
|||
synchronized(fCacheMap) {
|
||||
ITypeCache cache = (ITypeCache) fCacheMap.get(project);
|
||||
if (cache == null) {
|
||||
cache = new TypeCache(project, fWorkingCopyProvider);
|
||||
cache = new TypeCache(project, fWorkingCopyProvider, this);
|
||||
fCacheMap.put(project, cache);
|
||||
}
|
||||
return cache;
|
||||
|
@ -241,4 +266,164 @@ public class TypeCacheManager {
|
|||
}
|
||||
return subTypes;
|
||||
}
|
||||
|
||||
public void updateCache(ITypeSearchScope scope, IProgressMonitor monitor) {
|
||||
// schedule jobs to update cache
|
||||
IProject[] projects = scope.getEnclosingProjects();
|
||||
monitor.beginTask(TypeCacheMessages.getString("AllTypesCache.updateCache.taskName"), projects.length); //$NON-NLS-1$
|
||||
for (int i = 0; i < projects.length; ++i) {
|
||||
IProject project = projects[i];
|
||||
// wait for any running jobs to finish
|
||||
getCache(project).reconcileAndWait(true, Job.SHORT, monitor);
|
||||
}
|
||||
monitor.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a type location.
|
||||
*
|
||||
* @param info the type to search for
|
||||
* @param monitor the progress monitor
|
||||
*/
|
||||
public ITypeReference resolveTypeLocation(ITypeInfo info, IProgressMonitor monitor, boolean enableIndexing) {
|
||||
ITypeReference location = info.getResolvedReference();
|
||||
if (location == null) {
|
||||
// cancel background jobs
|
||||
IProject project = info.getEnclosingProject();
|
||||
ITypeCache cache = getCache(project);
|
||||
cache.cancelJobs();
|
||||
|
||||
// start the search job
|
||||
cache.locateTypeAndWait(info, Job.SHORT, monitor);
|
||||
|
||||
// get the newly parsed location
|
||||
location = info.getResolvedReference();
|
||||
|
||||
// resume background jobs
|
||||
reconcile(enableIndexing, Job.BUILD, 0);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public synchronized void processElementChanged(ElementChangedEvent event, boolean enableIndexing) {
|
||||
processDelta(event.getDelta());
|
||||
reconcile(enableIndexing, Job.BUILD, 0);
|
||||
}
|
||||
|
||||
public void addTypeCacheChangedListener(ITypeCacheChangedListener listener) {
|
||||
// add listener only if it is not already present
|
||||
synchronized(fChangeListeners) {
|
||||
if (!fChangeListeners.contains(listener)) {
|
||||
fChangeListeners.add(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTypeCacheChangedListener(ITypeCacheChangedListener listener) {
|
||||
synchronized(fChangeListeners) {
|
||||
fChangeListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.browser.ITypeCacheChangedListener#typeCacheChanged(org.eclipse.core.resources.IProject)
|
||||
*/
|
||||
public void typeCacheChanged(final IProject project) {
|
||||
// clone so that a listener cannot have a side-effect on this list when being notified
|
||||
ArrayList listeners;
|
||||
synchronized(fChangeListeners) {
|
||||
listeners = (ArrayList) fChangeListeners.clone();
|
||||
}
|
||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
|
||||
final ITypeCacheChangedListener listener = (ITypeCacheChangedListener) i.next();
|
||||
Platform.run(new ISafeRunnable() {
|
||||
public void handleException(Throwable e) {
|
||||
IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, IStatus.ERROR, "Exception occurred in listener of type cache change notification", e); //$NON-NLS-1$
|
||||
CCorePlugin.log(status);
|
||||
}
|
||||
public void run() throws Exception {
|
||||
listener.typeCacheChanged(project);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ITypeInfo getTypeForElement(ICElement element, boolean forceUpdate, boolean forceResolve, boolean enableIndexing, IProgressMonitor monitor) {
|
||||
ITypeInfo cachedInfo = (ITypeInfo) fElementToTypeMap.get(element);
|
||||
if (cachedInfo != null && cachedInfo.exists())
|
||||
return cachedInfo;
|
||||
|
||||
IQualifiedTypeName qualifiedName = TypeUtil.getFullyQualifiedName(element);
|
||||
if (qualifiedName != null) {
|
||||
ICProject cProject = element.getCProject();
|
||||
IProject project = cProject.getProject();
|
||||
ITypeCache cache = getCache(project);
|
||||
if (!cache.isUpToDate() && forceUpdate) {
|
||||
if (monitor == null)
|
||||
monitor = new NullProgressMonitor();
|
||||
// wait for any running jobs to finish
|
||||
cache.reconcileAndWait(true, Job.SHORT, monitor);
|
||||
}
|
||||
|
||||
ITypeInfo info = cache.getType(element.getElementType(), qualifiedName);
|
||||
if (info != null) {
|
||||
ITypeReference ref = info.getResolvedReference();
|
||||
if (ref == null && forceResolve) {
|
||||
if (monitor == null)
|
||||
monitor = new NullProgressMonitor();
|
||||
ref = resolveTypeLocation(info, monitor, enableIndexing);
|
||||
}
|
||||
|
||||
// cache for later use
|
||||
fElementToTypeMap.put(element, info);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ICElement getElementForType(ITypeInfo type, boolean forceUpdate, boolean forceResolve, boolean enableIndexing, IProgressMonitor monitor) {
|
||||
ICElement cachedElem = (ICElement) fTypeToElementMap.get(type);
|
||||
if (cachedElem != null && cachedElem.exists())
|
||||
return cachedElem;
|
||||
|
||||
IProject project = type.getEnclosingProject();
|
||||
ITypeCache cache = getCache(project);
|
||||
if (!cache.isUpToDate() && forceUpdate) {
|
||||
if (monitor == null)
|
||||
monitor = new NullProgressMonitor();
|
||||
// wait for any running jobs to finish
|
||||
cache.reconcileAndWait(true, Job.SHORT, monitor);
|
||||
|
||||
//TODO replace type with new type from cache???
|
||||
}
|
||||
|
||||
ITypeReference ref = type.getResolvedReference();
|
||||
if (ref == null && forceResolve) {
|
||||
ref = resolveTypeLocation(type, monitor, enableIndexing);
|
||||
}
|
||||
if (ref != null) {
|
||||
ICElement[] elems = ref.getCElements();
|
||||
if (elems != null && elems.length > 0) {
|
||||
ICElement foundElem = elems[0];
|
||||
if (elems.length > 1) {
|
||||
for (int i = 0; i < elems.length; ++i) {
|
||||
ICElement elem = elems[i];
|
||||
if (elem.getElementType() == type.getCElementType() && elem.getElementName().equals(type.getName())) {
|
||||
//TODO should check fully qualified name
|
||||
foundElem = elem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundElem != null) {
|
||||
// cache for later use
|
||||
fTypeToElementMap.put(type, foundElem);
|
||||
return foundElem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue