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 CSC.Namespace Namespace {
299 my_namespace = value;
303 public int ResolveParents (Tree root)
306 base_class_name = "System.Object";
310 if (type_bases.Count == 0){
311 base_class_name = "System.Object";
318 override public Type Define (Tree tree)
323 public delegate void VisitContainer (TypeContainer container, object cback_data);
325 void VisitTypesAt (TypeContainer root, VisitContainer visit, object cback)
330 foreach (DictionaryEntry de in root.Types){
331 TypeContainer type = (TypeContainer) de.Value;
334 VisitTypesAt (type, visit, cback);
339 // Use this method to visit all the types in a type container.
340 // You can use cback to pass arbitrary data to your callback.
342 public void VisitTypes (VisitContainer visit, object cback)
344 foreach (DictionaryEntry de in types){
345 TypeContainer type = (TypeContainer) de.Value;
347 VisitTypesAt (type, visit, cback);
352 internal class VisitExpressions_Lambda {
353 VisitExpressionRoot vb;
356 void walk_arguments (ArrayList args)
361 int top = args.Count;
363 for (int i = 0; i < top; i++){
364 Argument arg = (Argument) args [i];
366 vb (arg.Expr, user_data);
370 void walk_block (Block b)
374 void walk_constructor (Constructor c)
376 ConstructorInitializer init = c.Initializer;
378 if (init != null && init.Arguments != null)
379 walk_arguments (init.Arguments);
381 walk_block (c.Block);
384 void walk_properties (Property p)
388 void walk_method (Method m)
392 void type_walker_1 (TypeContainer type, object cback)
394 if (type.Fields != null){
395 foreach (DictionaryEntry de in type.Fields){
396 Field f = (Field) de.Value;
398 if (f.Initializer != null){
399 if (f.Initializer is Expression)
400 vb ((Expression) f.Initializer, user_data);
405 if (type.Constructors != null){
406 foreach (DictionaryEntry de in type.Constructors)
407 walk_constructor ((Constructor) de.Value);
410 if (type.Properties != null){
411 foreach (DictionaryEntry de in type.Properties)
412 walk_properties ((Property) de.Value);
415 if (type.MethodGroups != null){
416 foreach (DictionaryEntry de in type.MethodGroups){
417 Hashtable methods = ((MethodGroup) de.Value).Methods;
418 foreach (Method m in methods)
425 internal VisitExpressions_Lambda (TypeContainer tc,
426 VisitExpressionRoot vb,
430 this.user_data = user_data;
432 tc.VisitTypes (new VisitContainer (type_walker_1), null);
436 public delegate void VisitExpressionRoot (Expression e, object cback);
438 // Use this method to visit all the code blocks in a TypeContainer
440 public void VisitExpressionRoots (VisitExpressionRoot vb, object cback)
442 VisitExpressions_Lambda l = new VisitExpressions_Lambda (this, vb, cback);
446 public class Class : TypeContainer {
448 // Modifiers allowed in a class declaration
450 public const int AllowedModifiers =
453 Modifiers.PROTECTED |
459 public Class (TypeContainer parent, string name, int mod)
460 : base (parent, name)
464 if (parent.Parent == null)
465 accmods = Modifiers.INTERNAL;
467 accmods = Modifiers.PRIVATE;
469 this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
473 public class Struct : TypeContainer {
475 // Modifiers allowed in a struct declaration
477 public const int AllowedModifiers =
480 Modifiers.PROTECTED |
484 public Struct (TypeContainer parent, string name, int mod)
485 : base (parent, name)
489 if (parent.Parent == null)
490 accmods = Modifiers.INTERNAL;
492 accmods = Modifiers.PRIVATE;
494 this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
498 public class Method {
499 Parameters parameters;
500 TypeRef return_typeref;
505 // return_type can be "null" for VOID values.
506 public Method (TypeRef return_typeref, int mod, string name, Parameters parameters)
508 this.return_typeref = return_typeref;
510 this.parameters = parameters;
511 this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
515 // Modifiers allowed in a class declaration
517 const int AllowedModifiers =
520 Modifiers.PROTECTED |
546 public int ModFlags {
552 public Parameters Parameters {
558 public Type ReturnType {
560 return return_typeref.Type;
564 public string ArgumentSignature {
566 return ""; // TYPEFIX: Type.MakeParameterSignature (name, parameters);
573 Object expr_or_array_init;
578 // Modifiers allowed in a class declaration
580 const int AllowedModifiers =
583 Modifiers.PROTECTED |
589 public Field (TypeRef typeref, int mod, string name, Object expr_or_array_init)
592 this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
594 this.expr_or_array_init = expr_or_array_init;
603 public object Initializer {
605 return expr_or_array_init;
615 public int ModFlags {
622 public abstract class ConstructorInitializer {
623 ArrayList argument_list;
625 public ConstructorInitializer (ArrayList argument_list)
627 this.argument_list = argument_list;
630 public ArrayList Arguments {
632 return argument_list;
637 public class ConstructorBaseInitializer : ConstructorInitializer {
638 public ConstructorBaseInitializer (ArrayList argument_list) : base (argument_list)
643 public class ConstructorThisInitializer : ConstructorInitializer {
644 public ConstructorThisInitializer (ArrayList argument_list) : base (argument_list)
649 public class Constructor {
650 ConstructorInitializer init;
657 // Modifiers allowed for a constructor.
659 const int AllowedModifiers =
661 Modifiers.PROTECTED |
667 // The spec claims that static is not permitted, but
668 // my very own code has static constructors.
671 public Constructor (string name, Parameters args, ConstructorInitializer init)
684 public ConstructorInitializer Initializer {
690 public Parameters Parameters {
706 public int ModFlags {
712 mod_flags = Modifiers.Check (AllowedModifiers, value, 0);
717 public class Property {
721 Block get_block, set_block;
723 const int AllowedModifiers =
726 Modifiers.PROTECTED |
735 public Property (TypeRef typeref, string name, int mod_flags, Block get_block, Block set_block)
737 this.typeref = typeref;
739 this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
740 this.get_block = get_block;
741 this.set_block = set_block;
756 public int ModFlags {