diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 19514f6ace4..95f529858f9 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,14 @@ +2004-08-13 Chris Wiebe + + Extra functionality in type cache to support new class wizard + * browser/org/eclipse/cdt/core/browser/AllTypesCache.java + * browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java + * browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java + * browser/org/eclipse/cdt/core/browser/ITypeInfo.java + * browser/org/eclipse/cdt/core/browser/TypeInfo.java + * browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java + * browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java + 2004-08-13 Chris Wiebe Add findSourceRoot() method needed for class wizard 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 3ae26d8c516..6e97b173ead 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 @@ -313,6 +313,33 @@ public class AllTypesCache { public static ITypeInfo getTypeForElement(ICElement elem) { return TypeUtil.getTypeForElement(elem); } + + /** Returns first type in the cache which matches the given + * type and name. If no type is found, null + * is returned. + * + * @param project the enclosing project + * @param type the ICElement type + * @param qualifiedName the qualified type name to match + * @return the matching type + */ + public static ITypeInfo getType(IProject project, int type, IQualifiedTypeName qualifiedName) { + ITypeCache cache = TypeCacheManager.getInstance().getCache(project); + return cache.getType(type, qualifiedName); + } + + /** + * Returns all types matching name in the given project. + * + * @param project the enclosing project + * @param qualifiedName The qualified type name + * @param ignoreCase true if case-insensitive + * @return Array of types + */ + public static ITypeInfo[] getTypes(IProject project, IQualifiedTypeName qualifiedName, boolean ignoreCase) { + ITypeCache cache = TypeCacheManager.getInstance().getCache(project); + return cache.getTypes(qualifiedName, ignoreCase); + } /** * Creates and returns a type hierarchy for this type containing diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java index 81ebd60a5bb..673b5d73be3 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java @@ -40,4 +40,9 @@ public interface IQualifiedTypeName extends Comparable { public boolean isLowLevel(); public boolean validate(); + + public boolean equals(IQualifiedTypeName typeName); + public boolean equalsIgnoreCase(IQualifiedTypeName typeName); + public int compareTo(IQualifiedTypeName typeName); + public int compareToIgnoreCase(IQualifiedTypeName typeName); } 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 9c1eb6aad5a..fe2c89fea01 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 @@ -72,6 +72,11 @@ public interface ITypeInfo extends Comparable { */ public ITypeInfo getEnclosingType(); + /** Gets the enclosing namespace for this type. + * @return the enclosing namespace, or null if none exists. + */ + public ITypeInfo getEnclosingNamespace(); + /** Gets the first enclosing type which matches one of the given kinds. * @param kinds Array containing CElement types: C_NAMESPACE, C_CLASS, C_STRUCT * @return the enclosing type, or null if not found. diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java index ec0a1390bf3..fb7d2c97eb1 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java @@ -246,8 +246,35 @@ public class QualifiedTypeName implements IQualifiedTypeName { if (!(obj instanceof IQualifiedTypeName)) { throw new ClassCastException(); } - IQualifiedTypeName typeName = (IQualifiedTypeName) obj; - return getFullyQualifiedName().compareTo(typeName.getFullyQualifiedName()); + return compareTo((IQualifiedTypeName)obj); + } + + public int compareTo(IQualifiedTypeName typeName) { + if (typeName == this) + return 0; + if (typeName == null) + return 1; + String[] segments = typeName.segments(); + int len = Math.min(fSegments.length, segments.length); + int result = 0; + for (int i = 0; result == 0 && i < len; ++i) { + result = fSegments[i].compareTo(segments[i]); + } + return result; + } + + public int compareToIgnoreCase(IQualifiedTypeName typeName) { + if (typeName == this) + return 0; + if (typeName == null) + return 1; + String[] segments = typeName.segments(); + int len = Math.min(fSegments.length, segments.length); + int result = 0; + for (int i = 0; result == 0 && i < len; ++i) { + result = fSegments[i].compareToIgnoreCase(segments[i]); + } + return result; } public boolean equals(Object obj) { @@ -255,23 +282,40 @@ public class QualifiedTypeName implements IQualifiedTypeName { return true; } if (!(obj instanceof IQualifiedTypeName)) { - return false; + throw new ClassCastException(); } - IQualifiedTypeName typeName = (IQualifiedTypeName) obj; - return matchSegments(fSegments, typeName.segments()); + return equals((IQualifiedTypeName)obj); + } + + public boolean equals(IQualifiedTypeName typeName) { + if (typeName == this) + return true; + if (typeName == null) + return false; + String[] segments = typeName.segments(); + int len = segments.length; + if (fSegments.length != len) + return false; + for (int i = 0; i < len; ++i) { + if (!fSegments[i].equals(segments[i])) + return false; + } + return true; } - private static boolean matchSegments(String[] a, String[] b) { - if (a == null && b == null) + public boolean equalsIgnoreCase(IQualifiedTypeName typeName) { + if (typeName == this) return true; - if (a == null || b == null) - return false; - if (a.length != b.length) - return false; - for (int i = 0; i < a.length; ++i) { - if (!a[i].equals(b[i])) - return false; - } - return true; + if (typeName == null) + return false; + String[] segments = typeName.segments(); + int len = segments.length; + if (fSegments.length != len) + return false; + for (int i = 0; i < len; ++i) { + if (!fSegments[i].equalsIgnoreCase(segments[i])) + return false; + } + return true; } } 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 117929e491d..a32640988ff 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,6 +149,13 @@ public class TypeInfo implements ITypeInfo return getEnclosingType(KNOWN_TYPES); } + public ITypeInfo getEnclosingNamespace() { + if (fTypeCache != null) { + return fTypeCache.getEnclosingNamespace(this); + } + return null; + } + public ITypeInfo getRootNamespace(boolean includeGlobalNamespace) { if (fTypeCache != null) { return fTypeCache.getRootNamespace(this, true); 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 a4e4e1188e4..2e3dec8d986 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 @@ -85,6 +85,7 @@ public class TypeUtil { return (ICElement[])typeList.toArray(new ICElement[typeList.size()]); } +// TODO move method to CModelUtil public static IQualifiedTypeName getFullyQualifiedName(ICElement type) { String name = type.getElementName(); IQualifiedTypeName qualifiedName = new QualifiedTypeName(name); 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 3e229984c4f..57927ec3072 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 @@ -105,7 +105,7 @@ public interface ITypeCache extends ISchedulingRule { * @param qualifiedName the qualified type name to match * @return Array of types */ - public ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName); + public ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName, boolean ignoreCase); /** Returns first type in the cache which matches the given * type and name. If no type is found, null @@ -126,6 +126,13 @@ public interface ITypeCache extends ISchedulingRule { */ public ITypeInfo getEnclosingType(ITypeInfo info, int[] kinds); + /** Returns the enclosing namespace for the given type, or + * null if none exists. + * + * @param type the ICElement type + * @return the namespace + */ + public ITypeInfo getEnclosingNamespace(ITypeInfo info); /** 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 76f2ab3aa1b..fd97c2a846f 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 @@ -218,8 +218,7 @@ public class TypeCache implements ITypeCache { if (!(obj instanceof IQualifiedTypeName)) { return false; } - IQualifiedTypeName typeName = (IQualifiedTypeName) obj; - return (typeName instanceof GlobalNamespace); + return equals((IQualifiedTypeName)obj); } public int compareTo(Object obj) { @@ -229,9 +228,36 @@ public class TypeCache implements ITypeCache { if (!(obj instanceof IQualifiedTypeName)) { throw new ClassCastException(); } - IQualifiedTypeName typeName = (IQualifiedTypeName) obj; - return getFullyQualifiedName().compareTo(typeName.getFullyQualifiedName()); + return compareTo((IQualifiedTypeName)obj); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.browser.IQualifiedTypeName#equals(org.eclipse.cdt.core.browser.IQualifiedTypeName) + */ + public boolean equals(IQualifiedTypeName typeName) { + return (typeName instanceof GlobalNamespace); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.browser.IQualifiedTypeName#equalsIgnoreCase(org.eclipse.cdt.core.browser.IQualifiedTypeName) + */ + public boolean equalsIgnoreCase(IQualifiedTypeName typeName) { + return (typeName instanceof GlobalNamespace); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.browser.IQualifiedTypeName#compareTo(org.eclipse.cdt.core.browser.IQualifiedTypeName) + */ + public int compareTo(IQualifiedTypeName typeName) { + return getFullyQualifiedName().compareTo(typeName.getFullyQualifiedName()); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.browser.IQualifiedTypeName#compareToIgnoreCase(org.eclipse.cdt.core.browser.IQualifiedTypeName) + */ + public int compareToIgnoreCase(IQualifiedTypeName typeName) { + return getFullyQualifiedName().compareToIgnoreCase(typeName.getFullyQualifiedName()); + } } private static class HashKey { @@ -454,17 +480,28 @@ public class TypeCache implements ITypeCache { return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]); } - public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName) { + public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName, boolean ignoreCase) { Collection results = new ArrayList(); - for (int i = 0; i < ITypeInfo.KNOWN_TYPES.length; ++i) { - ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, ITypeInfo.KNOWN_TYPES[i])); + if (!ignoreCase) { + for (int i = 0; i < ITypeInfo.KNOWN_TYPES.length; ++i) { + ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, ITypeInfo.KNOWN_TYPES[i])); + if (info != null) { + results.add(info); + } + } + ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, 0)); if (info != null) { results.add(info); } - } - ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, 0)); - if (info != null) { - results.add(info); + } else { + // TODO this should probably use a more efficient search algorithm + for (Iterator mapIter = fTypeKeyMap.entrySet().iterator(); mapIter.hasNext(); ) { + Map.Entry entry = (Map.Entry) mapIter.next(); + ITypeInfo info = (ITypeInfo) entry.getValue(); + if (info.getQualifiedTypeName().compareToIgnoreCase(qualifiedName) == 0) { + results.add(info); + } + } } return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]); } @@ -492,6 +529,26 @@ public class TypeCache implements ITypeCache { return null; } + public synchronized ITypeInfo getEnclosingNamespace(ITypeInfo info) { + IQualifiedTypeName enclosingName = info.getQualifiedTypeName().getEnclosingTypeName(); + if (enclosingName != null) { + // look for namespace + ITypeInfo enclosingType = (ITypeInfo) fTypeKeyMap.get(new HashKey(enclosingName, ICElement.C_NAMESPACE)); + if (enclosingType != null) { + return enclosingType; + } + // try class, struct, then undefined + final int[] kinds = {ICElement.C_CLASS, ICElement.C_STRUCT, 0}; + for (int i = 0; enclosingType == null && i < kinds.length; ++i) { + enclosingType = (ITypeInfo) fTypeKeyMap.get(new HashKey(enclosingName, kinds[i])); + } + if (enclosingType != null) { + return getEnclosingNamespace(enclosingType); + } + } + return null; + } + public synchronized ITypeInfo getRootNamespace(ITypeInfo info, boolean includeGlobalNamespace) { IQualifiedTypeName qualifiedName = info.getQualifiedTypeName(); if (qualifiedName.isGlobal()) {