2 using System.Collections.Generic;
3 using System.Runtime.CompilerServices;
4 using System.Runtime.InteropServices;
5 using System.Reflection;
7 using Mono.Cecil.Metadata;
9 namespace Mono.Debugger.Soft {
11 public sealed class CustomAttributeDataMirror {
12 MethodMirror ctorInfo;
13 IList<CustomAttributeTypedArgumentMirror> ctorArgs;
14 IList<CustomAttributeNamedArgumentMirror> namedArgs;
16 internal CustomAttributeDataMirror (MethodMirror ctorInfo, object [] ctorArgs, object [] namedArgs)
18 this.ctorInfo = ctorInfo;
20 this.ctorArgs = Array.AsReadOnly<CustomAttributeTypedArgumentMirror>
21 (ctorArgs != null ? UnboxValues<CustomAttributeTypedArgumentMirror> (ctorArgs) : new CustomAttributeTypedArgumentMirror [0]);
23 this.namedArgs = Array.AsReadOnly<CustomAttributeNamedArgumentMirror>
24 (namedArgs != null ? UnboxValues<CustomAttributeNamedArgumentMirror> (namedArgs) : new CustomAttributeNamedArgumentMirror [0]);
28 public MethodMirror Constructor {
35 public IList<CustomAttributeTypedArgumentMirror> ConstructorArguments {
41 public IList<CustomAttributeNamedArgumentMirror> NamedArguments {
47 public override string ToString ()
49 StringBuilder sb = new StringBuilder ();
51 sb.Append ("[" + ctorInfo.DeclaringType.FullName + "(");
52 if (ctorArgs != null) {
53 for (int i = 0; i < ctorArgs.Count; i++) {
54 sb.Append (ctorArgs [i].ToString ());
55 if (i + 1 < ctorArgs.Count)
60 if (namedArgs != null) {
61 if (namedArgs.Count > 0)
64 for (int j = 0; j < namedArgs.Count; j++) {
65 sb.Append (namedArgs [j].ToString ());
66 if (j + 1 < namedArgs.Count)
70 sb.AppendFormat (")]");
72 return sb.ToString ();
75 static T [] UnboxValues<T> (object [] values)
77 T [] retval = new T [values.Length];
78 for (int i = 0; i < values.Length; i++)
79 retval [i] = (T) values [i];
85 * Construct a normal object from the value, so accessing the cattr doesn't
86 * require remoting calls.
88 static CustomAttributeTypedArgumentMirror CreateArg (VirtualMachine vm, ValueImpl vi) {
91 /* Instead of receiving a mirror of the Type object, we receive the id of the type */
92 if (vi.Type == (ElementType)ValueTypeId.VALUE_TYPE_ID_TYPE)
93 val = vm.GetType (vi.Id);
95 Value v = vm.DecodeValue (vi);
96 if (v is PrimitiveValue)
97 val = (v as PrimitiveValue).Value;
98 else if (v is StringMirror)
99 val = (v as StringMirror).Value;
104 return new CustomAttributeTypedArgumentMirror (null, val);
107 internal static CustomAttributeDataMirror[] Create (VirtualMachine vm, CattrInfo[] info) {
108 var res = new CustomAttributeDataMirror [info.Length];
109 for (int i = 0; i < info.Length; ++i) {
110 CattrInfo attr = info [i];
111 MethodMirror ctor = vm.GetMethod (attr.ctor_id);
112 var ctor_args = new object [attr.ctor_args.Length];
113 for (int j = 0; j < ctor_args.Length; ++j)
114 ctor_args [j] = CreateArg (vm, attr.ctor_args [j]);
115 var named_args = new object [attr.named_args.Length];
116 for (int j = 0; j < named_args.Length; ++j) {
117 CattrNamedArgInfo arg = attr.named_args [j];
118 CustomAttributeTypedArgumentMirror val;
120 val = CreateArg (vm, arg.value);
122 TypeMirror t = ctor.DeclaringType;
123 while (named_args [j] == null && t != null) {
124 if (arg.is_property) {
125 foreach (var prop in t.GetProperties ()) {
126 if (prop.Id == arg.id)
127 named_args [j] = new CustomAttributeNamedArgumentMirror (prop, null, val);
130 foreach (var field in t.GetFields ()) {
131 if (field.Id == arg.id)
132 named_args [j] = new CustomAttributeNamedArgumentMirror (null, field, val);
137 if (named_args [j] == null)
138 throw new NotImplementedException ();
140 res [i] = new CustomAttributeDataMirror (ctor, ctor_args, named_args);