diff --git a/core/org.eclipse.cdt.core/browser/ChangeLog-browser b/core/org.eclipse.cdt.core/browser/ChangeLog-browser index ffeb38777bc..a13047d83a4 100644 --- a/core/org.eclipse.cdt.core/browser/ChangeLog-browser +++ b/core/org.eclipse.cdt.core/browser/ChangeLog-browser @@ -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 diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java index 99d5e49b1a5..b2e16338db3 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java @@ -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); + } } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeCacheChangedListener.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeCacheChangedListener.java new file mode 100644 index 00000000000..1f78994b9aa --- /dev/null +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeCacheChangedListener.java @@ -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. + *
+ * This interface may be implemented by clients. + *
+ */ +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); +} diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java index fe2c89fea01..b664faa58a8 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java @@ -75,7 +75,7 @@ public interface ITypeInfo extends Comparable { /** Gets the enclosing namespace for this type. * @return the enclosing namespace, ornull
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
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java
index 40ac9a54f1a..b575a4e94a7 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java
@@ -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;
}
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeUtil.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeUtil.java
index 2e3dec8d986..4032d357239 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeUtil.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeUtil.java
@@ -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;
}
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/typehierarchy/TypeHierarchy.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/typehierarchy/TypeHierarchy.java
index 07caef7c2a6..bc6c2e28fe1 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/typehierarchy/TypeHierarchy.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/typehierarchy/TypeHierarchy.java
@@ -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(
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java
index d43d0f82e0c..3f0f13326e4 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java
@@ -132,9 +132,10 @@ public interface ITypeCache extends ISchedulingRule {
* null
if none exists.
*
* @param type the ICElement type
- * @return the namespace
+ * @param includeGlobalNamespace true
if the global (default) namespace should be returned
+ * @return the enclosing namespace, or null
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.
*
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
index 905eeebbc86..01a35be01e1 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
@@ -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;
}
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java
index ba731eb7f71..b98bfb678dc 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheManager.java
@@ -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;
+ }
}