PageRenderTime 36ms CodeModel.GetById 7ms app.highlight 20ms RepoModel.GetById 2ms app.codeStats 0ms

/Mono.Cecil/CustomAttribute.cs

http://github.com/jbevain/cecil
C# | 220 lines | 164 code | 47 blank | 9 comment | 20 complexity | c8c8c827af50a1220fc6960f541f498c 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.Diagnostics;
 13using System.Threading;
 14using Mono.Collections.Generic;
 15
 16namespace Mono.Cecil {
 17
 18	public struct CustomAttributeArgument {
 19
 20		readonly TypeReference type;
 21		readonly object value;
 22
 23		public TypeReference Type {
 24			get { return type; }
 25		}
 26
 27		public object Value {
 28			get { return value; }
 29		}
 30
 31		public CustomAttributeArgument (TypeReference type, object value)
 32		{
 33			Mixin.CheckType (type);
 34			this.type = type;
 35			this.value = value;
 36		}
 37	}
 38
 39	public struct CustomAttributeNamedArgument {
 40
 41		readonly string name;
 42		readonly CustomAttributeArgument argument;
 43
 44		public string Name {
 45			get { return name; }
 46		}
 47
 48		public CustomAttributeArgument Argument {
 49			get { return argument; }
 50		}
 51
 52		public CustomAttributeNamedArgument (string name, CustomAttributeArgument argument)
 53		{
 54			Mixin.CheckName (name);
 55			this.name = name;
 56			this.argument = argument;
 57		}
 58	}
 59
 60	public interface ICustomAttribute {
 61
 62		TypeReference AttributeType { get; }
 63
 64		bool HasFields { get; }
 65		bool HasProperties { get; }
 66		bool HasConstructorArguments { get; }
 67		Collection<CustomAttributeNamedArgument> Fields { get; }
 68		Collection<CustomAttributeNamedArgument> Properties { get; }
 69		Collection<CustomAttributeArgument> ConstructorArguments { get; }
 70	}
 71
 72	[DebuggerDisplay ("{AttributeType}")]
 73	public sealed class CustomAttribute : ICustomAttribute {
 74
 75		internal CustomAttributeValueProjection projection;
 76		readonly internal uint signature;
 77		internal bool resolved;
 78		MethodReference constructor;
 79		byte [] blob;
 80		internal Collection<CustomAttributeArgument> arguments;
 81		internal Collection<CustomAttributeNamedArgument> fields;
 82		internal Collection<CustomAttributeNamedArgument> properties;
 83
 84		public MethodReference Constructor {
 85			get { return constructor; }
 86			set { constructor = value; }
 87		}
 88
 89		public TypeReference AttributeType {
 90			get { return constructor.DeclaringType; }
 91		}
 92
 93		public bool IsResolved {
 94			get { return resolved; }
 95		}
 96
 97		public bool HasConstructorArguments {
 98			get {
 99				Resolve ();
100
101				return !arguments.IsNullOrEmpty ();
102			}
103		}
104
105		public Collection<CustomAttributeArgument> ConstructorArguments {
106			get {
107				Resolve ();
108
109				if (arguments == null)
110					Interlocked.CompareExchange (ref arguments, new Collection<CustomAttributeArgument> (), null);
111
112				return arguments;
113			}
114		}
115
116		public bool HasFields {
117			get {
118				Resolve ();
119
120				return !fields.IsNullOrEmpty ();
121			}
122		}
123
124		public Collection<CustomAttributeNamedArgument> Fields {
125			get {
126				Resolve ();
127
128				if (fields == null)
129					Interlocked.CompareExchange (ref fields, new Collection<CustomAttributeNamedArgument> (), null);
130
131				return fields;
132			}
133		}
134
135		public bool HasProperties {
136			get {
137				Resolve ();
138
139				return !properties.IsNullOrEmpty ();
140			}
141		}
142
143		public Collection<CustomAttributeNamedArgument> Properties {
144			get {
145				Resolve ();
146
147				if (properties == null)
148					Interlocked.CompareExchange (ref properties, new Collection<CustomAttributeNamedArgument> (), null);
149
150				return properties;
151			}
152		}
153
154		internal bool HasImage {
155			get { return constructor != null && constructor.HasImage; }
156		}
157
158		internal ModuleDefinition Module {
159			get { return constructor.Module; }
160		}
161
162		internal CustomAttribute (uint signature, MethodReference constructor)
163		{
164			this.signature = signature;
165			this.constructor = constructor;
166			this.resolved = false;
167		}
168
169		public CustomAttribute (MethodReference constructor)
170		{
171			this.constructor = constructor;
172			this.resolved = true;
173		}
174
175		public CustomAttribute (MethodReference constructor, byte [] blob)
176		{
177			this.constructor = constructor;
178			this.resolved = false;
179			this.blob = blob;
180		}
181
182		public byte [] GetBlob ()
183		{
184			if (blob != null)
185				return blob;
186
187			if (!HasImage)
188				throw new NotSupportedException ();
189
190			return Module.Read (ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature));
191		}
192
193		void Resolve ()
194		{
195			if (resolved || !HasImage)
196				return;
197
198			lock (Module.SyncRoot) {
199				if (resolved)
200					return;
201
202				Module.Read (this, (attribute, reader) => {
203					try {
204						reader.ReadCustomAttributeSignature (attribute);
205						resolved = true;
206					} catch (ResolutionException) {
207						if (arguments != null)
208							arguments.Clear ();
209						if (fields != null)
210							fields.Clear ();
211						if (properties != null)
212							properties.Clear ();
213
214						resolved = false;
215					}
216				});
217			}
218		}
219	}
220}