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 
11 using Mono.Collections.Generic;
12 
13 namespace Mono.Cecil {
14 
15 	public sealed class EventDefinition : EventReference, IMemberDefinition {
16 
17 		ushort attributes;
18 
19 		Collection<CustomAttribute> custom_attributes;
20 
21 		internal MethodDefinition add_method;
22 		internal MethodDefinition invoke_method;
23 		internal MethodDefinition remove_method;
24 		internal Collection<MethodDefinition> other_methods;
25 
26 		public EventAttributes Attributes {
27 			get { return (EventAttributes) attributes; }
28 			set { attributes = (ushort) value; }
29 		}
30 
31 		public MethodDefinition AddMethod {
32 			get {
33 				if (add_method != null)
34 					return add_method;
35 
36 				InitializeMethods ();
37 				return add_method;
38 			}
39 			set { add_method = value; }
40 		}
41 
42 		public MethodDefinition InvokeMethod {
43 			get {
44 				if (invoke_method != null)
45 					return invoke_method;
46 
47 				InitializeMethods ();
48 				return invoke_method;
49 			}
50 			set { invoke_method = value; }
51 		}
52 
53 		public MethodDefinition RemoveMethod {
54 			get {
55 				if (remove_method != null)
56 					return remove_method;
57 
58 				InitializeMethods ();
59 				return remove_method;
60 			}
61 			set { remove_method = value; }
62 		}
63 
64 		public bool HasOtherMethods {
65 			get {
66 				if (other_methods != null)
67 					return other_methods.Count > 0;
68 
69 				InitializeMethods ();
70 				return !other_methods.IsNullOrEmpty ();
71 			}
72 		}
73 
74 		public Collection<MethodDefinition> OtherMethods {
75 			get {
76 				if (other_methods != null)
77 					return other_methods;
78 
79 				InitializeMethods ();
80 
81 				if (other_methods != null)
82 					return other_methods;
83 
84 				return other_methods = new Collection<MethodDefinition> ();
85 			}
86 		}
87 
88 		public bool HasCustomAttributes {
89 			get {
90 				if (custom_attributes != null)
91 					return custom_attributes.Count > 0;
92 
93 				return this.GetHasCustomAttributes (Module);
94 			}
95 		}
96 
97 		public Collection<CustomAttribute> CustomAttributes {
98 			get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
99 		}
100 
101 		#region EventAttributes
102 
103 		public bool IsSpecialName {
104 			get { return attributes.GetAttributes ((ushort) EventAttributes.SpecialName); }
105 			set { attributes = attributes.SetAttributes ((ushort) EventAttributes.SpecialName, value); }
106 		}
107 
108 		public bool IsRuntimeSpecialName {
109 			get { return attributes.GetAttributes ((ushort) EventAttributes.RTSpecialName); }
110 			set { attributes = attributes.SetAttributes ((ushort) EventAttributes.RTSpecialName, value); }
111 		}
112 
113 		#endregion
114 
115 		public new TypeDefinition DeclaringType {
116 			get { return (TypeDefinition) base.DeclaringType; }
117 			set { base.DeclaringType = value; }
118 		}
119 
120 		public override bool IsDefinition {
121 			get { return true; }
122 		}
123 
EventDefinition(string name, EventAttributes attributes, TypeReference eventType)124 		public EventDefinition (string name, EventAttributes attributes, TypeReference eventType)
125 			: base (name, eventType)
126 		{
127 			this.attributes = (ushort) attributes;
128 			this.token = new MetadataToken (TokenType.Event);
129 		}
130 
InitializeMethods()131 		void InitializeMethods ()
132 		{
133 			var module = this.Module;
134 			if (module == null)
135 				return;
136 
137 			lock (module.SyncRoot) {
138 				if (add_method != null
139 					|| invoke_method != null
140 					|| remove_method != null)
141 					return;
142 
143 				if (!module.HasImage ())
144 					return;
145 
146 				module.Read (this, (@event, reader) => reader.ReadMethods (@event));
147 			}
148 		}
149 
Resolve()150 		public override EventDefinition Resolve ()
151 		{
152 			return this;
153 		}
154 	}
155 }
156