5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2010 Jb Evain
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
31 using Mono.Collections.Generic;
33 namespace Mono.Cecil {
35 public struct CustomAttributeArgument {
37 readonly TypeReference type;
38 readonly object value;
40 public TypeReference Type {
48 public CustomAttributeArgument (TypeReference type, object value)
50 Mixin.CheckType (type);
56 public struct CustomAttributeNamedArgument {
59 readonly CustomAttributeArgument argument;
65 public CustomAttributeArgument Argument {
66 get { return argument; }
69 public CustomAttributeNamedArgument (string name, CustomAttributeArgument argument)
71 Mixin.CheckName (name);
73 this.argument = argument;
77 public interface ICustomAttribute {
79 TypeReference AttributeType { get; }
81 bool HasFields { get; }
82 bool HasProperties { get; }
83 Collection<CustomAttributeNamedArgument> Fields { get; }
84 Collection<CustomAttributeNamedArgument> Properties { get; }
87 public sealed class CustomAttribute : ICustomAttribute {
89 readonly internal uint signature;
90 internal bool resolved;
91 MethodReference constructor;
93 internal Collection<CustomAttributeArgument> arguments;
94 internal Collection<CustomAttributeNamedArgument> fields;
95 internal Collection<CustomAttributeNamedArgument> properties;
97 public MethodReference Constructor {
98 get { return constructor; }
99 set { constructor = value; }
102 public TypeReference AttributeType {
103 get { return constructor.DeclaringType; }
106 public bool IsResolved {
107 get { return resolved; }
110 public bool HasConstructorArguments {
114 return !arguments.IsNullOrEmpty ();
118 public Collection<CustomAttributeArgument> ConstructorArguments {
122 return arguments ?? (arguments = new Collection<CustomAttributeArgument> ());
126 public bool HasFields {
130 return !fields.IsNullOrEmpty ();
134 public Collection<CustomAttributeNamedArgument> Fields {
138 return fields ?? (fields = new Collection<CustomAttributeNamedArgument> ());
142 public bool HasProperties {
146 return !properties.IsNullOrEmpty ();
150 public Collection<CustomAttributeNamedArgument> Properties {
154 return properties ?? (properties = new Collection<CustomAttributeNamedArgument> ());
158 internal bool HasImage {
159 get { return constructor != null && constructor.HasImage; }
162 internal ModuleDefinition Module {
163 get { return constructor.Module; }
166 internal CustomAttribute (uint signature, MethodReference constructor)
168 this.signature = signature;
169 this.constructor = constructor;
170 this.resolved = false;
173 public CustomAttribute (MethodReference constructor)
175 this.constructor = constructor;
176 this.resolved = true;
179 public CustomAttribute (MethodReference constructor, byte [] blob)
181 this.constructor = constructor;
182 this.resolved = false;
186 public byte [] GetBlob ()
191 if (!HasImage || signature == 0)
192 throw new NotSupportedException ();
194 return blob = Module.Read (this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature));
199 if (resolved || !HasImage)
203 Module.Read (this, (attribute, reader) => {
204 reader.ReadCustomAttributeSignature (attribute);
209 } catch (ResolutionException) {
210 if (arguments != null)
214 if (properties != null)
222 static partial class Mixin {
224 public static void CheckName (string name)
227 throw new ArgumentNullException ("name");
228 if (name.Length == 0)
229 throw new ArgumentException ("Empty name");