| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2015 Jb Evain
- // Copyright (c) 2008 - 2011 Novell, Inc.
- //
- // Licensed under the MIT/X11 license.
- //
- using System;
- using System.Diagnostics;
- using System.Threading;
- using ILRuntime.Mono.Collections.Generic;
- namespace ILRuntime.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; }
- bool HasConstructorArguments { get; }
- Collection<CustomAttributeNamedArgument> Fields { get; }
- Collection<CustomAttributeNamedArgument> Properties { get; }
- Collection<CustomAttributeArgument> ConstructorArguments { get; }
- }
- [DebuggerDisplay ("{AttributeType}")]
- public sealed class CustomAttribute : ICustomAttribute {
- internal CustomAttributeValueProjection projection;
- 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 !arguments.IsNullOrEmpty ();
- }
- }
- public Collection<CustomAttributeArgument> ConstructorArguments {
- get {
- Resolve ();
- if (arguments == null)
- Interlocked.CompareExchange (ref arguments, new Collection<CustomAttributeArgument> (), null);
- return arguments;
- }
- }
- public bool HasFields {
- get {
- Resolve ();
- return !fields.IsNullOrEmpty ();
- }
- }
- public Collection<CustomAttributeNamedArgument> Fields {
- get {
- Resolve ();
- if (fields == null)
- Interlocked.CompareExchange (ref fields, new Collection<CustomAttributeNamedArgument> (), null);
- return fields;
- }
- }
- public bool HasProperties {
- get {
- Resolve ();
- return !properties.IsNullOrEmpty ();
- }
- }
- public Collection<CustomAttributeNamedArgument> Properties {
- get {
- Resolve ();
- if (properties == null)
- Interlocked.CompareExchange (ref properties, new Collection<CustomAttributeNamedArgument> (), null);
- return properties;
- }
- }
- 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;
- lock (Module.SyncRoot) {
- if (resolved)
- 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;
- }
- });
- }
- }
- }
- }
|