2002-08-16 Martin Baulig <martin@gnome.org>
authorMartin Baulig <martin@novell.com>
Mon, 19 Aug 2002 21:36:33 +0000 (21:36 -0000)
committerMartin Baulig <martin@novell.com>
Mon, 19 Aug 2002 21:36:33 +0000 (21:36 -0000)
* decl.cs (DeclSpace.Define): Splitted this in Define and
DefineMembers.  DefineMembers is called first and initializes the
MemberCache.

* rootcontext.cs (RootContext.DefineMembers): New function.  Calls
DefineMembers() on all our DeclSpaces.

* class.cs (TypeContainer.Define): Moved all code to DefineMembers(),
but call DefineMembers() on all nested interfaces.  We call their
Define() in our new Define() function.

* interface.cs (Interface): Implement IMemberContainer.
(Interface.Define): Moved all code except the attribute stuf to
DefineMembers().
(Interface.DefineMembers): Initialize the member cache.

* typemanager.cs (IMemberFinder): Removed this interface, we don't
need this anymore since we can use MemberCache.FindMembers directly.

svn path=/trunk/mcs/; revision=6764

mcs/mcs/ChangeLog
mcs/mcs/class.cs
mcs/mcs/decl.cs
mcs/mcs/delegate.cs
mcs/mcs/driver.cs
mcs/mcs/enum.cs
mcs/mcs/interface.cs
mcs/mcs/rootcontext.cs
mcs/mcs/typemanager.cs

index e0767adfa885dab1d38c3dc99239216fb9525eef..8f65f65641e4e2e92a47920ff0439ae07c4bbbd1 100755 (executable)
@@ -1,3 +1,24 @@
+2002-08-16  Martin Baulig  <martin@gnome.org>
+
+       * decl.cs (DeclSpace.Define): Splitted this in Define and
+       DefineMembers.  DefineMembers is called first and initializes the
+       MemberCache.
+
+       * rootcontext.cs (RootContext.DefineMembers): New function.  Calls
+       DefineMembers() on all our DeclSpaces.
+
+       * class.cs (TypeContainer.Define): Moved all code to DefineMembers(),
+       but call DefineMembers() on all nested interfaces.  We call their
+       Define() in our new Define() function.
+
+       * interface.cs (Interface): Implement IMemberContainer.
+       (Interface.Define): Moved all code except the attribute stuf to
+       DefineMembers().
+       (Interface.DefineMembers): Initialize the member cache.
+
+       * typemanager.cs (IMemberFinder): Removed this interface, we don't
+       need this anymore since we can use MemberCache.FindMembers directly.
+
 2002-08-19  Martin Baulig  <martin@gnome.org>
 
        * typemanager.cs (MemberCache): When creating the cache for an
index 6d9aae5212bef47be790bb1765bb243e900d32c9..11d1b9be24a0a75746342c0c201dfe0186bebf01 100755 (executable)
@@ -956,14 +956,14 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Populates our TypeBuilder with fields and methods
                /// </summary>
-               public override bool Define (TypeContainer parent)
+               public override bool DefineMembers (TypeContainer parent)
                {
                        MemberInfo [] defined_names = null;
 
                        if (interface_order != null){
                                foreach (Interface iface in interface_order)
                                        if ((iface.ModFlags & Modifiers.NEW) == 0)
-                                               iface.Define (this);
+                                               iface.DefineMembers (this);
                                        else
                                                Report1530 (iface.Location);
                        }
@@ -1053,6 +1053,17 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public override bool Define (TypeContainer parent)
+               {
+                       if (interface_order != null){
+                               foreach (Interface iface in interface_order)
+                                       if ((iface.ModFlags & Modifiers.NEW) == 0)
+                                               iface.Define (this);
+                       }
+
+                       return true;
+               }
+
                /// <summary>
                ///   This function is based by a delegate to the FindMembers routine
                /// </summary>
index 043e7b9b52882617ccfc2362f9e020127169aa0d..e0da1ccb0ad37fcef415e320a8595da88678a592 100755 (executable)
@@ -351,6 +351,12 @@ namespace Mono.CSharp {
                /// <remarks>
                public abstract TypeBuilder DefineType ();
                
+               /// <summary>
+               ///   Define all members, but don't apply any attributes or do anything which may
+               ///   access not-yet-defined classes.  This method also creates the MemberCache.
+               /// </summary>
+               public abstract bool DefineMembers (TypeContainer parent);
+
                //
                // Whether this is an `unsafe context'
                //
index d63509e5c3d7638addab061a08c1844e59381ab0..94b64d95d4dfd16c527b7ff49626bda1642db65a 100644 (file)
@@ -85,6 +85,11 @@ namespace Mono.CSharp {
                        return TypeBuilder;\r
                }\r
 \r
+               public override bool DefineMembers (TypeContainer container)\r
+               {\r
+                       return true;\r
+               }\r
+\r
                public override bool Define (TypeContainer container)\r
                {\r
                        MethodAttributes mattr;\r
index 6b4d6e3e3ec3f8b0cbcb210d30c7020e1d96ecd1..7f71e0dd0b96d41fd5240cdb5cbfbb9eb6f70c4f 100755 (executable)
@@ -1180,6 +1180,7 @@ namespace Mono.CSharp
                        if (!RootContext.StdLib)
                                RootContext.BootCorlib_PopulateCoreTypes ();
                        RootContext.PopulateTypes ();
+                       RootContext.DefineTypes ();
                        
                        TypeManager.InitCodeHelpers ();
                                
index 4c287d593a667f1bb2cbe12ef138800c7d4c8cd7..89d19aa812b7d08da98f3874ee9c49eebc705a48 100755 (executable)
@@ -366,6 +366,11 @@ namespace Mono.CSharp {
                        
                        return default_value;
                }
+
+               public override bool DefineMembers (TypeContainer parent)
+               {
+                       return true;
+               }
                
                public override bool Define (TypeContainer parent)
                {
index 6f8b655d4c447ee3bfc6245b92acfa24062de1ac..e5b9f80721e1f05a0fe646df69cb85bb3b3d4dda 100755 (executable)
@@ -7,7 +7,7 @@
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
 //
-
+#define CACHE
 using System.Collections;
 using System;
 using System.IO;
@@ -19,7 +19,7 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Interfaces
        /// </summary>
-       public class Interface : DeclSpace {
+       public class Interface : DeclSpace, IMemberContainer {
                const MethodAttributes interface_method_attributes =
                        MethodAttributes.Public |
                        MethodAttributes.Abstract |
@@ -50,6 +50,9 @@ namespace Mono.CSharp {
 
                public string IndexerName;
 
+               IMemberContainer parent_container;
+               MemberCache member_cache;
+
                // These will happen after the semantic analysis
                
                // Hashtable defined_indexers;
@@ -273,7 +276,7 @@ namespace Mono.CSharp {
 
                public override MemberCache MemberCache {
                        get {
-                               return null;
+                               return member_cache;
                        }
                }
 
@@ -754,7 +757,7 @@ namespace Mono.CSharp {
 
                        TypeManager.AddUserInterface (Name, TypeBuilder, this, ifaces);
                        InTransit = false;
-                       
+
                        return TypeBuilder;
                }
 
@@ -795,7 +798,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Performs semantic analysis, and then generates the IL interfaces
                /// </summary>
-               public override bool Define (TypeContainer parent)
+               public override bool DefineMembers (TypeContainer parent)
                {
                        if (!SemanticAnalysis ())
                                return false;
@@ -823,6 +826,21 @@ namespace Mono.CSharp {
                                        TypeBuilder.SetCustomAttribute (cb);
                        }
 
+#if CACHE
+                       if (TypeBuilder.BaseType != null)
+                               parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
+
+                       member_cache = new MemberCache (this);
+#endif
+
+                       return true;
+               }
+
+               /// <summary>
+               ///   Applies all the attributes.
+               /// </summary>
+               public override bool Define (TypeContainer parent)
+               {
                        if (OptAttributes != null) {
                                EmitContext ec = new EmitContext (parent, this, Location, null, null,
                                                                  ModFlags, false);
@@ -865,6 +883,60 @@ namespace Mono.CSharp {
                        return cb;
                }
 
+               //
+               // IMemberContainer
+               //
+
+               string IMemberContainer.Name {
+                       get {
+                               return Name;
+                       }
+               }
+
+               Type IMemberContainer.Type {
+                       get {
+                               return TypeBuilder;
+                       }
+               }
+
+               IMemberContainer IMemberContainer.Parent {
+                       get {
+                               return parent_container;
+                       }
+               }
+
+               MemberCache IMemberContainer.MemberCache {
+                       get {
+                               return member_cache;
+                       }
+               }
+
+               bool IMemberContainer.IsInterface {
+                       get {
+                               return true;
+                       }
+               }
+
+               MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
+               {
+                       if ((bf & BindingFlags.Instance) == 0)
+                               return MemberList.Empty;
+                       if ((bf & BindingFlags.Public) == 0)
+                               return MemberList.Empty;
+
+                       ArrayList members = new ArrayList ();
+
+                       if ((mt & MemberTypes.Method) != 0)
+                               members.AddRange (method_builders);
+
+                       if ((mt & MemberTypes.Property) != 0)
+                               members.AddRange (property_builders);
+
+                       if ((mt & MemberTypes.Event) != 0)
+                               members.AddRange (event_builders);
+
+                       return new MemberList (members);
+               }
        }
 
        public class InterfaceMemberBase {
index 2fa43966c0c6ee42cb265970d9be3e82c6aabcfa..9d7ac28af7885c0bd3a9428d6e2461e1a5a543b4 100755 (executable)
@@ -602,6 +602,7 @@ namespace Mono.CSharp {
                {
                        DeclSpace ds = (DeclSpace) root.GetDefinition (name);
 
+                       ds.DefineMembers (root);
                        ds.Define (root);
                }
                
@@ -626,12 +627,12 @@ namespace Mono.CSharp {
 
                        if (attribute_types != null)
                                foreach (TypeContainer tc in attribute_types)
-                                       tc.Define (root);
+                                       tc.DefineMembers (root);
                        
                        if (interface_resolve_order != null){
                                foreach (Interface iface in interface_resolve_order)
                                        if ((iface.ModFlags & Modifiers.NEW) == 0)
-                                               iface.Define (root);
+                                               iface.DefineMembers (root);
                                        else
                                                Report1530 (iface.Location);
                        }
@@ -648,7 +649,7 @@ namespace Mono.CSharp {
                                                continue;
 
                                        if ((tc.ModFlags & Modifiers.NEW) == 0)
-                                               tc.Define (root);
+                                               tc.DefineMembers (root);
                                        else
                                                Report1530 (tc.Location);
                                }
@@ -658,7 +659,7 @@ namespace Mono.CSharp {
                        if (delegates != null){
                                foreach (Delegate d in delegates)
                                        if ((d.ModFlags & Modifiers.NEW) == 0)
-                                               d.Define (root);
+                                               d.DefineMembers (root);
                                        else
                                                Report1530 (d.Location);
                        }
@@ -667,12 +668,57 @@ namespace Mono.CSharp {
                        if (enums != null){
                                foreach (Enum en in enums)
                                        if ((en.ModFlags & Modifiers.NEW) == 0)
-                                               en.Define (root);
+                                               en.DefineMembers (root);
                                        else
                                                Report1530 (en.Location);
                        }
                }
 
+               static public void DefineTypes ()
+               {
+                       TypeContainer root = Tree.Types;
+
+                       if (attribute_types != null)
+                               foreach (TypeContainer tc in attribute_types)
+                                       tc.Define (root);
+                       
+                       if (interface_resolve_order != null){
+                               foreach (Interface iface in interface_resolve_order)
+                                       if ((iface.ModFlags & Modifiers.NEW) == 0)
+                                               iface.Define (root);
+                       }
+
+
+                       if (type_container_resolve_order != null){
+                               foreach (TypeContainer tc in type_container_resolve_order) {
+                                       // When compiling corlib, these types have already been
+                                       // populated from BootCorlib_PopulateCoreTypes ().
+                                       if (!RootContext.StdLib &&
+                                           ((tc.Name == "System.Object") ||
+                                            (tc.Name == "System.Attribute") ||
+                                            (tc.Name == "System.ValueType")))
+                                               continue;
+
+                                       if ((tc.ModFlags & Modifiers.NEW) == 0)
+                                               tc.Define (root);
+                               }
+                       }
+
+                       ArrayList delegates = root.Delegates;
+                       if (delegates != null){
+                               foreach (Delegate d in delegates)
+                                       if ((d.ModFlags & Modifiers.NEW) == 0)
+                                               d.Define (root);
+                       }
+
+                       ArrayList enums = root.Enums;
+                       if (enums != null){
+                               foreach (Enum en in enums)
+                                       if ((en.ModFlags & Modifiers.NEW) == 0)
+                                               en.Define (root);
+                       }
+               }
+
                static public void EmitCode ()
                {
                        //
index 48d7738299df8e57dc372b560b5accb18565f523..56849f39e662900f862325cc0d3af2e4f8ce1338 100755 (executable)
@@ -167,43 +167,13 @@ public class MemberList : IList {
        }
 }
 
-/// <summary>
-///   This interface provides a cache-based member lookup.     
-/// </summary> 
-public interface IMemberFinder {
-       /// <summary>
-       ///   Looks up members with name `name'.  If you provide an optional
-       ///   filter function, it'll only be called with members matching the
-       ///   requested member name.
-       ///
-       ///   This method will try to use the cache to do the lookup if possible.
-       ///
-       ///   Unlike other FindMembers implementations, this method will always
-       ///   check all inherited members - even when called on an interface type.
-       /// </summary>
-       /// <remarks>
-       ///   When implementing this function, you must manually check for the
-       ///   member name and only call the filter function on members with the
-       ///   requested name.
-       /// </remarks>
-       MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
-                               MemberFilter filter, object criteria);
-
-       /// <summary>
-       ///   If we have a MemberCache, return it.
-       /// </summary>
-       MemberCache MemberCache {
-               get;
-       }
-}
-
 /// <summary>
 ///   This interface is used to get all members of a class when creating the
 ///   member cache.  It must be implemented by all DeclSpace derivatives which
 ///   want to support the member cache and by TypeHandle to get caching of
 ///   non-dynamic types.
 /// </summary>
-public interface IMemberContainer : IMemberFinder {
+public interface IMemberContainer {
        /// <summary>
        ///   The name of the IMemberContainer.  This is only used for
        ///   debugging purposes.
@@ -249,6 +219,13 @@ public interface IMemberContainer : IMemberFinder {
        ///   this method is called multiple times with different BindingFlags.
        /// </remarks>
        MemberList GetMembers (MemberTypes mt, BindingFlags bf);
+
+       /// <summary>
+       ///   Return the container's member cache.
+       /// </summary>
+       MemberCache MemberCache {
+               get;
+       }
 }
 
 public class TypeManager {
@@ -1178,6 +1155,10 @@ public class TypeManager {
                        DeclSpace decl = (DeclSpace) builder_to_declspace [t];
                        MemberCache cache = decl.MemberCache;
 
+                       //
+                       // If this DeclSpace has a MemberCache, use it.
+                       //
+
                        if (cache != null) {
                                used_cache = true;
                                return cache.FindMembers (
@@ -1200,10 +1181,10 @@ public class TypeManager {
                // type, TypeHandle.GetTypeHandle() will either return it or create a new one
                // if it didn't already exist.
                //
-               IMemberFinder finder = TypeHandle.GetTypeHandle (t);
+               TypeHandle handle = TypeHandle.GetTypeHandle (t);
 
                used_cache = true;
-               return finder.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
+               return handle.MemberCache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
        }
 
        public static bool IsBuiltinType (Type t)
@@ -2598,6 +2579,16 @@ public class MemberCache {
                return false;
        }
 
+       /// <summary>
+       ///   Looks up members with name `name'.  If you provide an optional
+       ///   filter function, it'll only be called with members matching the
+       ///   requested member name.
+       ///
+       ///   This method will try to use the cache to do the lookup if possible.
+       ///
+       ///   Unlike other FindMembers implementations, this method will always
+       ///   check all inherited members - even when called on an interface type.
+       /// </summary>
        public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
                                       MemberFilter filter, object criteria)
        {