// // 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 MonoFN.Collections.Generic; using System.Threading; namespace MonoFN.Cecil { public sealed class EventDefinition : EventReference, IMemberDefinition { private ushort attributes; private Collection custom_attributes; internal MethodDefinition add_method; internal MethodDefinition invoke_method; internal MethodDefinition remove_method; internal Collection other_methods; public EventAttributes Attributes { get { return (EventAttributes)attributes; } set { attributes = (ushort)value; } } public MethodDefinition AddMethod { get { if (add_method != null) return add_method; InitializeMethods(); return add_method; } set { add_method = value; } } public MethodDefinition InvokeMethod { get { if (invoke_method != null) return invoke_method; InitializeMethods(); return invoke_method; } set { invoke_method = value; } } public MethodDefinition RemoveMethod { get { if (remove_method != null) return remove_method; InitializeMethods(); return remove_method; } set { remove_method = value; } } public bool HasOtherMethods { get { if (other_methods != null) return other_methods.Count > 0; InitializeMethods(); return !other_methods.IsNullOrEmpty(); } } public Collection OtherMethods { get { if (other_methods != null) return other_methods; InitializeMethods(); if (other_methods == null) Interlocked.CompareExchange(ref other_methods, new(), null); return other_methods; } } public bool HasCustomAttributes { get { if (custom_attributes != null) return custom_attributes.Count > 0; return this.GetHasCustomAttributes(Module); } } public Collection CustomAttributes { get { return custom_attributes ?? this.GetCustomAttributes(ref custom_attributes, Module); } } #region EventAttributes public bool IsSpecialName { get { return attributes.GetAttributes((ushort)EventAttributes.SpecialName); } set { attributes = attributes.SetAttributes((ushort)EventAttributes.SpecialName, value); } } public bool IsRuntimeSpecialName { get { return attributes.GetAttributes((ushort)EventAttributes.RTSpecialName); } set { attributes = attributes.SetAttributes((ushort)EventAttributes.RTSpecialName, value); } } #endregion public new TypeDefinition DeclaringType { get { return (TypeDefinition)base.DeclaringType; } set { base.DeclaringType = value; } } public override bool IsDefinition { get { return true; } } public EventDefinition(string name, EventAttributes attributes, TypeReference eventType) : base(name, eventType) { this.attributes = (ushort)attributes; token = new(TokenType.Event); } private void InitializeMethods() { ModuleDefinition module = Module; if (module == null) return; lock (module.SyncRoot) { if (add_method != null || invoke_method != null || remove_method != null) return; if (!module.HasImage()) return; module.Read(this, (@event, reader) => reader.ReadMethods(@event)); } } public override EventDefinition Resolve() { return this; } } }