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_namespace + ".");
63 for (var i = 0; i < param_info.Length; i++) {
64 sb.Append(param_info[i].Name);
65 if (i != param_info.Length - 1)
69 return sb.ToString ();
75 info = vm.conn.Method_GetInfo (id);
78 public int MetadataToken {
85 public MethodAttributes Attributes {
88 return (MethodAttributes)info.attributes;
92 public bool IsPublic {
94 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
97 public bool IsPrivate {
99 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
102 public bool IsFamily {
104 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family;
107 public bool IsAssembly {
109 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly;
112 public bool IsFamilyAndAssembly {
114 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
117 public bool IsFamilyOrAssembly {
119 return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
122 public bool IsStatic {
124 return (Attributes & MethodAttributes.Static) != 0;
127 public bool IsFinal {
129 return (Attributes & MethodAttributes.Final) != 0;
132 public bool IsVirtual {
134 return (Attributes & MethodAttributes.Virtual) != 0;
137 public bool IsHideBySig {
139 return (Attributes & MethodAttributes.HideBySig) != 0;
142 public bool IsAbstract {
144 return (Attributes & MethodAttributes.Abstract) != 0;
147 public bool IsSpecialName {
149 return (Attributes & MethodAttributes.SpecialName) != 0;
153 public bool IsConstructor {
155 int attr = (int)Attributes;
156 return ((attr & (int)MethodAttributes.RTSpecialName) != 0
157 && (Name == ".ctor"));
161 public ParameterInfoMirror[] GetParameters () {
162 if (param_info == null) {
163 var pi = vm.conn.Method_GetParamInfo (id);
164 param_info = new ParameterInfoMirror [pi.param_count];
166 ret_param = new ParameterInfoMirror (this, -1, vm.GetType (pi.ret_type), null, ParameterAttributes.Retval);
169 for (int i = 0; i < pi.param_count; ++i) {
170 param_info [i] = new ParameterInfoMirror (this, i, vm.GetType (pi.param_types [i]), pi.param_names [i], 0);
177 public ParameterInfoMirror ReturnParameter {
179 if (ret_param == null)
185 public LocalVariable[] GetLocals () {
186 if (locals == null) {
187 var li = vm.conn.Method_GetLocalsInfo (id);
188 // Add the arguments as well
189 var pi = vm.conn.Method_GetParamInfo (id);
191 locals = new LocalVariable [pi.param_count + li.names.Length];
193 for (int i = 0; i < pi.param_count; ++i)
194 locals [i] = new LocalVariable (vm, this, i, pi.param_types [i], pi.param_names [i], -1, -1, true);
196 for (int i = 0; i < li.names.Length; ++i)
197 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);
202 public LocalVariable GetLocal (string name) {
204 throw new ArgumentNullException ("name");
208 LocalVariable res = null;
209 for (int i = 0; i < locals.Length; ++i) {
210 if (locals [i].Name == name) {
212 throw new AmbiguousMatchException ("More that one local has the name '" + name + "'.");
220 public MethodBodyMirror GetMethodBody () {
222 MethodBodyInfo info = vm.conn.Method_GetBody (id);
224 body = new MethodBodyMirror (vm, this, info.il);
229 public IList<int> ILOffsets {
231 if (debug_info == null)
232 debug_info = vm.conn.Method_GetDebugInfo (id);
233 return Array.AsReadOnly (debug_info.il_offsets);
237 public IList<int> LineNumbers {
239 if (debug_info == null)
240 debug_info = vm.conn.Method_GetDebugInfo (id);
241 return Array.AsReadOnly (debug_info.line_numbers);
245 public string SourceFile {
247 if (debug_info == null)
248 debug_info = vm.conn.Method_GetDebugInfo (id);
249 return debug_info.filename;
253 public IList<Location> Locations {
255 if (locations == null) {
256 var il_offsets = ILOffsets;
257 var line_numbers = LineNumbers;
258 IList<Location> res = new Location [ILOffsets.Count];
259 for (int i = 0; i < il_offsets.Count; ++i)
260 res [i] = new Location (vm, this, -1, il_offsets [i], SourceFile, line_numbers [i], 0);
267 internal int il_offset_to_line_number (int il_offset) {
268 if (debug_info == null)
269 debug_info = vm.conn.Method_GetDebugInfo (id);
271 // FIXME: Optimize this
272 for (int i = debug_info.il_offsets.Length - 1; i >= 0; --i) {
273 if (debug_info.il_offsets [i] <= il_offset)
274 return debug_info.line_numbers [i];
279 public Location LocationAtILOffset (int il_offset) {
280 IList<Location> locs = Locations;
282 // FIXME: Optimize this
283 for (int i = locs.Count - 1; i >= 0; --i) {
284 if (locs [i].ILOffset <= il_offset)
291 public C.MethodDefinition Metadata {
294 meta = (C.MethodDefinition)DeclaringType.Assembly.Metadata.MainModule.LookupToken (MetadataToken);