2
Copyright (C) 2009-2011 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
25
using System.Collections.Generic;
26
using System.Runtime.CompilerServices;
27
using IKVM.Reflection.Metadata;
28
using IKVM.Reflection.Writer;
30
namespace IKVM.Reflection.Emit
32
public sealed class EventBuilder : EventInfo
34
private readonly TypeBuilder typeBuilder;
35
private readonly string name;
36
private EventAttributes attributes;
37
private readonly int eventtype;
38
private MethodBuilder addOnMethod;
39
private MethodBuilder removeOnMethod;
40
private MethodBuilder fireMethod;
41
private readonly List<Accessor> accessors = new List<Accessor>();
42
private int lazyPseudoToken;
44
private struct Accessor
46
internal short Semantics;
47
internal MethodBuilder Method;
50
internal EventBuilder(TypeBuilder typeBuilder, string name, EventAttributes attributes, Type eventtype)
52
this.typeBuilder = typeBuilder;
54
this.attributes = attributes;
55
this.eventtype = typeBuilder.ModuleBuilder.GetTypeTokenForMemberRef(eventtype);
58
public void SetAddOnMethod(MethodBuilder mdBuilder)
60
addOnMethod = mdBuilder;
62
acc.Semantics = MethodSemanticsTable.AddOn;
63
acc.Method = mdBuilder;
67
public void SetRemoveOnMethod(MethodBuilder mdBuilder)
69
removeOnMethod = mdBuilder;
71
acc.Semantics = MethodSemanticsTable.RemoveOn;
72
acc.Method = mdBuilder;
76
public void SetRaiseMethod(MethodBuilder mdBuilder)
78
fireMethod = mdBuilder;
80
acc.Semantics = MethodSemanticsTable.Fire;
81
acc.Method = mdBuilder;
85
public void AddOtherMethod(MethodBuilder mdBuilder)
88
acc.Semantics = MethodSemanticsTable.Other;
89
acc.Method = mdBuilder;
93
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
95
SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
98
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
100
Universe u = typeBuilder.ModuleBuilder.universe;
101
if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute)
103
attributes |= EventAttributes.SpecialName;
107
if (lazyPseudoToken == 0)
109
lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken();
111
typeBuilder.ModuleBuilder.SetCustomAttribute(lazyPseudoToken, customBuilder);
115
public override EventAttributes Attributes
117
get { return attributes; }
120
public override MethodInfo GetAddMethod(bool nonPublic)
122
return nonPublic || (addOnMethod != null && addOnMethod.IsPublic) ? addOnMethod : null;
125
public override MethodInfo GetRemoveMethod(bool nonPublic)
127
return nonPublic || (removeOnMethod != null && removeOnMethod.IsPublic) ? removeOnMethod : null;
130
public override MethodInfo GetRaiseMethod(bool nonPublic)
132
return nonPublic || (fireMethod != null && fireMethod.IsPublic) ? fireMethod : null;
135
public override MethodInfo[] GetOtherMethods(bool nonPublic)
137
List<MethodInfo> list = new List<MethodInfo>();
138
foreach (Accessor acc in accessors)
140
if (acc.Semantics == MethodSemanticsTable.Other && (nonPublic || acc.Method.IsPublic))
142
list.Add(acc.Method);
145
return list.ToArray();
148
public override MethodInfo[] __GetMethods()
150
List<MethodInfo> list = new List<MethodInfo>();
151
foreach (Accessor acc in accessors)
153
list.Add(acc.Method);
155
return list.ToArray();
158
public override Type DeclaringType
160
get { return typeBuilder; }
163
public override string Name
168
public override Module Module
170
get { return typeBuilder.ModuleBuilder; }
173
public EventToken GetEventToken()
175
if (lazyPseudoToken == 0)
177
lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken();
179
return new EventToken(lazyPseudoToken);
182
public override Type EventHandlerType
184
get { return typeBuilder.ModuleBuilder.ResolveType(eventtype); }
189
EventTable.Record rec = new EventTable.Record();
190
rec.EventFlags = (short)attributes;
191
rec.Name = typeBuilder.ModuleBuilder.Strings.Add(name);
192
rec.EventType = eventtype;
193
int token = 0x14000000 | typeBuilder.ModuleBuilder.Event.AddRecord(rec);
195
if (lazyPseudoToken == 0)
197
lazyPseudoToken = token;
201
typeBuilder.ModuleBuilder.RegisterTokenFixup(lazyPseudoToken, token);
204
foreach (Accessor acc in accessors)
206
AddMethodSemantics(acc.Semantics, acc.Method.MetadataToken, token);
210
private void AddMethodSemantics(short semantics, int methodToken, int propertyToken)
212
MethodSemanticsTable.Record rec = new MethodSemanticsTable.Record();
213
rec.Semantics = semantics;
214
rec.Method = methodToken;
215
rec.Association = propertyToken;
216
typeBuilder.ModuleBuilder.MethodSemantics.AddRecord(rec);
219
internal override bool IsPublic
223
foreach (Accessor acc in accessors)
225
if (acc.Method.IsPublic)
234
internal override bool IsNonPrivate
238
foreach (Accessor acc in accessors)
240
if ((acc.Method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private)
249
internal override bool IsStatic
253
foreach (Accessor acc in accessors)
255
if (acc.Method.IsStatic)
264
internal override bool IsBaked
266
get { return typeBuilder.IsBaked; }
269
internal override int GetCurrentToken()
271
if (typeBuilder.ModuleBuilder.IsSaved && ModuleBuilder.IsPseudoToken(lazyPseudoToken))
273
return typeBuilder.ModuleBuilder.ResolvePseudoToken(lazyPseudoToken);
277
return lazyPseudoToken;