PageRenderTime 82ms CodeModel.GetById 69ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/Mono.Cecil/TypeReference.cs

http://github.com/jbevain/cecil
C# | 352 lines | 286 code | 57 blank | 9 comment | 39 complexity | a7757a898608f631371d84a6a5385137 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 enum MetadataType : byte {
 19		Void = ElementType.Void,
 20		Boolean = ElementType.Boolean,
 21		Char = ElementType.Char,
 22		SByte = ElementType.I1,
 23		Byte = ElementType.U1,
 24		Int16 = ElementType.I2,
 25		UInt16 = ElementType.U2,
 26		Int32 = ElementType.I4,
 27		UInt32 = ElementType.U4,
 28		Int64 = ElementType.I8,
 29		UInt64 = ElementType.U8,
 30		Single = ElementType.R4,
 31		Double = ElementType.R8,
 32		String = ElementType.String,
 33		Pointer = ElementType.Ptr,
 34		ByReference = ElementType.ByRef,
 35		ValueType = ElementType.ValueType,
 36		Class = ElementType.Class,
 37		Var = ElementType.Var,
 38		Array = ElementType.Array,
 39		GenericInstance = ElementType.GenericInst,
 40		TypedByReference = ElementType.TypedByRef,
 41		IntPtr = ElementType.I,
 42		UIntPtr = ElementType.U,
 43		FunctionPointer = ElementType.FnPtr,
 44		Object = ElementType.Object,
 45		MVar = ElementType.MVar,
 46		RequiredModifier = ElementType.CModReqD,
 47		OptionalModifier = ElementType.CModOpt,
 48		Sentinel = ElementType.Sentinel,
 49		Pinned = ElementType.Pinned,
 50	}
 51
 52	public class TypeReference : MemberReference, IGenericParameterProvider, IGenericContext {
 53
 54		string @namespace;
 55		bool value_type;
 56		internal IMetadataScope scope;
 57		internal ModuleDefinition module;
 58
 59		internal ElementType etype = ElementType.None;
 60
 61		string fullname;
 62
 63		protected Collection<GenericParameter> generic_parameters;
 64
 65		public override string Name {
 66			get { return base.Name; }
 67			set {
 68				if (IsWindowsRuntimeProjection && value != base.Name)
 69					throw new InvalidOperationException ("Projected type reference name can't be changed.");
 70				base.Name = value;
 71				ClearFullName ();
 72			}
 73		}
 74
 75		public virtual string Namespace {
 76			get { return @namespace; }
 77			set {
 78				if (IsWindowsRuntimeProjection && value != @namespace)
 79					throw new InvalidOperationException ("Projected type reference namespace can't be changed.");
 80				@namespace = value;
 81				ClearFullName ();
 82			}
 83		}
 84
 85		public virtual bool IsValueType {
 86			get { return value_type; }
 87			set { value_type = value; }
 88		}
 89
 90		public override ModuleDefinition Module {
 91			get {
 92				if (module != null)
 93					return module;
 94
 95				var declaring_type = this.DeclaringType;
 96				if (declaring_type != null)
 97					return declaring_type.Module;
 98
 99				return null;
100			}
101		}
102
103		internal new TypeReferenceProjection WindowsRuntimeProjection {
104			get { return (TypeReferenceProjection) projection; }
105			set { projection = value; }
106		}
107
108		IGenericParameterProvider IGenericContext.Type {
109			get { return this; }
110		}
111
112		IGenericParameterProvider IGenericContext.Method {
113			get { return null; }
114		}
115
116		GenericParameterType IGenericParameterProvider.GenericParameterType {
117			get { return GenericParameterType.Type; }
118		}
119
120		public virtual bool HasGenericParameters {
121			get { return !generic_parameters.IsNullOrEmpty (); }
122		}
123
124		public virtual Collection<GenericParameter> GenericParameters {
125			get {
126				if (generic_parameters == null)
127					Interlocked.CompareExchange (ref generic_parameters, new GenericParameterCollection (this), null);
128					
129				return generic_parameters;
130			}
131		}
132
133		public virtual IMetadataScope Scope {
134			get {
135				var declaring_type = this.DeclaringType;
136				if (declaring_type != null)
137					return declaring_type.Scope;
138
139				return scope;
140			}
141			set {
142				var declaring_type = this.DeclaringType;
143				if (declaring_type != null) {
144					if (IsWindowsRuntimeProjection && value != declaring_type.Scope)
145						throw new InvalidOperationException ("Projected type scope can't be changed.");
146					declaring_type.Scope = value;
147					return;
148				}
149
150				if (IsWindowsRuntimeProjection && value != scope)
151					throw new InvalidOperationException ("Projected type scope can't be changed.");
152				scope = value;
153			}
154		}
155
156		public bool IsNested {
157			get { return this.DeclaringType != null; }
158		}
159
160		public override TypeReference DeclaringType {
161			get { return base.DeclaringType; }
162			set {
163				if (IsWindowsRuntimeProjection && value != base.DeclaringType)
164					throw new InvalidOperationException ("Projected type declaring type can't be changed.");
165				base.DeclaringType = value;
166				ClearFullName ();
167			}
168		}
169
170		public override string FullName {
171			get {
172				if (fullname != null)
173					return fullname;
174
175				var new_fullname = this.TypeFullName ();
176
177				if (IsNested)
178					new_fullname = DeclaringType.FullName + "/" + new_fullname;
179				Interlocked.CompareExchange (ref fullname, new_fullname, null);
180				return fullname;
181			}
182		}
183
184		public virtual bool IsByReference {
185			get { return false; }
186		}
187
188		public virtual bool IsPointer {
189			get { return false; }
190		}
191
192		public virtual bool IsSentinel {
193			get { return false; }
194		}
195
196		public virtual bool IsArray {
197			get { return false; }
198		}
199
200		public virtual bool IsGenericParameter {
201			get { return false; }
202		}
203
204		public virtual bool IsGenericInstance {
205			get { return false; }
206		}
207
208		public virtual bool IsRequiredModifier {
209			get { return false; }
210		}
211
212		public virtual bool IsOptionalModifier {
213			get { return false; }
214		}
215
216		public virtual bool IsPinned {
217			get { return false; }
218		}
219
220		public virtual bool IsFunctionPointer {
221			get { return false; }
222		}
223
224		public virtual bool IsPrimitive {
225			get { return etype.IsPrimitive (); }
226		}
227
228		public virtual MetadataType MetadataType {
229			get {
230				switch (etype) {
231				case ElementType.None:
232					return IsValueType ? MetadataType.ValueType : MetadataType.Class;
233				default:
234					return (MetadataType) etype;
235				}
236			}
237		}
238
239		protected TypeReference (string @namespace, string name)
240			: base (name)
241		{
242			this.@namespace = @namespace ?? string.Empty;
243			this.token = new MetadataToken (TokenType.TypeRef, 0);
244		}
245
246		public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope)
247			: this (@namespace, name)
248		{
249			this.module = module;
250			this.scope = scope;
251		}
252
253		public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) :
254			this (@namespace, name, module, scope)
255		{
256			value_type = valueType;
257		}
258
259		protected virtual void ClearFullName ()
260		{
261			this.fullname = null;
262		}
263
264		public virtual TypeReference GetElementType ()
265		{
266			return this;
267		}
268
269		protected override IMemberDefinition ResolveDefinition ()
270		{
271			return this.Resolve ();
272		}
273
274		public new virtual TypeDefinition Resolve ()
275		{
276			var module = this.Module;
277			if (module == null)
278				throw new NotSupportedException ();
279
280			return module.Resolve (this);
281		}
282	}
283
284	static partial class Mixin {
285
286		public static bool IsPrimitive (this ElementType self)
287		{
288			switch (self) {
289			case ElementType.Boolean:
290			case ElementType.Char:
291			case ElementType.I:
292			case ElementType.U:
293			case ElementType.I1:
294			case ElementType.U1:
295			case ElementType.I2:
296			case ElementType.U2:
297			case ElementType.I4:
298			case ElementType.U4:
299			case ElementType.I8:
300			case ElementType.U8:
301			case ElementType.R4:
302			case ElementType.R8:
303				return true;
304			default:
305				return false;
306			}
307		}
308
309		public static string TypeFullName (this TypeReference self)
310		{
311			return string.IsNullOrEmpty (self.Namespace)
312				? self.Name
313				: self.Namespace + '.' + self.Name;
314		}
315
316		public static bool IsTypeOf (this TypeReference self, string @namespace, string name)
317		{
318			return self.Name == name
319				&& self.Namespace == @namespace;
320		}
321
322		public static bool IsTypeSpecification (this TypeReference type)
323		{
324			switch (type.etype) {
325			case ElementType.Array:
326			case ElementType.ByRef:
327			case ElementType.CModOpt:
328			case ElementType.CModReqD:
329			case ElementType.FnPtr:
330			case ElementType.GenericInst:
331			case ElementType.MVar:
332			case ElementType.Pinned:
333			case ElementType.Ptr:
334			case ElementType.SzArray:
335			case ElementType.Sentinel:
336			case ElementType.Var:
337				return true;
338			}
339
340			return false;
341		}
342
343		public static TypeDefinition CheckedResolve (this TypeReference self)
344		{
345			var type = self.Resolve ();
346			if (type == null)
347				throw new ResolutionException (self);
348
349			return type;
350		}
351	}
352}