using System.Reflection;
using C = Mono.Cecil;
using Mono.Cecil.Metadata;
+#if NET_4_5
+using System.Threading.Tasks;
+#endif
namespace Mono.Debugger.Soft
{
TypeMirror[] ifaces;
Dictionary<TypeMirror, InterfaceMappingMirror> iface_map;
TypeMirror[] type_args;
+ bool cached_base_type;
+ bool inited;
internal const BindingFlags DefaultBindingFlags =
BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
public TypeMirror BaseType {
get {
- // FIXME: base_type could be null for object/interfaces
- if (base_type == null) {
+ if (!cached_base_type) {
base_type = vm.GetType (GetInfo ().base_type);
+ cached_base_type = true;
}
return base_type;
}
switch (Name) {
case "Byte":
return "byte";
+ case "Sbyte":
+ return "sbyte";
+ case "Char":
+ return "char";
+ case "UInt16":
+ return "ushort";
+ case "Int16":
+ return "short";
+ case "UInt32":
+ return "uint";
case "Int32":
return "int";
+ case "UInt64":
+ return "ulong";
+ case "Int64":
+ return "long";
+ case "Single":
+ return "float";
+ case "Double":
+ return "double";
case "Boolean":
return "bool";
default:
if (Namespace == "System") {
string s = Name;
switch (s) {
+ case "Decimal":
+ return "decimal";
+ case "Object":
+ return "object";
case "String":
return "string";
default:
string[] source_files;
string[] source_files_full_path;
- public string[] GetSourceFiles (bool return_full_paths) {
- string[] res = return_full_paths ? source_files_full_path : source_files;
+ public string[] GetSourceFiles (bool returnFullPaths) {
+ string[] res = returnFullPaths ? source_files_full_path : source_files;
if (res == null) {
- res = vm.conn.Type_GetSourceFiles (id, return_full_paths);
- if (return_full_paths)
+ res = vm.conn.Type_GetSourceFiles (id, returnFullPaths);
+ if (returnFullPaths)
source_files_full_path = res;
else
source_files = res;
* used by the reflection-only functionality on .net.
*/
public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) {
- return GetCAttrs (null, inherit);
+ return GetCustomAttrs (null, inherit);
}
public CustomAttributeDataMirror[] GetCustomAttributes (TypeMirror attributeType, bool inherit) {
if (attributeType == null)
throw new ArgumentNullException ("attributeType");
- return GetCAttrs (attributeType, inherit);
+ return GetCustomAttrs (attributeType, inherit);
}
- CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) {
+ void AppendCustomAttrs (IList<CustomAttributeDataMirror> attrs, TypeMirror type, bool inherit)
+ {
if (cattrs == null && Metadata != null && !Metadata.HasCustomAttributes)
cattrs = new CustomAttributeDataMirror [0];
- // FIXME: Handle inherit
if (cattrs == null) {
CattrInfo[] info = vm.conn.Type_GetCustomAttributes (id, 0, false);
cattrs = CustomAttributeDataMirror.Create (vm, info);
}
- var res = new List<CustomAttributeDataMirror> ();
- foreach (var attr in cattrs)
+
+ foreach (var attr in cattrs) {
if (type == null || attr.Constructor.DeclaringType == type)
- res.Add (attr);
- return res.ToArray ();
+ attrs.Add (attr);
+ }
+
+ if (inherit && BaseType != null)
+ BaseType.AppendCustomAttrs (attrs, type, inherit);
+ }
+
+ CustomAttributeDataMirror[] GetCustomAttrs (TypeMirror type, bool inherit) {
+ var attrs = new List<CustomAttributeDataMirror> ();
+ AppendCustomAttrs (attrs, type, inherit);
+ return attrs.ToArray ();
}
public MethodMirror[] GetMethodsByNameFlags (string name, BindingFlags flags, bool ignoreCase) {
m [i] = vm.GetMethod (ids [i]);
return m;
} else {
- if (flags != (BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.NonPublic))
+ if ((flags & BindingFlags.IgnoreCase) != 0) {
+ flags &= ~BindingFlags.IgnoreCase;
+ ignoreCase = true;
+ }
+
+ if (flags == BindingFlags.Default)
+ flags = BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.Static;
+
+ MethodAttributes access = (MethodAttributes) 0;
+ bool matchInstance = false;
+ bool matchStatic = false;
+
+ if ((flags & BindingFlags.NonPublic) != 0) {
+ access |= MethodAttributes.Private;
+ flags &= ~BindingFlags.NonPublic;
+ }
+ if ((flags & BindingFlags.Public) != 0) {
+ access |= MethodAttributes.Public;
+ flags &= ~BindingFlags.Public;
+ }
+ if ((flags & BindingFlags.Instance) != 0) {
+ flags &= ~BindingFlags.Instance;
+ matchInstance = true;
+ }
+ if ((flags & BindingFlags.Static) != 0) {
+ flags &= ~BindingFlags.Static;
+ matchStatic = true;
+ }
+
+ if ((int) flags != 0)
throw new NotImplementedException ();
+
var res = new List<MethodMirror> ();
foreach (MethodMirror m in GetMethods ()) {
+ if ((m.Attributes & access) == (MethodAttributes) 0)
+ continue;
+
+ if (!((matchStatic && m.IsStatic) || (matchInstance && !m.IsStatic)))
+ continue;
+
if ((!ignoreCase && m.Name == name) || (ignoreCase && m.Name.Equals (name, StringComparison.CurrentCultureIgnoreCase)))
res.Add (m);
}
return ObjectMirror.EndInvokeMethodInternal (asyncResult);
}
+#if NET_4_5
+ public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
+ var tcs = new TaskCompletionSource<Value> ();
+ BeginInvokeMethod (thread, method, arguments, options, iar =>
+ {
+ try {
+ tcs.SetResult (EndInvokeMethod (iar));
+ } catch (OperationCanceledException) {
+ tcs.TrySetCanceled ();
+ } catch (Exception ex) {
+ tcs.TrySetException (ex);
+ }
+ }, null);
+ return tcs.Task;
+ }
+#endif
+
public Value NewInstance (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
return ObjectMirror.InvokeMethod (vm, thread, method, null, arguments, InvokeOptions.None);
}
return res;
}
+ // Return whenever the type initializer of this type has ran
+ // Since protocol version 2.23
+ public bool IsInitialized {
+ get {
+ vm.CheckProtocolVersion (2, 23);
+ if (!inited)
+ inited = vm.conn.Type_IsInitialized (id);
+ return inited;
+ }
+ }
}
}