2 using System.Collections.Generic;
4 using System.Reflection;
6 using Mono.Cecil.Metadata;
8 namespace Mono.Debugger.Soft
10 public class MethodMirror : Mirror
14 TypeMirror declaring_type;
16 C.MethodDefinition meta;
17 ParameterInfoMirror[] param_info;
18 ParameterInfoMirror ret_param;
19 LocalVariable[] locals;
20 IList<Location> locations;
21 MethodBodyMirror body;
23 internal MethodMirror (VirtualMachine vm, long id) : base (vm, id) {
29 name = vm.conn.Method_GetName (id);
34 public TypeMirror DeclaringType {
36 if (declaring_type == null)
37 declaring_type = vm.GetType (vm.conn.Method_GetDeclaringType (id));
38 return declaring_type;
42 public TypeMirror ReturnType {
44 return ReturnParameter.ParameterType;
49 public string FullName {
51 string type_namespace = DeclaringType.Namespace;
52 string type_name = DeclaringType.Name;
53 StringBuilder sb = new StringBuilder ();
54 sb.Append (ReturnType.Name);
56 if (type_namespace == String.Empty)
57 sb.Append (type_name + ":" + Name + " ()");
59 sb.Append (type_namespace + "." + type_name + ":" + Name + " ()");
60 return sb.ToString ();
66 info = vm.conn.Method_GetInfo (id);
69 public int MetadataToken {
76 public MethodAttributes Attributes {
79 return (MethodAttributes)info.attributes;
83 public bool IsPublic {
85 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
88 public bool IsPrivate {
90 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
93 public bool IsFamily {
95 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family;
98 public bool IsAssembly {
100 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly;
103 public bool IsFamilyAndAssembly {
105 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
108 public bool IsFamilyOrAssembly {
110 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
113 public bool IsStatic {
115 return (Attributes & MethodAttributes.Static) != 0;
118 public bool IsFinal {
120 return (Attributes & MethodAttributes.Final) != 0;
123 public bool IsVirtual {
125 return (Attributes & MethodAttributes.Virtual) != 0;
128 public bool IsHideBySig {
130 return (Attributes & MethodAttributes.HideBySig) != 0;
133 public bool IsAbstract {
135 return (Attributes & MethodAttributes.Abstract) != 0;
138 public bool IsSpecialName {
140 return (Attributes & MethodAttributes.SpecialName) != 0;
144 public bool IsConstructor {
146 int attr = (int)Attributes;
147 return ((attr & (int)MethodAttributes.RTSpecialName) != 0
148 && (Name == ".ctor"));
152 public ParameterInfoMirror[] GetParameters () {
153 if (param_info == null) {
154 var pi = vm.conn.Method_GetParamInfo (id);
155 param_info = new ParameterInfoMirror [pi.param_count];
157 ret_param = new ParameterInfoMirror (this, -1, vm.GetType (pi.ret_type), null, ParameterAttributes.Retval);
160 for (int i = 0; i < pi.param_count; ++i) {
161 param_info [i] = new ParameterInfoMirror (this, i, vm.GetType (pi.param_types [i]), pi.param_names [i], 0);
168 public ParameterInfoMirror ReturnParameter {
170 if (ret_param == null)
176 public LocalVariable[] GetLocals () {
177 if (locals == null) {
178 var li = vm.conn.Method_GetLocalsInfo (id);
179 // Add the arguments as well
180 var pi = vm.conn.Method_GetParamInfo (id);
182 locals = new LocalVariable [pi.param_count + li.names.Length];
184 for (int i = 0; i < pi.param_count; ++i)
185 locals [i] = new LocalVariable (vm, this, i, pi.param_types [i], pi.param_names [i], -1, -1, true);
187 for (int i = 0; i < li.names.Length; ++i)
188 locals [i + pi.param_count] = new LocalVariable (vm, this, i, li.types [i], li.names [i], li.live_range_start [i], li.live_range_end [i], false);
193 public LocalVariable GetLocal (string name) {
195 throw new ArgumentNullException ("name");
199 LocalVariable res = null;
200 for (int i = 0; i < locals.Length; ++i) {
201 if (locals [i].Name == name) {
203 throw new AmbiguousMatchException ("More that one local has the name '" + name + "'.");
211 public MethodBodyMirror GetMethodBody () {
213 MethodBodyInfo info = vm.conn.Method_GetBody (id);
215 body = new MethodBodyMirror (vm, this, info.il);
220 public IList<int> ILOffsets {
222 if (debug_info == null)
223 debug_info = vm.conn.Method_GetDebugInfo (id);
224 return Array.AsReadOnly (debug_info.il_offsets);
228 public IList<int> LineNumbers {
230 if (debug_info == null)
231 debug_info = vm.conn.Method_GetDebugInfo (id);
232 return Array.AsReadOnly (debug_info.line_numbers);
236 public string SourceFile {
238 if (debug_info == null)
239 debug_info = vm.conn.Method_GetDebugInfo (id);
240 return debug_info.filename;
244 public IList<Location> Locations {
246 if (locations == null) {
247 var il_offsets = ILOffsets;
248 var line_numbers = LineNumbers;
249 IList<Location> res = new Location [ILOffsets.Count];
250 for (int i = 0; i < il_offsets.Count; ++i)
251 res [i] = new Location (vm, this, -1, il_offsets [i], SourceFile, line_numbers [i], 0);
258 internal int il_offset_to_line_number (int il_offset) {
259 if (debug_info == null)
260 debug_info = vm.conn.Method_GetDebugInfo (id);
262 // FIXME: Optimize this
263 for (int i = debug_info.il_offsets.Length - 1; i >= 0; --i) {
264 if (debug_info.il_offsets [i] <= il_offset)
265 return debug_info.line_numbers [i];
270 public Location LocationAtILOffset (int il_offset) {
271 IList<Location> locs = Locations;
273 // FIXME: Optimize this
274 for (int i = locs.Count - 1; i >= 0; --i) {
275 if (locs [i].ILOffset <= il_offset)
282 public C.MethodDefinition Metadata {
285 meta = (C.MethodDefinition)DeclaringType.Assembly.Metadata.MainModule.LookupToken (MetadataToken);