+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
/// <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);
}
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>
/// <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'
//
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
if (!RootContext.StdLib)
RootContext.BootCorlib_PopulateCoreTypes ();
RootContext.PopulateTypes ();
+ RootContext.DefineTypes ();
TypeManager.InitCodeHelpers ();
return default_value;
}
+
+ public override bool DefineMembers (TypeContainer parent)
+ {
+ return true;
+ }
public override bool Define (TypeContainer parent)
{
//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
//
-
+#define CACHE
using System.Collections;
using System;
using System.IO;
/// <summary>
/// Interfaces
/// </summary>
- public class Interface : DeclSpace {
+ public class Interface : DeclSpace, IMemberContainer {
const MethodAttributes interface_method_attributes =
MethodAttributes.Public |
MethodAttributes.Abstract |
public string IndexerName;
+ IMemberContainer parent_container;
+ MemberCache member_cache;
+
// These will happen after the semantic analysis
// Hashtable defined_indexers;
public override MemberCache MemberCache {
get {
- return null;
+ return member_cache;
}
}
TypeManager.AddUserInterface (Name, TypeBuilder, this, ifaces);
InTransit = false;
-
+
return TypeBuilder;
}
/// <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;
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);
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 {
{
DeclSpace ds = (DeclSpace) root.GetDefinition (name);
+ ds.DefineMembers (root);
ds.Define (root);
}
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);
}
continue;
if ((tc.ModFlags & Modifiers.NEW) == 0)
- tc.Define (root);
+ tc.DefineMembers (root);
else
Report1530 (tc.Location);
}
if (delegates != null){
foreach (Delegate d in delegates)
if ((d.ModFlags & Modifiers.NEW) == 0)
- d.Define (root);
+ d.DefineMembers (root);
else
Report1530 (d.Location);
}
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 ()
{
//
}
}
-/// <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.
/// 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 {
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 (
// 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)
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)
{