//
// (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, IMemberFinder {
+ public class Interface : DeclSpace, IMemberContainer {
const MethodAttributes interface_method_attributes =
MethodAttributes.Public |
MethodAttributes.Abstract |
public string IndexerName;
+ IMemberContainer parent_container;
+ MemberCache member_cache;
+
+ bool members_defined;
+
// These will happen after the semantic analysis
// Hashtable defined_indexers;
return true;
}
- public MethodInfo [] GetMethods ()
+ //
+ // This might trigger a definition of the methods. This happens only
+ // with Attributes, as Attribute classes are processed before interfaces.
+ // Ideally, we should make everything just define recursively in terms
+ // of its dependencies.
+ //
+ public MethodInfo [] GetMethods (TypeContainer container)
{
- int n = method_builders.Count;
+ int n = 0;
+
+ if (!members_defined){
+ if (DefineMembers (container))
+ n = method_builders.Count;
+ } else
+ n = method_builders.Count;
+
MethodInfo [] mi = new MethodInfo [n];
method_builders.CopyTo (mi, 0);
}
// Hack around System.Reflection as found everywhere else
- public MemberList FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
+ public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+ MemberFilter filter, object criteria)
{
ArrayList members = new ArrayList ();
return new MemberList (members);
}
+ public override MemberCache MemberCache {
+ get {
+ return member_cache;
+ }
+ }
+
//
// Populates the methods in the interface
//
if (return_type.IsPointer && !UnsafeOK (this))
return;
+ if (arg_types == null)
+ return;
+
foreach (Type t in arg_types){
if (t == null)
PropertyBuilder pb;
MethodBuilder get = null, set = null;
ip.Type = this.ResolveTypeExpr (ip.Type, false, ip.Location);
+ if (ip.Type == null)
+ return;
+
Type prop_type = ip.Type.Type;
Type [] setter_args = new Type [1];
MyEventBuilder eb;
MethodBuilder add = null, remove = null;
ie.Type = this.ResolveTypeExpr (ie.Type, false, ie.Location);
+ if (ie.Type == null)
+ return;
+
Type event_type = ie.Type.Type;
if (event_type == null)
Type [] parameters = new Type [1];
parameters [0] = event_type;
- eb = new MyEventBuilder (TypeBuilder, ie.Name,
+ eb = new MyEventBuilder (null, TypeBuilder, ie.Name,
EventAttributes.None, event_type);
//
{
PropertyBuilder pb;
ii.Type = this.ResolveTypeExpr (ii.Type, false, ii.Location);
+ if (ii.Type == null)
+ return;
+
Type prop_type = ii.Type.Type;
Type [] arg_types = ii.ParameterTypes (this);
Type [] value_arg_types;
Type GetInterfaceTypeByName (string name)
{
- Type t = FindType (name);
+ Type t = FindType (Location, name);
if (t == null) {
Report.Error (246, Location, "The type or namespace `" + name +
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
+ members_defined = true;
+ 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)
+ {
+ // Interfaces only contain instance members.
+ 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 {