2
Copyright (C) 2008-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.Writer;
28
using IKVM.Reflection.Metadata;
30
namespace IKVM.Reflection.Emit
32
public sealed class PropertyBuilder : PropertyInfo
34
private readonly TypeBuilder typeBuilder;
35
private readonly string name;
36
private PropertyAttributes attributes;
37
private PropertySignature sig;
38
private MethodBuilder getter;
39
private MethodBuilder setter;
40
private readonly List<Accessor> accessors = new List<Accessor>();
41
private int lazyPseudoToken;
42
private bool patchCallingConvention;
44
private struct Accessor
46
internal short Semantics;
47
internal MethodBuilder Method;
50
internal PropertyBuilder(TypeBuilder typeBuilder, string name, PropertyAttributes attributes, PropertySignature sig, bool patchCallingConvention)
52
this.typeBuilder = typeBuilder;
54
this.attributes = attributes;
56
this.patchCallingConvention = patchCallingConvention;
59
internal override PropertySignature PropertySignature
64
public void SetGetMethod(MethodBuilder mdBuilder)
68
acc.Semantics = MethodSemanticsTable.Getter;
69
acc.Method = mdBuilder;
73
public void SetSetMethod(MethodBuilder mdBuilder)
77
acc.Semantics = MethodSemanticsTable.Setter;
78
acc.Method = mdBuilder;
82
public void AddOtherMethod(MethodBuilder mdBuilder)
85
acc.Semantics = MethodSemanticsTable.Other;
86
acc.Method = mdBuilder;
90
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
92
SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
95
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
97
Universe u = typeBuilder.ModuleBuilder.universe;
98
if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute)
100
attributes |= PropertyAttributes.SpecialName;
104
if (lazyPseudoToken == 0)
106
lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken();
108
typeBuilder.ModuleBuilder.SetCustomAttribute(lazyPseudoToken, customBuilder);
112
public override object GetRawConstantValue()
114
if (lazyPseudoToken != 0)
116
return typeBuilder.ModuleBuilder.Constant.GetRawConstantValue(typeBuilder.ModuleBuilder, lazyPseudoToken);
118
throw new InvalidOperationException();
121
public override PropertyAttributes Attributes
123
get { return attributes; }
126
public override bool CanRead
128
get { return getter != null; }
131
public override bool CanWrite
133
get { return setter != null; }
136
public override MethodInfo GetGetMethod(bool nonPublic)
138
return nonPublic || (getter != null && getter.IsPublic) ? getter : null;
141
public override MethodInfo GetSetMethod(bool nonPublic)
143
return nonPublic || (setter != null && setter.IsPublic) ? setter : null;
146
public override MethodInfo[] GetAccessors(bool nonPublic)
148
List<MethodInfo> list = new List<MethodInfo>();
149
foreach (Accessor acc in accessors)
151
AddAccessor(list, nonPublic, acc.Method);
153
return list.ToArray();
156
private static void AddAccessor(List<MethodInfo> list, bool nonPublic, MethodInfo method)
158
if (method != null && (nonPublic || method.IsPublic))
164
public override Type DeclaringType
166
get { return typeBuilder; }
169
public override string Name
174
public override Module Module
176
get { return typeBuilder.Module; }
179
public void SetConstant(object defaultValue)
181
if (lazyPseudoToken == 0)
183
lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken();
185
attributes |= PropertyAttributes.HasDefault;
186
typeBuilder.ModuleBuilder.AddConstant(lazyPseudoToken, defaultValue);
191
if (patchCallingConvention)
193
sig.HasThis = !this.IsStatic;
196
PropertyTable.Record rec = new PropertyTable.Record();
197
rec.Flags = (short)attributes;
198
rec.Name = typeBuilder.ModuleBuilder.Strings.Add(name);
199
rec.Type = typeBuilder.ModuleBuilder.GetSignatureBlobIndex(sig);
200
int token = 0x17000000 | typeBuilder.ModuleBuilder.Property.AddRecord(rec);
202
if (lazyPseudoToken == 0)
204
lazyPseudoToken = token;
208
typeBuilder.ModuleBuilder.RegisterTokenFixup(lazyPseudoToken, token);
211
foreach (Accessor acc in accessors)
213
AddMethodSemantics(acc.Semantics, acc.Method.MetadataToken, token);
217
private void AddMethodSemantics(short semantics, int methodToken, int propertyToken)
219
MethodSemanticsTable.Record rec = new MethodSemanticsTable.Record();
220
rec.Semantics = semantics;
221
rec.Method = methodToken;
222
rec.Association = propertyToken;
223
typeBuilder.ModuleBuilder.MethodSemantics.AddRecord(rec);
226
internal override bool IsPublic
230
foreach (Accessor acc in accessors)
232
if (acc.Method.IsPublic)
241
internal override bool IsNonPrivate
245
foreach (Accessor acc in accessors)
247
if ((acc.Method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private)
256
internal override bool IsStatic
260
foreach (Accessor acc in accessors)
262
if (acc.Method.IsStatic)
271
internal override bool IsBaked
273
get { return typeBuilder.IsBaked; }
276
internal override int GetCurrentToken()
278
if (typeBuilder.ModuleBuilder.IsSaved && ModuleBuilder.IsPseudoToken(lazyPseudoToken))
280
return typeBuilder.ModuleBuilder.ResolvePseudoToken(lazyPseudoToken);
284
return lazyPseudoToken;