/main/contrib/Mono.Cecil/Mono.Cecil/Mono.Cecil/TypeReference.cs

https://github.com/jfcantin/monodevelop · C# · 327 lines · 247 code · 53 blank · 27 comment · 23 complexity · ba78761ae1e798cd741837e1f51a4cbf MD5 · raw file

  1. //
  2. // TypeReference.cs
  3. //
  4. // Author:
  5. // Jb Evain (jbevain@gmail.com)
  6. //
  7. // Copyright (c) 2008 - 2010 Jb Evain
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using Mono.Cecil.Metadata;
  30. using Mono.Collections.Generic;
  31. namespace Mono.Cecil {
  32. public enum MetadataType : byte {
  33. Void = ElementType.Void,
  34. Boolean = ElementType.Boolean,
  35. Char = ElementType.Char,
  36. SByte = ElementType.I1,
  37. Byte = ElementType.U1,
  38. Int16 = ElementType.I2,
  39. UInt16 = ElementType.U2,
  40. Int32 = ElementType.I4,
  41. UInt32 = ElementType.U4,
  42. Int64 = ElementType.I8,
  43. UInt64 = ElementType.U8,
  44. Single = ElementType.R4,
  45. Double = ElementType.R8,
  46. String = ElementType.String,
  47. Pointer = ElementType.Ptr,
  48. ByReference = ElementType.ByRef,
  49. ValueType = ElementType.ValueType,
  50. Class = ElementType.Class,
  51. Var = ElementType.Var,
  52. Array = ElementType.Array,
  53. GenericInstance = ElementType.GenericInst,
  54. TypedByReference = ElementType.TypedByRef,
  55. IntPtr = ElementType.I,
  56. UIntPtr = ElementType.U,
  57. FunctionPointer = ElementType.FnPtr,
  58. Object = ElementType.Object,
  59. MVar = ElementType.MVar,
  60. RequiredModifier = ElementType.CModReqD,
  61. OptionalModifier = ElementType.CModOpt,
  62. Sentinel = ElementType.Sentinel,
  63. Pinned = ElementType.Pinned,
  64. }
  65. public class TypeReference : MemberReference, IGenericParameterProvider, IGenericContext {
  66. string @namespace;
  67. bool value_type;
  68. internal IMetadataScope scope;
  69. internal ModuleDefinition module;
  70. internal ElementType etype = ElementType.None;
  71. string fullname;
  72. protected Collection<GenericParameter> generic_parameters;
  73. public override string Name {
  74. get { return base.Name; }
  75. set {
  76. base.Name = value;
  77. fullname = null;
  78. }
  79. }
  80. public virtual string Namespace {
  81. get { return @namespace; }
  82. set {
  83. @namespace = value;
  84. fullname = null;
  85. }
  86. }
  87. public virtual bool IsValueType {
  88. get { return value_type; }
  89. set { value_type = value; }
  90. }
  91. public override ModuleDefinition Module {
  92. get {
  93. if (module != null)
  94. return module;
  95. var declaring_type = this.DeclaringType;
  96. if (declaring_type != null)
  97. return declaring_type.Module;
  98. return null;
  99. }
  100. }
  101. IGenericParameterProvider IGenericContext.Type {
  102. get { return this; }
  103. }
  104. IGenericParameterProvider IGenericContext.Method {
  105. get { return null; }
  106. }
  107. GenericParameterType IGenericParameterProvider.GenericParameterType {
  108. get { return GenericParameterType.Type; }
  109. }
  110. public virtual bool HasGenericParameters {
  111. get { return !generic_parameters.IsNullOrEmpty (); }
  112. }
  113. public virtual Collection<GenericParameter> GenericParameters {
  114. get {
  115. if (generic_parameters != null)
  116. return generic_parameters;
  117. return generic_parameters = new Collection<GenericParameter> ();
  118. }
  119. }
  120. public virtual IMetadataScope Scope {
  121. get {
  122. var declaring_type = this.DeclaringType;
  123. if (declaring_type != null)
  124. return declaring_type.Scope;
  125. return scope;
  126. }
  127. }
  128. public bool IsNested {
  129. get { return this.DeclaringType != null; }
  130. }
  131. public override TypeReference DeclaringType {
  132. get { return base.DeclaringType; }
  133. set {
  134. base.DeclaringType = value;
  135. fullname = null;
  136. }
  137. }
  138. public override string FullName {
  139. get {
  140. if (fullname != null)
  141. return fullname;
  142. if (IsNested)
  143. return fullname = DeclaringType.FullName + "/" + Name;
  144. if (string.IsNullOrEmpty (@namespace))
  145. return fullname = Name;
  146. return fullname = @namespace + "." + Name;
  147. }
  148. }
  149. public virtual bool IsByReference {
  150. get { return false; }
  151. }
  152. public virtual bool IsPointer {
  153. get { return false; }
  154. }
  155. public virtual bool IsSentinel {
  156. get { return false; }
  157. }
  158. public virtual bool IsArray {
  159. get { return false; }
  160. }
  161. public virtual bool IsGenericParameter {
  162. get { return false; }
  163. }
  164. public virtual bool IsGenericInstance {
  165. get { return false; }
  166. }
  167. public virtual bool IsRequiredModifier {
  168. get { return false; }
  169. }
  170. public virtual bool IsOptionalModifier {
  171. get { return false; }
  172. }
  173. public virtual bool IsPinned {
  174. get { return false; }
  175. }
  176. public virtual bool IsFunctionPointer {
  177. get { return false; }
  178. }
  179. public bool IsPrimitive {
  180. get {
  181. switch (etype) {
  182. case ElementType.Boolean:
  183. case ElementType.Char:
  184. case ElementType.I:
  185. case ElementType.U:
  186. case ElementType.I1:
  187. case ElementType.U1:
  188. case ElementType.I2:
  189. case ElementType.U2:
  190. case ElementType.I4:
  191. case ElementType.U4:
  192. case ElementType.I8:
  193. case ElementType.U8:
  194. case ElementType.R4:
  195. case ElementType.R8:
  196. return true;
  197. default:
  198. return false;
  199. }
  200. }
  201. }
  202. public virtual MetadataType MetadataType {
  203. get {
  204. switch (etype) {
  205. case ElementType.None:
  206. return IsValueType ? MetadataType.ValueType : MetadataType.Class;
  207. default:
  208. return (MetadataType) etype;
  209. }
  210. }
  211. }
  212. protected TypeReference (string @namespace, string name)
  213. : base (name)
  214. {
  215. this.@namespace = @namespace ?? string.Empty;
  216. this.token = new MetadataToken (TokenType.TypeRef, 0);
  217. }
  218. public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope)
  219. : this (@namespace, name)
  220. {
  221. this.module = module;
  222. this.scope = scope;
  223. }
  224. public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) :
  225. this (@namespace, name, module, scope)
  226. {
  227. value_type = valueType;
  228. }
  229. public virtual TypeReference GetElementType ()
  230. {
  231. return this;
  232. }
  233. public virtual TypeDefinition Resolve ()
  234. {
  235. var module = this.Module;
  236. if (module == null)
  237. throw new NotSupportedException ();
  238. return module.Resolve (this);
  239. }
  240. }
  241. static partial class Mixin {
  242. public static bool IsTypeOf (this TypeReference self, string @namespace, string name)
  243. {
  244. return self.Name == name
  245. && self.Namespace == @namespace;
  246. }
  247. public static bool IsTypeSpecification (this TypeReference type)
  248. {
  249. switch (type.etype) {
  250. case ElementType.Array:
  251. case ElementType.ByRef:
  252. case ElementType.CModOpt:
  253. case ElementType.CModReqD:
  254. case ElementType.FnPtr:
  255. case ElementType.GenericInst:
  256. case ElementType.MVar:
  257. case ElementType.Pinned:
  258. case ElementType.Ptr:
  259. case ElementType.SzArray:
  260. case ElementType.Sentinel:
  261. case ElementType.Var:
  262. return true;
  263. }
  264. return false;
  265. }
  266. public static TypeDefinition CheckedResolve (this TypeReference self)
  267. {
  268. var type = self.Resolve ();
  269. if (type == null)
  270. throw new InvalidOperationException (string.Format ("Failed to resolve type: {0}", self.FullName));
  271. return type;
  272. }
  273. }
  274. }