Author: raja
Date: 2005-03-02 10:31:50 -0500 (Wed, 02 Mar 2005)
New Revision: 41361
Modified:
trunk/mcs/mcs/ChangeLog
trunk/mcs/mcs/class.cs
trunk/mcs/mcs/decl.cs
trunk/mcs/mcs/doc.cs
trunk/mcs/mcs/ecore.cs
trunk/mcs/mcs/namespace.cs
trunk/mcs/mcs/typemanager.cs
Log:
Unify DeclSpace.LookupType and DeclSpace.FindType.
* decl.cs (DeclSpace.FindNestedType): New virtual function. This
is in charge of defining nested types on demand.
(DeclSpace.LookupType): Use it when the current_type is a
TypeBuilder. Use LookupTypeDirect for reflected types.
(DeclSpace.FindType): Remove.
(DeclSpace.LookupInterfaceOrClass): Likewise.
(DeclSpace.DefineTypeAndParents): Likewise.
* ecore.cs (SimpleName.ResolveAsTypeStep): Just call
DeclSpace.LookupType.
* doc.cs (FindDocumentedTypeNonArray): Use DeclSpace.LookupType.
* typemanager.cs (LookupType): Simplify.
(AddUserType): Remove type from negative_hits.
* namespace.cs (Namespace.Lookup): Use TypeManager.LookupTypeDirect.
* class.cs (TypeContainer.FindMembers): Move handling of nested
types ...
(TypeContainer.FindMembers_NestedTypes): ... here.
(TypeContainer.FindNestedType): Implement override.
(ClassPart.FindNestedType): Delegate to PartialContainer.
(ClassPart.PartFindNestedType): Looks up the nested types of the
part alone.
Here's the memory savings when compiling corlib:
w/o patch: 124938 KB
with patch: 119036 KB
Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog 2005-03-02 14:58:49 UTC (rev 41360)
+++ trunk/mcs/mcs/ChangeLog 2005-03-02 15:31:50 UTC (rev 41361)
@@ -1,3 +1,27 @@
+2005-03-02 Raja R Harinath <[EMAIL PROTECTED]>
+
+ Unify DeclSpace.LookupType and DeclSpace.FindType.
+ * decl.cs (DeclSpace.FindNestedType): New virtual function. This
+ is in charge of defining nested types on demand.
+ (DeclSpace.LookupType): Use it when the current_type is a
+ TypeBuilder. Use LookupTypeDirect for reflected types.
+ (DeclSpace.FindType): Remove.
+ (DeclSpace.LookupInterfaceOrClass): Likewise.
+ (DeclSpace.DefineTypeAndParents): Likewise.
+ * ecore.cs (SimpleName.ResolveAsTypeStep): Just call
+ DeclSpace.LookupType.
+ * doc.cs (FindDocumentedTypeNonArray): Use DeclSpace.LookupType.
+ * typemanager.cs (LookupType): Simplify.
+ (AddUserType): Remove type from negative_hits.
+ * namespace.cs (Namespace.Lookup): Use TypeManager.LookupTypeDirect.
+ * class.cs (TypeContainer.FindMembers): Move handling of nested
+ types ...
+ (TypeContainer.FindMembers_NestedTypes): ... here.
+ (TypeContainer.FindNestedType): Implement override.
+ (ClassPart.FindNestedType): Delegate to PartialContainer.
+ (ClassPart.PartFindNestedType): Looks up the nested types of the
+ part alone.
+
2005-03-02 Martin Baulig <[EMAIL PROTECTED]>
* class.cs (TypeContainer.DoDefineMembers): We also need a default
Modified: trunk/mcs/mcs/class.cs
===================================================================
--- trunk/mcs/mcs/class.cs 2005-03-02 14:58:49 UTC (rev 41360)
+++ trunk/mcs/mcs/class.cs 2005-03-02 15:31:50 UTC (rev 41361)
@@ -1554,6 +1554,70 @@
return false;
}
}
+
+ public override Type FindNestedType (string name)
+ {
+ ArrayList [] lists = { types, enums, delegates,
interfaces };
+
+ for (int j = 0; j < lists.Length; ++j) {
+ ArrayList list = lists [j];
+ if (list == null)
+ continue;
+
+ int len = list.Count;
+ for (int i = 0; i < len; ++i) {
+ DeclSpace ds = (DeclSpace) list [i];
+ if (ds.Basename == name) {
+ ds.DefineType ();
+ return ds.TypeBuilder;
+ }
+ }
+ }
+
+ if (Parts != null) {
+ foreach (ClassPart cp in Parts) {
+ Type t = cp.PartFindNestedType (name);
+ if (t != null)
+ return t;
+ }
+ }
+
+ return null;
+ }
+
+ private void FindMembers_NestedTypes (int modflags,
+ BindingFlags bf,
MemberFilter filter, object criteria,
+ ref ArrayList members)
+ {
+ ArrayList [] lists = { types, enums, delegates,
interfaces };
+
+ for (int j = 0; j < lists.Length; ++j) {
+ ArrayList list = lists [j];
+ if (list == null)
+ continue;
+
+ int len = list.Count;
+ for (int i = 0; i < len; i++) {
+ DeclSpace ds = (DeclSpace) list [i];
+
+ if ((ds.ModFlags & modflags) == 0)
+ continue;
+
+ TypeBuilder tb = ds.TypeBuilder;
+ if (tb == null) {
+ if (!(criteria is string) ||
ds.Basename.Equals (criteria))
+ tb = ds.DefineType ();
+ }
+
+ if (tb != null && (filter (tb,
criteria) == true)) {
+ if (members == null)
+ members = new ArrayList
();
+
+ members.Add (tb);
+ }
+ }
+ }
+ }
/// <summary>
/// This method returns the members of this type just like
Type.FindMembers would
@@ -1820,83 +1884,9 @@
}
}
- if ((mt & MemberTypes.NestedType) != 0) {
- if (types != null) {
- int len = types.Count;
- for (int i = 0; i < len; i++) {
- TypeContainer t =
(TypeContainer) types [i];
-
- if ((t.ModFlags & modflags) ==
0)
- continue;
+ if ((mt & MemberTypes.NestedType) != 0)
+ FindMembers_NestedTypes (modflags, bf, filter,
criteria, ref members);
- TypeBuilder tb = t.TypeBuilder;
- if (tb == null)
- tb = t.DefineType ();
-
- if (tb != null && (filter (tb,
criteria) == true)) {
- if (members == null)
- members = new
ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- if (enums != null) {
- int len = enums.Count;
- for (int i = 0; i < len; i++) {
- Enum en = (Enum) enums [i];
-
- if ((en.ModFlags & modflags) ==
0)
- continue;
-
- TypeBuilder tb = en.TypeBuilder;
- if (tb != null && (filter (tb,
criteria) == true)) {
- if (members == null)
- members = new
ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- if (delegates != null) {
- int len = delegates.Count;
- for (int i = 0; i < len; i++) {
- Delegate d = (Delegate)
delegates [i];
-
- if ((d.ModFlags & modflags) ==
0)
- continue;
-
- TypeBuilder tb = d.TypeBuilder;
- if (tb != null && (filter (tb,
criteria) == true)) {
- if (members == null)
- members = new
ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- if (interfaces != null) {
- int len = interfaces.Count;
- for (int i = 0; i < len; i++) {
- TypeContainer iface =
(TypeContainer) interfaces [i];
-
- if ((iface.ModFlags & modflags)
== 0)
- continue;
-
- TypeBuilder tb =
iface.TypeBuilder;
- if (tb != null && (filter (tb,
criteria) == true)) {
- if (members == null)
- members = new
ArrayList ();
-
- members.Add (tb);
- }
- }
- }
- }
-
if ((mt & MemberTypes.Constructor) != 0){
if (((bf & BindingFlags.Instance) != 0) &&
(instance_constructors != null)){
int len = instance_constructors.Count;
@@ -2619,6 +2609,16 @@
interface_type, full, name, loc);
}
+ public override Type FindNestedType (string name)
+ {
+ return PartialContainer.FindNestedType (name);
+ }
+
+ public Type PartFindNestedType (string name)
+ {
+ return base.FindNestedType (name);
+ }
+
public override MemberCache BaseCache {
get {
return PartialContainer.BaseCache;
Modified: trunk/mcs/mcs/decl.cs
===================================================================
--- trunk/mcs/mcs/decl.cs 2005-03-02 14:58:49 UTC (rev 41360)
+++ trunk/mcs/mcs/decl.cs 2005-03-02 15:31:50 UTC (rev 41361)
@@ -673,20 +673,9 @@
protected bool NestedAccessible (Type check_type)
{
- string check_type_name = check_type.FullName;
-
- // At this point, we already know check_type is a
nested class.
- int cio = check_type_name.LastIndexOf ('+');
-
- // Ensure that the string 'container' has a '+' in it
to avoid false matches
- string container = check_type_name.Substring (0, cio +
1);
-
- // Ensure that type_name ends with a '+' so that it can
match 'container', if necessary
- string type_name = TypeBuilder.FullName + "+";
-
- // If the current class is nested inside the container
of check_type,
- // we can access check_type even if it is private or
protected.
- return type_name.StartsWith (container);
+ Type declaring = check_type.DeclaringType;
+ return TypeBuilder == declaring ||
+ TypeManager.IsNestedChildOf (TypeBuilder,
declaring);
}
protected bool FamilyAccessible (Type check_type)
@@ -799,99 +788,7 @@
return ~ (~ mAccess | pAccess) == 0;
}
-
- static DoubleHash dh = new DoubleHash (1000);
- Type DefineTypeAndParents (DeclSpace tc)
- {
- DeclSpace container = tc.Parent;
-
- if (container.TypeBuilder == null && container.Name !=
"")
- DefineTypeAndParents (container);
-
- return tc.DefineType ();
- }
-
- FullNamedExpression LookupInterfaceOrClass (string ns, string
name, out bool error)
- {
- DeclSpace parent;
- FullNamedExpression result;
- Type t;
- object r;
-
- error = false;
- int p = name.LastIndexOf ('.');
-
- if (dh.Lookup (ns, name, out r))
- return (FullNamedExpression) r;
- else {
- //
- // If the type is not a nested type, we do not
need `LookupType's processing.
- // If the @name does not have a `.' in it, this
cant be a nested type.
- //
- if (ns != ""){
- if (Namespace.IsNamespace (ns)) {
- if (p != -1)
- t =
TypeManager.LookupType (ns + "." + name);
- else
- t =
TypeManager.LookupTypeDirect (ns + "." + name);
- } else
- t = null;
- } else if (p != -1)
- t = TypeManager.LookupType (name);
- else
- t = TypeManager.LookupTypeDirect (name);
- }
-
- if (t != null) {
- result = new TypeExpression (t, Location.Null);
- dh.Insert (ns, name, result);
- return result;
- }
-
- if (ns != "" && Namespace.IsNamespace (ns)) {
- result = Namespace.LookupNamespace (ns,
false).Lookup (this, name, Location.Null);
- if (result != null) {
- dh.Insert (ns, name, result);
- return result;
- }
- }
-
- if (ns == "" && Namespace.IsNamespace (name)) {
- result = Namespace.LookupNamespace (name,
false);
- dh.Insert (ns, name, result);
- return result;
- }
-
- //
- // In case we are fed a composite name, normalize it.
- //
-
- if (p != -1){
- ns = MakeFQN (ns, name.Substring (0, p));
- name = name.Substring (p+1);
- }
-
- if (ns.IndexOf ('+') != -1)
- ns = ns.Replace ('+', '.');
-
- parent = RootContext.Tree.LookupByNamespace (ns, name);
- if (parent == null) {
- dh.Insert (ns, name, null);
- return null;
- }
-
- t = DefineTypeAndParents (parent);
- if (t == null){
- error = true;
- return null;
- }
-
- result = new TypeExpression (t, Location.Null);
- dh.Insert (ns, name, result);
- return result;
- }
-
public static void Error_AmbiguousTypeReference (Location loc,
string name, string t1, string t2)
{
Report.Error (104, loc,
@@ -899,117 +796,12 @@
name, t1, t2);
}
- /// <summary>
- /// GetType is used to resolve type names at the DeclSpace
level.
- /// Use this to lookup class/struct bases, interface bases or
- /// delegate type references
- /// </summary>
- ///
- /// <remarks>
- /// Contrast this to LookupType which is used inside method
bodies to
- /// lookup types that have already been defined. GetType is
used
- /// during the tree resolution process and potentially define
- /// recursively the type
- /// </remarks>
- public FullNamedExpression FindType (Location loc, string name)
+ //
+ // Return the nested type with name @name. Ensures that the
nested type
+ // is defined if necessary. Do _not_ use this when you have a
MemberCache handy.
+ //
+ public virtual Type FindNestedType (string name)
{
- FullNamedExpression t;
- bool error;
-
- //
- // For the case the type we are looking for is nested
within this one
- // or is in any base class
- //
-
- DeclSpace containing_ds = this;
-
- while (containing_ds != null){
- Type container_type = containing_ds.TypeBuilder;
- Type current_type = container_type;
-
- while (current_type != null && current_type !=
TypeManager.object_type) {
- string pre = current_type.FullName;
-
- t = LookupInterfaceOrClass (pre, name,
out error);
- if (error)
- return null;
-
- if ((t != null) &&
containing_ds.CheckAccessLevel (t.Type))
- return t;
-
- current_type = current_type.BaseType;
- }
- containing_ds = containing_ds.Parent;
- }
-
- //
- // Attempt to lookup the class on our namespace and all
it's implicit parents
- //
- for (NamespaceEntry ns = NamespaceEntry; ns != null; ns
= ns.ImplicitParent) {
- t = LookupInterfaceOrClass (ns.FullName, name,
out error);
- if (error)
- return null;
-
- if (t != null)
- return t;
- }
-
- //
- // Attempt to do a direct unqualified lookup
- //
- t = LookupInterfaceOrClass ("", name, out error);
- if (error)
- return null;
-
- if (t != null)
- return t;
-
- //
- // Attempt to lookup the class on any of the `using'
- // namespaces
- //
-
- for (NamespaceEntry ns = NamespaceEntry; ns != null; ns
= ns.Parent){
-
- t = LookupInterfaceOrClass (ns.FullName, name,
out error);
- if (error)
- return null;
-
- if (t != null)
- return t;
-
- if (name.IndexOf ('.') > 0)
- continue;
-
- t = ns.LookupAlias (name);
- if (t != null)
- return t;
-
- //
- // Now check the using clause list
- //
- FullNamedExpression match = null;
- foreach (Namespace using_ns in ns.GetUsingTable
()) {
- match = LookupInterfaceOrClass
(using_ns.Name, name, out error);
- if (error)
- return null;
-
- if ((match != null) && (match is
TypeExpr)) {
- Type matched = ((TypeExpr)
match).Type;
- if (!CheckAccessLevel (matched))
- continue;
- if (t != null){
-
Error_AmbiguousTypeReference (loc, name, t.FullName, match.FullName);
- return null;
- }
- t = match;
- }
- }
- if (t != null)
- return t;
- }
-
- //Report.Error (246, Location, "Can not find type
`"+name+"'");
return null;
}
@@ -1033,17 +825,15 @@
// For the case the type we are looking for is
nested within this one
// or is in any base class
//
- DeclSpace containing_ds = this;
- while (containing_ds != null){
-
+
+ Type t = null;
+ for (DeclSpace containing_ds = this;
containing_ds != null; containing_ds = containing_ds.Parent) {
// if the member cache has been
created, lets use it.
// the member cache is MUCH faster.
if (containing_ds.MemberCache != null) {
- Type t =
containing_ds.MemberCache.FindNestedType (name);
- if (t == null) {
- containing_ds =
containing_ds.Parent;
+ t =
containing_ds.MemberCache.FindNestedType (name);
+ if (t == null)
continue;
- }
e = new TypeExpression (t,
Location.Null);
Cache [name] = e;
@@ -1051,34 +841,34 @@
}
// no member cache. Do it the hard way
-- reflection
- Type current_type =
containing_ds.TypeBuilder;
-
- while (current_type != null &&
- current_type !=
TypeManager.object_type) {
- //
- // nested class
- //
- Type t = TypeManager.LookupType
(current_type.FullName + "." + name);
- if (t != null){
+ for (Type current_type =
containing_ds.TypeBuilder;
+ current_type != null &&
current_type != TypeManager.object_type;
+ current_type =
current_type.BaseType) {
+ if (current_type is
TypeBuilder) {
+ DeclSpace decl =
containing_ds;
+ if (current_type !=
containing_ds.TypeBuilder)
+ decl =
TypeManager.LookupDeclSpace (current_type);
+
+ t = decl.FindNestedType
(name);
+ } else {
+ t =
TypeManager.LookupTypeDirect (current_type.FullName + "+" + name);
+ }
+
+ if (t != null &&
containing_ds.CheckAccessLevel (t)) {
e = new TypeExpression
(t, Location.Null);
Cache [name] = e;
return e;
}
-
- current_type =
current_type.BaseType;
}
-
- containing_ds = containing_ds.Parent;
}
e = NamespaceEntry.LookupNamespaceOrType (this,
name, loc, ignore_cs0104);
- if (!silent || e != null)
- Cache [name] = e;
+ Cache [name] = e;
}
if (e == null && !silent)
Report.Error (246, loc, "Cannot find type
`"+name+"'");
-
+
return e;
}
Modified: trunk/mcs/mcs/doc.cs
===================================================================
--- trunk/mcs/mcs/doc.cs 2005-03-02 14:58:49 UTC (rev 41360)
+++ trunk/mcs/mcs/doc.cs 2005-03-02 15:31:50 UTC (rev 41361)
@@ -317,7 +317,7 @@
case "void":
return typeof (void);
}
- FullNamedExpression e = ds.FindType (mc.Location,
identifier);
+ FullNamedExpression e = ds.LookupType (identifier,
mc.Location, true, false);
if (e != null) {
if (!(e is TypeExpr))
return null;
Modified: trunk/mcs/mcs/ecore.cs
===================================================================
--- trunk/mcs/mcs/ecore.cs 2005-03-02 14:58:49 UTC (rev 41360)
+++ trunk/mcs/mcs/ecore.cs 2005-03-02 15:31:50 UTC (rev 41361)
@@ -2050,13 +2050,9 @@
public override FullNamedExpression ResolveAsTypeStep
(EmitContext ec)
{
- DeclSpace ds = ec.DeclSpace;
- FullNamedExpression dt;
-
int errors = Report.Errors;
- dt = ec.ResolvingTypeTree
- ? ds.FindType (loc, Name)
- : ds.LookupType (Name, loc, /*silent=*/ true,
/*ignore_cs0104=*/ false);
+ FullNamedExpression dt = ec.DeclSpace.LookupType (
+ Name, loc, /*silent=*/ true,
/*ignore_cs0104=*/ false);
if (Report.Errors != errors)
return null;
Modified: trunk/mcs/mcs/namespace.cs
===================================================================
--- trunk/mcs/mcs/namespace.cs 2005-03-02 14:58:49 UTC (rev 41360)
+++ trunk/mcs/mcs/namespace.cs 2005-03-02 15:31:50 UTC (rev 41361)
@@ -113,7 +113,18 @@
Type t;
DeclSpace tdecl = o as DeclSpace;
if (tdecl != null) {
- t = tdecl.DefineType ();
+ //
+ // Note that this is not:
+ //
+ // t = tdecl.DefineType ()
+ //
+ // This is to make it somewhat more useful when
a DefineType
+ // fails due to problems in nested types (more
useful in the sense
+ // of fewer misleading error messages)
+ //
+ tdecl.DefineType ();
+ t = tdecl.TypeBuilder;
+
if (t == null)
return null;
@@ -125,7 +136,8 @@
if (ns != null)
return ns;
- t = TypeManager.LookupType (DeclSpace.MakeFQN
(fullname, name));
+ // We are sure that 'name' is a simple name (no dots).
+ t = TypeManager.LookupTypeDirect (DeclSpace.MakeFQN
(fullname, name));
if ((t == null) || ((ds != null) &&
!ds.CheckAccessLevel (t)))
return null;
Modified: trunk/mcs/mcs/typemanager.cs
===================================================================
--- trunk/mcs/mcs/typemanager.cs 2005-03-02 14:58:49 UTC (rev 41360)
+++ trunk/mcs/mcs/typemanager.cs 2005-03-02 15:31:50 UTC (rev 41361)
@@ -438,6 +438,9 @@
} catch {
HandleDuplicate (name, t);
}
+
+ negative_hits.Remove (t);
+
user_types.Add (t);
}
@@ -740,57 +743,48 @@
// First lookup in user defined and cached values
//
- t = (Type) types [name];
+ t = LookupTypeDirect (name);
if (t != null)
return t;
- // Two thirds of the failures are caught here.
- if (negative_hits.Contains (name))
- return null;
-
- // Sadly, split takes a param array, so this ends up allocating
*EVERY TIME*
string [] elements = name.Split (dot_array);
int count = elements.Length;
- for (int n = 1; n <= count; n++){
- string top_level_type = String.Join (".", elements, 0,
n);
+ if (count == 1)
+ return null;
- // One third of the failures are caught here.
- if (negative_hits.Contains (top_level_type))
- continue;
-
- t = (Type) types [top_level_type];
- if (t == null){
- t = LookupTypeReflection (top_level_type);
- if (t == null){
- negative_hits [top_level_type] = null;
- continue;
- }
- }
-
- if (count == n){
- types [name] = t;
+ string top_level_type = elements [0];
+ int n = 1;
+ for (;;) {
+ t = LookupTypeDirect (top_level_type);
+
+ if (count == n)
return t;
- }
- //
- // We know that System.Object does not have children,
and since its the base of
- // all the objects, it always gets probbed for inner
classes.
- //
- if (top_level_type == "System.Object")
- return null;
-
- string newt = top_level_type + "+" + String.Join ("+",
elements, n, count - n);
- //Console.WriteLine ("Looking up: " + newt + " " +
name);
- t = LookupTypeReflection (newt);
- if (t == null)
- negative_hits [name] = null;
- else
- types [name] = t;
- return t;
+ if (t != null)
+ break;
+
+ top_level_type = top_level_type + "." + elements [n++];
}
- negative_hits [name] = null;
- return null;
+
+ //
+ // We know that System.Object does not have children, and since
its the base of
+ // all the objects, it always gets probed for inner classes.
+ //
+ if (top_level_type == "System.Object")
+ return null;
+
+ string nested_type = top_level_type + "+" + String.Join ("+",
elements, n, count - n);
+ //Console.WriteLine ("Looking up: " + newt + " " + name);
+
+ t = LookupTypeDirect (nested_type);
+
+ // Cache the dotted version of the name too.
+ if (t == null)
+ negative_hits [name] = null;
+ else
+ types [name] = t;
+ return t;
}
/// <summary>
@@ -1268,7 +1262,7 @@
Type [] string_string_string_string = { string_type,
string_type, string_type, string_type };
string_concat_string_string_string_string = GetMethod (
string_type, "Concat", string_string_string_string);
- Type[] params_string = { TypeManager.LookupType
("System.String[]") };
+ Type[] params_string = { TypeManager.LookupTypeDirect
("System.String[]") };
string_concat_string_dot_dot_dot = GetMethod (
string_type, "Concat", params_string);
@@ -1278,7 +1272,7 @@
Type [] object_object_object = { object_type, object_type,
object_type };
string_concat_object_object_object = GetMethod (
string_type, "Concat", object_object_object);
- Type[] params_object = { TypeManager.LookupType
("System.Object[]") };
+ Type[] params_object = { TypeManager.LookupTypeDirect
("System.Object[]") };
string_concat_object_dot_dot_dot = GetMethod (
string_type, "Concat", params_object);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches