X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Finterface.cs;h=2c5b939f41e93f6902ef39ac9182bc7e6281993e;hb=f282c09a4f474c0994bf739e0b300043fd342b80;hp=b94dc9caa5cef65050aa7c2e131e74bd0bdf8fd4;hpb=438589918ca842e7e8b837598dd9a22c3d59797d;p=mono.git diff --git a/mcs/mcs/interface.cs b/mcs/mcs/interface.cs index b94dc9caa5c..2c5b939f41e 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,11 @@ namespace Mono.CSharp { public string IndexerName; + IMemberContainer parent_container; + MemberCache member_cache; + + bool members_defined; + // These will happen after the semantic analysis // Hashtable defined_indexers; @@ -225,9 +230,22 @@ namespace Mono.CSharp { 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); @@ -236,7 +254,8 @@ namespace Mono.CSharp { } // Hack around System.Reflection as found everywhere else - public MemberInfo [] 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 (); @@ -259,26 +278,21 @@ namespace Mono.CSharp { } if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) { - MemberInfo [] parent_mi; + MemberList parent_mi; parent_mi = TypeContainer.FindMembers ( TypeBuilder.BaseType, mt, bf, filter, criteria); - if (parent_mi != null) - members.AddRange (parent_mi); + members.AddRange (parent_mi); } - - // The rest of the cases, if any, are unhandled at present. - int count = members.Count; + return new MemberList (members); + } - if (count > 0) { - MemberInfo [] mi = new MemberInfo [count]; - members.CopyTo (mi, 0); - return mi; + public override MemberCache MemberCache { + get { + return member_cache; } - - return null; } // @@ -298,6 +312,9 @@ namespace Mono.CSharp { if (return_type.IsPointer && !UnsafeOK (this)) return; + if (arg_types == null) + return; + foreach (Type t in arg_types){ if (t == null) @@ -349,6 +366,9 @@ namespace Mono.CSharp { 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]; @@ -378,7 +398,7 @@ namespace Mono.CSharp { // Type [] null_types = null; InternalParameters inp = new InternalParameters - (null_types, Parameters.GetEmptyReadOnlyParameters ()); + (null_types, Parameters.EmptyReadOnlyParameters); if (!RegisterMethod (get, inp, null)) { Error111 (ip); @@ -434,6 +454,9 @@ namespace Mono.CSharp { 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) @@ -445,7 +468,7 @@ namespace Mono.CSharp { 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); // @@ -497,6 +520,9 @@ namespace Mono.CSharp { { 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; @@ -640,10 +666,13 @@ namespace Mono.CSharp { Type GetInterfaceTypeByName (string name) { - Type t = FindType (name); + Type t = FindType (Location, name); - if (t == null) + if (t == null) { + Report.Error (246, Location, "The type or namespace `" + name + + "' could not be found"); return null; + } if (t.IsInterface) return t; @@ -755,7 +784,7 @@ namespace Mono.CSharp { TypeManager.AddUserInterface (Name, TypeBuilder, this, ifaces); InTransit = false; - + return TypeBuilder; } @@ -796,7 +825,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,7 +852,28 @@ namespace Mono.CSharp { if (cb != null) 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; + } + + /// + /// Applies all the attributes. + /// + public override bool Define (TypeContainer parent) + { + if (OptAttributes != null) { + EmitContext ec = new EmitContext (parent, this, Location, null, null, + ModFlags, false); + Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location); + } + return true; } @@ -860,6 +910,61 @@ 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) + { + // 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 {