System.Drawing: added email to icon and test file headers
[mono.git] / mcs / class / IKVM.Reflection / CustomAttributeData.cs
1 /*
2   Copyright (C) 2009-2011 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Text;
27 using System.IO;
28 using IKVM.Reflection.Reader;
29 using IKVM.Reflection.Emit;
30 using IKVM.Reflection.Metadata;
31
32 namespace IKVM.Reflection
33 {
34         public sealed class CustomAttributeData
35         {
36                 internal static readonly IList<CustomAttributeData> EmptyList = new List<CustomAttributeData>(0).AsReadOnly();
37
38                 /*
39                  * There are several states a CustomAttributeData object can be in:
40                  * 
41                  * 1) Unresolved Custom Attribute
42                  *    - customAttributeIndex >= 0
43                  *    - declSecurityIndex == -1
44                  *    - declSecurityBlob == null
45                  *    - lazyConstructor = null
46                  *    - lazyConstructorArguments = null
47                  *    - lazyNamedArguments = null
48                  * 
49                  * 2) Resolved Custom Attribute
50                  *    - customAttributeIndex >= 0
51                  *    - declSecurityIndex == -1
52                  *    - declSecurityBlob == null
53                  *    - lazyConstructor != null
54                  *    - lazyConstructorArguments != null
55                  *    - lazyNamedArguments != null
56                  *    
57                  * 3) Pre-resolved Custom Attribute
58                  *    - customAttributeIndex = -1
59                  *    - declSecurityIndex == -1
60                  *    - declSecurityBlob == null
61                  *    - lazyConstructor != null
62                  *    - lazyConstructorArguments != null
63                  *    - lazyNamedArguments != null
64                  *    
65                  * 4) Pseudo Custom Attribute, .NET 1.x declarative security or result of CustomAttributeBuilder.ToData()
66                  *    - customAttributeIndex = -1
67                  *    - declSecurityIndex == -1
68                  *    - declSecurityBlob == null
69                  *    - lazyConstructor != null
70                  *    - lazyConstructorArguments != null
71                  *    - lazyNamedArguments != null
72                  *    
73                  * 5) Unresolved declarative security
74                  *    - customAttributeIndex = -1
75                  *    - declSecurityIndex >= 0
76                  *    - declSecurityBlob != null
77                  *    - lazyConstructor != null
78                  *    - lazyConstructorArguments != null
79                  *    - lazyNamedArguments == null
80                  * 
81                  * 6) Resolved declarative security
82                  *    - customAttributeIndex = -1
83                  *    - declSecurityIndex >= 0
84                  *    - declSecurityBlob == null
85                  *    - lazyConstructor != null
86                  *    - lazyConstructorArguments != null
87                  *    - lazyNamedArguments != null
88                  * 
89                  */
90                 private readonly Module module;
91                 private readonly int customAttributeIndex;
92                 private readonly int declSecurityIndex;
93                 private readonly byte[] declSecurityBlob;
94                 private ConstructorInfo lazyConstructor;
95                 private IList<CustomAttributeTypedArgument> lazyConstructorArguments;
96                 private IList<CustomAttributeNamedArgument> lazyNamedArguments;
97
98                 // 1) Unresolved Custom Attribute
99                 internal CustomAttributeData(Module module, int index)
100                 {
101                         this.module = module;
102                         this.customAttributeIndex = index;
103                         this.declSecurityIndex = -1;
104                 }
105
106                 // 4) Pseudo Custom Attribute, .NET 1.x declarative security
107                 internal CustomAttributeData(Module module, ConstructorInfo constructor, object[] args, List<CustomAttributeNamedArgument> namedArguments)
108                         : this(module, constructor, WrapConstructorArgs(args, constructor.MethodSignature), namedArguments)
109                 {
110                 }
111
112                 private static List<CustomAttributeTypedArgument> WrapConstructorArgs(object[] args, MethodSignature sig)
113                 {
114                         List<CustomAttributeTypedArgument> list = new List<CustomAttributeTypedArgument>();
115                         for (int i = 0; i < args.Length; i++)
116                         {
117                                 list.Add(new CustomAttributeTypedArgument(sig.GetParameterType(i), args[i]));
118                         }
119                         return list;
120                 }
121
122                 // 4) Pseudo Custom Attribute, .NET 1.x declarative security or result of CustomAttributeBuilder.ToData()
123                 internal CustomAttributeData(Module module, ConstructorInfo constructor, List<CustomAttributeTypedArgument> constructorArgs, List<CustomAttributeNamedArgument> namedArguments)
124                 {
125                         this.module = module;
126                         this.customAttributeIndex = -1;
127                         this.declSecurityIndex = -1;
128                         this.lazyConstructor = constructor;
129                         lazyConstructorArguments = constructorArgs.AsReadOnly();
130                         if (namedArguments == null)
131                         {
132                                 this.lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
133                         }
134                         else
135                         {
136                                 this.lazyNamedArguments = namedArguments.AsReadOnly();
137                         }
138                 }
139
140                 // 3) Pre-resolved Custom Attribute
141                 internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, ByteReader br)
142                 {
143                         this.module = asm.ManifestModule;
144                         this.customAttributeIndex = -1;
145                         this.declSecurityIndex = -1;
146                         this.lazyConstructor = constructor;
147                         if (br.Length == 0)
148                         {
149                                 // it's legal to have an empty blob
150                                 lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array;
151                                 lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
152                         }
153                         else
154                         {
155                                 if (br.ReadUInt16() != 1)
156                                 {
157                                         throw new BadImageFormatException();
158                                 }
159                                 lazyConstructorArguments = ReadConstructorArguments(asm, br, constructor);
160                                 lazyNamedArguments = ReadNamedArguments(asm, br, br.ReadUInt16(), constructor.DeclaringType);
161                         }
162                 }
163
164                 public override string ToString()
165                 {
166                         StringBuilder sb = new StringBuilder();
167                         sb.Append('[');
168                         sb.Append(Constructor.DeclaringType.FullName);
169                         sb.Append('(');
170                         string sep = "";
171                         ParameterInfo[] parameters = Constructor.GetParameters();
172                         IList<CustomAttributeTypedArgument> args = ConstructorArguments;
173                         for (int i = 0; i < parameters.Length; i++)
174                         {
175                                 sb.Append(sep);
176                                 sep = ", ";
177                                 AppendValue(sb, parameters[i].ParameterType, args[i]);
178                         }
179                         foreach (CustomAttributeNamedArgument named in NamedArguments)
180                         {
181                                 sb.Append(sep);
182                                 sep = ", ";
183                                 sb.Append(named.MemberInfo.Name);
184                                 sb.Append(" = ");
185                                 FieldInfo fi = named.MemberInfo as FieldInfo;
186                                 Type type = fi != null ? fi.FieldType : ((PropertyInfo)named.MemberInfo).PropertyType;
187                                 AppendValue(sb, type, named.TypedValue);
188                         }
189                         sb.Append(')');
190                         sb.Append(']');
191                         return sb.ToString();
192                 }
193
194                 private static void AppendValue(StringBuilder sb, Type type, CustomAttributeTypedArgument arg)
195                 {
196                         if (arg.ArgumentType == arg.ArgumentType.Module.universe.System_String)
197                         {
198                                 sb.Append('"').Append(arg.Value).Append('"');
199                         }
200                         else if (arg.ArgumentType.IsArray)
201                         {
202                                 Type elementType = arg.ArgumentType.GetElementType();
203                                 string elementTypeName;
204                                 if (elementType.IsPrimitive
205                                         || elementType == type.Module.universe.System_Object
206                                         || elementType == type.Module.universe.System_String
207                                         || elementType == type.Module.universe.System_Type)
208                                 {
209                                         elementTypeName = elementType.Name;
210                                 }
211                                 else
212                                 {
213                                         elementTypeName = elementType.FullName;
214                                 }
215                                 sb.Append("new ").Append(elementTypeName).Append("[").Append(((Array)arg.Value).Length).Append("] { ");
216                                 string sep = "";
217                                 foreach (CustomAttributeTypedArgument elem in (CustomAttributeTypedArgument[])arg.Value)
218                                 {
219                                         sb.Append(sep);
220                                         sep = ", ";
221                                         AppendValue(sb, elementType, elem);
222                                 }
223                                 sb.Append(" }");
224                         }
225                         else
226                         {
227                                 if (arg.ArgumentType != type)
228                                 {
229                                         sb.Append('(');
230                                         sb.Append(arg.ArgumentType.FullName);
231                                         sb.Append(')');
232                                 }
233                                 sb.Append(arg.Value);
234                         }
235                 }
236
237                 internal static void ReadDeclarativeSecurity(Module module, int index, List<CustomAttributeData> list)
238                 {
239                         Universe u = module.universe;
240                         Assembly asm = module.Assembly;
241                         int action = module.DeclSecurity.records[index].Action;
242                         ByteReader br = module.GetBlob(module.DeclSecurity.records[index].PermissionSet);
243                         if (br.PeekByte() == '.')
244                         {
245                                 br.ReadByte();
246                                 int count = br.ReadCompressedInt();
247                                 for (int j = 0; j < count; j++)
248                                 {
249                                         Type type = ReadType(asm, br);
250                                         ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(u.System_Security_Permissions_SecurityAction);
251                                         // LAMESPEC there is an additional length here (probably of the named argument list)
252                                         byte[] blob = br.ReadBytes(br.ReadCompressedInt());
253                                         list.Add(new CustomAttributeData(asm, constructor, action, blob, index));
254                                 }
255                         }
256                         else
257                         {
258                                 // .NET 1.x format (xml)
259                                 char[] buf = new char[br.Length / 2];
260                                 for (int i = 0; i < buf.Length; i++)
261                                 {
262                                         buf[i] = br.ReadChar();
263                                 }
264                                 string xml = new String(buf);
265                                 ConstructorInfo constructor = u.System_Security_Permissions_PermissionSetAttribute.GetPseudoCustomAttributeConstructor(u.System_Security_Permissions_SecurityAction);
266                                 List<CustomAttributeNamedArgument> args = new List<CustomAttributeNamedArgument>();
267                                 args.Add(new CustomAttributeNamedArgument(GetProperty(u.System_Security_Permissions_PermissionSetAttribute, "XML", u.System_String),
268                                         new CustomAttributeTypedArgument(u.System_String, xml)));
269                                 list.Add(new CustomAttributeData(asm.ManifestModule, constructor, new object[] { action }, args));
270                         }
271                 }
272
273                 // 5) Unresolved declarative security
274                 internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, int securityAction, byte[] blob, int index)
275                 {
276                         this.module = asm.ManifestModule;
277                         this.customAttributeIndex = -1;
278                         this.declSecurityIndex = index;
279                         Universe u = constructor.Module.universe;
280                         this.lazyConstructor = constructor;
281                         List<CustomAttributeTypedArgument> list = new List<CustomAttributeTypedArgument>();
282                         list.Add(new CustomAttributeTypedArgument(u.System_Security_Permissions_SecurityAction, securityAction));
283                         this.lazyConstructorArguments =  list.AsReadOnly();
284                         this.declSecurityBlob = blob;
285                 }
286
287                 private static Type ReadFieldOrPropType(Assembly asm, ByteReader br)
288                 {
289                         Universe u = asm.universe;
290                         switch (br.ReadByte())
291                         {
292                                 case Signature.ELEMENT_TYPE_BOOLEAN:
293                                         return u.System_Boolean;
294                                 case Signature.ELEMENT_TYPE_CHAR:
295                                         return u.System_Char;
296                                 case Signature.ELEMENT_TYPE_I1:
297                                         return u.System_SByte;
298                                 case Signature.ELEMENT_TYPE_U1:
299                                         return u.System_Byte;
300                                 case Signature.ELEMENT_TYPE_I2:
301                                         return u.System_Int16;
302                                 case Signature.ELEMENT_TYPE_U2:
303                                         return u.System_UInt16;
304                                 case Signature.ELEMENT_TYPE_I4:
305                                         return u.System_Int32;
306                                 case Signature.ELEMENT_TYPE_U4:
307                                         return u.System_UInt32;
308                                 case Signature.ELEMENT_TYPE_I8:
309                                         return u.System_Int64;
310                                 case Signature.ELEMENT_TYPE_U8:
311                                         return u.System_UInt64;
312                                 case Signature.ELEMENT_TYPE_R4:
313                                         return u.System_Single;
314                                 case Signature.ELEMENT_TYPE_R8:
315                                         return u.System_Double;
316                                 case Signature.ELEMENT_TYPE_STRING:
317                                         return u.System_String;
318                                 case Signature.ELEMENT_TYPE_SZARRAY:
319                                         return ReadFieldOrPropType(asm, br).MakeArrayType();
320                                 case 0x55:
321                                         return ReadType(asm, br);
322                                 case 0x50:
323                                         return u.System_Type;
324                                 case 0x51:
325                                         return u.System_Object;
326                                 default:
327                                         throw new BadImageFormatException();
328                         }
329                 }
330
331                 private static CustomAttributeTypedArgument ReadFixedArg(Assembly asm, ByteReader br, Type type)
332                 {
333                         Universe u = asm.universe;
334                         if (type == u.System_String)
335                         {
336                                 return new CustomAttributeTypedArgument(type, br.ReadString());
337                         }
338                         else if (type == u.System_Boolean)
339                         {
340                                 return new CustomAttributeTypedArgument(type, br.ReadByte() != 0);
341                         }
342                         else if (type == u.System_Char)
343                         {
344                                 return new CustomAttributeTypedArgument(type, br.ReadChar());
345                         }
346                         else if (type == u.System_Single)
347                         {
348                                 return new CustomAttributeTypedArgument(type, br.ReadSingle());
349                         }
350                         else if (type == u.System_Double)
351                         {
352                                 return new CustomAttributeTypedArgument(type, br.ReadDouble());
353                         }
354                         else if (type == u.System_SByte)
355                         {
356                                 return new CustomAttributeTypedArgument(type, br.ReadSByte());
357                         }
358                         else if (type == u.System_Int16)
359                         {
360                                 return new CustomAttributeTypedArgument(type, br.ReadInt16());
361                         }
362                         else if (type == u.System_Int32)
363                         {
364                                 return new CustomAttributeTypedArgument(type, br.ReadInt32());
365                         }
366                         else if (type == u.System_Int64)
367                         {
368                                 return new CustomAttributeTypedArgument(type, br.ReadInt64());
369                         }
370                         else if (type == u.System_Byte)
371                         {
372                                 return new CustomAttributeTypedArgument(type, br.ReadByte());
373                         }
374                         else if (type == u.System_UInt16)
375                         {
376                                 return new CustomAttributeTypedArgument(type, br.ReadUInt16());
377                         }
378                         else if (type == u.System_UInt32)
379                         {
380                                 return new CustomAttributeTypedArgument(type, br.ReadUInt32());
381                         }
382                         else if (type == u.System_UInt64)
383                         {
384                                 return new CustomAttributeTypedArgument(type, br.ReadUInt64());
385                         }
386                         else if (type == u.System_Type)
387                         {
388                                 return new CustomAttributeTypedArgument(type, ReadType(asm, br));
389                         }
390                         else if (type == u.System_Object)
391                         {
392                                 return ReadFixedArg(asm, br, ReadFieldOrPropType(asm, br));
393                         }
394                         else if (type.IsArray)
395                         {
396                                 int length = br.ReadInt32();
397                                 if (length == -1)
398                                 {
399                                         return new CustomAttributeTypedArgument(type, null);
400                                 }
401                                 Type elementType = type.GetElementType();
402                                 CustomAttributeTypedArgument[] array = new CustomAttributeTypedArgument[length];
403                                 for (int i = 0; i < length; i++)
404                                 {
405                                         array[i] = ReadFixedArg(asm, br, elementType);
406                                 }
407                                 return new CustomAttributeTypedArgument(type, array);
408                         }
409                         else if (type.IsEnum)
410                         {
411                                 return new CustomAttributeTypedArgument(type, ReadFixedArg(asm, br, type.GetEnumUnderlyingTypeImpl()).Value);
412                         }
413                         else
414                         {
415                                 throw new InvalidOperationException();
416                         }
417                 }
418
419                 private static Type ReadType(Assembly asm, ByteReader br)
420                 {
421                         string typeName = br.ReadString();
422                         if (typeName == null)
423                         {
424                                 return null;
425                         }
426                         if (typeName.Length > 0 && typeName[typeName.Length - 1] == 0)
427                         {
428                                 // there are broken compilers that emit an extra NUL character after the type name
429                                 typeName = typeName.Substring(0, typeName.Length - 1);
430                         }
431                         return TypeNameParser.Parse(typeName, true).GetType(asm.universe, asm, true, typeName, true, false);
432                 }
433
434                 private static IList<CustomAttributeTypedArgument> ReadConstructorArguments(Assembly asm, ByteReader br, ConstructorInfo constructor)
435                 {
436                         MethodSignature sig = constructor.MethodSignature;
437                         int count = sig.GetParameterCount();
438                         List<CustomAttributeTypedArgument> list = new List<CustomAttributeTypedArgument>(count);
439                         for (int i = 0; i < count; i++)
440                         {
441                                 list.Add(ReadFixedArg(asm, br, sig.GetParameterType(i)));
442                         }
443                         return list.AsReadOnly();
444                 }
445
446                 private static IList<CustomAttributeNamedArgument> ReadNamedArguments(Assembly asm, ByteReader br, int named, Type type)
447                 {
448                         List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>(named);
449                         for (int i = 0; i < named; i++)
450                         {
451                                 byte fieldOrProperty = br.ReadByte();
452                                 Type fieldOrPropertyType = ReadFieldOrPropType(asm, br);
453                                 string name = br.ReadString();
454                                 CustomAttributeTypedArgument value = ReadFixedArg(asm, br, fieldOrPropertyType);
455                                 MemberInfo member;
456                                 switch (fieldOrProperty)
457                                 {
458                                         case 0x53:
459                                                 member = GetField(type, name, fieldOrPropertyType);
460                                                 break;
461                                         case 0x54:
462                                                 member = GetProperty(type, name, fieldOrPropertyType);
463                                                 break;
464                                         default:
465                                                 throw new BadImageFormatException();
466                                 }
467                                 list.Add(new CustomAttributeNamedArgument(member, value));
468                         }
469                         return list.AsReadOnly();
470                 }
471
472                 private static FieldInfo GetField(Type type, string name, Type fieldType)
473                 {
474                         Type org = type;
475                         for (; type != null && !type.__IsMissing; type = type.BaseType)
476                         {
477                                 foreach (FieldInfo field in type.__GetDeclaredFields())
478                                 {
479                                         if (field.IsPublic && !field.IsStatic && field.Name == name)
480                                         {
481                                                 return field;
482                                         }
483                                 }
484                         }
485                         // if the field is missing, we stick the missing field on the first missing base type
486                         if (type == null)
487                         {
488                                 type = org;
489                         }
490                         FieldSignature sig = FieldSignature.Create(fieldType, new CustomModifiers());
491                         return type.FindField(name, sig)
492                                 ?? type.Module.universe.GetMissingFieldOrThrow(type, name, sig);
493                 }
494
495                 private static PropertyInfo GetProperty(Type type, string name, Type propertyType)
496                 {
497                         Type org = type;
498                         for (; type != null && !type.__IsMissing; type = type.BaseType)
499                         {
500                                 foreach (PropertyInfo property in type.__GetDeclaredProperties())
501                                 {
502                                         if (property.IsPublic && !property.IsStatic && property.Name == name)
503                                         {
504                                                 return property;
505                                         }
506                                 }
507                         }
508                         // if the property is missing, we stick the missing property on the first missing base type
509                         if (type == null)
510                         {
511                                 type = org;
512                         }
513                         return type.Module.universe.GetMissingPropertyOrThrow(type, name, PropertySignature.Create(CallingConventions.Standard | CallingConventions.HasThis, propertyType, null, new PackedCustomModifiers()));
514                 }
515
516                 [Obsolete("Use Constructor.DeclaringType instead.")]
517                 internal bool __TryReadTypeName(out string ns, out string name)
518                 {
519                         if (Constructor.DeclaringType.IsNested)
520                         {
521                                 ns = null;
522                                 name = null;
523                                 return false;
524                         }
525                         ns = Constructor.DeclaringType.__Namespace;
526                         name = Constructor.DeclaringType.__Name;
527                         return true;
528                 }
529
530                 public byte[] __GetBlob()
531                 {
532                         if (declSecurityBlob != null)
533                         {
534                                 return (byte[])declSecurityBlob.Clone();
535                         }
536                         else if (customAttributeIndex == -1)
537                         {
538                                 return __ToBuilder().GetBlob(module.Assembly);
539                         }
540                         else
541                         {
542                                 return ((ModuleReader)module).GetBlobCopy(module.CustomAttribute.records[customAttributeIndex].Value);
543                         }
544                 }
545
546                 public int __Parent
547                 {
548                         get
549                         {
550                                 return customAttributeIndex >= 0
551                                         ? module.CustomAttribute.records[customAttributeIndex].Parent
552                                         : declSecurityIndex >= 0
553                                                 ? module.DeclSecurity.records[declSecurityIndex].Parent
554                                                 : 0;
555                         }
556                 }
557
558                 public ConstructorInfo Constructor
559                 {
560                         get
561                         {
562                                 if (lazyConstructor == null)
563                                 {
564                                         lazyConstructor = (ConstructorInfo)module.ResolveMethod(module.CustomAttribute.records[customAttributeIndex].Type);
565                                 }
566                                 return lazyConstructor;
567                         }
568                 }
569
570                 public IList<CustomAttributeTypedArgument> ConstructorArguments
571                 {
572                         get
573                         {
574                                 if (lazyConstructorArguments == null)
575                                 {
576                                         LazyParseArguments();
577                                 }
578                                 return lazyConstructorArguments;
579                         }
580                 }
581
582                 public IList<CustomAttributeNamedArgument> NamedArguments
583                 {
584                         get
585                         {
586                                 if (lazyNamedArguments == null)
587                                 {
588                                         if (customAttributeIndex >= 0)
589                                         {
590                                                 // 1) Unresolved Custom Attribute
591                                                 LazyParseArguments();
592                                         }
593                                         else
594                                         {
595                                                 // 5) Unresolved declarative security
596                                                 ByteReader br = new ByteReader(declSecurityBlob, 0, declSecurityBlob.Length);
597                                                 // LAMESPEC the count of named arguments is a compressed integer (instead of UInt16 as NumNamed in custom attributes)
598                                                 lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadCompressedInt(), Constructor.DeclaringType);
599                                         }
600                                 }
601                                 return lazyNamedArguments;
602                         }
603                 }
604
605                 private void LazyParseArguments()
606                 {
607                         ByteReader br = module.GetBlob(module.CustomAttribute.records[customAttributeIndex].Value);
608                         if (br.Length == 0)
609                         {
610                                 // it's legal to have an empty blob
611                                 lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array;
612                                 lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
613                         }
614                         else
615                         {
616                                 if (br.ReadUInt16() != 1)
617                                 {
618                                         throw new BadImageFormatException();
619                                 }
620                                 lazyConstructorArguments = ReadConstructorArguments(module.Assembly, br, Constructor);
621                                 lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadUInt16(), Constructor.DeclaringType);
622                         }
623                 }
624
625                 public CustomAttributeBuilder __ToBuilder()
626                 {
627                         ParameterInfo[] parameters = Constructor.GetParameters();
628                         object[] args = new object[ConstructorArguments.Count];
629                         for (int i = 0; i < args.Length; i++)
630                         {
631                                 args[i] = RewrapArray(parameters[i].ParameterType, ConstructorArguments[i]);
632                         }
633                         List<PropertyInfo> namedProperties = new List<PropertyInfo>();
634                         List<object> propertyValues = new List<object>();
635                         List<FieldInfo> namedFields = new List<FieldInfo>();
636                         List<object> fieldValues = new List<object>();
637                         foreach (CustomAttributeNamedArgument named in NamedArguments)
638                         {
639                                 PropertyInfo pi = named.MemberInfo as PropertyInfo;
640                                 if (pi != null)
641                                 {
642                                         namedProperties.Add(pi);
643                                         propertyValues.Add(RewrapArray(pi.PropertyType, named.TypedValue));
644                                 }
645                                 else
646                                 {
647                                         FieldInfo fi = (FieldInfo)named.MemberInfo;
648                                         namedFields.Add(fi);
649                                         fieldValues.Add(RewrapArray(fi.FieldType, named.TypedValue));
650                                 }
651                         }
652                         return new CustomAttributeBuilder(Constructor, args, namedProperties.ToArray(), propertyValues.ToArray(), namedFields.ToArray(), fieldValues.ToArray());
653                 }
654
655                 private static object RewrapArray(Type type, CustomAttributeTypedArgument arg)
656                 {
657                         IList<CustomAttributeTypedArgument> list = arg.Value as IList<CustomAttributeTypedArgument>;
658                         if (list != null)
659                         {
660                                 Type elementType = arg.ArgumentType.GetElementType();
661                                 object[] arr = new object[list.Count];
662                                 for (int i = 0; i < arr.Length; i++)
663                                 {
664                                         arr[i] = RewrapArray(elementType, list[i]);
665                                 }
666                                 if (type == type.Module.universe.System_Object)
667                                 {
668                                         return CustomAttributeBuilder.__MakeTypedArgument(arg.ArgumentType, arr);
669                                 }
670                                 return arr;
671                         }
672                         else
673                         {
674                                 return arg.Value;
675                         }
676                 }
677
678                 public static IList<CustomAttributeData> GetCustomAttributes(MemberInfo member)
679                 {
680                         return member.GetCustomAttributesData(null);
681                 }
682
683                 public static IList<CustomAttributeData> GetCustomAttributes(Assembly assembly)
684                 {
685                         return assembly.GetCustomAttributesData(null);
686                 }
687
688                 public static IList<CustomAttributeData> GetCustomAttributes(Module module)
689                 {
690                         return module.GetCustomAttributesData(null);
691                 }
692
693                 public static IList<CustomAttributeData> GetCustomAttributes(ParameterInfo parameter)
694                 {
695                         return parameter.GetCustomAttributesData(null);
696                 }
697
698                 public static IList<CustomAttributeData> __GetCustomAttributes(Assembly assembly, Type attributeType, bool inherit)
699                 {
700                         return assembly.GetCustomAttributesData(attributeType);
701                 }
702
703                 public static IList<CustomAttributeData> __GetCustomAttributes(Module module, Type attributeType, bool inherit)
704                 {
705                         return module.GetCustomAttributesData(attributeType);
706                 }
707
708                 public static IList<CustomAttributeData> __GetCustomAttributes(ParameterInfo parameter, Type attributeType, bool inherit)
709                 {
710                         return parameter.GetCustomAttributesData(attributeType);
711                 }
712
713                 public static IList<CustomAttributeData> __GetCustomAttributes(MemberInfo member, Type attributeType, bool inherit)
714                 {
715                         if (!inherit || !IsInheritableAttribute(attributeType))
716                         {
717                                 return member.GetCustomAttributesData(attributeType);
718                         }
719                         List<CustomAttributeData> list = new List<CustomAttributeData>();
720                         for (; ; )
721                         {
722                                 list.AddRange(member.GetCustomAttributesData(attributeType));
723                                 Type type = member as Type;
724                                 if (type != null)
725                                 {
726                                         type = type.BaseType;
727                                         if (type == null)
728                                         {
729                                                 return list;
730                                         }
731                                         member = type;
732                                         continue;
733                                 }
734                                 MethodInfo method = member as MethodInfo;
735                                 if (method != null)
736                                 {
737                                         MemberInfo prev = member;
738                                         method = method.GetBaseDefinition();
739                                         if (method == null || method == prev)
740                                         {
741                                                 return list;
742                                         }
743                                         member = method;
744                                         continue;
745                                 }
746                                 return list;
747                         }
748                 }
749
750                 public static IList<CustomAttributeData> __GetCustomAttributes(Type type, Type interfaceType, Type attributeType, bool inherit)
751                 {
752                         return type.GetInterfaceImplCustomAttributes(interfaceType, attributeType);
753                 }
754
755                 public static IList<CustomAttributeData> __GetDeclarativeSecurity(Assembly assembly)
756                 {
757                         if (assembly.__IsMissing)
758                         {
759                                 throw new MissingAssemblyException((MissingAssembly)assembly);
760                         }
761                         return assembly.ManifestModule.GetDeclarativeSecurity(0x20000001);
762                 }
763
764                 public static IList<CustomAttributeData> __GetDeclarativeSecurity(Type type)
765                 {
766                         if ((type.Attributes & TypeAttributes.HasSecurity) != 0)
767                         {
768                                 return type.Module.GetDeclarativeSecurity(type.MetadataToken);
769                         }
770                         else
771                         {
772                                 return EmptyList;
773                         }
774                 }
775
776                 public static IList<CustomAttributeData> __GetDeclarativeSecurity(MethodBase method)
777                 {
778                         if ((method.Attributes & MethodAttributes.HasSecurity) != 0)
779                         {
780                                 return method.Module.GetDeclarativeSecurity(method.MetadataToken);
781                         }
782                         else
783                         {
784                                 return EmptyList;
785                         }
786                 }
787
788                 private static bool IsInheritableAttribute(Type attribute)
789                 {
790                         Type attributeUsageAttribute = attribute.Module.universe.System_AttributeUsageAttribute;
791                         IList<CustomAttributeData> attr = attribute.GetCustomAttributesData(attributeUsageAttribute);
792                         if (attr.Count != 0)
793                         {
794                                 foreach (CustomAttributeNamedArgument named in attr[0].NamedArguments)
795                                 {
796                                         if (named.MemberInfo.Name == "Inherited")
797                                         {
798                                                 return (bool)named.TypedValue.Value;
799                                         }
800                                 }
801                         }
802                         return true;
803                 }
804         }
805 }