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 // a. Maybe keep a list of defined names in the order they
13 // appeared, so we can walk things in this way to present
14 // the users with errors in that order?
17 using System.Collections;
22 public class TypeContainer : DeclSpace {
23 protected int mod_flags;
24 Hashtable types, fields, properties;
25 Hashtable enums, constants, interfaces, method_groups;
27 ArrayList constructor_list;
30 // This is the namespace in which this typecontainer
31 // was declared. We use this to resolve names.
33 CSC.Namespace my_namespace;
36 // This one is computed after we can distinguish interfaces
37 // from classes from the arraylist `type_bases'
39 string base_class_name;
44 public TypeContainer (TypeContainer parent, string name) : base (name)
46 types = new Hashtable ();
55 base_class_name = null;
57 //Console.WriteLine ("New class " + name + " inside " + n);
60 public AdditionResult AddConstant (Constant constant)
63 string name = constant.Name;
65 if ((res = IsValid (name)) != AdditionResult.Success)
68 if (constants == null)
69 constants = new Hashtable ();
71 constants.Add (name, constant);
72 DefineName (name, constant);
74 return AdditionResult.Success;
77 public AdditionResult AddEnum (CIR.Enum e)
82 if ((res = IsValid (name)) != AdditionResult.Success)
86 enums = new Hashtable ();
91 return AdditionResult.Success;
94 public AdditionResult AddClass (Class c)
100 if ((res = IsValid (name)) != AdditionResult.Success)
103 DefineName (name, c);
106 return AdditionResult.Success;
109 public AdditionResult AddStruct (Struct s)
112 string name = s.Name;
114 if ((res = IsValid (name)) != AdditionResult.Success)
117 DefineName (name, s);
120 return AdditionResult.Success;
123 public AdditionResult AddMethod (Method method)
125 string name = method.Name;
126 Object value = defined_names [name];
128 if (value != null && (!(value is MethodGroup)))
129 return AdditionResult.NameExists;
131 if (method_groups == null)
132 method_groups = new Hashtable ();
134 MethodGroup mg = (MethodGroup) method_groups [name];
136 mg = new MethodGroup (name);
139 method_groups.Add (name, mg);
141 return AdditionResult.Success;
146 DefineName (name, mg);
148 return AdditionResult.Success;
151 public AdditionResult AddConstructor (Constructor c)
153 if (c.Name != Basename)
154 return AdditionResult.NotAConstructor;
156 if (constructor_list == null)
157 constructor_list = new ArrayList ();
159 constructor_list.Add (c);
161 return AdditionResult.Success;
164 public AdditionResult AddInterface (Interface iface)
167 string name = iface.Name;
169 if ((res = IsValid (name)) != AdditionResult.Success)
172 if (interfaces == null)
173 interfaces = new Hashtable ();
174 interfaces.Add (name, iface);
175 DefineName (name, iface);
177 return AdditionResult.Success;
180 public AdditionResult AddField (Field field)
183 string name = field.Name;
185 if ((res = IsValid (name)) != AdditionResult.Success)
189 fields = new Hashtable ();
191 fields.Add (name, field);
192 DefineName (name, field);
193 return AdditionResult.Success;
196 public AdditionResult AddProperty (Property prop)
199 string name = prop.Name;
201 if ((res = IsValid (name)) != AdditionResult.Success)
204 if (properties == null)
205 properties = new Hashtable ();
207 properties.Add (name, prop);
208 DefineName (name, prop);
210 return AdditionResult.Success;
213 public Constant GetConstant (string name) {
214 return (Constant) constants [name];
217 public TypeContainer Parent {
223 public Hashtable Types {
229 public Hashtable MethodGroups {
231 return method_groups;
235 public Hashtable Constants {
241 public Hashtable Interfaces {
247 public int ModFlags {
255 return base_class_name;
259 public ArrayList Bases {
269 public Hashtable Fields {
275 public Hashtable Constructors {
277 return null; // constructors;
281 public Hashtable Properties {
287 public Hashtable Enums {
293 public Type ResolveName (string name)
298 public CSC.Namespace Namespace {
304 my_namespace = value;
308 public int ResolveParents (Tree root)
311 if (type_bases.Count == 0){
312 base_class_name = "System.Object";
318 foreach (Type t in Bases){
319 Type resolved = ResolveName (t.Name);
326 public delegate void VisitContainer (TypeContainer container, object cback_data);
328 void VisitTypesAt (TypeContainer root, VisitContainer visit, object cback)
333 foreach (DictionaryEntry de in root.Types){
334 TypeContainer type = (TypeContainer) de.Value;
337 VisitTypesAt (type, visit, cback);
342 // Use this method to visit all the types in a type container.
343 // You can use cback to pass arbitrary data to your callback.
345 public void VisitTypes (VisitContainer visit, object cback)
347 foreach (DictionaryEntry de in types){
348 TypeContainer type = (TypeContainer) de.Value;
350 VisitTypesAt (type, visit, cback);
355 internal class VisitExpressions_Lambda {
356 VisitExpressionRoot vb;
359 void walk_arguments (ArrayList args)
364 int top = args.Count;
366 for (int i = 0; i < top; i++){
367 Argument arg = (Argument) args [i];
369 vb (arg.Expr, user_data);
373 void walk_block (Block b)
377 void walk_constructor (Constructor c)
379 ConstructorInitializer init = c.Initializer;
381 if (init != null && init.Arguments != null)
382 walk_arguments (init.Arguments);
384 walk_block (c.Block);
387 void walk_properties (Property p)
391 void walk_method (Method m)
395 void type_walker_1 (TypeContainer type, object cback)
397 if (type.Fields != null){
398 foreach (DictionaryEntry de in type.Fields){
399 Field f = (Field) de.Value;
401 if (f.Initializer != null){
402 if (f.Initializer is Expression)
403 vb ((Expression) f.Initializer, user_data);
408 if (type.Constructors != null){
409 foreach (DictionaryEntry de in type.Constructors)
410 walk_constructor ((Constructor) de.Value);
413 if (type.Properties != null){
414 foreach (DictionaryEntry de in type.Properties)
415 walk_properties ((Property) de.Value);
418 if (type.MethodGroups != null){
419 foreach (DictionaryEntry de in type.MethodGroups){
420 Hashtable methods = ((MethodGroup) de.Value).Methods;
421 foreach (Method m in methods)
428 internal VisitExpressions_Lambda (TypeContainer tc,
429 VisitExpressionRoot vb,
433 this.user_data = user_data;
435 tc.VisitTypes (new VisitContainer (type_walker_1), null);
439 public delegate void VisitExpressionRoot (Expression e, object cback);
441 // Use this method to visit all the code blocks in a TypeContainer
443 public void VisitExpressionRoots (VisitExpressionRoot vb, object cback)
445 VisitExpressions_Lambda l = new VisitExpressions_Lambda (this, vb, cback);
449 public class Class : TypeContainer {
451 // Modifiers allowed in a class declaration
453 public const int AllowedModifiers =
456 Modifiers.PROTECTED |
462 public Class (TypeContainer parent, string name, int mod)
463 : base (parent, name)
467 if (parent.Parent == null)
468 accmods = Modifiers.INTERNAL;
470 accmods = Modifiers.PRIVATE;
472 this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
476 public class Struct : TypeContainer {
478 // Modifiers allowed in a struct declaration
480 public const int AllowedModifiers =
483 Modifiers.PROTECTED |
487 public Struct (TypeContainer parent, string name, int mod)
488 : base (parent, name)
492 if (parent.Parent == null)
493 accmods = Modifiers.INTERNAL;
495 accmods = Modifiers.PRIVATE;
497 this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
501 public class Method {
502 Parameters parameters;
503 TypeRef return_typeref;
508 // return_type can be "null" for VOID values.
509 public Method (TypeRef return_typeref, int mod, string name, Parameters parameters)
511 this.return_typeref = return_typeref;
513 this.parameters = parameters;
514 this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
518 // Modifiers allowed in a class declaration
520 const int AllowedModifiers =
523 Modifiers.PROTECTED |
549 public int ModFlags {
555 public Parameters Parameters {
561 public Type ReturnType {
563 return return_typeref.Type;
567 public string ArgumentSignature {
569 return ""; // TYPEFIX: Type.MakeParameterSignature (name, parameters);
576 Object expr_or_array_init;
581 // Modifiers allowed in a class declaration
583 const int AllowedModifiers =
586 Modifiers.PROTECTED |
592 public Field (TypeRef typeref, int mod, string name, Object expr_or_array_init)
595 this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
597 this.expr_or_array_init = expr_or_array_init;
606 public object Initializer {
608 return expr_or_array_init;
618 public int ModFlags {
625 public abstract class ConstructorInitializer {
626 ArrayList argument_list;
628 public ConstructorInitializer (ArrayList argument_list)
630 this.argument_list = argument_list;
633 public ArrayList Arguments {
635 return argument_list;
640 public class ConstructorBaseInitializer : ConstructorInitializer {
641 public ConstructorBaseInitializer (ArrayList argument_list) : base (argument_list)
646 public class ConstructorThisInitializer : ConstructorInitializer {
647 public ConstructorThisInitializer (ArrayList argument_list) : base (argument_list)
652 public class Constructor {
653 ConstructorInitializer init;
660 // Modifiers allowed for a constructor.
662 const int AllowedModifiers =
664 Modifiers.PROTECTED |
670 // The spec claims that static is not permitted, but
671 // my very own code has static constructors.
674 public Constructor (string name, Parameters args, ConstructorInitializer init)
687 public ConstructorInitializer Initializer {
693 public Parameters Parameters {
709 public int ModFlags {
715 mod_flags = Modifiers.Check (AllowedModifiers, value, 0);
720 public class Property {
724 Block get_block, set_block;
726 const int AllowedModifiers =
729 Modifiers.PROTECTED |
738 public Property (TypeRef typeref, string name, int mod_flags, Block get_block, Block set_block)
740 this.typeref = typeref;
742 this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
743 this.get_block = get_block;
744 this.set_block = set_block;
759 public int ModFlags {