X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fclass.cs;h=f05f3c0a3235859642fd452eaf38bc6387246957;hb=985fca6fd28bd88ca224ddefcf76a819e1359b41;hp=131f29a43b7a6dfcba100ad3c4ed41aa6804fa46;hpb=2680ce338548529160f8d391d9cfe41bd7d85f60;p=mono.git diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index 131f29a43b7..f05f3c0a323 100755 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -7,30 +7,76 @@ // // (C) 2001 Ximian, Inc (http://www.ximian.com) // -// TODO: -// -// a. Maybe keep a list of defined names in the order they -// appeared, so we can walk things in this way to present -// the users with errors in that order? // using System.Collections; +using System.Reflection; +using System.Reflection.Emit; using System; namespace CIR { public class TypeContainer : DeclSpace { protected int mod_flags; - Hashtable types, fields, properties; - Hashtable enums, constants, interfaces, method_groups; - ArrayList constructor_list; + // Holds a list of classes and structures + ArrayList types; + + // Holds the list of properties + ArrayList properties; + + // Holds the list of enumerations + ArrayList enums; + + // Holds the list of delegates + ArrayList delegates; + + // Holds the list of constructors + ArrayList constructors; + + // Holds the list of fields + ArrayList fields; + + // Holds a list of fields that have initializers + ArrayList initialized_fields; + // Holds a list of static fields that have initializers + ArrayList initialized_static_fields; + + // Holds the list of constants + ArrayList constants; + + // Holds the list of + ArrayList interfaces; + + // Holds the methods. + ArrayList methods; + + // Holds the events + ArrayList events; + + // Holds the indexers + ArrayList indexers; + + // Holds the operators + ArrayList operators; + + // + // Pointers to the default constructor and the default static constructor + // + Constructor default_constructor; + Constructor default_static_constructor; + + // + // Whether we have seen a static constructor for this class or not + // + bool have_static_constructor = false; + // // This is the namespace in which this typecontainer // was declared. We use this to resolve names. // - CSC.Namespace my_namespace; + Namespace my_namespace; // // This one is computed after we can distinguish interfaces @@ -41,12 +87,23 @@ namespace CIR { TypeContainer parent; ArrayList type_bases; - public TypeContainer (TypeContainer parent, string name) : base (name) + // + // This behaves like a property ;-) + // + public readonly RootContext RootContext; + + // Attributes for this type + protected Attributes attributes; + + public TypeContainer (RootContext rc, TypeContainer parent, string name) : base (name) { - types = new Hashtable (); + string n; + types = new ArrayList (); this.parent = parent; + RootContext = rc; - string n; + object a = rc.Report; + if (parent == null) n = ""; else @@ -66,9 +123,9 @@ namespace CIR { return res; if (constants == null) - constants = new Hashtable (); + constants = new ArrayList (); - constants.Add (name, constant); + constants.Add (constant); DefineName (name, constant); return AdditionResult.Success; @@ -83,9 +140,9 @@ namespace CIR { return res; if (enums == null) - enums = new Hashtable (); + enums = new ArrayList (); - enums.Add (name, e); + enums.Add (e); DefineName (name, e); return AdditionResult.Success; @@ -101,7 +158,7 @@ namespace CIR { return res; DefineName (name, c); - types.Add (name, c); + types.Add (c); return AdditionResult.Success; } @@ -115,7 +172,24 @@ namespace CIR { return res; DefineName (name, s); - types.Add (name, s); + types.Add (s); + + return AdditionResult.Success; + } + + public AdditionResult AddDelegate (Delegate d) + { + AdditionResult res; + string name = d.Name; + + if ((res = IsValid (name)) != AdditionResult.Success) + return res; + + if (delegates == null) + delegates = new ArrayList (); + + DefineName (name, d); + delegates.Add (d); return AdditionResult.Success; } @@ -125,26 +199,15 @@ namespace CIR { string name = method.Name; Object value = defined_names [name]; - if (value != null && (!(value is MethodGroup))) + if (value != null && (!(value is Method))) return AdditionResult.NameExists; - if (method_groups == null) - method_groups = new Hashtable (); - - MethodGroup mg = (MethodGroup) method_groups [name]; - if (mg == null){ - mg = new MethodGroup (name); - - mg.Add (method); - method_groups.Add (name, mg); + if (methods == null) + methods = new ArrayList (); - return AdditionResult.Success; - } - mg.Add (method); + methods.Add (method); + DefineName (name, method); - if (value == null) - DefineName (name, mg); - return AdditionResult.Success; } @@ -153,10 +216,22 @@ namespace CIR { if (c.Name != Basename) return AdditionResult.NotAConstructor; - if (constructor_list == null) - constructor_list = new ArrayList (); + if (constructors == null) + constructors = new ArrayList (); - constructor_list.Add (c); + constructors.Add (c); + + bool is_static = (c.ModFlags & Modifiers.STATIC) != 0; + + if (is_static) + have_static_constructor = true; + + if (c.IsDefault ()){ + if (is_static) + default_static_constructor = c; + else + default_constructor = c; + } return AdditionResult.Success; } @@ -170,8 +245,8 @@ namespace CIR { return res; if (interfaces == null) - interfaces = new Hashtable (); - interfaces.Add (name, iface); + interfaces = new ArrayList (); + interfaces.Add (iface); DefineName (name, iface); return AdditionResult.Success; @@ -186,9 +261,29 @@ namespace CIR { return res; if (fields == null) - fields = new Hashtable (); - - fields.Add (name, field); + fields = new ArrayList (); + + fields.Add (field); + if (field.Initializer != null){ + if ((field.ModFlags & Modifiers.STATIC) != 0){ + if (initialized_static_fields == null) + initialized_static_fields = new ArrayList (); + + initialized_static_fields.Add (field); + + // + // We have not seen a static constructor, + // but we will provide static initialization of fields + // + have_static_constructor = true; + } else { + if (initialized_fields == null) + initialized_fields = new ArrayList (); + + initialized_fields.Add (field); + } + } + DefineName (name, field); return AdditionResult.Success; } @@ -202,16 +297,49 @@ namespace CIR { return res; if (properties == null) - properties = new Hashtable (); + properties = new ArrayList (); - properties.Add (name, prop); + properties.Add (prop); DefineName (name, prop); return AdditionResult.Success; } - - public Constant GetConstant (string name) { - return (Constant) constants [name]; + + public AdditionResult AddEvent (Event e) + { + AdditionResult res; + string name = e.Name; + + if ((res = IsValid (name)) != AdditionResult.Success) + return res; + + if (events == null) + events = new ArrayList (); + + events.Add (e); + DefineName (name, e); + + return AdditionResult.Success; + } + + public AdditionResult AddIndexer (Indexer i) + { + if (indexers == null) + indexers = new ArrayList (); + + indexers.Add (i); + + return AdditionResult.Success; + } + + public AdditionResult AddOperator (Operator op) + { + if (operators == null) + operators = new ArrayList (); + + operators.Add (op); + + return AdditionResult.Success; } public TypeContainer Parent { @@ -220,25 +348,25 @@ namespace CIR { } } - public Hashtable Types { + public ArrayList Types { get { return types; } } - public Hashtable MethodGroups { + public ArrayList Methods { get { - return method_groups; + return methods; } } - public Hashtable Constants { + public ArrayList Constants { get { return constants; } } - public Hashtable Interfaces { + public ArrayList Interfaces { get { return interfaces; } @@ -266,31 +394,61 @@ namespace CIR { } } - public Hashtable Fields { + public ArrayList Fields { get { return fields; } } - public Hashtable Constructors { + public ArrayList Constructors { get { - return null; // constructors; + return constructors; } } - public Hashtable Properties { + public ArrayList Properties { get { return properties; } } - public Hashtable Enums { + public ArrayList Events { + get { + return events; + } + } + + public ArrayList Enums { get { return enums; } } - public CSC.Namespace Namespace { + public ArrayList Indexers { + get { + return indexers; + } + } + + public ArrayList Operators { + get { + return operators; + } + } + + public ArrayList Delegates { + get { + return delegates; + } + } + + public Attributes OptAttributes { + get { + return attributes; + } + } + + public Namespace Namespace { get { return my_namespace; } @@ -299,148 +457,297 @@ namespace CIR { my_namespace = value; } } - - public int ResolveParents (Tree root) - { - if (Bases == null){ - base_class_name = "System.Object"; - return 0; + + // + // The Toplevel is `root_types' which is a containerfor all + // types defined, hence the non-obviios parent.parent. + // + // If we were not tracking Namespaces we could remove this. + // + bool IsTopLevel { + get { + if (parent != null){ + if (parent.parent == null) + return true; + } + + return false; } - - if (type_bases.Count == 0){ - base_class_name = "System.Object"; - return 0; + } + + // + // Returns the TypeAttributes for this TypeContainer + // + public virtual TypeAttributes TypeAttr { + get { + TypeAttributes x = 0; + + // + // FIXME: Figure out exactly how private, public and protected + // map to the TypeAttribute flags. + // + // FIXME: Figure out what `new' in the context of a class/struct means. + // + // FIXME: figure out what `internal' means in the context of class/structs + // + if ((mod_flags & Modifiers.PUBLIC) != 0) + x |= TypeAttributes.Public; + + if ((mod_flags & Modifiers.PRIVATE) != 0) + x |= TypeAttributes.NotPublic; + + if ((mod_flags & Modifiers.ABSTRACT) != 0) + x |= TypeAttributes.Abstract; + + if ((mod_flags & Modifiers.SEALED) != 0) + x |= TypeAttributes.Sealed; + + if (!IsTopLevel){ + if ((mod_flags & Modifiers.PUBLIC) != 0) + x |= TypeAttributes.NestedPublic; + else + x |= TypeAttributes.NestedPrivate; + } + + // + // If we have static constructors, the runtime needs to + // initialize the class, otherwise we can optimize + // the case. + // + if (!have_static_constructor) + x |= TypeAttributes.BeforeFieldInit; + return x; } + } + + void EmitField (Field f) + { + Type t = LookupType (f.Type, false); + + if (t == null) + return; - return 0; + TypeBuilder.DefineField (f.Name, t, Modifiers.FieldAttr (f.ModFlags)); } - override public Type Define (Tree tree) + // + // Emits the class field initializers + // + void EmitStaticFieldInitializers (ConstructorBuilder cb) { - return null; + // FIXME: Implement } - - public delegate void VisitContainer (TypeContainer container, object cback_data); - void VisitTypesAt (TypeContainer root, VisitContainer visit, object cback) + // + // Emits the instance field initializers + // + void EmitFieldInitializers (ConstructorBuilder cb) { - if (root == null) - return; - - foreach (DictionaryEntry de in root.Types){ - TypeContainer type = (TypeContainer) de.Value; + // FIXME: Implement + } - visit (type, cback); - VisitTypesAt (type, visit, cback); + // + // Emits a constructor + // + void EmitConstructor (Constructor c) + { + if ((c.ModFlags & Modifiers.STATIC) != 0){ + if (initialized_static_fields != null) + EmitStaticFieldInitializers (c.ConstructorBuilder); + } else { + if (initialized_fields != null) + EmitFieldInitializers (c.ConstructorBuilder); } + } - // - // Use this method to visit all the types in a type container. - // You can use cback to pass arbitrary data to your callback. - // - public void VisitTypes (VisitContainer visit, object cback) + // + // This function is used to emit instance and static constructors + // when the user did not provide one. + // + void EmitDefaultConstructor (bool is_static) { - foreach (DictionaryEntry de in types){ - TypeContainer type = (TypeContainer) de.Value; + ConstructorBuilder cb; + MethodAttributes ca = (MethodAttributes.RTSpecialName | + MethodAttributes.SpecialName); - VisitTypesAt (type, visit, cback); - } + if (is_static) + ca |= MethodAttributes.Static; - } + // + // Default constructors provided by the compiler should be `protected' + // if the class is abstract, otherwise it is public + // + if ((mod_flags & Modifiers.ABSTRACT) != 0) + ca |= MethodAttributes.Family; + else + ca |= MethodAttributes.Public; + + cb = TypeBuilder.DefineDefaultConstructor (ca); - internal class VisitExpressions_Lambda { - VisitExpressionRoot vb; - object user_data; + if (is_static) + EmitStaticFieldInitializers (cb); + else + EmitFieldInitializers (cb); + } - void walk_arguments (ArrayList args) - { - if (args == null) - return; - - int top = args.Count; + // + // Populates our TypeBuilder with fields and methods + // + public void Populate () + { + if (Constants != null){ + foreach (Constant c in Constants) + c.EmitConstant (RootContext, this); + } - for (int i = 0; i < top; i++){ - Argument arg = (Argument) args [i]; + if (Fields != null){ + foreach (Field f in Fields) + EmitField (f); + } - vb (arg.Expr, user_data); - } + if (Constructors != null){ + foreach (Constructor c in Constructors) + c.Define (this); } - void walk_block (Block b) - { + if (Methods != null){ + foreach (Method m in Methods) + m.Define (this); } - - void walk_constructor (Constructor c) - { - ConstructorInitializer init = c.Initializer; - - if (init != null && init.Arguments != null) - walk_arguments (init.Arguments); - walk_block (c.Block); + if (Properties != null) { + foreach (Property p in Properties) + p.Define (this); } - void walk_properties (Property p) - { + if (Enums != null) { + foreach (Enum e in Enums) + e.Define (this); } - void walk_method (Method m) - { + if (Events != null) { + foreach (Event e in Events) + e.Define (this); } - - void type_walker_1 (TypeContainer type, object cback) - { - if (type.Fields != null){ - foreach (DictionaryEntry de in type.Fields){ - Field f = (Field) de.Value; - - if (f.Initializer != null){ - if (f.Initializer is Expression) - vb ((Expression) f.Initializer, user_data); - } - } - } - if (type.Constructors != null){ - foreach (DictionaryEntry de in type.Constructors) - walk_constructor ((Constructor) de.Value); - } + if (Indexers != null) { + foreach (Indexer i in Indexers) + i.Define (this); + } - if (type.Properties != null){ - foreach (DictionaryEntry de in type.Properties) - walk_properties ((Property) de.Value); - } + if (Operators != null) { + foreach (Operator o in Operators) + o.Define (this); + } - if (type.MethodGroups != null){ - foreach (DictionaryEntry de in type.MethodGroups){ - Hashtable methods = ((MethodGroup) de.Value).Methods; - foreach (Method m in methods) - walk_method (m); - } - } + if (Delegates != null) { + foreach (Delegate d in Delegates) + d.Define (this); } + + + } + + // + // Emits the code, this step is performed after all + // the types, enumerations, constructors + // + public void Emit () + { + if (default_constructor == null) + EmitDefaultConstructor (false); + + if (initialized_static_fields != null && default_static_constructor == null) + EmitDefaultConstructor (true); + if (Constructors != null) + foreach (Constructor c in Constructors) + c.Emit (); - internal VisitExpressions_Lambda (TypeContainer tc, - VisitExpressionRoot vb, - object user_data) - { - this.vb = vb; - this.user_data = user_data; + if (Methods != null) + foreach (Method m in Methods) + m.Emit (this); + } + + public delegate void ExamineType (TypeContainer container, object cback_data); + + void WalkTypesAt (TypeContainer root, ExamineType visit, object cback_data) + { + if (root == null) + return; - tc.VisitTypes (new VisitContainer (type_walker_1), null); + foreach (TypeContainer type in root.Types){ + visit (type, cback_data); + WalkTypesAt (type, visit, cback_data); } } - - public delegate void VisitExpressionRoot (Expression e, object cback); + + public void WalkTypes (ExamineType visit, object cback) + { + WalkTypesAt (this, visit, cback); + } + + public Type LookupType (string name, bool silent) + { + return RootContext.LookupType (this, name, silent); + } + // - // Use this method to visit all the code blocks in a TypeContainer + // This method returns the members of this type just like Type.FindMembers would + // Only, we need to use this for types which are _being_ defined because MS' brain + // dead implementation can't take care of that ;-) // - public void VisitExpressionRoots (VisitExpressionRoot vb, object cback) + public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria) { - VisitExpressions_Lambda l = new VisitExpressions_Lambda (this, vb, cback); + // FIXME : Need to actually take care of all the various + // arguments being passed in but for now, we only bother with + // the MemberTypes and criteria arguments. + + switch (mt) { + + case MemberTypes.All: + + break; + + case MemberTypes.Constructor: + + break; + + case MemberTypes.Custom: + + break; + + case MemberTypes.Event: + + break; + + case MemberTypes.Field: + + break; + + case MemberTypes.Method: + + break; + + case MemberTypes.NestedType: + + break; + + case MemberTypes.Property: + + break; + + case MemberTypes.TypeInfo: + + break; + + } + + return null; + } + } public class Class : TypeContainer { @@ -456,8 +763,8 @@ namespace CIR { Modifiers.ABSTRACT | Modifiers.SEALED; - public Class (TypeContainer parent, string name, int mod) - : base (parent, name) + public Class (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs) + : base (rc, parent, name) { int accmods; @@ -467,6 +774,17 @@ namespace CIR { accmods = Modifiers.PRIVATE; this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods); + this.attributes = attrs; + } + + // + // FIXME: How do we deal with the user specifying a different + // layout? + // + public override TypeAttributes TypeAttr { + get { + return base.TypeAttr | TypeAttributes.AutoLayout; + } } } @@ -481,8 +799,8 @@ namespace CIR { Modifiers.INTERNAL | Modifiers.PRIVATE; - public Struct (TypeContainer parent, string name, int mod) - : base (parent, name) + public Struct (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs) + : base (rc, parent, name) { int accmods; @@ -492,23 +810,45 @@ namespace CIR { accmods = Modifiers.PRIVATE; this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods); + + this.mod_flags |= Modifiers.SEALED; + this.attributes = attrs; + + } + + // + // FIXME: Allow the user to specify a different set of attributes + // in some cases (Sealed for example is mandatory for a class, + // but what SequentialLayout can be changed + // + public override TypeAttributes TypeAttr { + get { + return base.TypeAttr | + TypeAttributes.SequentialLayout | + TypeAttributes.Sealed | + TypeAttributes.BeforeFieldInit; + } } } public class Method { - Parameters parameters; - TypeRef return_typeref; - string name; - int modifiers; - Block block; - + public readonly Parameters Parameters; + public readonly string ReturnType; + public readonly string Name; + public readonly int ModFlags; + public MethodBuilder MethodBuilder; + public readonly Attributes OptAttributes; + + Block block; + // return_type can be "null" for VOID values. - public Method (TypeRef return_typeref, int mod, string name, Parameters parameters) + public Method (string return_type, int mod, string name, Parameters parameters, Attributes attrs) { - this.return_typeref = return_typeref; - this.name = name; - this.parameters = parameters; - this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE); + Name = name; + ReturnType = return_type; + Parameters = parameters; + ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE); + OptAttributes = attrs; } // @@ -537,42 +877,110 @@ namespace CIR { } } - public string Name { - get { - return name; - } + // + // Returns the `System.Type' for the ReturnType of this + // function. Provides a nice cache. (used between semantic analysis + // and actual code generation + // + Type type_return_type; + public Type GetReturnType (TypeContainer parent) + { + if (type_return_type == null) + type_return_type = parent.LookupType (ReturnType, false); + + return type_return_type; } - public int ModFlags { - get { - return modifiers; - } + // + // Returns the System.Type array for the parameters of this method + // + Type [] parameter_types; + public Type [] ParameterTypes (TypeContainer parent) + { + if (Parameters == null) + return null; + + if (parameter_types == null) + parameter_types = Parameters.GetParameterInfo (parent); + + return parameter_types; } - public Parameters Parameters { - get { - return parameters; - } + public CallingConventions GetCallingConvention (bool is_class) + { + CallingConventions cc = 0; + + cc = Parameters.GetCallingConvention (); + + if (is_class) + if ((ModFlags & Modifiers.STATIC) == 0) + cc |= CallingConventions.HasThis; + + return cc; } - public Type ReturnType { - get { - return return_typeref.Type; + // + // Creates the type + // + public void Define (TypeContainer parent) + { + Type ret_type = GetReturnType (parent); + Type [] parameters = ParameterTypes (parent); + + // + // Create the method + // + MethodBuilder = parent.TypeBuilder.DefineMethod ( + Name, Modifiers.MethodAttr (ModFlags), + GetCallingConvention (parent is Class), + ret_type, parameters); + + // + // This is used to track the Entry Point, + // + // FIXME: Allow pluggable entry point, check arguments, etc. + // + if (Name == "Main"){ + if ((ModFlags & Modifiers.STATIC) != 0){ + parent.RootContext.EntryPoint = MethodBuilder; + } } - } + + // + // Define each type attribute (in/out/ref) and + // the argument names. + // + Parameter [] p = Parameters.FixedParameters; + if (p != null){ + int i; + + for (i = 0; i < p.Length; i++) + MethodBuilder.DefineParameter ( + i + 1, p [i].Attributes, p [i].Name); - public string ArgumentSignature { - get { - return ""; // TYPEFIX: Type.MakeParameterSignature (name, parameters); + if (i != parameters.Length) + Console.WriteLine ("Implement the type definition for params"); } } + + // + // Emits the code + // + public void Emit (TypeContainer parent) + { + ILGenerator ig = MethodBuilder.GetILGenerator (); + EmitContext ec = new EmitContext (parent, ig); + + ec.EmitTopBlock (block); + } } public class Field { - Type type; - Object expr_or_array_init; - string name; - int modifiers; + public readonly string Type; + public readonly Object Initializer; + public readonly string Name; + public readonly int ModFlags; + public readonly Attributes OptAttributes; // // Modifiers allowed in a class declaration @@ -586,36 +994,13 @@ namespace CIR { Modifiers.STATIC | Modifiers.READONLY; - public Field (TypeRef typeref, int mod, string name, Object expr_or_array_init) + public Field (string type, int mod, string name, Object expr_or_array_init, Attributes attrs) { - this.type = type; - this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE); - this.name = name; - this.expr_or_array_init = expr_or_array_init; - } - - public Type Type { - get { - return type; - } - } - - public object Initializer { - get { - return expr_or_array_init; - } - } - - public string Name { - get { - return name; - } - } - - public int ModFlags { - get { - return modifiers; - } + Type = type; + ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE); + Name = name; + Initializer = expr_or_array_init; + OptAttributes = attrs; } } @@ -647,9 +1032,10 @@ namespace CIR { } public class Constructor { - ConstructorInitializer init; - string name; - Parameters args; + public ConstructorBuilder ConstructorBuilder; + public readonly ConstructorInitializer Initializer; + public readonly Parameters Parameters; + public readonly string Name; Block block; int mod_flags; @@ -667,32 +1053,33 @@ namespace CIR { // The spec claims that static is not permitted, but // my very own code has static constructors. // - public Constructor (string name, Parameters args, ConstructorInitializer init) { - this.name = name; - this.args = args; - this.init = init; + Name = name; + Parameters = args; + Initializer = init; } - public string Name { - get { - return name; - } + // + // Returns true if this is a default constructor + // + public bool IsDefault () + { + return (Parameters == null) && + (Initializer is ConstructorBaseInitializer) && + (Initializer.Arguments == null); } - public ConstructorInitializer Initializer { + public int ModFlags { get { - return init; + return mod_flags; } - } - public Parameters Parameters { - get { - return args; + set { + mod_flags = value; } } - + public Block Block { get { return block; @@ -703,23 +1090,72 @@ namespace CIR { } } - public int ModFlags { - get { - return mod_flags; - } + public CallingConventions GetCallingConvention (bool parent_is_class) + { + CallingConventions cc = 0; + + if (Parameters.ArrayParameter != null) + cc |= CallingConventions.VarArgs; + else + cc |= CallingConventions.Standard; - set { - mod_flags = Modifiers.Check (AllowedModifiers, value, 0); - } + if (parent_is_class) + if ((ModFlags & Modifiers.STATIC) != 0) + cc |= CallingConventions.HasThis; + + // FIXME: How is `ExplicitThis' used in C#? + + return cc; + } + + // + // Cached representation + /// + Type [] parameter_types; + public Type [] ParameterTypes (TypeContainer tc) + { + if (Parameters == null) + return null; + + if (parameter_types == null) + parameter_types = Parameters.GetParameterInfo (tc); + + return parameter_types; + } + + // + // Creates the ConstructorBuilder + // + public void Define (TypeContainer parent) + { + MethodAttributes ca = (MethodAttributes.RTSpecialName | + MethodAttributes.SpecialName); + + if ((ModFlags & Modifiers.STATIC) != 0) + ca |= MethodAttributes.Static; + + ConstructorBuilder = parent.TypeBuilder.DefineConstructor ( + ca, GetCallingConvention (parent is Class), + ParameterTypes (parent)); + } + + // + // Emits the code + // + public void Emit () + { } } public class Property { - TypeRef typeref; - string name; - int mod_flags; - Block get_block, set_block; - + + public readonly string Type; + public readonly string Name; + public readonly int ModFlags; + public Block Get, Set; + public PropertyBuilder PropertyBuilder; + public Attributes OptAttributes; + const int AllowedModifiers = Modifiers.NEW | Modifiers.PUBLIC | @@ -732,44 +1168,272 @@ namespace CIR { Modifiers.ABSTRACT | Modifiers.VIRTUAL; - public Property (TypeRef typeref, string name, int mod_flags, Block get_block, Block set_block) + public Property (string type, string name, int mod_flags, Block get_block, Block set_block, Attributes attrs) { - this.typeref = typeref; - this.name = name; - this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE); - this.get_block = get_block; - this.set_block = set_block; + Type = type; + Name = name; + ModFlags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE); + Get = get_block; + Set = set_block; + OptAttributes = attrs; } - public Type Type { - get { - return typeref.Type; + public void Define (TypeContainer parent) + { + + MethodAttributes method_attr = Modifiers.MethodAttr(ModFlags); + + // FIXME - how to handle PropertyAttributes.HasDefault + + PropertyAttributes prop_attr = PropertyAttributes.RTSpecialName | + PropertyAttributes.SpecialName; + + + Type tp = parent.LookupType (Type, false); + Type [] prop_type = new Type [1]; + prop_type [0] = tp; + + MethodBuilder mb; + + PropertyBuilder = parent.TypeBuilder.DefineProperty(Name, prop_attr, tp, null); + + if (Get != null) + { + mb = parent.TypeBuilder.DefineMethod("get_" + Name, method_attr, tp, null); + PropertyBuilder.SetGetMethod (mb); } + + if (Set != null) + { + mb = parent.TypeBuilder.DefineMethod("set_" + Name, method_attr, null, prop_type); + mb.DefineParameter(1, ParameterAttributes.None, "value"); + PropertyBuilder.SetSetMethod (mb); + } + } - public string Name { - get { - return name; - } + } + + public class Event { + + const int AllowedModifiers = + Modifiers.NEW | + Modifiers.PUBLIC | + Modifiers.PROTECTED | + Modifiers.INTERNAL | + Modifiers.PRIVATE | + Modifiers.STATIC | + Modifiers.VIRTUAL | + Modifiers.SEALED | + Modifiers.OVERRIDE | + Modifiers.ABSTRACT; + + public readonly string Type; + public readonly string Name; + public readonly Object Initializer; + public readonly int ModFlags; + public readonly Block Add; + public readonly Block Remove; + public EventBuilder EventBuilder; + public Attributes OptAttributes; + + public Event (string type, string name, Object init, int flags, Block add_block, Block rem_block, + Attributes attrs) + { + Type = type; + Name = name; + Initializer = init; + ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PRIVATE); + Add = add_block; + Remove = rem_block; + OptAttributes = attrs; } - public int ModFlags { - get { - return mod_flags; + public void Define (TypeContainer parent) + { + MethodAttributes m_attr = Modifiers.MethodAttr (ModFlags); + + EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName; + + MethodBuilder mb; + + Type t = parent.LookupType (Type, false); + Type [] p_type = new Type [1]; + p_type [0] = t; + + EventBuilder = parent.TypeBuilder.DefineEvent (Name, e_attr, t); + + if (Add != null) { + mb = parent.TypeBuilder.DefineMethod ("add_" + Name, m_attr, null, p_type); + mb.DefineParameter (1, ParameterAttributes.None, "value"); + EventBuilder.SetAddOnMethod (mb); } - } - public Block Get { - get { - return get_block; + if (Remove != null) { + mb = parent.TypeBuilder.DefineMethod ("remove_" + Name, m_attr, null, p_type); + mb.DefineParameter (1, ParameterAttributes.None, "value"); + EventBuilder.SetRemoveOnMethod (mb); } } + + } - public Block Set { - get { - return set_block; + public class Indexer { + + const int AllowedModifiers = + Modifiers.NEW | + Modifiers.PUBLIC | + Modifiers.PROTECTED | + Modifiers.INTERNAL | + Modifiers.PRIVATE | + Modifiers.VIRTUAL | + Modifiers.SEALED | + Modifiers.OVERRIDE | + Modifiers.ABSTRACT; + + public readonly string Type; + public readonly string InterfaceType; + public readonly Parameters FormalParameters; + public readonly int ModFlags; + public readonly Block Get; + public readonly Block Set; + public Attributes OptAttributes; + public MethodBuilder GetMethodBuilder; + public MethodBuilder SetMethodBuilder; + + + public Indexer (string type, string int_type, int flags, Parameters parms, + Block get_block, Block set_block, Attributes attrs) + { + + Type = type; + InterfaceType = int_type; + ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PRIVATE); + FormalParameters = parms; + Get = get_block; + Set = set_block; + OptAttributes = attrs; + } + + public void Define (TypeContainer parent) + { + MethodAttributes attr = Modifiers.MethodAttr (ModFlags); + + Type ret_type = parent.LookupType (Type, false); + Type [] param_types = FormalParameters.GetParameterInfo (parent); + + GetMethodBuilder = parent.TypeBuilder.DefineMethod ("get_Item", attr, ret_type, param_types); + SetMethodBuilder = parent.TypeBuilder.DefineMethod ("set_Item", attr, ret_type, param_types); + + Parameter [] p = FormalParameters.FixedParameters; + + if (p != null) { + int i; + + for (i = 0; i < p.Length; ++i) { + GetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name); + SetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name); + } + + if (i != param_types.Length) + Console.WriteLine ("Implement type definition for params"); } + } + + } + + public class Operator { + + const int AllowedModifiers = + Modifiers.PUBLIC | + Modifiers.STATIC; + + public enum OpType { + + // Unary operators + Bang, + Tilde, + Increment, + Decrement, + True, + False, + + // Unary and Binary operators + Plus, + Minus, + + // Binary operators + Star, + Div, + Percent, + BitAnd, + BitOr, + Carret, + ShiftLeft, + ShiftRight, + Eq, + NotEq, + GreaterThan, + LesserThan, + GreaterOrEq, + LesserOrEq, + + // Implicit and Explicit + Implicit, + Explicit + }; + + public readonly OpType OperatorType; + public readonly string ReturnType; + public readonly string FirstArgType; + public readonly string FirstArgName; + public readonly string SecondArgType; + public readonly string SecondArgName; + public readonly int ModFlags; + public readonly Block Block; + public Attributes OptAttributes; + public MethodBuilder OperatorMethodBuilder; + + public Operator (OpType type, string ret_type, int flags, string arg1type, string arg1name, + string arg2type, string arg2name, Block block, Attributes attrs) + { + OperatorType = type; + ReturnType = ret_type; + ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC); + FirstArgType = arg1type; + FirstArgName = arg1name; + SecondArgType = arg2type; + SecondArgName = arg2name; + Block = block; + OptAttributes = attrs; + } + + public void Define (TypeContainer parent) + { + MethodAttributes attr = Modifiers.MethodAttr (ModFlags); + + string name = "Operator" + OperatorType; + + Type ret_type = parent.LookupType (ReturnType, false); + + Type [] param_types = new Type [2]; + + param_types [0] = parent.LookupType (FirstArgType, false); + if (SecondArgType != null) + param_types [1] = parent.LookupType (SecondArgType, false); + + OperatorMethodBuilder = parent.TypeBuilder.DefineMethod (name, attr, ret_type, param_types); + + OperatorMethodBuilder.DefineParameter (1, ParameterAttributes.None, FirstArgName); + + if (SecondArgType != null) + OperatorMethodBuilder.DefineParameter (2, ParameterAttributes.None, SecondArgName); + + } + + } + }