From d43ab974ad944444ec9137536f8d1c8f8b497c14 Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Mon, 19 Aug 2002 21:36:33 +0000 Subject: [PATCH] 2002-08-16 Martin Baulig * 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 | 21 +++++++++++ mcs/mcs/class.cs | 15 ++++++-- mcs/mcs/decl.cs | 6 ++++ mcs/mcs/delegate.cs | 5 +++ mcs/mcs/driver.cs | 1 + mcs/mcs/enum.cs | 5 +++ mcs/mcs/interface.cs | 82 +++++++++++++++++++++++++++++++++++++++--- mcs/mcs/rootcontext.cs | 56 ++++++++++++++++++++++++++--- mcs/mcs/typemanager.cs | 57 +++++++++++++---------------- 9 files changed, 203 insertions(+), 45 deletions(-) diff --git a/mcs/mcs/ChangeLog b/mcs/mcs/ChangeLog index e0767adfa88..8f65f65641e 100755 --- a/mcs/mcs/ChangeLog +++ b/mcs/mcs/ChangeLog @@ -1,3 +1,24 @@ +2002-08-16 Martin Baulig + + * 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 * typemanager.cs (MemberCache): When creating the cache for an diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index 6d9aae5212b..11d1b9be24a 100755 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -956,14 +956,14 @@ namespace Mono.CSharp { /// /// Populates our TypeBuilder with fields and methods /// - 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; + } + /// /// This function is based by a delegate to the FindMembers routine /// diff --git a/mcs/mcs/decl.cs b/mcs/mcs/decl.cs index 043e7b9b528..e0da1ccb0ad 100755 --- a/mcs/mcs/decl.cs +++ b/mcs/mcs/decl.cs @@ -351,6 +351,12 @@ namespace Mono.CSharp { /// public abstract TypeBuilder DefineType (); + /// + /// 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. + /// + public abstract bool DefineMembers (TypeContainer parent); + // // Whether this is an `unsafe context' // diff --git a/mcs/mcs/delegate.cs b/mcs/mcs/delegate.cs index d63509e5c3d..94b64d95d4d 100644 --- a/mcs/mcs/delegate.cs +++ b/mcs/mcs/delegate.cs @@ -85,6 +85,11 @@ namespace Mono.CSharp { return TypeBuilder; } + public override bool DefineMembers (TypeContainer container) + { + return true; + } + public override bool Define (TypeContainer container) { MethodAttributes mattr; diff --git a/mcs/mcs/driver.cs b/mcs/mcs/driver.cs index 6b4d6e3e3ec..7f71e0dd0b9 100755 --- a/mcs/mcs/driver.cs +++ b/mcs/mcs/driver.cs @@ -1180,6 +1180,7 @@ namespace Mono.CSharp if (!RootContext.StdLib) RootContext.BootCorlib_PopulateCoreTypes (); RootContext.PopulateTypes (); + RootContext.DefineTypes (); TypeManager.InitCodeHelpers (); diff --git a/mcs/mcs/enum.cs b/mcs/mcs/enum.cs index 4c287d593a6..89d19aa812b 100755 --- a/mcs/mcs/enum.cs +++ b/mcs/mcs/enum.cs @@ -366,6 +366,11 @@ namespace Mono.CSharp { return default_value; } + + public override bool DefineMembers (TypeContainer parent) + { + return true; + } public override bool Define (TypeContainer parent) { diff --git a/mcs/mcs/interface.cs b/mcs/mcs/interface.cs index 6f8b655d4c4..e5b9f80721e 100755 --- a/mcs/mcs/interface.cs +++ b/mcs/mcs/interface.cs @@ -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 { /// /// Interfaces /// - 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 { /// /// Performs semantic analysis, and then generates the IL interfaces /// - 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; + } + + /// + /// Applies all the attributes. + /// + 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 { diff --git a/mcs/mcs/rootcontext.cs b/mcs/mcs/rootcontext.cs index 2fa43966c0c..9d7ac28af78 100755 --- a/mcs/mcs/rootcontext.cs +++ b/mcs/mcs/rootcontext.cs @@ -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 () { // diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs index 48d7738299d..56849f39e66 100755 --- a/mcs/mcs/typemanager.cs +++ b/mcs/mcs/typemanager.cs @@ -167,43 +167,13 @@ public class MemberList : IList { } } -/// -/// This interface provides a cache-based member lookup. -/// -public interface IMemberFinder { - /// - /// 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. - /// - /// - /// When implementing this function, you must manually check for the - /// member name and only call the filter function on members with the - /// requested name. - /// - MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name, - MemberFilter filter, object criteria); - - /// - /// If we have a MemberCache, return it. - /// - MemberCache MemberCache { - get; - } -} - /// /// 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. /// -public interface IMemberContainer : IMemberFinder { +public interface IMemberContainer { /// /// 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. /// MemberList GetMembers (MemberTypes mt, BindingFlags bf); + + /// + /// Return the container's member cache. + /// + 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; } + /// + /// 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. + /// public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name, MemberFilter filter, object criteria) { -- 2.25.1