| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- //
- // CustomAttribute.cs
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2011 Jb Evain
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using Mono.Collections.Generic;
- namespace Mono.Cecil {
- public struct CustomAttributeArgument {
- readonly TypeReference type;
- readonly object value;
- public TypeReference Type {
- get { return type; }
- }
- public object Value {
- get { return value; }
- }
- public CustomAttributeArgument (TypeReference type, object value)
- {
- Mixin.CheckType (type);
- this.type = type;
- this.value = value;
- }
- }
- public struct CustomAttributeNamedArgument {
- readonly string name;
- readonly CustomAttributeArgument argument;
- public string Name {
- get { return name; }
- }
- public CustomAttributeArgument Argument {
- get { return argument; }
- }
- public CustomAttributeNamedArgument (string name, CustomAttributeArgument argument)
- {
- Mixin.CheckName (name);
- this.name = name;
- this.argument = argument;
- }
- }
- public interface ICustomAttribute {
- TypeReference AttributeType { get; }
- bool HasFields { get; }
- bool HasProperties { get; }
- Collection<CustomAttributeNamedArgument> Fields { get; }
- Collection<CustomAttributeNamedArgument> Properties { get; }
- }
- public sealed class CustomAttribute : ICustomAttribute {
- readonly internal uint signature;
- internal bool resolved;
- MethodReference constructor;
- byte [] blob;
- internal Collection<CustomAttributeArgument> arguments;
- internal Collection<CustomAttributeNamedArgument> fields;
- internal Collection<CustomAttributeNamedArgument> properties;
- public MethodReference Constructor {
- get { return constructor; }
- set { constructor = value; }
- }
- public TypeReference AttributeType {
- get { return constructor.DeclaringType; }
- }
- public bool IsResolved {
- get { return resolved; }
- }
- public bool HasConstructorArguments {
- get {
- Resolve ();
- return !Mixin.IsNullOrEmpty (arguments);
- }
- }
- public Collection<CustomAttributeArgument> ConstructorArguments {
- get {
- Resolve ();
- return arguments ?? (arguments = new Collection<CustomAttributeArgument> ());
- }
- }
- public bool HasFields {
- get {
- Resolve ();
- return !Mixin.IsNullOrEmpty (fields);
- }
- }
- public Collection<CustomAttributeNamedArgument> Fields {
- get {
- Resolve ();
- return fields ?? (fields = new Collection<CustomAttributeNamedArgument> ());
- }
- }
- public bool HasProperties {
- get {
- Resolve ();
- return !Mixin.IsNullOrEmpty (properties);
- }
- }
- public Collection<CustomAttributeNamedArgument> Properties {
- get {
- Resolve ();
- return properties ?? (properties = new Collection<CustomAttributeNamedArgument> ());
- }
- }
- internal bool HasImage {
- get { return constructor != null && constructor.HasImage; }
- }
- internal ModuleDefinition Module {
- get { return constructor.Module; }
- }
- internal CustomAttribute (uint signature, MethodReference constructor)
- {
- this.signature = signature;
- this.constructor = constructor;
- this.resolved = false;
- }
- public CustomAttribute (MethodReference constructor)
- {
- this.constructor = constructor;
- this.resolved = true;
- }
- public CustomAttribute (MethodReference constructor, byte [] blob)
- {
- this.constructor = constructor;
- this.resolved = false;
- this.blob = blob;
- }
- public byte [] GetBlob ()
- {
- if (blob != null)
- return blob;
- if (!HasImage)
- throw new NotSupportedException ();
- return Module.Read (ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature));
- }
- void Resolve ()
- {
- if (resolved || !HasImage)
- return;
- Module.Read (this, (attribute, reader) => {
- try {
- reader.ReadCustomAttributeSignature (attribute);
- resolved = true;
- } catch (ResolutionException) {
- if (arguments != null)
- arguments.Clear ();
- if (fields != null)
- fields.Clear ();
- if (properties != null)
- properties.Clear ();
- resolved = false;
- }
- return this;
- });
- }
- }
- static partial class Mixin {
- public static void CheckName (string name)
- {
- if (name == null)
- throw new ArgumentNullException ("name");
- if (name.Length == 0)
- throw new ArgumentException ("Empty name");
- }
- }
- }
|