1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Reflection;
7 using System.Diagnostics;
8 using System.Collections.Generic;
9 using System.Runtime.CompilerServices;
10 using System.Reflection.Runtime.General;
11 using System.Reflection.Runtime.TypeInfos;
12 using System.Reflection.Runtime.ParameterInfos;
13 using System.Reflection.Runtime.CustomAttributes;
14 
15 using Internal.Reflection.Core.Execution;
16 using Internal.Reflection.Tracing;
17 
18 namespace System.Reflection.Runtime.EventInfos
19 {
20     //
21     // The runtime's implementation of EventInfo's
22     //
23     [DebuggerDisplay("{_debugName}")]
24     internal abstract partial class RuntimeEventInfo : EventInfo, ITraceableTypeMember
25     {
RuntimeEventInfo(RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)26         protected RuntimeEventInfo(RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)
27         {
28             ContextTypeInfo = contextTypeInfo;
29             ReflectedTypeInfo = reflectedType;
30         }
31 
32         public sealed override MethodInfo AddMethod
33         {
34             get
35             {
36 #if ENABLE_REFLECTION_TRACE
37                 if (ReflectionTrace.Enabled)
38                     ReflectionTrace.EventInfo_AddMethod(this);
39 #endif
40 
41                 MethodInfo adder = _lazyAdder;
42                 if (adder == null)
43                 {
44                     adder = GetEventMethod(EventMethodSemantics.Add);
45                     if (adder != null)
46                         return _lazyAdder = adder;
47 
48                     throw new BadImageFormatException(); // Added is a required method.
49                 }
50                 return adder;
51             }
52         }
53 
54         public sealed override Type DeclaringType
55         {
56             get
57             {
58 #if ENABLE_REFLECTION_TRACE
59                 if (ReflectionTrace.Enabled)
60                     ReflectionTrace.EventInfo_DeclaringType(this);
61 #endif
62 
63                 return ContextTypeInfo;
64             }
65         }
66 
GetOtherMethods(bool nonPublic)67         public sealed override MethodInfo[] GetOtherMethods(bool nonPublic)
68         {
69             throw new PlatformNotSupportedException();
70         }
71 
HasSameMetadataDefinitionAs(MemberInfo other)72         public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other);
73 
74         public sealed override Module Module
75         {
76             get
77             {
78                 return DefiningTypeInfo.Module;
79             }
80         }
81 
82         public sealed override String Name
83         {
84             get
85             {
86 #if ENABLE_REFLECTION_TRACE
87                 if (ReflectionTrace.Enabled)
88                     ReflectionTrace.EventInfo_Name(this);
89 #endif
90 
91                 return MetadataName;
92             }
93         }
94 
95         public sealed override Type ReflectedType
96         {
97             get
98             {
99                 return ReflectedTypeInfo;
100             }
101         }
102 
103         public sealed override MethodInfo RaiseMethod
104         {
105             get
106             {
107 #if ENABLE_REFLECTION_TRACE
108                 if (ReflectionTrace.Enabled)
109                     ReflectionTrace.EventInfo_RaiseMethod(this);
110 #endif
111 
112                 return GetEventMethod(EventMethodSemantics.Fire);
113             }
114         }
115 
116         public sealed override MethodInfo RemoveMethod
117         {
118             get
119             {
120 #if ENABLE_REFLECTION_TRACE
121                 if (ReflectionTrace.Enabled)
122                     ReflectionTrace.EventInfo_RemoveMethod(this);
123 #endif
124 
125                 MethodInfo remover = _lazyRemover;
126                 if (remover == null)
127                 {
128                     remover = GetEventMethod(EventMethodSemantics.Remove);
129                     if (remover != null)
130                         return _lazyRemover = remover;
131 
132                     throw new BadImageFormatException(); // Removed is a required method.
133                 }
134                 return remover;
135             }
136         }
137 
ToString()138         public sealed override String ToString()
139         {
140             MethodInfo addMethod = this.AddMethod;
141             ParameterInfo[] parameters = addMethod.GetParametersNoCopy();
142             if (parameters.Length == 0)
143                 throw new InvalidOperationException(); // Legacy: Why is a ToString() intentionally throwing an exception?
144             RuntimeParameterInfo runtimeParameterInfo = (RuntimeParameterInfo)(parameters[0]);
145             return runtimeParameterInfo.ParameterTypeString + " " + this.Name;
146         }
147 
148         String ITraceableTypeMember.MemberName
149         {
150             get
151             {
152                 return MetadataName;
153             }
154         }
155 
156         Type ITraceableTypeMember.ContainingType
157         {
158             get
159             {
160                 return ContextTypeInfo;
161             }
162         }
163 
WithDebugName()164         protected RuntimeEventInfo WithDebugName()
165         {
166             bool populateDebugNames = DeveloperExperienceState.DeveloperExperienceModeEnabled;
167 #if DEBUG
168             populateDebugNames = true;
169 #endif
170             if (!populateDebugNames)
171                 return this;
172 
173             if (_debugName == null)
174             {
175                 _debugName = "Constructing..."; // Protect against any inadvertent reentrancy.
176                 _debugName = MetadataName;
177             }
178             return this;
179         }
180 
181         // Types that derive from RuntimeEventInfo must implement the following public surface area members
182         public abstract override EventAttributes Attributes { get; }
183         public abstract override IEnumerable<CustomAttributeData> CustomAttributes { get; }
Equals(Object obj)184         public abstract override bool Equals(Object obj);
GetHashCode()185         public abstract override int GetHashCode();
186         public abstract override Type EventHandlerType { get; }
187         public abstract override int MetadataToken { get; }
188 
189         protected enum EventMethodSemantics
190         {
191             Add,
192             Remove,
193             Fire
194         }
195 
196         /// <summary>
197         /// Override to return the Method that corresponds to the specified semantic.
198         /// Return null if no method is to be found.
199         /// </summary>
GetEventMethod(EventMethodSemantics whichMethod)200         protected abstract MethodInfo GetEventMethod(EventMethodSemantics whichMethod);
201 
202         /// <summary>
203         /// Override to provide the metadata based name of an event. (Different from the Name
204         /// property in that it does not go into the reflection trace logic.)
205         /// </summary>
206         protected abstract string MetadataName { get; }
207 
208         /// <summary>
209         /// Return the DefiningTypeInfo as a RuntimeTypeInfo (instead of as a format specific type info)
210         /// </summary>
211         protected abstract RuntimeTypeInfo DefiningTypeInfo { get; }
212 
213 
214         protected readonly RuntimeTypeInfo ContextTypeInfo;
215         protected readonly RuntimeTypeInfo ReflectedTypeInfo;
216 
217         private volatile MethodInfo _lazyAdder;
218         private volatile MethodInfo _lazyRemover;
219 
220         private String _debugName;
221     }
222 }
223