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 Report
.Error (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 Report
.Error (String
.Format ("Method: {0} defined in multiple locations.",