2
Copyright (C) 2009-2012 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;
27
using IKVM.Reflection.Metadata;
29
namespace IKVM.Reflection.Reader
31
sealed class MethodDefImpl : MethodInfo
33
private readonly ModuleReader module;
34
private readonly int index;
35
private readonly TypeDefImpl declaringType;
36
private MethodSignature lazyMethodSignature;
37
private ParameterInfo returnParameter;
38
private ParameterInfo[] parameters;
39
private Type[] typeArgs;
41
internal MethodDefImpl(ModuleReader module, TypeDefImpl declaringType, int index)
45
this.declaringType = declaringType;
48
public override MethodBody GetMethodBody()
50
return GetMethodBody(this);
53
internal MethodBody GetMethodBody(IGenericContext context)
55
if ((GetMethodImplementationFlags() & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL)
60
int rva = module.MethodDef.records[index].RVA;
61
return rva == 0 ? null : new MethodBody(module, rva, context);
64
public override int __MethodRVA
66
get { return module.MethodDef.records[index].RVA; }
69
public override CallingConventions CallingConvention
71
get { return this.MethodSignature.CallingConvention; }
74
public override MethodAttributes Attributes
76
get { return (MethodAttributes)module.MethodDef.records[index].Flags; }
79
public override MethodImplAttributes GetMethodImplementationFlags()
81
return (MethodImplAttributes)module.MethodDef.records[index].ImplFlags;
84
public override ParameterInfo[] GetParameters()
87
return (ParameterInfo[])parameters.Clone();
90
private void PopulateParameters()
92
if (parameters == null)
94
MethodSignature methodSignature = this.MethodSignature;
95
parameters = new ParameterInfo[methodSignature.GetParameterCount()];
96
int parameter = module.MethodDef.records[index].ParamList - 1;
97
int end = module.MethodDef.records.Length > index + 1 ? module.MethodDef.records[index + 1].ParamList - 1 : module.Param.records.Length;
98
for (; parameter < end; parameter++)
100
int seq = module.Param.records[parameter].Sequence - 1;
103
returnParameter = new ParameterInfoImpl(this, seq, parameter);
107
parameters[seq] = new ParameterInfoImpl(this, seq, parameter);
110
for (int i = 0; i < parameters.Length; i++)
112
if (parameters[i] == null)
114
parameters[i] = new ParameterInfoImpl(this, i, -1);
117
if (returnParameter == null)
119
returnParameter = new ParameterInfoImpl(this, -1, -1);
124
internal override int ParameterCount
126
get { return this.MethodSignature.GetParameterCount(); }
129
public override ParameterInfo ReturnParameter
133
PopulateParameters();
134
return returnParameter;
138
public override Type ReturnType
142
return this.ReturnParameter.ParameterType;
146
public override Type DeclaringType
148
get { return declaringType.IsModulePseudoType ? null : declaringType; }
151
public override string Name
153
get { return module.GetString(module.MethodDef.records[index].Name); }
156
public override int MetadataToken
158
get { return (MethodDefTable.Index << 24) + index + 1; }
161
public override bool IsGenericMethodDefinition
165
PopulateGenericArguments();
166
return typeArgs.Length > 0;
170
public override bool IsGenericMethod
172
get { return IsGenericMethodDefinition; }
175
public override Type[] GetGenericArguments()
177
PopulateGenericArguments();
178
return Util.Copy(typeArgs);
181
private void PopulateGenericArguments()
183
if (typeArgs == null)
185
int token = this.MetadataToken;
186
int first = module.GenericParam.FindFirstByOwner(token);
189
typeArgs = Type.EmptyTypes;
193
List<Type> list = new List<Type>();
194
int len = module.GenericParam.records.Length;
195
for (int i = first; i < len && module.GenericParam.records[i].Owner == token; i++)
197
list.Add(new GenericTypeParameter(module, i));
199
typeArgs = list.ToArray();
204
internal override Type GetGenericMethodArgument(int index)
206
PopulateGenericArguments();
207
return typeArgs[index];
210
internal override int GetGenericMethodArgumentCount()
212
PopulateGenericArguments();
213
return typeArgs.Length;
216
public override MethodInfo GetGenericMethodDefinition()
218
if (this.IsGenericMethodDefinition)
222
throw new InvalidOperationException();
225
public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
227
return new GenericMethodInstance(declaringType, this, typeArguments);
230
public override Module Module
232
get { return module; }
235
internal override MethodSignature MethodSignature
237
get { return lazyMethodSignature ?? (lazyMethodSignature = MethodSignature.ReadSig(module, module.GetBlob(module.MethodDef.records[index].Signature), this)); }
240
internal override int ImportTo(Emit.ModuleBuilder module)
242
return module.ImportMethodOrField(declaringType, this.Name, this.MethodSignature);
245
public override MethodInfo[] __GetMethodImpls()
247
Type[] typeArgs = null;
248
List<MethodInfo> list = null;
249
foreach (int i in module.MethodImpl.Filter(declaringType.MetadataToken))
251
if (module.MethodImpl.records[i].MethodBody == this.MetadataToken)
253
if (typeArgs == null)
255
typeArgs = declaringType.GetGenericArguments();
259
list = new List<MethodInfo>();
261
list.Add((MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodDeclaration, typeArgs, null));
264
return Util.ToArray(list, Empty<MethodInfo>.Array);
267
internal override int GetCurrentToken()
269
return this.MetadataToken;
272
internal override bool IsBaked
278
sealed class ParameterInfoImpl : ParameterInfo
280
private readonly MethodDefImpl method;
281
private readonly int position;
282
private readonly int index;
284
internal ParameterInfoImpl(MethodDefImpl method, int position, int index)
286
this.method = method;
287
this.position = position;
291
public override string Name
293
get { return index == -1 ? null : ((ModuleReader)this.Module).GetString(this.Module.Param.records[index].Name); }
296
public override Type ParameterType
298
get { return position == -1 ? method.MethodSignature.GetReturnType(method) : method.MethodSignature.GetParameterType(method, position); }
301
public override ParameterAttributes Attributes
303
get { return index == -1 ? ParameterAttributes.None : (ParameterAttributes)this.Module.Param.records[index].Flags; }
306
public override int Position
308
get { return position; }
311
public override object RawDefaultValue
315
if ((this.Attributes & ParameterAttributes.HasDefault) != 0)
317
return this.Module.Constant.GetRawConstantValue(this.Module, this.MetadataToken);
319
Universe universe = this.Module.universe;
320
if (this.ParameterType == universe.System_Decimal)
322
Type attr = universe.System_Runtime_CompilerServices_DecimalConstantAttribute;
325
foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(this, attr, false))
327
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
330
if (args[0].ArgumentType == universe.System_Byte
331
&& args[1].ArgumentType == universe.System_Byte
332
&& args[2].ArgumentType == universe.System_Int32
333
&& args[3].ArgumentType == universe.System_Int32
334
&& args[4].ArgumentType == universe.System_Int32)
336
return new Decimal((int)args[4].Value, (int)args[3].Value, (int)args[2].Value, (byte)args[1].Value != 0, (byte)args[0].Value);
338
else if (args[0].ArgumentType == universe.System_Byte
339
&& args[1].ArgumentType == universe.System_Byte
340
&& args[2].ArgumentType == universe.System_UInt32
341
&& args[3].ArgumentType == universe.System_UInt32
342
&& args[4].ArgumentType == universe.System_UInt32)
344
return new Decimal(unchecked((int)(uint)args[4].Value), unchecked((int)(uint)args[3].Value), unchecked((int)(uint)args[2].Value), (byte)args[1].Value != 0, (byte)args[0].Value);
350
if ((this.Attributes & ParameterAttributes.Optional) != 0)
352
return Missing.Value;
358
public override CustomModifiers __GetCustomModifiers()
360
return position == -1
361
? method.MethodSignature.GetReturnTypeCustomModifiers(method)
362
: method.MethodSignature.GetParameterCustomModifiers(method, position);
365
public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
367
return FieldMarshal.ReadFieldMarshal(this.Module, this.MetadataToken, out fieldMarshal);
370
public override MemberInfo Member
374
// return the right ConstructorInfo wrapper
375
return method.Module.ResolveMethod(method.MetadataToken);
379
public override int MetadataToken
383
// for parameters that don't have a row in the Param table, we return 0x08000000 (because index is -1 in that case),
385
return (ParamTable.Index << 24) + index + 1;
389
internal override Module Module
391
get { return method.Module; }