/Mono.Cecil/GenericParameter.cs

http://github.com/jbevain/cecil · C# · 362 lines · 275 code · 78 blank · 9 comment · 26 complexity · 82382fe810fb1173d9e1bafde0e292e9 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.Threading;
  12. using Mono.Collections.Generic;
  13. using Mono.Cecil.Metadata;
  14. namespace Mono.Cecil {
  15. public sealed class GenericParameter : TypeReference, ICustomAttributeProvider {
  16. internal int position;
  17. internal GenericParameterType type;
  18. internal IGenericParameterProvider owner;
  19. ushort attributes;
  20. GenericParameterConstraintCollection constraints;
  21. Collection<CustomAttribute> custom_attributes;
  22. public GenericParameterAttributes Attributes {
  23. get { return (GenericParameterAttributes) attributes; }
  24. set { attributes = (ushort) value; }
  25. }
  26. public int Position {
  27. get { return position; }
  28. }
  29. public GenericParameterType Type {
  30. get { return type; }
  31. }
  32. public IGenericParameterProvider Owner {
  33. get { return owner; }
  34. }
  35. public bool HasConstraints {
  36. get {
  37. if (constraints != null)
  38. return constraints.Count > 0;
  39. return HasImage && Module.Read (this, (generic_parameter, reader) => reader.HasGenericConstraints (generic_parameter));
  40. }
  41. }
  42. public Collection<GenericParameterConstraint> Constraints {
  43. get {
  44. if (constraints != null)
  45. return constraints;
  46. if (HasImage)
  47. return Module.Read (ref constraints, this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter));
  48. Interlocked.CompareExchange (ref constraints, new GenericParameterConstraintCollection (this), null);
  49. return constraints;
  50. }
  51. }
  52. public bool HasCustomAttributes {
  53. get {
  54. if (custom_attributes != null)
  55. return custom_attributes.Count > 0;
  56. return this.GetHasCustomAttributes (Module);
  57. }
  58. }
  59. public Collection<CustomAttribute> CustomAttributes {
  60. get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
  61. }
  62. public override IMetadataScope Scope {
  63. get {
  64. if (owner == null)
  65. return null;
  66. return owner.GenericParameterType == GenericParameterType.Method
  67. ? ((MethodReference) owner).DeclaringType.Scope
  68. : ((TypeReference) owner).Scope;
  69. }
  70. set { throw new InvalidOperationException (); }
  71. }
  72. public override TypeReference DeclaringType {
  73. get { return owner as TypeReference; }
  74. set { throw new InvalidOperationException (); }
  75. }
  76. public MethodReference DeclaringMethod {
  77. get { return owner as MethodReference; }
  78. }
  79. public override ModuleDefinition Module {
  80. get { return module ?? owner.Module; }
  81. }
  82. public override string Name {
  83. get {
  84. if (!string.IsNullOrEmpty (base.Name))
  85. return base.Name;
  86. return base.Name = (type == GenericParameterType.Method ? "!!" : "!") + position;
  87. }
  88. }
  89. public override string Namespace {
  90. get { return string.Empty; }
  91. set { throw new InvalidOperationException (); }
  92. }
  93. public override string FullName {
  94. get { return Name; }
  95. }
  96. public override bool IsGenericParameter {
  97. get { return true; }
  98. }
  99. public override bool ContainsGenericParameter {
  100. get { return true; }
  101. }
  102. public override MetadataType MetadataType {
  103. get { return (MetadataType) etype; }
  104. }
  105. #region GenericParameterAttributes
  106. public bool IsNonVariant {
  107. get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant); }
  108. set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant, value); }
  109. }
  110. public bool IsCovariant {
  111. get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant); }
  112. set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant, value); }
  113. }
  114. public bool IsContravariant {
  115. get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant); }
  116. set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant, value); }
  117. }
  118. public bool HasReferenceTypeConstraint {
  119. get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint); }
  120. set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint, value); }
  121. }
  122. public bool HasNotNullableValueTypeConstraint {
  123. get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint); }
  124. set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint, value); }
  125. }
  126. public bool HasDefaultConstructorConstraint {
  127. get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint); }
  128. set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint, value); }
  129. }
  130. #endregion
  131. public GenericParameter (IGenericParameterProvider owner)
  132. : this (string.Empty, owner)
  133. {
  134. }
  135. public GenericParameter (string name, IGenericParameterProvider owner)
  136. : base (string.Empty, name)
  137. {
  138. if (owner == null)
  139. throw new ArgumentNullException ();
  140. this.position = -1;
  141. this.owner = owner;
  142. this.type = owner.GenericParameterType;
  143. this.etype = ConvertGenericParameterType (this.type);
  144. this.token = new MetadataToken (TokenType.GenericParam);
  145. }
  146. internal GenericParameter (int position, GenericParameterType type, ModuleDefinition module)
  147. : base (string.Empty, string.Empty)
  148. {
  149. Mixin.CheckModule (module);
  150. this.position = position;
  151. this.type = type;
  152. this.etype = ConvertGenericParameterType (type);
  153. this.module = module;
  154. this.token = new MetadataToken (TokenType.GenericParam);
  155. }
  156. static ElementType ConvertGenericParameterType (GenericParameterType type)
  157. {
  158. switch (type) {
  159. case GenericParameterType.Type:
  160. return ElementType.Var;
  161. case GenericParameterType.Method:
  162. return ElementType.MVar;
  163. }
  164. throw new ArgumentOutOfRangeException ();
  165. }
  166. public override TypeDefinition Resolve ()
  167. {
  168. return null;
  169. }
  170. }
  171. sealed class GenericParameterCollection : Collection<GenericParameter> {
  172. readonly IGenericParameterProvider owner;
  173. internal GenericParameterCollection (IGenericParameterProvider owner)
  174. {
  175. this.owner = owner;
  176. }
  177. internal GenericParameterCollection (IGenericParameterProvider owner, int capacity)
  178. : base (capacity)
  179. {
  180. this.owner = owner;
  181. }
  182. protected override void OnAdd (GenericParameter item, int index)
  183. {
  184. UpdateGenericParameter (item, index);
  185. }
  186. protected override void OnInsert (GenericParameter item, int index)
  187. {
  188. UpdateGenericParameter (item, index);
  189. for (int i = index; i < size; i++)
  190. items[i].position = i + 1;
  191. }
  192. protected override void OnSet (GenericParameter item, int index)
  193. {
  194. UpdateGenericParameter (item, index);
  195. }
  196. void UpdateGenericParameter (GenericParameter item, int index)
  197. {
  198. item.owner = owner;
  199. item.position = index;
  200. item.type = owner.GenericParameterType;
  201. }
  202. protected override void OnRemove (GenericParameter item, int index)
  203. {
  204. item.owner = null;
  205. item.position = -1;
  206. item.type = GenericParameterType.Type;
  207. for (int i = index + 1; i < size; i++)
  208. items[i].position = i - 1;
  209. }
  210. }
  211. public sealed class GenericParameterConstraint : ICustomAttributeProvider {
  212. internal GenericParameter generic_parameter;
  213. internal MetadataToken token;
  214. TypeReference constraint_type;
  215. Collection<CustomAttribute> custom_attributes;
  216. public TypeReference ConstraintType {
  217. get { return constraint_type; }
  218. set { constraint_type = value; }
  219. }
  220. public bool HasCustomAttributes {
  221. get {
  222. if (custom_attributes != null)
  223. return custom_attributes.Count > 0;
  224. if (generic_parameter == null)
  225. return false;
  226. return this.GetHasCustomAttributes (generic_parameter.Module);
  227. }
  228. }
  229. public Collection<CustomAttribute> CustomAttributes {
  230. get {
  231. if (generic_parameter == null) {
  232. if (custom_attributes == null)
  233. Interlocked.CompareExchange (ref custom_attributes, new Collection<CustomAttribute> (), null);
  234. return custom_attributes;
  235. }
  236. return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, generic_parameter.Module));
  237. }
  238. }
  239. public MetadataToken MetadataToken {
  240. get { return token; }
  241. set { token = value; }
  242. }
  243. internal GenericParameterConstraint (TypeReference constraintType, MetadataToken token)
  244. {
  245. this.constraint_type = constraintType;
  246. this.token = token;
  247. }
  248. public GenericParameterConstraint (TypeReference constraintType)
  249. {
  250. Mixin.CheckType (constraintType, Mixin.Argument.constraintType);
  251. this.constraint_type = constraintType;
  252. this.token = new MetadataToken (TokenType.GenericParamConstraint);
  253. }
  254. }
  255. class GenericParameterConstraintCollection : Collection<GenericParameterConstraint>
  256. {
  257. readonly GenericParameter generic_parameter;
  258. internal GenericParameterConstraintCollection (GenericParameter genericParameter)
  259. {
  260. this.generic_parameter = genericParameter;
  261. }
  262. internal GenericParameterConstraintCollection (GenericParameter genericParameter, int length)
  263. : base (length)
  264. {
  265. this.generic_parameter = genericParameter;
  266. }
  267. protected override void OnAdd (GenericParameterConstraint item, int index)
  268. {
  269. item.generic_parameter = generic_parameter;
  270. }
  271. protected override void OnInsert (GenericParameterConstraint item, int index)
  272. {
  273. item.generic_parameter = generic_parameter;
  274. }
  275. protected override void OnSet (GenericParameterConstraint item, int index)
  276. {
  277. item.generic_parameter = generic_parameter;
  278. }
  279. protected override void OnRemove (GenericParameterConstraint item, int index)
  280. {
  281. item.generic_parameter = null;
  282. }
  283. }
  284. }