PageRenderTime 25ms CodeModel.GetById 10ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

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