2 // Mono.ILASM.MethodTable.cs
5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
13 using System.Collections;
15 namespace Mono.ILASM {
18 public delegate void MethodDefinedEvent (object sender, MethodDefinedEventArgs args);
19 public delegate void MethodReferencedEvent (object sender, MethodReferencedEventArgs args);
21 public class MethodEventArgs : EventArgs {
23 public readonly string Signature;
24 public readonly string Name;
25 public readonly TypeRef ReturnType;
26 public readonly Param[] ParamList;
27 public readonly bool IsInTable;
29 public MethodEventArgs (string signature, string name,
30 TypeRef return_type, Param[] param_list, bool is_in_table)
32 Signature = signature;
34 ReturnType = return_type;
35 ParamList = param_list;
36 IsInTable = is_in_table;
40 public class MethodDefinedEventArgs : MethodEventArgs {
42 public readonly MethAttr MethodAttributes;
43 public readonly ImplAttr ImplAttributes;
44 public readonly CallConv CallConv;
46 public MethodDefinedEventArgs (string signature, string name,
47 TypeRef return_type, Param[] param_list, bool is_in_table, MethAttr method_attr,
48 ImplAttr impl_attr, CallConv call_conv) : base (signature, name,
49 return_type, param_list, is_in_table)
51 MethodAttributes = method_attr;
52 ImplAttributes = impl_attr;
57 public class MethodReferencedEventArgs : MethodEventArgs {
59 public MethodReferencedEventArgs (string signature, string name,
60 TypeRef return_type, Param[] param_list, bool is_in_table) : base (signature, name,
61 return_type, param_list, is_in_table)
68 public class MethodTable {
70 private class MethodTableItem {
72 private static readonly int DefinedFlag = 2;
76 public ArrayList LocationList;
77 public MethodDef Method;
79 public MethodTableItem (MethodDef method, Location location)
83 LocationList = new ArrayList ();
84 LocationList.Add (location);
88 get { return ((flags & DefinedFlag) != 0); }
98 protected Hashtable table;
99 protected ClassDef parent_class;
101 public static event MethodReferencedEvent MethodReferencedEvent;
102 public static event MethodDefinedEvent MethodDefinedEvent;
104 public MethodTable (ClassDef parent_class)
106 this.parent_class = parent_class;
107 table = new Hashtable ();
110 public Method GetReference (string name, TypeRef return_type,
111 Param[] param_list, TypeRef[] param_type_list, Location location)
113 string signature = GetSignature (name, return_type, param_type_list);
115 if (MethodReferencedEvent != null)
116 MethodReferencedEvent (this, new MethodReferencedEventArgs (signature, name,
117 return_type, param_list, table.Contains (signature)));
119 MethodTableItem item = table[signature] as MethodTableItem;
122 item.LocationList.Add (location);
126 MethodDef method = parent_class.AddMethod (name, return_type.Type,
129 AddReferenced (signature, method, location);
134 public MethodDef AddDefinition (MethAttr method_attr, ImplAttr impl_attr, CallConv call_conv,
135 string name, TypeRef return_type, Param[] param_list,
136 TypeRef[] param_type_list, Location location)
138 string signature = GetSignature (name, return_type, param_type_list);
140 if (MethodDefinedEvent != null)
141 MethodDefinedEvent (this, new MethodDefinedEventArgs (signature, name,
142 return_type, param_list, table.Contains (signature), method_attr,
143 impl_attr, call_conv));
145 MethodTableItem item = (MethodTableItem) table[signature];
148 MethodDef method = parent_class.AddMethod (method_attr, impl_attr, name,
149 return_type.Type, param_list);
150 method.AddCallConv (call_conv);
151 AddDefined (signature, method, location);
155 item.Method.AddMethAttribute (method_attr);
156 item.Method.AddImplAttribute (impl_attr);
157 item.Method.AddCallConv (call_conv);
163 public bool CheckDefined ()
165 foreach (DictionaryEntry dic_entry in table) {
166 MethodTableItem table_item = (MethodTableItem) dic_entry.Value;
167 if (table_item.Defined)
169 throw new Exception (String.Format ("Method: {0} is not defined.", dic_entry.Key));
174 protected string GetSignature (string name, TypeRef return_type,
175 TypeRef[] param_list)
177 StringBuilder builder = new StringBuilder ();
179 builder.Append (return_type.FullName);
180 builder.Append ('_');
181 builder.Append (name);
182 builder.Append ('(');
185 foreach (TypeRef type_ref in param_list) {
187 builder.Append (',');
188 builder.Append (type_ref.FullName);
190 builder.Append (')');
192 return builder.ToString ();
195 protected void AddDefined (string signature, MethodDef method, Location location)
197 if (table.Contains (signature))
200 MethodTableItem item = new MethodTableItem (method, location);
203 table[signature] = item;
206 protected void AddReferenced (string signature, MethodDef method, Location location)
208 MethodTableItem item = new MethodTableItem (method, location);
210 table[signature] = item;
214 /// If a method is allready defined throw an Error
216 protected void CheckExists (string signature)
218 MethodTableItem item = table[signature] as MethodTableItem;
220 if ((item != null) && (item.Defined)) {
221 throw new Exception (String.Format ("Method: {0} defined in multiple locations.",