2
Copyright (C) 2009-2012 Jeroen Frijters
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.
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:
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.
25
using System.Collections.Generic;
28
using IKVM.Reflection.Reader;
29
using IKVM.Reflection.Emit;
30
using IKVM.Reflection.Metadata;
32
namespace IKVM.Reflection
34
public sealed class CustomAttributeData
36
internal static readonly IList<CustomAttributeData> EmptyList = new List<CustomAttributeData>(0).AsReadOnly();
39
* There are several states a CustomAttributeData object can be in:
41
* 1) Unresolved Custom Attribute
42
* - customAttributeIndex >= 0
43
* - declSecurityIndex == -1
44
* - declSecurityBlob == null
45
* - lazyConstructor = null
46
* - lazyConstructorArguments = null
47
* - lazyNamedArguments = null
49
* 2) Resolved Custom Attribute
50
* - customAttributeIndex >= 0
51
* - declSecurityIndex == -1
52
* - declSecurityBlob == null
53
* - lazyConstructor != null
54
* - lazyConstructorArguments != null
55
* - lazyNamedArguments != null
57
* 3) Pre-resolved Custom Attribute
58
* - customAttributeIndex = -1
59
* - declSecurityIndex == -1
60
* - declSecurityBlob == null
61
* - lazyConstructor != null
62
* - lazyConstructorArguments != null
63
* - lazyNamedArguments != null
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
73
* 5) Unresolved declarative security
74
* - customAttributeIndex = -1
75
* - declSecurityIndex >= 0
76
* - declSecurityBlob != null
77
* - lazyConstructor != null
78
* - lazyConstructorArguments != null
79
* - lazyNamedArguments == null
81
* 6) Resolved declarative security
82
* - customAttributeIndex = -1
83
* - declSecurityIndex >= 0
84
* - declSecurityBlob == null
85
* - lazyConstructor != null
86
* - lazyConstructorArguments != null
87
* - lazyNamedArguments != null
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;
98
// 1) Unresolved Custom Attribute
99
internal CustomAttributeData(Module module, int index)
101
this.module = module;
102
this.customAttributeIndex = index;
103
this.declSecurityIndex = -1;
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)
112
private static List<CustomAttributeTypedArgument> WrapConstructorArgs(object[] args, MethodSignature sig)
114
List<CustomAttributeTypedArgument> list = new List<CustomAttributeTypedArgument>();
115
for (int i = 0; i < args.Length; i++)
117
list.Add(new CustomAttributeTypedArgument(sig.GetParameterType(i), args[i]));
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)
125
this.module = module;
126
this.customAttributeIndex = -1;
127
this.declSecurityIndex = -1;
128
this.lazyConstructor = constructor;
129
lazyConstructorArguments = constructorArgs.AsReadOnly();
130
if (namedArguments == null)
132
this.lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
136
this.lazyNamedArguments = namedArguments.AsReadOnly();
140
// 3) Pre-resolved Custom Attribute
141
internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, ByteReader br)
143
this.module = asm.ManifestModule;
144
this.customAttributeIndex = -1;
145
this.declSecurityIndex = -1;
146
this.lazyConstructor = constructor;
149
// it's legal to have an empty blob
150
lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array;
151
lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
155
if (br.ReadUInt16() != 1)
157
throw new BadImageFormatException();
159
lazyConstructorArguments = ReadConstructorArguments(asm, br, constructor);
160
lazyNamedArguments = ReadNamedArguments(asm, br, br.ReadUInt16(), constructor.DeclaringType);
164
public override string ToString()
166
StringBuilder sb = new StringBuilder();
168
sb.Append(Constructor.DeclaringType.FullName);
171
ParameterInfo[] parameters = Constructor.GetParameters();
172
IList<CustomAttributeTypedArgument> args = ConstructorArguments;
173
for (int i = 0; i < parameters.Length; i++)
177
AppendValue(sb, parameters[i].ParameterType, args[i]);
179
foreach (CustomAttributeNamedArgument named in NamedArguments)
183
sb.Append(named.MemberInfo.Name);
185
FieldInfo fi = named.MemberInfo as FieldInfo;
186
Type type = fi != null ? fi.FieldType : ((PropertyInfo)named.MemberInfo).PropertyType;
187
AppendValue(sb, type, named.TypedValue);
191
return sb.ToString();
194
private static void AppendValue(StringBuilder sb, Type type, CustomAttributeTypedArgument arg)
196
if (arg.ArgumentType == arg.ArgumentType.Module.universe.System_String)
198
sb.Append('"').Append(arg.Value).Append('"');
200
else if (arg.ArgumentType.IsArray)
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)
209
elementTypeName = elementType.Name;
213
elementTypeName = elementType.FullName;
215
sb.Append("new ").Append(elementTypeName).Append("[").Append(((Array)arg.Value).Length).Append("] { ");
217
foreach (CustomAttributeTypedArgument elem in (CustomAttributeTypedArgument[])arg.Value)
221
AppendValue(sb, elementType, elem);
227
if (arg.ArgumentType != type || (type.IsEnum && !arg.Value.Equals(0)))
230
sb.Append(arg.ArgumentType.FullName);
233
sb.Append(arg.Value);
237
internal static void ReadDeclarativeSecurity(Module module, int index, List<CustomAttributeData> list)
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() == '.')
246
int count = br.ReadCompressedUInt();
247
for (int j = 0; j < count; j++)
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.ReadCompressedUInt());
253
list.Add(new CustomAttributeData(asm, constructor, action, blob, index));
258
// .NET 1.x format (xml)
259
char[] buf = new char[br.Length / 2];
260
for (int i = 0; i < buf.Length; i++)
262
buf[i] = br.ReadChar();
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));
273
// 5) Unresolved declarative security
274
internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, int securityAction, byte[] blob, int index)
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;
287
private static Type ReadFieldOrPropType(Assembly asm, ByteReader br)
289
Universe u = asm.universe;
290
switch (br.ReadByte())
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();
321
return ReadType(asm, br);
323
return u.System_Type;
325
return u.System_Object;
327
throw new BadImageFormatException();
331
private static CustomAttributeTypedArgument ReadFixedArg(Assembly asm, ByteReader br, Type type)
333
Universe u = asm.universe;
334
if (type == u.System_String)
336
return new CustomAttributeTypedArgument(type, br.ReadString());
338
else if (type == u.System_Boolean)
340
return new CustomAttributeTypedArgument(type, br.ReadByte() != 0);
342
else if (type == u.System_Char)
344
return new CustomAttributeTypedArgument(type, br.ReadChar());
346
else if (type == u.System_Single)
348
return new CustomAttributeTypedArgument(type, br.ReadSingle());
350
else if (type == u.System_Double)
352
return new CustomAttributeTypedArgument(type, br.ReadDouble());
354
else if (type == u.System_SByte)
356
return new CustomAttributeTypedArgument(type, br.ReadSByte());
358
else if (type == u.System_Int16)
360
return new CustomAttributeTypedArgument(type, br.ReadInt16());
362
else if (type == u.System_Int32)
364
return new CustomAttributeTypedArgument(type, br.ReadInt32());
366
else if (type == u.System_Int64)
368
return new CustomAttributeTypedArgument(type, br.ReadInt64());
370
else if (type == u.System_Byte)
372
return new CustomAttributeTypedArgument(type, br.ReadByte());
374
else if (type == u.System_UInt16)
376
return new CustomAttributeTypedArgument(type, br.ReadUInt16());
378
else if (type == u.System_UInt32)
380
return new CustomAttributeTypedArgument(type, br.ReadUInt32());
382
else if (type == u.System_UInt64)
384
return new CustomAttributeTypedArgument(type, br.ReadUInt64());
386
else if (type == u.System_Type)
388
return new CustomAttributeTypedArgument(type, ReadType(asm, br));
390
else if (type == u.System_Object)
392
return ReadFixedArg(asm, br, ReadFieldOrPropType(asm, br));
394
else if (type.IsArray)
396
int length = br.ReadInt32();
399
return new CustomAttributeTypedArgument(type, null);
401
Type elementType = type.GetElementType();
402
CustomAttributeTypedArgument[] array = new CustomAttributeTypedArgument[length];
403
for (int i = 0; i < length; i++)
405
array[i] = ReadFixedArg(asm, br, elementType);
407
return new CustomAttributeTypedArgument(type, array);
409
else if (type.IsEnum)
411
return new CustomAttributeTypedArgument(type, ReadFixedArg(asm, br, type.GetEnumUnderlyingTypeImpl()).Value);
415
throw new InvalidOperationException();
419
private static Type ReadType(Assembly asm, ByteReader br)
421
string typeName = br.ReadString();
422
if (typeName == null)
426
if (typeName.Length > 0 && typeName[typeName.Length - 1] == 0)
428
// there are broken compilers that emit an extra NUL character after the type name
429
typeName = typeName.Substring(0, typeName.Length - 1);
431
return TypeNameParser.Parse(typeName, true).GetType(asm.universe, asm, true, typeName, true, false);
434
private static IList<CustomAttributeTypedArgument> ReadConstructorArguments(Assembly asm, ByteReader br, ConstructorInfo constructor)
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++)
441
list.Add(ReadFixedArg(asm, br, sig.GetParameterType(i)));
443
return list.AsReadOnly();
446
private static IList<CustomAttributeNamedArgument> ReadNamedArguments(Assembly asm, ByteReader br, int named, Type type)
448
List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>(named);
449
for (int i = 0; i < named; i++)
451
byte fieldOrProperty = br.ReadByte();
452
Type fieldOrPropertyType = ReadFieldOrPropType(asm, br);
453
string name = br.ReadString();
454
CustomAttributeTypedArgument value = ReadFixedArg(asm, br, fieldOrPropertyType);
456
switch (fieldOrProperty)
459
member = GetField(type, name, fieldOrPropertyType);
462
member = GetProperty(type, name, fieldOrPropertyType);
465
throw new BadImageFormatException();
467
list.Add(new CustomAttributeNamedArgument(member, value));
469
return list.AsReadOnly();
472
private static FieldInfo GetField(Type type, string name, Type fieldType)
475
for (; type != null && !type.__IsMissing; type = type.BaseType)
477
foreach (FieldInfo field in type.__GetDeclaredFields())
479
if (field.IsPublic && !field.IsStatic && field.Name == name)
485
// if the field is missing, we stick the missing field on the first missing base type
490
FieldSignature sig = FieldSignature.Create(fieldType, new CustomModifiers());
491
return type.FindField(name, sig)
492
?? type.Module.universe.GetMissingFieldOrThrow(type, name, sig);
495
private static PropertyInfo GetProperty(Type type, string name, Type propertyType)
498
for (; type != null && !type.__IsMissing; type = type.BaseType)
500
foreach (PropertyInfo property in type.__GetDeclaredProperties())
502
if (property.IsPublic && !property.IsStatic && property.Name == name)
508
// if the property is missing, we stick the missing property on the first missing base type
513
return type.Module.universe.GetMissingPropertyOrThrow(type, name, PropertySignature.Create(CallingConventions.Standard | CallingConventions.HasThis, propertyType, null, new PackedCustomModifiers()));
516
[Obsolete("Use AttributeType property instead.")]
517
internal bool __TryReadTypeName(out string ns, out string name)
519
if (Constructor.DeclaringType.IsNested)
525
ns = Constructor.DeclaringType.__Namespace;
526
name = Constructor.DeclaringType.__Name;
530
public byte[] __GetBlob()
532
if (declSecurityBlob != null)
534
return (byte[])declSecurityBlob.Clone();
536
else if (customAttributeIndex == -1)
538
return __ToBuilder().GetBlob(module.Assembly);
542
return ((ModuleReader)module).GetBlobCopy(module.CustomAttribute.records[customAttributeIndex].Value);
550
return customAttributeIndex >= 0
551
? module.CustomAttribute.records[customAttributeIndex].Parent
552
: declSecurityIndex >= 0
553
? module.DeclSecurity.records[declSecurityIndex].Parent
559
public Type AttributeType
561
get { return Constructor.DeclaringType; }
564
public ConstructorInfo Constructor
568
if (lazyConstructor == null)
570
lazyConstructor = (ConstructorInfo)module.ResolveMethod(module.CustomAttribute.records[customAttributeIndex].Type);
572
return lazyConstructor;
576
public IList<CustomAttributeTypedArgument> ConstructorArguments
580
if (lazyConstructorArguments == null)
582
LazyParseArguments();
584
return lazyConstructorArguments;
588
public IList<CustomAttributeNamedArgument> NamedArguments
592
if (lazyNamedArguments == null)
594
if (customAttributeIndex >= 0)
596
// 1) Unresolved Custom Attribute
597
LazyParseArguments();
601
// 5) Unresolved declarative security
602
ByteReader br = new ByteReader(declSecurityBlob, 0, declSecurityBlob.Length);
603
// LAMESPEC the count of named arguments is a compressed integer (instead of UInt16 as NumNamed in custom attributes)
604
lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadCompressedUInt(), Constructor.DeclaringType);
607
return lazyNamedArguments;
611
private void LazyParseArguments()
613
ByteReader br = module.GetBlob(module.CustomAttribute.records[customAttributeIndex].Value);
616
// it's legal to have an empty blob
617
lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array;
618
lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
622
if (br.ReadUInt16() != 1)
624
throw new BadImageFormatException();
626
lazyConstructorArguments = ReadConstructorArguments(module.Assembly, br, Constructor);
627
lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadUInt16(), Constructor.DeclaringType);
631
public CustomAttributeBuilder __ToBuilder()
633
ParameterInfo[] parameters = Constructor.GetParameters();
634
object[] args = new object[ConstructorArguments.Count];
635
for (int i = 0; i < args.Length; i++)
637
args[i] = RewrapArray(parameters[i].ParameterType, ConstructorArguments[i]);
639
List<PropertyInfo> namedProperties = new List<PropertyInfo>();
640
List<object> propertyValues = new List<object>();
641
List<FieldInfo> namedFields = new List<FieldInfo>();
642
List<object> fieldValues = new List<object>();
643
foreach (CustomAttributeNamedArgument named in NamedArguments)
645
PropertyInfo pi = named.MemberInfo as PropertyInfo;
648
namedProperties.Add(pi);
649
propertyValues.Add(RewrapArray(pi.PropertyType, named.TypedValue));
653
FieldInfo fi = (FieldInfo)named.MemberInfo;
655
fieldValues.Add(RewrapArray(fi.FieldType, named.TypedValue));
658
return new CustomAttributeBuilder(Constructor, args, namedProperties.ToArray(), propertyValues.ToArray(), namedFields.ToArray(), fieldValues.ToArray());
661
private static object RewrapArray(Type type, CustomAttributeTypedArgument arg)
663
IList<CustomAttributeTypedArgument> list = arg.Value as IList<CustomAttributeTypedArgument>;
666
Type elementType = arg.ArgumentType.GetElementType();
667
object[] arr = new object[list.Count];
668
for (int i = 0; i < arr.Length; i++)
670
arr[i] = RewrapArray(elementType, list[i]);
672
if (type == type.Module.universe.System_Object)
674
return CustomAttributeBuilder.__MakeTypedArgument(arg.ArgumentType, arr);
684
public static IList<CustomAttributeData> GetCustomAttributes(MemberInfo member)
686
return __GetCustomAttributes(member, null, false);
689
public static IList<CustomAttributeData> GetCustomAttributes(Assembly assembly)
691
return assembly.GetCustomAttributesData(null);
694
public static IList<CustomAttributeData> GetCustomAttributes(Module module)
696
return __GetCustomAttributes(module, null, false);
699
public static IList<CustomAttributeData> GetCustomAttributes(ParameterInfo parameter)
701
return __GetCustomAttributes(parameter, null, false);
704
public static IList<CustomAttributeData> __GetCustomAttributes(Assembly assembly, Type attributeType, bool inherit)
706
return assembly.GetCustomAttributesData(attributeType);
709
public static IList<CustomAttributeData> __GetCustomAttributes(Module module, Type attributeType, bool inherit)
711
if (module.__IsMissing)
713
throw new MissingModuleException((MissingModule)module);
715
return GetCustomAttributesImpl(null, module, 0x00000001, attributeType) ?? EmptyList;
718
public static IList<CustomAttributeData> __GetCustomAttributes(ParameterInfo parameter, Type attributeType, bool inherit)
720
Module module = parameter.Module;
721
List<CustomAttributeData> list = null;
722
if (module.universe.ReturnPseudoCustomAttributes)
724
if (attributeType == null || attributeType.IsAssignableFrom(parameter.Module.universe.System_Runtime_InteropServices_MarshalAsAttribute))
727
if (parameter.__TryGetFieldMarshal(out spec))
731
list = new List<CustomAttributeData>();
733
list.Add(CustomAttributeData.CreateMarshalAsPseudoCustomAttribute(parameter.Module, spec));
737
ModuleBuilder mb = module as ModuleBuilder;
738
int token = parameter.MetadataToken;
739
if (mb != null && mb.IsSaved && ModuleBuilder.IsPseudoToken(token))
741
token = mb.ResolvePseudoToken(token);
743
return GetCustomAttributesImpl(list, module, token, attributeType) ?? EmptyList;
746
public static IList<CustomAttributeData> __GetCustomAttributes(MemberInfo member, Type attributeType, bool inherit)
750
// like .NET we we don't return custom attributes for unbaked members
751
throw new NotImplementedException();
753
if (!inherit || !IsInheritableAttribute(attributeType))
755
return GetCustomAttributesImpl(null, member, attributeType) ?? EmptyList;
757
List<CustomAttributeData> list = new List<CustomAttributeData>();
760
GetCustomAttributesImpl(list, member, attributeType);
761
Type type = member as Type;
764
type = type.BaseType;
772
MethodInfo method = member as MethodInfo;
775
MemberInfo prev = member;
776
method = method.GetBaseDefinition();
777
if (method == null || method == prev)
788
private static List<CustomAttributeData> GetCustomAttributesImpl(List<CustomAttributeData> list, MemberInfo member, Type attributeType)
790
if (member.Module.universe.ReturnPseudoCustomAttributes)
792
List<CustomAttributeData> pseudo = member.GetPseudoCustomAttributes(attributeType);
797
else if (pseudo != null)
799
list.AddRange(pseudo);
802
return GetCustomAttributesImpl(list, member.Module, member.GetCurrentToken(), attributeType);
805
internal static List<CustomAttributeData> GetCustomAttributesImpl(List<CustomAttributeData> list, Module module, int token, Type attributeType)
807
foreach (int i in module.CustomAttribute.Filter(token))
809
if (attributeType == null)
813
list = new List<CustomAttributeData>();
815
list.Add(new CustomAttributeData(module, i));
819
if (attributeType.IsAssignableFrom(module.ResolveMethod(module.CustomAttribute.records[i].Type).DeclaringType))
823
list = new List<CustomAttributeData>();
825
list.Add(new CustomAttributeData(module, i));
832
public static IList<CustomAttributeData> __GetCustomAttributes(Type type, Type interfaceType, Type attributeType, bool inherit)
834
Module module = type.Module;
835
foreach (int i in module.InterfaceImpl.Filter(type.MetadataToken))
837
if (module.ResolveType(module.InterfaceImpl.records[i].Interface, type) == interfaceType)
839
return GetCustomAttributesImpl(null, module, (InterfaceImplTable.Index << 24) | (i + 1), attributeType) ?? EmptyList;
845
public static IList<CustomAttributeData> __GetDeclarativeSecurity(Assembly assembly)
847
if (assembly.__IsMissing)
849
throw new MissingAssemblyException((MissingAssembly)assembly);
851
return assembly.ManifestModule.GetDeclarativeSecurity(0x20000001);
854
public static IList<CustomAttributeData> __GetDeclarativeSecurity(Type type)
856
if ((type.Attributes & TypeAttributes.HasSecurity) != 0)
858
return type.Module.GetDeclarativeSecurity(type.MetadataToken);
866
public static IList<CustomAttributeData> __GetDeclarativeSecurity(MethodBase method)
868
if ((method.Attributes & MethodAttributes.HasSecurity) != 0)
870
return method.Module.GetDeclarativeSecurity(method.MetadataToken);
878
private static bool IsInheritableAttribute(Type attribute)
880
Type attributeUsageAttribute = attribute.Module.universe.System_AttributeUsageAttribute;
881
IList<CustomAttributeData> attr = __GetCustomAttributes(attribute, attributeUsageAttribute, false);
884
foreach (CustomAttributeNamedArgument named in attr[0].NamedArguments)
886
if (named.MemberInfo.Name == "Inherited")
888
return (bool)named.TypedValue.Value;
895
internal static CustomAttributeData CreateDllImportPseudoCustomAttribute(Module module, ImplMapFlags flags, string entryPoint, string dllName, MethodImplAttributes attr)
897
Type type = module.universe.System_Runtime_InteropServices_DllImportAttribute;
898
ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(module.universe.System_String);
899
List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>();
900
System.Runtime.InteropServices.CharSet charSet;
901
switch (flags & ImplMapFlags.CharSetMask)
903
case ImplMapFlags.CharSetAnsi:
904
charSet = System.Runtime.InteropServices.CharSet.Ansi;
906
case ImplMapFlags.CharSetUnicode:
907
charSet = System.Runtime.InteropServices.CharSet.Unicode;
909
case ImplMapFlags.CharSetAuto:
910
charSet = System.Runtime.InteropServices.CharSet.Auto;
912
case ImplMapFlags.CharSetNotSpec:
914
charSet = System.Runtime.InteropServices.CharSet.None;
917
System.Runtime.InteropServices.CallingConvention callingConvention;
918
switch (flags & ImplMapFlags.CallConvMask)
920
case ImplMapFlags.CallConvCdecl:
921
callingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl;
923
case ImplMapFlags.CallConvFastcall:
924
callingConvention = System.Runtime.InteropServices.CallingConvention.FastCall;
926
case ImplMapFlags.CallConvStdcall:
927
callingConvention = System.Runtime.InteropServices.CallingConvention.StdCall;
929
case ImplMapFlags.CallConvThiscall:
930
callingConvention = System.Runtime.InteropServices.CallingConvention.ThisCall;
932
case ImplMapFlags.CallConvWinapi:
933
callingConvention = System.Runtime.InteropServices.CallingConvention.Winapi;
936
callingConvention = 0;
939
AddNamedArgument(list, type, "EntryPoint", entryPoint);
940
AddNamedArgument(list, type, "CharSet", module.universe.System_Runtime_InteropServices_CharSet, (int)charSet);
941
AddNamedArgument(list, type, "ExactSpelling", (int)flags, (int)ImplMapFlags.NoMangle);
942
AddNamedArgument(list, type, "SetLastError", (int)flags, (int)ImplMapFlags.SupportsLastError);
943
AddNamedArgument(list, type, "PreserveSig", (int)attr, (int)MethodImplAttributes.PreserveSig);
944
AddNamedArgument(list, type, "CallingConvention", module.universe.System_Runtime_InteropServices_CallingConvention, (int)callingConvention);
945
AddNamedArgument(list, type, "BestFitMapping", (int)flags, (int)ImplMapFlags.BestFitOn);
946
AddNamedArgument(list, type, "ThrowOnUnmappableChar", (int)flags, (int)ImplMapFlags.CharMapErrorOn);
947
return new CustomAttributeData(module, constructor, new object[] { dllName }, list);
950
internal static CustomAttributeData CreateMarshalAsPseudoCustomAttribute(Module module, FieldMarshal fm)
952
Type typeofMarshalAs = module.universe.System_Runtime_InteropServices_MarshalAsAttribute;
953
Type typeofUnmanagedType = module.universe.System_Runtime_InteropServices_UnmanagedType;
954
Type typeofVarEnum = module.universe.System_Runtime_InteropServices_VarEnum;
955
Type typeofType = module.universe.System_Type;
956
List<CustomAttributeNamedArgument> named = new List<CustomAttributeNamedArgument>();
957
AddNamedArgument(named, typeofMarshalAs, "ArraySubType", typeofUnmanagedType, (int)(fm.ArraySubType ?? 0));
958
AddNamedArgument(named, typeofMarshalAs, "SizeParamIndex", module.universe.System_Int16, fm.SizeParamIndex ?? 0);
959
AddNamedArgument(named, typeofMarshalAs, "SizeConst", module.universe.System_Int32, fm.SizeConst ?? 0);
960
AddNamedArgument(named, typeofMarshalAs, "IidParameterIndex", module.universe.System_Int32, fm.IidParameterIndex ?? 0);
961
AddNamedArgument(named, typeofMarshalAs, "SafeArraySubType", typeofVarEnum, (int)(fm.SafeArraySubType ?? 0));
962
if (fm.SafeArrayUserDefinedSubType != null)
964
AddNamedArgument(named, typeofMarshalAs, "SafeArrayUserDefinedSubType", typeofType, fm.SafeArrayUserDefinedSubType);
966
if (fm.MarshalType != null)
968
AddNamedArgument(named, typeofMarshalAs, "MarshalType", module.universe.System_String, fm.MarshalType);
970
if (fm.MarshalTypeRef != null)
972
AddNamedArgument(named, typeofMarshalAs, "MarshalTypeRef", module.universe.System_Type, fm.MarshalTypeRef);
974
if (fm.MarshalCookie != null)
976
AddNamedArgument(named, typeofMarshalAs, "MarshalCookie", module.universe.System_String, fm.MarshalCookie);
978
ConstructorInfo constructor = typeofMarshalAs.GetPseudoCustomAttributeConstructor(typeofUnmanagedType);
979
return new CustomAttributeData(module, constructor, new object[] { (int)fm.UnmanagedType }, named);
982
private static void AddNamedArgument(List<CustomAttributeNamedArgument> list, Type type, string fieldName, string value)
984
AddNamedArgument(list, type, fieldName, type.Module.universe.System_String, value);
987
private static void AddNamedArgument(List<CustomAttributeNamedArgument> list, Type type, string fieldName, int flags, int flagMask)
989
AddNamedArgument(list, type, fieldName, type.Module.universe.System_Boolean, (flags & flagMask) != 0);
992
private static void AddNamedArgument(List<CustomAttributeNamedArgument> list, Type attributeType, string fieldName, Type valueType, object value)
994
// some fields are not available on the .NET Compact Framework version of DllImportAttribute/MarshalAsAttribute
995
FieldInfo field = attributeType.FindField(fieldName, FieldSignature.Create(valueType, new CustomModifiers()));
998
list.Add(new CustomAttributeNamedArgument(field, new CustomAttributeTypedArgument(valueType, value)));
1002
internal static CustomAttributeData CreateFieldOffsetPseudoCustomAttribute(Module module, int offset)
1004
Type type = module.universe.System_Runtime_InteropServices_FieldOffsetAttribute;
1005
ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(module.universe.System_Int32);
1006
return new CustomAttributeData(module, constructor, new object[] { offset }, null);
1009
internal static CustomAttributeData CreatePreserveSigPseudoCustomAttribute(Module module)
1011
Type type = module.universe.System_Runtime_InteropServices_PreserveSigAttribute;
1012
ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor();
1013
return new CustomAttributeData(module, constructor, Empty<object>.Array, null);