PageRenderTime 51ms CodeModel.GetById 2ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/Mono.Cecil/TypeDefinition.cs

http://github.com/jbevain/cecil
C# | 620 lines | 477 code | 134 blank | 9 comment | 82 complexity | f54a820ebae9a2b201d3174a09562f3b 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
 11using System;
 12using System.Threading;
 13using Mono.Cecil.Metadata;
 14using Mono.Collections.Generic;
 15
 16namespace Mono.Cecil {
 17
 18	public sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider {
 19
 20		uint attributes;
 21		TypeReference base_type;
 22		internal Range fields_range;
 23		internal Range methods_range;
 24
 25		short packing_size = Mixin.NotResolvedMarker;
 26		int class_size = Mixin.NotResolvedMarker;
 27
 28		InterfaceImplementationCollection interfaces;
 29		Collection<TypeDefinition> nested_types;
 30		Collection<MethodDefinition> methods;
 31		Collection<FieldDefinition> fields;
 32		Collection<EventDefinition> events;
 33		Collection<PropertyDefinition> properties;
 34		Collection<CustomAttribute> custom_attributes;
 35		Collection<SecurityDeclaration> security_declarations;
 36
 37		public TypeAttributes Attributes {
 38			get { return (TypeAttributes) attributes; }
 39			set {
 40				if (IsWindowsRuntimeProjection && (ushort) value != attributes)
 41					throw new InvalidOperationException ();
 42
 43				attributes = (uint) value;
 44			}
 45		}
 46
 47		public TypeReference BaseType {
 48			get { return base_type; }
 49			set { base_type = value; }
 50		}
 51
 52		public override string Name {
 53			get { return base.Name; }
 54			set {
 55				if (IsWindowsRuntimeProjection && value != base.Name)
 56					throw new InvalidOperationException ();
 57
 58				base.Name = value;
 59			}
 60		}
 61
 62		void ResolveLayout ()
 63		{
 64			if (!HasImage) {
 65				packing_size = Mixin.NoDataMarker;
 66				class_size = Mixin.NoDataMarker;
 67				return;
 68			}
 69
 70			lock (Module.SyncRoot) {
 71				if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker)
 72					return;
 73
 74				var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type));
 75
 76				packing_size = row.Col1;
 77				class_size = row.Col2;
 78			}
 79		}
 80
 81		public bool HasLayoutInfo {
 82			get {
 83				if (packing_size >= 0 || class_size >= 0)
 84					return true;
 85
 86				ResolveLayout ();
 87
 88				return packing_size >= 0 || class_size >= 0;
 89			}
 90		}
 91
 92		public short PackingSize {
 93			get {
 94				if (packing_size >= 0)
 95					return packing_size;
 96
 97				ResolveLayout ();
 98
 99				return packing_size >= 0 ? packing_size : (short) -1;
100			}
101			set { packing_size = value; }
102		}
103
104		public int ClassSize {
105			get {
106				if (class_size >= 0)
107					return class_size;
108
109				ResolveLayout ();
110
111				return class_size >= 0 ? class_size : -1;
112			}
113			set { class_size = value; }
114		}
115
116		public bool HasInterfaces {
117			get {
118				if (interfaces != null)
119					return interfaces.Count > 0;
120
121				return HasImage && Module.Read (this, (type, reader) => reader.HasInterfaces (type));
122			}
123		}
124
125		public Collection<InterfaceImplementation> Interfaces {
126			get {
127				if (interfaces != null)
128					return interfaces;
129
130				if (HasImage)
131					return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type));
132
133				Interlocked.CompareExchange (ref interfaces, new InterfaceImplementationCollection (this), null);
134				return interfaces;
135			}
136		}
137
138		public bool HasNestedTypes {
139			get {
140				if (nested_types != null)
141					return nested_types.Count > 0;
142
143				return HasImage && Module.Read (this, (type, reader) => reader.HasNestedTypes (type));
144			}
145		}
146
147		public Collection<TypeDefinition> NestedTypes {
148			get {
149				if (nested_types != null)
150					return nested_types;
151
152				if (HasImage)
153					return Module.Read (ref nested_types, this, (type, reader) => reader.ReadNestedTypes (type));
154
155				Interlocked.CompareExchange (ref nested_types, new MemberDefinitionCollection<TypeDefinition> (this), null);
156				return nested_types;
157			}
158		}
159
160		public bool HasMethods {
161			get {
162				if (methods != null)
163					return methods.Count > 0;
164
165				return HasImage && methods_range.Length > 0;
166			}
167		}
168
169		public Collection<MethodDefinition> Methods {
170			get {
171				if (methods != null)
172					return methods;
173
174				if (HasImage)
175					return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type));
176
177				Interlocked.CompareExchange (ref methods, new MemberDefinitionCollection<MethodDefinition> (this) , null);
178				return methods;
179			}
180		}
181
182		public bool HasFields {
183			get {
184				if (fields != null)
185					return fields.Count > 0;
186
187				return HasImage && fields_range.Length > 0;
188			}
189		}
190
191		public Collection<FieldDefinition> Fields {
192			get {
193				if (fields != null)
194					return fields;
195
196				if (HasImage)
197					return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type));
198
199				Interlocked.CompareExchange (ref fields, new MemberDefinitionCollection<FieldDefinition> (this), null);
200				return fields;
201			}
202		}
203
204		public bool HasEvents {
205			get {
206				if (events != null)
207					return events.Count > 0;
208
209				return HasImage && Module.Read (this, (type, reader) => reader.HasEvents (type));
210			}
211		}
212
213		public Collection<EventDefinition> Events {
214			get {
215				if (events != null)
216					return events;
217
218				if (HasImage)
219					return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type));
220
221				Interlocked.CompareExchange (ref events, new MemberDefinitionCollection<EventDefinition> (this), null);
222				return events;
223			}
224		}
225
226		public bool HasProperties {
227			get {
228				if (properties != null)
229					return properties.Count > 0;
230
231				return HasImage && Module.Read (this, (type, reader) => reader.HasProperties (type));
232			}
233		}
234
235		public Collection<PropertyDefinition> Properties {
236			get {
237				if (properties != null)
238					return properties;
239
240				if (HasImage)
241					return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type));
242
243				Interlocked.CompareExchange (ref properties, new MemberDefinitionCollection<PropertyDefinition> (this), null);
244				return properties;
245			}
246		}
247
248		public bool HasSecurityDeclarations {
249			get {
250				if (security_declarations != null)
251					return security_declarations.Count > 0;
252
253				return this.GetHasSecurityDeclarations (Module);
254			}
255		}
256
257		public Collection<SecurityDeclaration> SecurityDeclarations {
258			get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); }
259		}
260
261		public bool HasCustomAttributes {
262			get {
263				if (custom_attributes != null)
264					return custom_attributes.Count > 0;
265
266				return this.GetHasCustomAttributes (Module);
267			}
268		}
269
270		public Collection<CustomAttribute> CustomAttributes {
271			get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
272		}
273
274		public override bool HasGenericParameters {
275			get {
276				if (generic_parameters != null)
277					return generic_parameters.Count > 0;
278
279				return this.GetHasGenericParameters (Module);
280			}
281		}
282
283		public override Collection<GenericParameter> GenericParameters {
284			get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); }
285		}
286
287		#region TypeAttributes
288
289		public bool IsNotPublic {
290			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); }
291			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); }
292		}
293
294		public bool IsPublic {
295			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); }
296			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); }
297		}
298
299		public bool IsNestedPublic {
300			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); }
301			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); }
302		}
303
304		public bool IsNestedPrivate {
305			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); }
306			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); }
307		}
308
309		public bool IsNestedFamily {
310			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); }
311			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); }
312		}
313
314		public bool IsNestedAssembly {
315			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); }
316			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); }
317		}
318
319		public bool IsNestedFamilyAndAssembly {
320			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); }
321			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); }
322		}
323
324		public bool IsNestedFamilyOrAssembly {
325			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); }
326			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); }
327		}
328
329		public bool IsAutoLayout {
330			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); }
331			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); }
332		}
333
334		public bool IsSequentialLayout {
335			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); }
336			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); }
337		}
338
339		public bool IsExplicitLayout {
340			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); }
341			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); }
342		}
343
344		public bool IsClass {
345			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); }
346			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); }
347		}
348
349		public bool IsInterface {
350			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); }
351			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); }
352		}
353
354		public bool IsAbstract {
355			get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); }
356			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); }
357		}
358
359		public bool IsSealed {
360			get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); }
361			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); }
362		}
363
364		public bool IsSpecialName {
365			get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); }
366			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); }
367		}
368
369		public bool IsImport {
370			get { return attributes.GetAttributes ((uint) TypeAttributes.Import); }
371			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); }
372		}
373
374		public bool IsSerializable {
375			get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); }
376			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); }
377		}
378
379		public bool IsWindowsRuntime {
380			get { return attributes.GetAttributes ((uint) TypeAttributes.WindowsRuntime); }
381			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.WindowsRuntime, value); }
382		}
383
384		public bool IsAnsiClass {
385			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); }
386			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); }
387		}
388
389		public bool IsUnicodeClass {
390			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); }
391			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); }
392		}
393
394		public bool IsAutoClass {
395			get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); }
396			set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); }
397		}
398
399		public bool IsBeforeFieldInit {
400			get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); }
401			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); }
402		}
403
404		public bool IsRuntimeSpecialName {
405			get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); }
406			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); }
407		}
408
409		public bool HasSecurity {
410			get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); }
411			set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); }
412		}
413
414		#endregion
415
416		public bool IsEnum {
417			get { return base_type != null && base_type.IsTypeOf ("System", "Enum"); }
418		}
419
420		public override bool IsValueType {
421			get {
422				if (base_type == null)
423					return false;
424
425				return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum"));
426			}
427			set {
428				throw new NotSupportedException ();
429			}
430		}
431
432		public override bool IsPrimitive {
433			get {
434				ElementType primitive_etype;
435				return MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype) && primitive_etype.IsPrimitive ();
436			}
437		}
438
439		public override MetadataType MetadataType {
440			get {
441				ElementType primitive_etype;
442				if (MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype))
443					return (MetadataType) primitive_etype;
444
445				return base.MetadataType;
446			}
447		}
448
449		public override bool IsDefinition {
450			get { return true; }
451		}
452
453		public new TypeDefinition DeclaringType {
454			get { return (TypeDefinition) base.DeclaringType; }
455			set { base.DeclaringType = value; }
456		}
457
458		internal new TypeDefinitionProjection WindowsRuntimeProjection {
459			get { return (TypeDefinitionProjection) projection; }
460			set { projection = value; }
461		}
462
463		public TypeDefinition (string @namespace, string name, TypeAttributes attributes)
464			: base (@namespace, name)
465		{
466			this.attributes = (uint) attributes;
467			this.token = new MetadataToken (TokenType.TypeDef);
468		}
469
470		public TypeDefinition (string @namespace, string name, TypeAttributes attributes, TypeReference baseType) :
471			this (@namespace, name, attributes)
472		{
473			this.BaseType = baseType;
474		}
475
476		protected override void ClearFullName ()
477		{
478			base.ClearFullName ();
479
480			if (!HasNestedTypes)
481				return;
482
483			var nested_types = this.NestedTypes;
484
485			for (int i = 0; i < nested_types.Count; i++)
486				nested_types [i].ClearFullName ();
487		}
488
489		public override TypeDefinition Resolve ()
490		{
491			return this;
492		}
493	}
494
495	public sealed class InterfaceImplementation : ICustomAttributeProvider
496	{
497		internal TypeDefinition type;
498		internal MetadataToken token;
499
500		TypeReference interface_type;
501		Collection<CustomAttribute> custom_attributes;
502
503		public TypeReference InterfaceType {
504			get { return interface_type; }
505			set { interface_type = value; }
506		}
507
508		public bool HasCustomAttributes {
509			get {
510				if (custom_attributes != null)
511					return custom_attributes.Count > 0;
512
513				if (type == null)
514					return false;
515
516				return this.GetHasCustomAttributes (type.Module);
517			}
518		}
519
520		public Collection<CustomAttribute> CustomAttributes {
521			get {
522				if (type == null) {
523					if (custom_attributes == null)
524						Interlocked.CompareExchange (ref custom_attributes, new Collection<CustomAttribute> (), null);
525					return custom_attributes;
526				}
527
528				return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, type.Module));
529			}
530		}
531
532		public MetadataToken MetadataToken {
533			get { return token; }
534			set { token = value; }
535		}
536
537		internal InterfaceImplementation (TypeReference interfaceType, MetadataToken token)
538		{
539			this.interface_type = interfaceType;
540			this.token = token;
541		}
542
543		public InterfaceImplementation (TypeReference interfaceType)
544		{
545			Mixin.CheckType (interfaceType, Mixin.Argument.interfaceType);
546
547			this.interface_type = interfaceType;
548			this.token = new MetadataToken (TokenType.InterfaceImpl);
549		}
550	}
551
552	class InterfaceImplementationCollection : Collection<InterfaceImplementation>
553	{
554		readonly TypeDefinition type;
555
556		internal InterfaceImplementationCollection (TypeDefinition type)
557		{
558			this.type = type;
559		}
560
561		internal InterfaceImplementationCollection (TypeDefinition type, int length)
562			: base (length)
563		{
564			this.type = type;
565		}
566
567		protected override void OnAdd (InterfaceImplementation item, int index)
568		{
569			item.type = type;
570		}
571
572		protected override void OnInsert (InterfaceImplementation item, int index)
573		{
574			item.type = type;
575		}
576
577		protected override void OnSet (InterfaceImplementation item, int index)
578		{
579			item.type = type;
580		}
581
582		protected override void OnRemove (InterfaceImplementation item, int index)
583		{
584			item.type = null;
585		}
586	}
587
588	static partial class Mixin {
589
590		public static TypeReference GetEnumUnderlyingType (this TypeDefinition self)
591		{
592			var fields = self.Fields;
593
594			for (int i = 0; i < fields.Count; i++) {
595				var field = fields [i];
596				if (!field.IsStatic)
597					return field.FieldType;
598			}
599
600			throw new ArgumentException ();
601		}
602
603		public static TypeDefinition GetNestedType (this TypeDefinition self, string fullname)
604		{
605			if (!self.HasNestedTypes)
606				return null;
607
608			var nested_types = self.NestedTypes;
609
610			for (int i = 0; i < nested_types.Count; i++) {
611				var nested_type = nested_types [i];
612
613				if (nested_type.TypeFullName () == fullname)
614					return nested_type;
615			}
616
617			return null;
618		}
619	}
620}