/Mono.Cecil/Mono.Cecil/TypeDefinition.cs

http://github.com/icsharpcode/ILSpy · C# · 518 lines · 378 code · 113 blank · 27 comment · 65 complexity · ec903166b00c14661274ca94e9ba377d MD5 · raw file

  1. //
  2. // TypeDefinition.cs
  3. //
  4. // Author:
  5. // Jb Evain (jbevain@gmail.com)
  6. //
  7. // Copyright (c) 2008 - 2011 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 sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider {
  33. uint attributes;
  34. TypeReference base_type;
  35. internal Range fields_range;
  36. internal Range methods_range;
  37. short packing_size = Mixin.NotResolvedMarker;
  38. int class_size = Mixin.NotResolvedMarker;
  39. Collection<TypeReference> interfaces;
  40. Collection<TypeDefinition> nested_types;
  41. Collection<MethodDefinition> methods;
  42. Collection<FieldDefinition> fields;
  43. Collection<EventDefinition> events;
  44. Collection<PropertyDefinition> properties;
  45. Collection<CustomAttribute> custom_attributes;
  46. Collection<SecurityDeclaration> security_declarations;
  47. public TypeAttributes Attributes {
  48. get { return (TypeAttributes) attributes; }
  49. set { attributes = (uint) value; }
  50. }
  51. public TypeReference BaseType {
  52. get { return base_type; }
  53. set { base_type = value; }
  54. }
  55. void ResolveLayout ()
  56. {
  57. if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker)
  58. return;
  59. if (!HasImage) {
  60. packing_size = Mixin.NoDataMarker;
  61. class_size = Mixin.NoDataMarker;
  62. return;
  63. }
  64. var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type));
  65. packing_size = row.Col1;
  66. class_size = row.Col2;
  67. }
  68. public bool HasLayoutInfo {
  69. get {
  70. if (packing_size >= 0 || class_size >= 0)
  71. return true;
  72. ResolveLayout ();
  73. return packing_size >= 0 || class_size >= 0;
  74. }
  75. }
  76. public short PackingSize {
  77. get {
  78. if (packing_size >= 0)
  79. return packing_size;
  80. ResolveLayout ();
  81. return packing_size >= 0 ? packing_size : (short) -1;
  82. }
  83. set { packing_size = value; }
  84. }
  85. public int ClassSize {
  86. get {
  87. if (class_size >= 0)
  88. return class_size;
  89. ResolveLayout ();
  90. return class_size >= 0 ? class_size : -1;
  91. }
  92. set { class_size = value; }
  93. }
  94. public bool HasInterfaces {
  95. get {
  96. if (interfaces != null)
  97. return interfaces.Count > 0;
  98. if (HasImage)
  99. return Module.Read (this, (type, reader) => reader.HasInterfaces (type));
  100. return false;
  101. }
  102. }
  103. public Collection<TypeReference> Interfaces {
  104. get {
  105. if (interfaces != null)
  106. return interfaces;
  107. if (HasImage)
  108. return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type));
  109. return interfaces = new Collection<TypeReference> ();
  110. }
  111. }
  112. public bool HasNestedTypes {
  113. get {
  114. if (nested_types != null)
  115. return nested_types.Count > 0;
  116. if (HasImage)
  117. return Module.Read (this, (type, reader) => reader.HasNestedTypes (type));
  118. return false;
  119. }
  120. }
  121. public Collection<TypeDefinition> NestedTypes {
  122. get {
  123. if (nested_types != null)
  124. return nested_types;
  125. if (HasImage)
  126. return Module.Read (ref nested_types, this, (type, reader) => reader.ReadNestedTypes (type));
  127. return nested_types = new MemberDefinitionCollection<TypeDefinition> (this);
  128. }
  129. }
  130. public bool HasMethods {
  131. get {
  132. if (methods != null)
  133. return methods.Count > 0;
  134. if (HasImage)
  135. return methods_range.Length > 0;
  136. return false;
  137. }
  138. }
  139. public Collection<MethodDefinition> Methods {
  140. get {
  141. if (methods != null)
  142. return methods;
  143. if (HasImage)
  144. return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type));
  145. return methods = new MemberDefinitionCollection<MethodDefinition> (this);
  146. }
  147. }
  148. public bool HasFields {
  149. get {
  150. if (fields != null)
  151. return fields.Count > 0;
  152. if (HasImage)
  153. return fields_range.Length > 0;
  154. return false;
  155. }
  156. }
  157. public Collection<FieldDefinition> Fields {
  158. get {
  159. if (fields != null)
  160. return fields;
  161. if (HasImage)
  162. return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type));
  163. return fields = new MemberDefinitionCollection<FieldDefinition> (this);
  164. }
  165. }
  166. public bool HasEvents {
  167. get {
  168. if (events != null)
  169. return events.Count > 0;
  170. if (HasImage)
  171. return Module.Read (this, (type, reader) => reader.HasEvents (type));
  172. return false;
  173. }
  174. }
  175. public Collection<EventDefinition> Events {
  176. get {
  177. if (events != null)
  178. return events;
  179. if (HasImage)
  180. return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type));
  181. return events = new MemberDefinitionCollection<EventDefinition> (this);
  182. }
  183. }
  184. public bool HasProperties {
  185. get {
  186. if (properties != null)
  187. return properties.Count > 0;
  188. if (HasImage)
  189. return Module.Read (this, (type, reader) => reader.HasProperties (type));
  190. return false;
  191. }
  192. }
  193. public Collection<PropertyDefinition> Properties {
  194. get {
  195. if (properties != null)
  196. return properties;
  197. if (HasImage)
  198. return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type));
  199. return properties = new MemberDefinitionCollection<PropertyDefinition> (this);
  200. }
  201. }
  202. public bool HasSecurityDeclarations {
  203. get {
  204. if (security_declarations != null)
  205. return security_declarations.Count > 0;
  206. return this.GetHasSecurityDeclarations (Module);
  207. }
  208. }
  209. public Collection<SecurityDeclaration> SecurityDeclarations {
  210. get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); }
  211. }
  212. public bool HasCustomAttributes {
  213. get {
  214. if (custom_attributes != null)
  215. return custom_attributes.Count > 0;
  216. return this.GetHasCustomAttributes (Module);
  217. }
  218. }
  219. public Collection<CustomAttribute> CustomAttributes {
  220. get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
  221. }
  222. public override bool HasGenericParameters {
  223. get {
  224. if (generic_parameters != null)
  225. return generic_parameters.Count > 0;
  226. return this.GetHasGenericParameters (Module);
  227. }
  228. }
  229. public override Collection<GenericParameter> GenericParameters {
  230. get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); }
  231. }
  232. #region TypeAttributes
  233. public bool IsNotPublic {
  234. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); }
  235. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); }
  236. }
  237. public bool IsPublic {
  238. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); }
  239. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); }
  240. }
  241. public bool IsNestedPublic {
  242. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); }
  243. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); }
  244. }
  245. public bool IsNestedPrivate {
  246. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); }
  247. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); }
  248. }
  249. public bool IsNestedFamily {
  250. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); }
  251. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); }
  252. }
  253. public bool IsNestedAssembly {
  254. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); }
  255. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); }
  256. }
  257. public bool IsNestedFamilyAndAssembly {
  258. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); }
  259. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); }
  260. }
  261. public bool IsNestedFamilyOrAssembly {
  262. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); }
  263. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); }
  264. }
  265. public bool IsAutoLayout {
  266. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); }
  267. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); }
  268. }
  269. public bool IsSequentialLayout {
  270. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); }
  271. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); }
  272. }
  273. public bool IsExplicitLayout {
  274. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); }
  275. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); }
  276. }
  277. public bool IsClass {
  278. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); }
  279. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); }
  280. }
  281. public bool IsInterface {
  282. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); }
  283. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); }
  284. }
  285. public bool IsAbstract {
  286. get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); }
  287. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); }
  288. }
  289. public bool IsSealed {
  290. get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); }
  291. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); }
  292. }
  293. public bool IsSpecialName {
  294. get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); }
  295. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); }
  296. }
  297. public bool IsImport {
  298. get { return attributes.GetAttributes ((uint) TypeAttributes.Import); }
  299. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); }
  300. }
  301. public bool IsSerializable {
  302. get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); }
  303. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); }
  304. }
  305. public bool IsWindowsRuntime {
  306. get { return attributes.GetAttributes ((uint) TypeAttributes.WindowsRuntime); }
  307. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.WindowsRuntime, value); }
  308. }
  309. public bool IsAnsiClass {
  310. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); }
  311. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); }
  312. }
  313. public bool IsUnicodeClass {
  314. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); }
  315. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); }
  316. }
  317. public bool IsAutoClass {
  318. get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); }
  319. set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); }
  320. }
  321. public bool IsBeforeFieldInit {
  322. get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); }
  323. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); }
  324. }
  325. public bool IsRuntimeSpecialName {
  326. get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); }
  327. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); }
  328. }
  329. public bool HasSecurity {
  330. get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); }
  331. set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); }
  332. }
  333. #endregion
  334. public bool IsEnum {
  335. get { return base_type != null && base_type.IsTypeOf ("System", "Enum"); }
  336. }
  337. public override bool IsValueType {
  338. get {
  339. if (base_type == null)
  340. return false;
  341. return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum"));
  342. }
  343. }
  344. public override bool IsPrimitive {
  345. get {
  346. ElementType primitive_etype;
  347. return MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype);
  348. }
  349. }
  350. public override MetadataType MetadataType {
  351. get {
  352. ElementType primitive_etype;
  353. if (MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype))
  354. return (MetadataType) primitive_etype;
  355. return base.MetadataType;
  356. }
  357. }
  358. public override bool IsDefinition {
  359. get { return true; }
  360. }
  361. public new TypeDefinition DeclaringType {
  362. get { return (TypeDefinition) base.DeclaringType; }
  363. set { base.DeclaringType = value; }
  364. }
  365. public TypeDefinition (string @namespace, string name, TypeAttributes attributes)
  366. : base (@namespace, name)
  367. {
  368. this.attributes = (uint) attributes;
  369. this.token = new MetadataToken (TokenType.TypeDef);
  370. }
  371. public TypeDefinition (string @namespace, string name, TypeAttributes attributes, TypeReference baseType) :
  372. this (@namespace, name, attributes)
  373. {
  374. this.BaseType = baseType;
  375. }
  376. public override TypeDefinition Resolve ()
  377. {
  378. return this;
  379. }
  380. }
  381. static partial class Mixin {
  382. public static TypeReference GetEnumUnderlyingType (this TypeDefinition self)
  383. {
  384. var fields = self.Fields;
  385. for (int i = 0; i < fields.Count; i++) {
  386. var field = fields [i];
  387. if (!field.IsStatic)
  388. return field.FieldType;
  389. }
  390. throw new ArgumentException ();
  391. }
  392. public static TypeDefinition GetNestedType (this TypeDefinition self, string name)
  393. {
  394. if (!self.HasNestedTypes)
  395. return null;
  396. var nested_types = self.NestedTypes;
  397. for (int i = 0; i < nested_types.Count; i++) {
  398. var nested_type = nested_types [i];
  399. if (nested_type.Name == name)
  400. return nested_type;
  401. }
  402. return null;
  403. }
  404. }
  405. }