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
.LookupByToken (new MetadataToken (MetadataToken
));