2 // class.cs: Class and Struct handlers
4 // Author: Miguel de Icaza (miguel@gnu.org)
6 // Licensed under the terms of the GNU GPL
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
12 using System.Collections;
13 using System.Reflection;
14 using System.Reflection.Emit;
19 public class TypeContainer : DeclSpace {
20 protected int mod_flags;
22 // Holds a list of classes and structures
25 // Holds the list of properties
28 // Holds the list of enumerations
31 // Holds the list of delegates
34 // Holds the list of constructors
35 ArrayList constructors;
37 // Holds the list of fields
40 // Holds a list of fields that have initializers
41 ArrayList initialized_fields;
43 // Holds a list of static fields that have initializers
44 ArrayList initialized_static_fields;
46 // Holds the list of constants
61 // Holds the operators
65 // Pointers to the default constructor and the default static constructor
67 Constructor default_constructor;
68 Constructor default_static_constructor;
71 // Whether we have seen a static constructor for this class or not
73 bool have_static_constructor = false;
76 // This is the namespace in which this typecontainer
77 // was declared. We use this to resolve names.
79 Namespace my_namespace;
82 // This one is computed after we can distinguish interfaces
83 // from classes from the arraylist `type_bases'
85 string base_class_name;
91 // This behaves like a property ;-)
93 public readonly RootContext RootContext;
95 // Attributes for this type
96 protected Attributes attributes;
98 public TypeContainer (RootContext rc, TypeContainer parent, string name) : base (name)
101 types = new ArrayList ();
102 this.parent = parent;
105 object a = rc.Report;
112 base_class_name = null;
114 //Console.WriteLine ("New class " + name + " inside " + n);
117 public AdditionResult AddConstant (Constant constant)
120 string name = constant.Name;
122 if ((res = IsValid (name)) != AdditionResult.Success)
125 if (constants == null)
126 constants = new ArrayList ();
128 constants.Add (constant);
129 DefineName (name, constant);
131 return AdditionResult.Success;
134 public AdditionResult AddEnum (CIR.Enum e)
137 string name = e.Name;
139 if ((res = IsValid (name)) != AdditionResult.Success)
143 enums = new ArrayList ();
146 DefineName (name, e);
148 return AdditionResult.Success;
151 public AdditionResult AddClass (Class c)
154 string name = c.Name;
157 if ((res = IsValid (name)) != AdditionResult.Success)
160 DefineName (name, c);
163 return AdditionResult.Success;
166 public AdditionResult AddStruct (Struct s)
169 string name = s.Name;
171 if ((res = IsValid (name)) != AdditionResult.Success)
174 DefineName (name, s);
177 return AdditionResult.Success;
180 public AdditionResult AddDelegate (Delegate d)
183 string name = d.Name;
185 if ((res = IsValid (name)) != AdditionResult.Success)
188 if (delegates == null)
189 delegates = new ArrayList ();
191 DefineName (name, d);
194 return AdditionResult.Success;
197 public AdditionResult AddMethod (Method method)
199 string name = method.Name;
200 Object value = defined_names [name];
202 if (value != null && (!(value is Method)))
203 return AdditionResult.NameExists;
206 methods = new ArrayList ();
208 methods.Add (method);
209 DefineName (name, method);
211 return AdditionResult.Success;
214 public AdditionResult AddConstructor (Constructor c)
216 if (c.Name != Basename)
217 return AdditionResult.NotAConstructor;
219 if (constructors == null)
220 constructors = new ArrayList ();
222 constructors.Add (c);
224 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
227 have_static_constructor = true;
231 default_static_constructor = c;
233 default_constructor = c;
236 return AdditionResult.Success;
239 public AdditionResult AddInterface (Interface iface)
242 string name = iface.Name;
244 if ((res = IsValid (name)) != AdditionResult.Success)
247 if (interfaces == null)
248 interfaces = new ArrayList ();
249 interfaces.Add (iface);
250 DefineName (name, iface);
252 return AdditionResult.Success;
255 public AdditionResult AddField (Field field)
258 string name = field.Name;
260 if ((res = IsValid (name)) != AdditionResult.Success)
264 fields = new ArrayList ();
267 if (field.Initializer != null){
268 if ((field.ModFlags & Modifiers.STATIC) != 0){
269 if (initialized_static_fields == null)
270 initialized_static_fields = new ArrayList ();
272 initialized_static_fields.Add (field);
275 // We have not seen a static constructor,
276 // but we will provide static initialization of fields
278 have_static_constructor = true;
280 if (initialized_fields == null)
281 initialized_fields = new ArrayList ();
283 initialized_fields.Add (field);
287 DefineName (name, field);
288 return AdditionResult.Success;
291 public AdditionResult AddProperty (Property prop)
294 string name = prop.Name;
296 if ((res = IsValid (name)) != AdditionResult.Success)
299 if (properties == null)
300 properties = new ArrayList ();
302 properties.Add (prop);
303 DefineName (name, prop);
305 return AdditionResult.Success;
308 public AdditionResult AddEvent (Event e)
311 string name = e.Name;
313 if ((res = IsValid (name)) != AdditionResult.Success)
317 events = new ArrayList ();
320 DefineName (name, e);
322 return AdditionResult.Success;
325 public AdditionResult AddIndexer (Indexer i)
327 if (indexers == null)
328 indexers = new ArrayList ();
332 return AdditionResult.Success;
335 public AdditionResult AddOperator (Operator op)
337 if (operators == null)
338 operators = new ArrayList ();
342 return AdditionResult.Success;
345 public TypeContainer Parent {
351 public ArrayList Types {
357 public ArrayList Methods {
363 public ArrayList Constants {
369 public ArrayList Interfaces {
375 public int ModFlags {
383 return base_class_name;
387 public ArrayList Bases {
397 public ArrayList Fields {
403 public ArrayList Constructors {
409 public ArrayList Properties {
415 public ArrayList Events {
421 public ArrayList Enums {
427 public ArrayList Indexers {
433 public ArrayList Operators {
439 public ArrayList Delegates {
445 public Attributes OptAttributes {
451 public Namespace Namespace {
457 my_namespace = value;
462 // The Toplevel is `root_types'Â which is a containerfor all
463 // types defined, hence the non-obviios parent.parent.
465 // If we were not tracking Namespaces we could remove this.
470 if (parent.parent == null)
479 // Returns the TypeAttributes for this TypeContainer
481 public virtual TypeAttributes TypeAttr {
483 TypeAttributes x = 0;
486 // FIXME: Figure out exactly how private, public and protected
487 // map to the TypeAttribute flags.
489 // FIXME: Figure out what `new' in the context of a class/struct means.
491 // FIXME: figure out what `internal' means in the context of class/structs
493 if ((mod_flags & Modifiers.PUBLIC) != 0)
494 x |= TypeAttributes.Public;
496 if ((mod_flags & Modifiers.PRIVATE) != 0)
497 x |= TypeAttributes.NotPublic;
499 if ((mod_flags & Modifiers.ABSTRACT) != 0)
500 x |= TypeAttributes.Abstract;
502 if ((mod_flags & Modifiers.SEALED) != 0)
503 x |= TypeAttributes.Sealed;
506 if ((mod_flags & Modifiers.PUBLIC) != 0)
507 x |= TypeAttributes.NestedPublic;
509 x |= TypeAttributes.NestedPrivate;
513 // If we have static constructors, the runtime needs to
514 // initialize the class, otherwise we can optimize
517 if (!have_static_constructor)
518 x |= TypeAttributes.BeforeFieldInit;
523 void EmitField (Field f)
525 Type t = LookupType (f.Type, false);
530 TypeBuilder.DefineField (f.Name, t, Modifiers.FieldAttr (f.ModFlags));
534 // Emits the class field initializers
536 void EmitStaticFieldInitializers (ConstructorBuilder cb)
542 // Emits the instance field initializers
544 void EmitFieldInitializers (ConstructorBuilder cb)
550 // Emits a constructor
552 void EmitConstructor (Constructor c)
554 if ((c.ModFlags & Modifiers.STATIC) != 0){
555 if (initialized_static_fields != null)
556 EmitStaticFieldInitializers (c.ConstructorBuilder);
558 if (initialized_fields != null)
559 EmitFieldInitializers (c.ConstructorBuilder);
565 // This function is used to emit instance and static constructors
566 // when the user did not provide one.
568 void EmitDefaultConstructor (bool is_static)
570 ConstructorBuilder cb;
571 MethodAttributes ca = (MethodAttributes.RTSpecialName |
572 MethodAttributes.SpecialName);
575 ca |= MethodAttributes.Static;
578 // Default constructors provided by the compiler should be `protected'
579 // if the class is abstract, otherwise it is public
581 if ((mod_flags & Modifiers.ABSTRACT) != 0)
582 ca |= MethodAttributes.Family;
584 ca |= MethodAttributes.Public;
586 cb = TypeBuilder.DefineDefaultConstructor (ca);
589 EmitStaticFieldInitializers (cb);
591 EmitFieldInitializers (cb);
595 // Populates our TypeBuilder with fields and methods
597 public void Populate ()
599 if (Constants != null){
600 foreach (Constant c in Constants)
601 c.EmitConstant (RootContext, this);
605 foreach (Field f in Fields)
609 if (Constructors != null){
610 foreach (Constructor c in Constructors)
614 if (Methods != null){
615 foreach (Method m in Methods)
619 if (Properties != null) {
620 foreach (Property p in Properties)
625 foreach (Enum e in Enums)
629 if (Events != null) {
630 foreach (Event e in Events)
634 if (Indexers != null) {
635 foreach (Indexer i in Indexers)
639 if (Operators != null) {
640 foreach (Operator o in Operators)
644 if (Delegates != null) {
645 foreach (Delegate d in Delegates)
653 // Emits the code, this step is performed after all
654 // the types, enumerations, constructors
658 if (default_constructor == null)
659 EmitDefaultConstructor (false);
661 if (initialized_static_fields != null && default_static_constructor == null)
662 EmitDefaultConstructor (true);
664 if (Constructors != null)
665 foreach (Constructor c in Constructors)
669 foreach (Method m in Methods)
673 public delegate void ExamineType (TypeContainer container, object cback_data);
675 void WalkTypesAt (TypeContainer root, ExamineType visit, object cback_data)
680 foreach (TypeContainer type in root.Types){
681 visit (type, cback_data);
682 WalkTypesAt (type, visit, cback_data);
686 public void WalkTypes (ExamineType visit, object cback)
688 WalkTypesAt (this, visit, cback);
691 public Type LookupType (string name, bool silent)
693 return RootContext.LookupType (this, name, silent);
697 // This method returns the members of this type just like Type.FindMembers would
698 // Only, we need to use this for types which are _being_ defined because MS' brain
699 // dead implementation can't take care of that ;-)
701 public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
703 // FIXME : Need to actually take care of all the various
704 // arguments being passed in but for now, we only bother with
705 // the MemberTypes and criteria arguments.
709 case MemberTypes.All:
713 case MemberTypes.Constructor:
717 case MemberTypes.Custom:
721 case MemberTypes.Event:
725 case MemberTypes.Field:
729 case MemberTypes.Method:
733 case MemberTypes.NestedType:
737 case MemberTypes.Property:
741 case MemberTypes.TypeInfo:
753 public class Class : TypeContainer {
755 // Modifiers allowed in a class declaration
757 public const int AllowedModifiers =
760 Modifiers.PROTECTED |
766 public Class (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
767 : base (rc, parent, name)
771 if (parent.Parent == null)
772 accmods = Modifiers.INTERNAL;
774 accmods = Modifiers.PRIVATE;
776 this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
777 this.attributes = attrs;
781 // FIXME: How do we deal with the user specifying a different
784 public override TypeAttributes TypeAttr {
786 return base.TypeAttr | TypeAttributes.AutoLayout;
791 public class Struct : TypeContainer {
793 // Modifiers allowed in a struct declaration
795 public const int AllowedModifiers =
798 Modifiers.PROTECTED |
802 public Struct (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
803 : base (rc, parent, name)
807 if (parent.Parent == null)
808 accmods = Modifiers.INTERNAL;
810 accmods = Modifiers.PRIVATE;
812 this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
814 this.mod_flags |= Modifiers.SEALED;
815 this.attributes = attrs;
820 // FIXME: Allow the user to specify a different set of attributes
821 // in some cases (Sealed for example is mandatory for a class,
822 // but what SequentialLayout can be changed
824 public override TypeAttributes TypeAttr {
826 return base.TypeAttr |
827 TypeAttributes.SequentialLayout |
828 TypeAttributes.Sealed |
829 TypeAttributes.BeforeFieldInit;
834 public class Method {
835 public readonly Parameters Parameters;
836 public readonly string ReturnType;
837 public readonly string Name;
838 public readonly int ModFlags;
839 public MethodBuilder MethodBuilder;
840 public readonly Attributes OptAttributes;
844 // return_type can be "null" for VOID values.
845 public Method (string return_type, int mod, string name, Parameters parameters, Attributes attrs)
848 ReturnType = return_type;
849 Parameters = parameters;
850 ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
851 OptAttributes = attrs;
855 // Modifiers allowed in a class declaration
857 const int AllowedModifiers =
860 Modifiers.PROTECTED |
881 // Returns the `System.Type' for the ReturnType of this
882 // function. Provides a nice cache. (used between semantic analysis
883 // and actual code generation
885 Type type_return_type;
886 public Type GetReturnType (TypeContainer parent)
888 if (type_return_type == null)
889 type_return_type = parent.LookupType (ReturnType, false);
891 return type_return_type;
895 // Returns the System.Type array for the parameters of this method
897 Type [] parameter_types;
898 public Type [] ParameterTypes (TypeContainer parent)
900 if (Parameters == null)
903 if (parameter_types == null)
904 parameter_types = Parameters.GetParameterInfo (parent);
906 return parameter_types;
909 public CallingConventions GetCallingConvention (bool is_class)
911 CallingConventions cc = 0;
913 cc = Parameters.GetCallingConvention ();
916 if ((ModFlags & Modifiers.STATIC) == 0)
917 cc |= CallingConventions.HasThis;
925 public void Define (TypeContainer parent)
927 Type ret_type = GetReturnType (parent);
928 Type [] parameters = ParameterTypes (parent);
933 MethodBuilder = parent.TypeBuilder.DefineMethod (
934 Name, Modifiers.MethodAttr (ModFlags),
935 GetCallingConvention (parent is Class),
936 ret_type, parameters);
939 // This is used to track the Entry Point,
941 // FIXME: Allow pluggable entry point, check arguments, etc.
944 if ((ModFlags & Modifiers.STATIC) != 0){
945 parent.RootContext.EntryPoint = MethodBuilder;
950 // Define each type attribute (in/out/ref) and
951 // the argument names.
953 Parameter [] p = Parameters.FixedParameters;
957 for (i = 0; i < p.Length; i++)
958 MethodBuilder.DefineParameter (
959 i + 1, p [i].Attributes, p [i].Name);
961 if (i != parameters.Length)
962 Console.WriteLine ("Implement the type definition for params");
969 public void Emit (TypeContainer parent)
971 ILGenerator ig = MethodBuilder.GetILGenerator ();
972 EmitContext ec = new EmitContext (parent, ig);
974 ec.EmitTopBlock (block);
979 public readonly string Type;
980 public readonly Object Initializer;
981 public readonly string Name;
982 public readonly int ModFlags;
983 public readonly Attributes OptAttributes;
986 // Modifiers allowed in a class declaration
988 const int AllowedModifiers =
991 Modifiers.PROTECTED |
997 public Field (string type, int mod, string name, Object expr_or_array_init, Attributes attrs)
1000 ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
1002 Initializer = expr_or_array_init;
1003 OptAttributes = attrs;
1007 public abstract class ConstructorInitializer {
1008 ArrayList argument_list;
1010 public ConstructorInitializer (ArrayList argument_list)
1012 this.argument_list = argument_list;
1015 public ArrayList Arguments {
1017 return argument_list;
1022 public class ConstructorBaseInitializer : ConstructorInitializer {
1023 public ConstructorBaseInitializer (ArrayList argument_list) : base (argument_list)
1028 public class ConstructorThisInitializer : ConstructorInitializer {
1029 public ConstructorThisInitializer (ArrayList argument_list) : base (argument_list)
1034 public class Constructor {
1035 public ConstructorBuilder ConstructorBuilder;
1036 public readonly ConstructorInitializer Initializer;
1037 public readonly Parameters Parameters;
1038 public readonly string Name;
1043 // Modifiers allowed for a constructor.
1045 const int AllowedModifiers =
1047 Modifiers.PROTECTED |
1048 Modifiers.INTERNAL |
1053 // The spec claims that static is not permitted, but
1054 // my very own code has static constructors.
1056 public Constructor (string name, Parameters args, ConstructorInitializer init)
1064 // Returns true if this is a default constructor
1066 public bool IsDefault ()
1068 return (Parameters == null) &&
1069 (Initializer is ConstructorBaseInitializer) &&
1070 (Initializer.Arguments == null);
1073 public int ModFlags {
1083 public Block Block {
1093 public CallingConventions GetCallingConvention (bool parent_is_class)
1095 CallingConventions cc = 0;
1097 if (Parameters.ArrayParameter != null)
1098 cc |= CallingConventions.VarArgs;
1100 cc |= CallingConventions.Standard;
1102 if (parent_is_class)
1103 if ((ModFlags & Modifiers.STATIC) != 0)
1104 cc |= CallingConventions.HasThis;
1106 // FIXME: How is `ExplicitThis' used in C#?
1112 // Cached representation
1114 Type [] parameter_types;
1115 public Type [] ParameterTypes (TypeContainer tc)
1117 if (Parameters == null)
1120 if (parameter_types == null)
1121 parameter_types = Parameters.GetParameterInfo (tc);
1123 return parameter_types;
1127 // Creates the ConstructorBuilder
1129 public void Define (TypeContainer parent)
1131 MethodAttributes ca = (MethodAttributes.RTSpecialName |
1132 MethodAttributes.SpecialName);
1134 if ((ModFlags & Modifiers.STATIC) != 0)
1135 ca |= MethodAttributes.Static;
1137 ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
1138 ca, GetCallingConvention (parent is Class),
1139 ParameterTypes (parent));
1150 public class Property {
1152 public readonly string Type;
1153 public readonly string Name;
1154 public readonly int ModFlags;
1155 public Block Get, Set;
1156 public PropertyBuilder PropertyBuilder;
1157 public Attributes OptAttributes;
1159 const int AllowedModifiers =
1162 Modifiers.PROTECTED |
1163 Modifiers.INTERNAL |
1167 Modifiers.OVERRIDE |
1168 Modifiers.ABSTRACT |
1171 public Property (string type, string name, int mod_flags, Block get_block, Block set_block, Attributes attrs)
1175 ModFlags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
1178 OptAttributes = attrs;
1181 public void Define (TypeContainer parent)
1184 MethodAttributes method_attr = Modifiers.MethodAttr(ModFlags);
1186 // FIXME - how to handle PropertyAttributes.HasDefault
1188 PropertyAttributes prop_attr = PropertyAttributes.RTSpecialName |
1189 PropertyAttributes.SpecialName;
1192 Type tp = parent.LookupType (Type, false);
1193 Type [] prop_type = new Type [1];
1198 PropertyBuilder = parent.TypeBuilder.DefineProperty(Name, prop_attr, tp, null);
1202 mb = parent.TypeBuilder.DefineMethod("get_" + Name, method_attr, tp, null);
1203 PropertyBuilder.SetGetMethod (mb);
1208 mb = parent.TypeBuilder.DefineMethod("set_" + Name, method_attr, null, prop_type);
1209 mb.DefineParameter(1, ParameterAttributes.None, "value");
1210 PropertyBuilder.SetSetMethod (mb);
1217 public class Event {
1219 const int AllowedModifiers =
1222 Modifiers.PROTECTED |
1223 Modifiers.INTERNAL |
1228 Modifiers.OVERRIDE |
1231 public readonly string Type;
1232 public readonly string Name;
1233 public readonly Object Initializer;
1234 public readonly int ModFlags;
1235 public readonly Block Add;
1236 public readonly Block Remove;
1237 public EventBuilder EventBuilder;
1238 public Attributes OptAttributes;
1240 public Event (string type, string name, Object init, int flags, Block add_block, Block rem_block,
1246 ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PRIVATE);
1249 OptAttributes = attrs;
1252 public void Define (TypeContainer parent)
1254 MethodAttributes m_attr = Modifiers.MethodAttr (ModFlags);
1256 EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
1260 Type t = parent.LookupType (Type, false);
1261 Type [] p_type = new Type [1];
1264 EventBuilder = parent.TypeBuilder.DefineEvent (Name, e_attr, t);
1267 mb = parent.TypeBuilder.DefineMethod ("add_" + Name, m_attr, null, p_type);
1268 mb.DefineParameter (1, ParameterAttributes.None, "value");
1269 EventBuilder.SetAddOnMethod (mb);
1272 if (Remove != null) {
1273 mb = parent.TypeBuilder.DefineMethod ("remove_" + Name, m_attr, null, p_type);
1274 mb.DefineParameter (1, ParameterAttributes.None, "value");
1275 EventBuilder.SetRemoveOnMethod (mb);
1281 public class Indexer {
1283 const int AllowedModifiers =
1286 Modifiers.PROTECTED |
1287 Modifiers.INTERNAL |
1291 Modifiers.OVERRIDE |
1294 public readonly string Type;
1295 public readonly string InterfaceType;
1296 public readonly Parameters FormalParameters;
1297 public readonly int ModFlags;
1298 public readonly Block Get;
1299 public readonly Block Set;
1300 public Attributes OptAttributes;
1301 public MethodBuilder GetMethodBuilder;
1302 public MethodBuilder SetMethodBuilder;
1305 public Indexer (string type, string int_type, int flags, Parameters parms,
1306 Block get_block, Block set_block, Attributes attrs)
1310 InterfaceType = int_type;
1311 ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PRIVATE);
1312 FormalParameters = parms;
1315 OptAttributes = attrs;
1318 public void Define (TypeContainer parent)
1320 MethodAttributes attr = Modifiers.MethodAttr (ModFlags);
1322 Type ret_type = parent.LookupType (Type, false);
1323 Type [] param_types = FormalParameters.GetParameterInfo (parent);
1325 GetMethodBuilder = parent.TypeBuilder.DefineMethod ("get_Item", attr, ret_type, param_types);
1326 SetMethodBuilder = parent.TypeBuilder.DefineMethod ("set_Item", attr, ret_type, param_types);
1328 Parameter [] p = FormalParameters.FixedParameters;
1333 for (i = 0; i < p.Length; ++i) {
1334 GetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
1335 SetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
1338 if (i != param_types.Length)
1339 Console.WriteLine ("Implement type definition for params");
1346 public class Operator {
1348 const int AllowedModifiers =
1352 public enum OpType {
1362 // Unary and Binary operators
1382 // Implicit and Explicit
1387 public readonly OpType OperatorType;
1388 public readonly string ReturnType;
1389 public readonly string FirstArgType;
1390 public readonly string FirstArgName;
1391 public readonly string SecondArgType;
1392 public readonly string SecondArgName;
1393 public readonly int ModFlags;
1394 public readonly Block Block;
1395 public Attributes OptAttributes;
1396 public MethodBuilder OperatorMethodBuilder;
1398 public Operator (OpType type, string ret_type, int flags, string arg1type, string arg1name,
1399 string arg2type, string arg2name, Block block, Attributes attrs)
1401 OperatorType = type;
1402 ReturnType = ret_type;
1403 ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC);
1404 FirstArgType = arg1type;
1405 FirstArgName = arg1name;
1406 SecondArgType = arg2type;
1407 SecondArgName = arg2name;
1409 OptAttributes = attrs;
1412 public void Define (TypeContainer parent)
1414 MethodAttributes attr = Modifiers.MethodAttr (ModFlags);
1416 string name = "Operator" + OperatorType;
1418 Type ret_type = parent.LookupType (ReturnType, false);
1420 Type [] param_types = new Type [2];
1422 param_types [0] = parent.LookupType (FirstArgType, false);
1423 if (SecondArgType != null)
1424 param_types [1] = parent.LookupType (SecondArgType, false);
1426 OperatorMethodBuilder = parent.TypeBuilder.DefineMethod (name, attr, ret_type, param_types);
1428 OperatorMethodBuilder.DefineParameter (1, ParameterAttributes.None, FirstArgName);
1430 if (SecondArgType != null)
1431 OperatorMethodBuilder.DefineParameter (2, ParameterAttributes.None, SecondArgName);