mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
2004-06-17 Alain Magloire
Changes from Chris Wiebe to deal with the memory consumption.
This commit is contained in:
parent
954d5b8b45
commit
d52cb5e624
9 changed files with 199 additions and 166 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2004-06-17 Alain Magloire
|
||||||
|
|
||||||
|
Changes from Chris Wiebe to deal
|
||||||
|
with the memory consumption.
|
||||||
|
|
||||||
2004-05-12 Chris Wiebe
|
2004-05-12 Chris Wiebe
|
||||||
Heavy refactoring of type cache to address scalability
|
Heavy refactoring of type cache to address scalability
|
||||||
concerns.
|
concerns.
|
||||||
|
|
|
@ -35,6 +35,11 @@ public interface ITypeInfo extends Comparable {
|
||||||
*/
|
*/
|
||||||
public int getCElementType();
|
public int getCElementType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the CElement type.
|
||||||
|
*/
|
||||||
|
public void setCElementType(int type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type name.
|
* Gets the type name.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -97,7 +97,6 @@ public class QualifiedTypeName implements IQualifiedTypeName {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO extra methods eg matchingFirstSegments() etc
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return fSegments.length == 0;
|
return fSegments.length == 0;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +178,7 @@ public class QualifiedTypeName implements IQualifiedTypeName {
|
||||||
|
|
||||||
public IQualifiedTypeName removeFirstSegments(int count) {
|
public IQualifiedTypeName removeFirstSegments(int count) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return new QualifiedTypeName(this);
|
return this;
|
||||||
} else if (count >= fSegments.length || count < 0) {
|
} else if (count >= fSegments.length || count < 0) {
|
||||||
return new QualifiedTypeName(new String[0]);
|
return new QualifiedTypeName(new String[0]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -192,7 +191,7 @@ public class QualifiedTypeName implements IQualifiedTypeName {
|
||||||
|
|
||||||
public IQualifiedTypeName removeLastSegments(int count) {
|
public IQualifiedTypeName removeLastSegments(int count) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return new QualifiedTypeName(this);
|
return this;
|
||||||
} else if (count >= fSegments.length || count < 0) {
|
} else if (count >= fSegments.length || count < 0) {
|
||||||
return new QualifiedTypeName(new String[0]);
|
return new QualifiedTypeName(new String[0]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,10 +10,6 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.browser;
|
package org.eclipse.cdt.core.browser;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.internal.core.browser.cache.ITypeCache;
|
import org.eclipse.cdt.internal.core.browser.cache.ITypeCache;
|
||||||
import org.eclipse.cdt.internal.core.browser.util.ArrayUtil;
|
import org.eclipse.cdt.internal.core.browser.util.ArrayUtil;
|
||||||
|
@ -23,26 +19,44 @@ public class TypeInfo implements ITypeInfo
|
||||||
{
|
{
|
||||||
protected ITypeCache fTypeCache;
|
protected ITypeCache fTypeCache;
|
||||||
protected int fElementType;
|
protected int fElementType;
|
||||||
protected QualifiedTypeName fQualifiedName;
|
protected IQualifiedTypeName fQualifiedName;
|
||||||
protected Set fSourceRefs = new HashSet();
|
protected ITypeReference[] fSourceRefs = null;
|
||||||
|
protected int fSourceRefsCount = 0;
|
||||||
|
|
||||||
|
protected final static int INITIAL_REFS_SIZE = 1;
|
||||||
|
protected final static int REFS_GROW_BY = 10;
|
||||||
protected final static ITypeInfo[] EMPTY_TYPES = new ITypeInfo[0];
|
protected final static ITypeInfo[] EMPTY_TYPES = new ITypeInfo[0];
|
||||||
|
|
||||||
public TypeInfo(int elementType, IQualifiedTypeName typeName) {
|
public TypeInfo(int elementType, IQualifiedTypeName typeName) {
|
||||||
fElementType = elementType;
|
fElementType = elementType;
|
||||||
fQualifiedName = new QualifiedTypeName(typeName);
|
fQualifiedName = typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addReference(ITypeReference location) {
|
public void addReference(ITypeReference location) {
|
||||||
fSourceRefs.add(location);
|
if (fSourceRefs == null) {
|
||||||
|
fSourceRefs = new ITypeReference[INITIAL_REFS_SIZE];
|
||||||
|
fSourceRefsCount = 0;
|
||||||
|
} else if (fSourceRefsCount == fSourceRefs.length) {
|
||||||
|
ITypeReference[] refs = new ITypeReference[fSourceRefs.length + REFS_GROW_BY];
|
||||||
|
System.arraycopy(fSourceRefs, 0, refs, 0, fSourceRefsCount);
|
||||||
|
fSourceRefs = refs;
|
||||||
|
}
|
||||||
|
fSourceRefs[fSourceRefsCount] = location;
|
||||||
|
++fSourceRefsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITypeReference[] getReferences() {
|
public ITypeReference[] getReferences() {
|
||||||
return (ITypeReference[]) fSourceRefs.toArray(new ITypeReference[fSourceRefs.size()]);
|
if (fSourceRefs != null) {
|
||||||
|
ITypeReference[] refs = new ITypeReference[fSourceRefsCount];
|
||||||
|
System.arraycopy(fSourceRefs, 0, refs, 0, fSourceRefsCount);
|
||||||
|
return refs;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITypeReference getResolvedReference() {
|
public ITypeReference getResolvedReference() {
|
||||||
for (Iterator i = fSourceRefs.iterator(); i.hasNext(); ) {
|
for (int i = 0; i < fSourceRefsCount; ++i) {
|
||||||
ITypeReference location = (ITypeReference) i.next();
|
ITypeReference location = fSourceRefs[i];
|
||||||
if (location.getLength() != 0) {
|
if (location.getLength() != 0) {
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +65,7 @@ public class TypeInfo implements ITypeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReferenced() {
|
public boolean isReferenced() {
|
||||||
return !fSourceRefs.isEmpty();
|
return (fSourceRefs != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUndefinedType() {
|
public boolean isUndefinedType() {
|
||||||
|
@ -171,12 +185,12 @@ public class TypeInfo implements ITypeInfo
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// check if path is in scope
|
// check if path is in scope
|
||||||
for (Iterator i = fSourceRefs.iterator(); i.hasNext(); ) {
|
for (int i = 0; i < fSourceRefsCount; ++i) {
|
||||||
ITypeReference location = (ITypeReference) i.next();
|
ITypeReference location = fSourceRefs[i];
|
||||||
if (scope.encloses(location.getPath()))
|
if (scope.encloses(location.getPath()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,18 +149,28 @@ public class IndexerTypesJob extends IndexerJob {
|
||||||
int[] references = entry.getFileReferences();
|
int[] references = entry.getFileReferences();
|
||||||
if (references != null && references.length > 0) {
|
if (references != null && references.length > 0) {
|
||||||
// add new type to cache
|
// add new type to cache
|
||||||
info = new TypeInfo(type, qualifiedName);
|
if (info != null) {
|
||||||
fTypeCache.insert(info);
|
info.setCElementType(type);
|
||||||
|
} else {
|
||||||
|
info = new TypeInfo(type, qualifiedName);
|
||||||
|
fTypeCache.insert(info);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < references.length; ++i) {
|
// for (int i = 0; i < references.length; ++i) {
|
||||||
if (monitor.isCanceled())
|
// if (monitor.isCanceled())
|
||||||
throw new InterruptedException();
|
// throw new InterruptedException();
|
||||||
|
//
|
||||||
IndexedFile file = input.getIndexedFile(references[i]);
|
// IndexedFile file = input.getIndexedFile(references[i]);
|
||||||
if (file != null && file.getPath() != null) {
|
// if (file != null && file.getPath() != null) {
|
||||||
IPath path = PathUtil.getWorkspaceRelativePath(file.getPath());
|
// IPath path = PathUtil.getWorkspaceRelativePath(file.getPath());
|
||||||
info.addReference(new TypeReference(path, project));
|
// info.addReference(new TypeReference(path, project));
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
// just grab the first reference
|
||||||
|
IndexedFile file = input.getIndexedFile(references[0]);
|
||||||
|
if (file != null && file.getPath() != null) {
|
||||||
|
IPath path = PathUtil.getWorkspaceRelativePath(file.getPath());
|
||||||
|
info.addReference(new TypeReference(path, project));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,12 +44,14 @@ import org.eclipse.core.runtime.jobs.Job;
|
||||||
public class TypeCache implements ITypeCache {
|
public class TypeCache implements ITypeCache {
|
||||||
|
|
||||||
private static final int INITIAL_TYPE_COUNT = 100;
|
private static final int INITIAL_TYPE_COUNT = 100;
|
||||||
private final Map fTypeNameMap = new HashMap(INITIAL_TYPE_COUNT);
|
private final Map fTypeKeyMap = new HashMap(INITIAL_TYPE_COUNT);
|
||||||
private final IProject fProject;
|
private final IProject fProject;
|
||||||
private final IWorkingCopyProvider fWorkingCopyProvider;
|
private final IWorkingCopyProvider fWorkingCopyProvider;
|
||||||
private final Collection fDeltas = new ArrayList();
|
private final Collection fDeltas = new ArrayList();
|
||||||
private final ITypeInfo fGlobalNamespace;
|
private final ITypeInfo fGlobalNamespace;
|
||||||
|
|
||||||
|
private static final int[] ENCLOSING_TYPES = {ICElement.C_NAMESPACE, ICElement.C_CLASS, ICElement.C_STRUCT, 0};
|
||||||
|
|
||||||
private IJobChangeListener fJobChangeListener = new IJobChangeListener() {
|
private IJobChangeListener fJobChangeListener = new IJobChangeListener() {
|
||||||
public void aboutToRun(IJobChangeEvent event) {
|
public void aboutToRun(IJobChangeEvent event) {
|
||||||
}
|
}
|
||||||
|
@ -94,7 +96,8 @@ public class TypeCache implements ITypeCache {
|
||||||
private static class GlobalNamespace implements IQualifiedTypeName {
|
private static class GlobalNamespace implements IQualifiedTypeName {
|
||||||
|
|
||||||
private static final String GLOBAL_NAMESPACE = TypeCacheMessages.getString("TypeCache.globalNamespace"); //$NON-NLS-1$
|
private static final String GLOBAL_NAMESPACE = TypeCacheMessages.getString("TypeCache.globalNamespace"); //$NON-NLS-1$
|
||||||
|
private static final String[] segments = new String[] { GLOBAL_NAMESPACE };
|
||||||
|
|
||||||
public GlobalNamespace() {
|
public GlobalNamespace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +130,7 @@ public class TypeCache implements ITypeCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] segments() {
|
public String[] segments() {
|
||||||
return new String[] { GLOBAL_NAMESPACE };
|
return segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String segment(int index) {
|
public String segment(int index) {
|
||||||
|
@ -161,11 +164,11 @@ public class TypeCache implements ITypeCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQualifiedTypeName removeFirstSegments(int count) {
|
public IQualifiedTypeName removeFirstSegments(int count) {
|
||||||
return new QualifiedTypeName(this);
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQualifiedTypeName removeLastSegments(int count) {
|
public IQualifiedTypeName removeLastSegments(int count) {
|
||||||
return new QualifiedTypeName(this);
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLowLevel() {
|
public boolean isLowLevel() {
|
||||||
|
@ -207,6 +210,28 @@ public class TypeCache implements ITypeCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class HashKey {
|
||||||
|
private IQualifiedTypeName name;
|
||||||
|
private int type;
|
||||||
|
public HashKey(IQualifiedTypeName name, int type) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
public int hashCode() {
|
||||||
|
return (this.name.hashCode() + this.type);
|
||||||
|
}
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof HashKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HashKey otherKey = (HashKey)obj;
|
||||||
|
return (this.type == otherKey.type && this.name.equals(otherKey.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TypeCache(IProject project, IWorkingCopyProvider workingCopyProvider) {
|
public TypeCache(IProject project, IWorkingCopyProvider workingCopyProvider) {
|
||||||
fProject = project;
|
fProject = project;
|
||||||
fWorkingCopyProvider = workingCopyProvider;
|
fWorkingCopyProvider = workingCopyProvider;
|
||||||
|
@ -240,89 +265,49 @@ public class TypeCache implements ITypeCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean isEmpty() {
|
public synchronized boolean isEmpty() {
|
||||||
return fTypeNameMap.isEmpty();
|
return fTypeKeyMap.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void insert(ITypeInfo newType) {
|
|
||||||
// check if type already exists
|
|
||||||
Collection typeCollection = (Collection) fTypeNameMap.get(newType.getName());
|
|
||||||
if (typeCollection != null) {
|
|
||||||
for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
|
|
||||||
ITypeInfo currType = (ITypeInfo) typeIter.next();
|
|
||||||
if (currType.canSubstituteFor(newType)) {
|
|
||||||
// merge references into new type
|
|
||||||
ITypeReference[] refs = currType.getReferences();
|
|
||||||
for (int i = 0; i < refs.length; ++i) {
|
|
||||||
newType.addReference(refs[i]);
|
|
||||||
}
|
|
||||||
// remove the old type
|
|
||||||
currType.setCache(null);
|
|
||||||
typeIter.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public synchronized void insert(ITypeInfo newType) {
|
||||||
// check if enclosing types are already in cache
|
// check if enclosing types are already in cache
|
||||||
IQualifiedTypeName enclosingName = newType.getQualifiedTypeName().getEnclosingTypeName();
|
IQualifiedTypeName enclosingName = newType.getQualifiedTypeName().getEnclosingTypeName();
|
||||||
if (enclosingName != null) {
|
if (enclosingName != null) {
|
||||||
while (!enclosingName.isEmpty()) {
|
while (!enclosingName.isEmpty()) {
|
||||||
boolean foundType = false;
|
boolean foundType = false;
|
||||||
Collection enclosingCollection = (Collection) fTypeNameMap.get(enclosingName.getName());
|
// try namespace, class, struct, then undefined
|
||||||
if (enclosingCollection == null) {
|
ITypeInfo enclosingType = null;
|
||||||
enclosingCollection = new HashSet();
|
for (int i = 0; enclosingType == null && i < ENCLOSING_TYPES.length; ++i) {
|
||||||
fTypeNameMap.put(enclosingName.getName(), enclosingCollection);
|
enclosingType = (ITypeInfo) fTypeKeyMap.get(new HashKey(enclosingName, ENCLOSING_TYPES[i]));
|
||||||
} else {
|
|
||||||
for (Iterator typeIter = enclosingCollection.iterator(); typeIter.hasNext(); ) {
|
|
||||||
ITypeInfo curr = (ITypeInfo) typeIter.next();
|
|
||||||
if (curr.getQualifiedTypeName().equals(enclosingName)) {
|
|
||||||
foundType = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!foundType) {
|
if (enclosingType == null) {
|
||||||
// create a dummy type to take this place (type 0 == unknown)
|
// create a dummy type to take this place (type 0 == unknown)
|
||||||
ITypeInfo dummyType = new TypeInfo(0, enclosingName);
|
ITypeInfo dummyType = new TypeInfo(0, enclosingName);
|
||||||
enclosingCollection.add(dummyType);
|
|
||||||
dummyType.setCache(this);
|
dummyType.setCache(this);
|
||||||
|
fTypeKeyMap.put(new HashKey(enclosingName, 0), dummyType);
|
||||||
}
|
}
|
||||||
enclosingName = enclosingName.removeLastSegments(1);
|
enclosingName = enclosingName.removeLastSegments(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typeCollection = (Collection) fTypeNameMap.get(newType.getName());
|
fTypeKeyMap.put(new HashKey(newType.getQualifiedTypeName(), newType.getCElementType()), newType);
|
||||||
if (typeCollection == null) {
|
|
||||||
typeCollection = new HashSet();
|
|
||||||
fTypeNameMap.put(newType.getName(), typeCollection);
|
|
||||||
}
|
|
||||||
typeCollection.add(newType);
|
|
||||||
newType.setCache(this);
|
newType.setCache(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void remove(ITypeInfo info) {
|
public synchronized void remove(ITypeInfo info) {
|
||||||
Collection typeCollection = (Collection) fTypeNameMap.get(info.getName());
|
fTypeKeyMap.remove(new HashKey(info.getQualifiedTypeName(), info.getCElementType()));
|
||||||
if (typeCollection != null) {
|
info.setCache(null);
|
||||||
info.setCache(null);
|
|
||||||
typeCollection.remove(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void flush(ITypeSearchScope scope) {
|
public synchronized void flush(ITypeSearchScope scope) {
|
||||||
if (scope.encloses(fProject)) {
|
if (scope.encloses(fProject)) {
|
||||||
flushAll();
|
flushAll();
|
||||||
} else {
|
} else {
|
||||||
for (Iterator mapIter = fTypeNameMap.entrySet().iterator(); mapIter.hasNext(); ) {
|
for (Iterator mapIter = fTypeKeyMap.entrySet().iterator(); mapIter.hasNext(); ) {
|
||||||
Map.Entry entry = (Map.Entry) mapIter.next();
|
Map.Entry entry = (Map.Entry) mapIter.next();
|
||||||
Collection typeCollection = (Collection) entry.getValue();
|
ITypeInfo info = (ITypeInfo) entry.getValue();
|
||||||
for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
|
if (info.isEnclosed(scope)) {
|
||||||
ITypeInfo info = (ITypeInfo) typeIter.next();
|
|
||||||
if (info.isEnclosed(scope)) {
|
|
||||||
info.setCache(null);
|
|
||||||
typeIter.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeCollection.isEmpty())
|
|
||||||
mapIter.remove();
|
mapIter.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,19 +327,16 @@ public class TypeCache implements ITypeCache {
|
||||||
}
|
}
|
||||||
public boolean shouldContinue() { return true; }
|
public boolean shouldContinue() { return true; }
|
||||||
});
|
});
|
||||||
fTypeNameMap.clear();
|
fTypeKeyMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void accept(ITypeInfoVisitor visitor) {
|
public synchronized void accept(ITypeInfoVisitor visitor) {
|
||||||
for (Iterator mapIter = fTypeNameMap.entrySet().iterator(); mapIter.hasNext(); ) {
|
for (Iterator mapIter = fTypeKeyMap.entrySet().iterator(); mapIter.hasNext(); ) {
|
||||||
Map.Entry entry = (Map.Entry) mapIter.next();
|
Map.Entry entry = (Map.Entry) mapIter.next();
|
||||||
Collection typeCollection = (Collection) entry.getValue();
|
ITypeInfo info = (ITypeInfo) entry.getValue();
|
||||||
for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
|
if (!visitor.shouldContinue())
|
||||||
ITypeInfo info = (ITypeInfo) typeIter.next();
|
return; // stop visiting
|
||||||
if (!visitor.shouldContinue())
|
visitor.visit(info);
|
||||||
return; // stop visiting
|
|
||||||
visitor.visit(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,10 +346,12 @@ public class TypeCache implements ITypeCache {
|
||||||
public boolean visit(ITypeInfo info) {
|
public boolean visit(ITypeInfo info) {
|
||||||
if (scope == null || info.isEnclosed(scope)) {
|
if (scope == null || info.isEnclosed(scope)) {
|
||||||
ITypeReference[] refs = info.getReferences();
|
ITypeReference[] refs = info.getReferences();
|
||||||
for (int i = 0; i < refs.length; ++i) {
|
if (refs != null) {
|
||||||
IPath path = refs[i].getPath();
|
for (int i = 0; i < refs.length; ++i) {
|
||||||
if (scope == null || scope.encloses(path))
|
IPath path = refs[i].getPath();
|
||||||
pathSet.add(path);
|
if (scope == null || scope.encloses(path))
|
||||||
|
pathSet.add(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -393,51 +377,38 @@ public class TypeCache implements ITypeCache {
|
||||||
|
|
||||||
public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName) {
|
public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName) {
|
||||||
Collection results = new ArrayList();
|
Collection results = new ArrayList();
|
||||||
Collection typeCollection = (Collection) fTypeNameMap.get(qualifiedName.getName());
|
for (int i = 0; i < ITypeInfo.KNOWN_TYPES.length; ++i) {
|
||||||
if (typeCollection != null) {
|
ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, ITypeInfo.KNOWN_TYPES[i]));
|
||||||
for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
|
if (info != null) {
|
||||||
ITypeInfo info = (ITypeInfo) typeIter.next();
|
results.add(info);
|
||||||
if (info.getQualifiedTypeName().equals(qualifiedName)) {
|
|
||||||
results.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, 0));
|
||||||
|
if (info != null) {
|
||||||
|
results.add(info);
|
||||||
|
}
|
||||||
return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]);
|
return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ITypeInfo getType(int type, IQualifiedTypeName qualifiedName) {
|
public synchronized ITypeInfo getType(int type, IQualifiedTypeName qualifiedName) {
|
||||||
Collection typeCollection = (Collection) fTypeNameMap.get(qualifiedName.getName());
|
ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, type));
|
||||||
if (typeCollection != null) {
|
if (info == null && type != 0) {
|
||||||
for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
|
info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, 0));
|
||||||
ITypeInfo info = (ITypeInfo) typeIter.next();
|
|
||||||
if ((info.getCElementType() == type || info.getCElementType() == 0)
|
|
||||||
&& info.getQualifiedTypeName().equals(qualifiedName)) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ITypeInfo getEnclosingType(ITypeInfo info, final int[] kinds) {
|
public synchronized ITypeInfo getEnclosingType(ITypeInfo info, final int[] kinds) {
|
||||||
IQualifiedTypeName enclosingName = info.getQualifiedTypeName().getEnclosingTypeName();
|
IQualifiedTypeName enclosingName = info.getQualifiedTypeName().getEnclosingTypeName();
|
||||||
if (enclosingName != null) {
|
if (enclosingName != null) {
|
||||||
Collection typeCollection = (Collection) fTypeNameMap.get(enclosingName.getName());
|
// try namespace, class, struct, then undefined
|
||||||
if (typeCollection != null) {
|
ITypeInfo enclosingType = null;
|
||||||
// try namespace, class, struct, then undefined
|
for (int i = 0; enclosingType == null && i < ENCLOSING_TYPES.length; ++i) {
|
||||||
final int[] validKinds = {ICElement.C_NAMESPACE, ICElement.C_CLASS, ICElement.C_STRUCT, 0};
|
if (ArrayUtil.contains(kinds, ENCLOSING_TYPES[i])) {
|
||||||
for (int i = 0; i < validKinds.length; ++i) {
|
enclosingType = (ITypeInfo) fTypeKeyMap.get(new HashKey(enclosingName, ENCLOSING_TYPES[i]));
|
||||||
if (ArrayUtil.contains(kinds, validKinds[i])) {
|
|
||||||
for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
|
|
||||||
ITypeInfo type = (ITypeInfo) typeIter.next();
|
|
||||||
if (type.getCElementType() == validKinds[i]
|
|
||||||
&& type.getQualifiedTypeName().equals(enclosingName)) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return enclosingType;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -451,23 +422,12 @@ public class TypeCache implements ITypeCache {
|
||||||
return fGlobalNamespace;
|
return fGlobalNamespace;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] segments = qualifiedName.segments();
|
IQualifiedTypeName namespace = qualifiedName.removeLastSegments(qualifiedName.segmentCount()-1);
|
||||||
String namespace = segments[0];
|
// try namespace, then undefined
|
||||||
Collection typeCollection = (Collection) fTypeNameMap.get(namespace);
|
ITypeInfo namespaceType = (ITypeInfo) fTypeKeyMap.get(new HashKey(namespace, ICElement.C_NAMESPACE));
|
||||||
if (typeCollection != null) {
|
if (namespaceType == null)
|
||||||
// try namespace, then undefined
|
namespaceType = (ITypeInfo) fTypeKeyMap.get(new HashKey(namespace, 0));
|
||||||
final int[] kinds = {ICElement.C_NAMESPACE, 0};
|
return namespaceType;
|
||||||
for (int i = 0; i < kinds.length; ++i) {
|
|
||||||
for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
|
|
||||||
ITypeInfo type = (ITypeInfo) typeIter.next();
|
|
||||||
if (type.getCElementType() == kinds[i]
|
|
||||||
&& type.getQualifiedTypeName().isGlobal()) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean hasEnclosedTypes(final ITypeInfo info) {
|
public synchronized boolean hasEnclosedTypes(final ITypeInfo info) {
|
||||||
|
|
|
@ -110,8 +110,8 @@ public class TypeParser implements ISourceElementRequestor {
|
||||||
private IWorkingCopyProvider fWorkingCopyProvider;
|
private IWorkingCopyProvider fWorkingCopyProvider;
|
||||||
private IProgressMonitor fProgressMonitor;
|
private IProgressMonitor fProgressMonitor;
|
||||||
private ISourceElementCallbackDelegate fLastDeclaration;
|
private ISourceElementCallbackDelegate fLastDeclaration;
|
||||||
private SimpleStack fScopeStack = new SimpleStack();
|
private final SimpleStack fScopeStack = new SimpleStack();
|
||||||
private SimpleStack fResourceStack = new SimpleStack();
|
private final SimpleStack fResourceStack = new SimpleStack();
|
||||||
private ITypeInfo fTypeToFind;
|
private ITypeInfo fTypeToFind;
|
||||||
private boolean fFoundType;
|
private boolean fFoundType;
|
||||||
|
|
||||||
|
@ -311,6 +311,8 @@ public class TypeParser implements ISourceElementRequestor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reader != null) {
|
if (reader != null) {
|
||||||
|
fResourceStack.clear();
|
||||||
|
fScopeStack.clear();
|
||||||
fResourceStack.push(stackObject);
|
fResourceStack.push(stackObject);
|
||||||
parseContents(path, project, reader, language, progressMonitor);
|
parseContents(path, project, reader, language, progressMonitor);
|
||||||
fResourceStack.pop();
|
fResourceStack.pop();
|
||||||
|
@ -419,7 +421,8 @@ public class TypeParser implements ISourceElementRequestor {
|
||||||
} catch (ParserFactoryError e) {
|
} catch (ParserFactoryError e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
} catch (ParseError e) {
|
} catch (ParseError e) {
|
||||||
CCorePlugin.log(e);
|
// no need to log
|
||||||
|
// CCorePlugin.log(e);
|
||||||
} catch (OperationCanceledException e) {
|
} catch (OperationCanceledException e) {
|
||||||
throw new InterruptedException();
|
throw new InterruptedException();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -622,19 +625,35 @@ public class TypeParser implements ISourceElementRequestor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect enclosing names
|
if (fTypeToFind != null) {
|
||||||
|
if ((fTypeToFind.getCElementType() == type || fTypeToFind.isUndefinedType()) && name.equals(fTypeToFind.getName())) {
|
||||||
|
String[] enclosingNames = getEnclosingNames(offsetable);
|
||||||
|
QualifiedTypeName qualifiedName = new QualifiedTypeName(name, enclosingNames);
|
||||||
|
if (qualifiedName.equals(fTypeToFind.getQualifiedTypeName())) {
|
||||||
|
fFoundType = true;
|
||||||
|
|
||||||
|
// add types to cache
|
||||||
|
addType(type, name, enclosingNames, fResourceStack.bottom(), fResourceStack.top(), offset, end - offset);
|
||||||
|
fProgressMonitor.worked(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// add types to cache
|
||||||
|
addType(type, name, getEnclosingNames(offsetable), fResourceStack.bottom(), fResourceStack.top(), offset, end - offset);
|
||||||
|
fProgressMonitor.worked(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] getEnclosingNames(IASTOffsetableNamedElement elem) {
|
||||||
String[] enclosingNames = null;
|
String[] enclosingNames = null;
|
||||||
if (offsetable instanceof IASTQualifiedNameElement) {
|
if (elem instanceof IASTQualifiedNameElement) {
|
||||||
String[] names = ((IASTQualifiedNameElement) offsetable).getFullyQualifiedName();
|
String[] names = ((IASTQualifiedNameElement) elem).getFullyQualifiedName();
|
||||||
if (names != null && names.length > 1) {
|
if (names != null && names.length > 1) {
|
||||||
enclosingNames = new String[names.length - 1];
|
enclosingNames = new String[names.length - 1];
|
||||||
System.arraycopy(names, 0, enclosingNames, 0, names.length - 1);
|
System.arraycopy(names, 0, enclosingNames, 0, names.length - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return enclosingNames;
|
||||||
// add types to cache
|
|
||||||
addType(type, name, enclosingNames, fResourceStack.bottom(), fResourceStack.top(), offset, end - offset);
|
|
||||||
fProgressMonitor.worked(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getElementType(IASTOffsetableNamedElement offsetable) {
|
private int getElementType(IASTOffsetableNamedElement offsetable) {
|
||||||
|
@ -667,8 +686,12 @@ public class TypeParser implements ISourceElementRequestor {
|
||||||
ITypeInfo info = fTypeCache.getType(type, qualifiedName);
|
ITypeInfo info = fTypeCache.getType(type, qualifiedName);
|
||||||
if (info == null || info.isUndefinedType()) {
|
if (info == null || info.isUndefinedType()) {
|
||||||
// add new type to cache
|
// add new type to cache
|
||||||
info = new TypeInfo(type, qualifiedName);
|
if (info != null) {
|
||||||
fTypeCache.insert(info);
|
info.setCElementType(type);
|
||||||
|
} else {
|
||||||
|
info = new TypeInfo(type, qualifiedName);
|
||||||
|
fTypeCache.insert(info);
|
||||||
|
}
|
||||||
|
|
||||||
TypeReference location;
|
TypeReference location;
|
||||||
if (originalRef instanceof IWorkingCopy) {
|
if (originalRef instanceof IWorkingCopy) {
|
||||||
|
@ -696,10 +719,6 @@ public class TypeParser implements ISourceElementRequestor {
|
||||||
location = new TypeReference(path, fProject, offset, length);
|
location = new TypeReference(path, fProject, offset, length);
|
||||||
}
|
}
|
||||||
info.addReference(location);
|
info.addReference(location);
|
||||||
|
|
||||||
if (fTypeToFind != null && fTypeToFind.equals(info)) {
|
|
||||||
fFoundType = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.browser.util;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IWorkspace;
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
@ -70,10 +71,26 @@ public class PathUtil {
|
||||||
return fullPath;
|
return fullPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IPath getProjectRelativePath(IPath fullPath, IProject project) {
|
||||||
|
IPath projectPath = project.getFullPath();
|
||||||
|
if (projectPath.isPrefixOf(fullPath)) {
|
||||||
|
return fullPath.removeFirstSegments(projectPath.segmentCount());
|
||||||
|
}
|
||||||
|
projectPath = project.getLocation();
|
||||||
|
if (projectPath.isPrefixOf(fullPath)) {
|
||||||
|
return fullPath.removeFirstSegments(projectPath.segmentCount());
|
||||||
|
}
|
||||||
|
return getWorkspaceRelativePath(fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
public static IPath getWorkspaceRelativePath(String fullPath) {
|
public static IPath getWorkspaceRelativePath(String fullPath) {
|
||||||
return getWorkspaceRelativePath(new Path(fullPath));
|
return getWorkspaceRelativePath(new Path(fullPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IPath getProjectRelativePath(String fullPath, IProject project) {
|
||||||
|
return getProjectRelativePath(new Path(fullPath), project);
|
||||||
|
}
|
||||||
|
|
||||||
public static IPath getRawLocation(IPath wsRelativePath) {
|
public static IPath getRawLocation(IPath wsRelativePath) {
|
||||||
IWorkspaceRoot workspaceRoot = getWorkspaceRoot();
|
IWorkspaceRoot workspaceRoot = getWorkspaceRoot();
|
||||||
if (workspaceRoot != null && wsRelativePath != null) {
|
if (workspaceRoot != null && wsRelativePath != null) {
|
||||||
|
|
|
@ -31,6 +31,10 @@ public class SimpleStack {
|
||||||
items = new ArrayList(initialSize);
|
items = new ArrayList(initialSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public Object push(Object item) {
|
public Object push(Object item) {
|
||||||
items.add(item);
|
items.add(item);
|
||||||
if (VERBOSE)
|
if (VERBOSE)
|
||||||
|
|
Loading…
Add table
Reference in a new issue