/Mono.Cecil/CustomAttribute.cs

http://github.com/jbevain/cecil · C# · 220 lines · 164 code · 47 blank · 9 comment · 20 complexity · c8c8c827af50a1220fc6960f541f498c MD5 · raw file

  1. //
  2. // Author:
  3. // Jb Evain (jbevain@gmail.com)
  4. //
  5. // Copyright (c) 2008 - 2015 Jb Evain
  6. // Copyright (c) 2008 - 2011 Novell, Inc.
  7. //
  8. // Licensed under the MIT/X11 license.
  9. //
  10. using System;
  11. using System.Diagnostics;
  12. using System.Threading;
  13. using Mono.Collections.Generic;
  14. namespace Mono.Cecil {
  15. public struct CustomAttributeArgument {
  16. readonly TypeReference type;
  17. readonly object value;
  18. public TypeReference Type {
  19. get { return type; }
  20. }
  21. public object Value {
  22. get { return value; }
  23. }
  24. public CustomAttributeArgument (TypeReference type, object value)
  25. {
  26. Mixin.CheckType (type);
  27. this.type = type;
  28. this.value = value;
  29. }
  30. }
  31. public struct CustomAttributeNamedArgument {
  32. readonly string name;
  33. readonly CustomAttributeArgument argument;
  34. public string Name {
  35. get { return name; }
  36. }
  37. public CustomAttributeArgument Argument {
  38. get { return argument; }
  39. }
  40. public CustomAttributeNamedArgument (string name, CustomAttributeArgument argument)
  41. {
  42. Mixin.CheckName (name);
  43. this.name = name;
  44. this.argument = argument;
  45. }
  46. }
  47. public interface ICustomAttribute {
  48. TypeReference AttributeType { get; }
  49. bool HasFields { get; }
  50. bool HasProperties { get; }
  51. bool HasConstructorArguments { get; }
  52. Collection<CustomAttributeNamedArgument> Fields { get; }
  53. Collection<CustomAttributeNamedArgument> Properties { get; }
  54. Collection<CustomAttributeArgument> ConstructorArguments { get; }
  55. }
  56. [DebuggerDisplay ("{AttributeType}")]
  57. public sealed class CustomAttribute : ICustomAttribute {
  58. internal CustomAttributeValueProjection projection;
  59. readonly internal uint signature;
  60. internal bool resolved;
  61. MethodReference constructor;
  62. byte [] blob;
  63. internal Collection<CustomAttributeArgument> arguments;
  64. internal Collection<CustomAttributeNamedArgument> fields;
  65. internal Collection<CustomAttributeNamedArgument> properties;
  66. public MethodReference Constructor {
  67. get { return constructor; }
  68. set { constructor = value; }
  69. }
  70. public TypeReference AttributeType {
  71. get { return constructor.DeclaringType; }
  72. }
  73. public bool IsResolved {
  74. get { return resolved; }
  75. }
  76. public bool HasConstructorArguments {
  77. get {
  78. Resolve ();
  79. return !arguments.IsNullOrEmpty ();
  80. }
  81. }
  82. public Collection<CustomAttributeArgument> ConstructorArguments {
  83. get {
  84. Resolve ();
  85. if (arguments == null)
  86. Interlocked.CompareExchange (ref arguments, new Collection<CustomAttributeArgument> (), null);
  87. return arguments;
  88. }
  89. }
  90. public bool HasFields {
  91. get {
  92. Resolve ();
  93. return !fields.IsNullOrEmpty ();
  94. }
  95. }
  96. public Collection<CustomAttributeNamedArgument> Fields {
  97. get {
  98. Resolve ();
  99. if (fields == null)
  100. Interlocked.CompareExchange (ref fields, new Collection<CustomAttributeNamedArgument> (), null);
  101. return fields;
  102. }
  103. }
  104. public bool HasProperties {
  105. get {
  106. Resolve ();
  107. return !properties.IsNullOrEmpty ();
  108. }
  109. }
  110. public Collection<CustomAttributeNamedArgument> Properties {
  111. get {
  112. Resolve ();
  113. if (properties == null)
  114. Interlocked.CompareExchange (ref properties, new Collection<CustomAttributeNamedArgument> (), null);
  115. return properties;
  116. }
  117. }
  118. internal bool HasImage {
  119. get { return constructor != null && constructor.HasImage; }
  120. }
  121. internal ModuleDefinition Module {
  122. get { return constructor.Module; }
  123. }
  124. internal CustomAttribute (uint signature, MethodReference constructor)
  125. {
  126. this.signature = signature;
  127. this.constructor = constructor;
  128. this.resolved = false;
  129. }
  130. public CustomAttribute (MethodReference constructor)
  131. {
  132. this.constructor = constructor;
  133. this.resolved = true;
  134. }
  135. public CustomAttribute (MethodReference constructor, byte [] blob)
  136. {
  137. this.constructor = constructor;
  138. this.resolved = false;
  139. this.blob = blob;
  140. }
  141. public byte [] GetBlob ()
  142. {
  143. if (blob != null)
  144. return blob;
  145. if (!HasImage)
  146. throw new NotSupportedException ();
  147. return Module.Read (ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature));
  148. }
  149. void Resolve ()
  150. {
  151. if (resolved || !HasImage)
  152. return;
  153. lock (Module.SyncRoot) {
  154. if (resolved)
  155. return;
  156. Module.Read (this, (attribute, reader) => {
  157. try {
  158. reader.ReadCustomAttributeSignature (attribute);
  159. resolved = true;
  160. } catch (ResolutionException) {
  161. if (arguments != null)
  162. arguments.Clear ();
  163. if (fields != null)
  164. fields.Clear ();
  165. if (properties != null)
  166. properties.Clear ();
  167. resolved = false;
  168. }
  169. });
  170. }
  171. }
  172. }
  173. }