~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Reader/Method.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2009-2012 Jeroen Frijters
 
3
 
 
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.
 
7
 
 
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:
 
11
 
 
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.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
  
 
23
*/
 
24
using System;
 
25
using System.Collections.Generic;
 
26
using System.Text;
 
27
using IKVM.Reflection.Metadata;
 
28
 
 
29
namespace IKVM.Reflection.Reader
 
30
{
 
31
        sealed class MethodDefImpl : MethodInfo
 
32
        {
 
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;
 
40
 
 
41
                internal MethodDefImpl(ModuleReader module, TypeDefImpl declaringType, int index)
 
42
                {
 
43
                        this.module = module;
 
44
                        this.index = index;
 
45
                        this.declaringType = declaringType;
 
46
                }
 
47
 
 
48
                public override MethodBody GetMethodBody()
 
49
                {
 
50
                        return GetMethodBody(this);
 
51
                }
 
52
 
 
53
                internal MethodBody GetMethodBody(IGenericContext context)
 
54
                {
 
55
                        if ((GetMethodImplementationFlags() & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL)
 
56
                        {
 
57
                                // method is not IL
 
58
                                return null;
 
59
                        }
 
60
                        int rva = module.MethodDef.records[index].RVA;
 
61
                        return rva == 0 ? null : new MethodBody(module, rva, context);
 
62
                }
 
63
 
 
64
                public override int __MethodRVA
 
65
                {
 
66
                        get { return module.MethodDef.records[index].RVA; }
 
67
                }
 
68
 
 
69
                public override CallingConventions CallingConvention
 
70
                {
 
71
                        get { return this.MethodSignature.CallingConvention; }
 
72
                }
 
73
 
 
74
                public override MethodAttributes Attributes
 
75
                {
 
76
                        get { return (MethodAttributes)module.MethodDef.records[index].Flags; }
 
77
                }
 
78
 
 
79
                public override MethodImplAttributes GetMethodImplementationFlags()
 
80
                {
 
81
                        return (MethodImplAttributes)module.MethodDef.records[index].ImplFlags;
 
82
                }
 
83
 
 
84
                public override ParameterInfo[] GetParameters()
 
85
                {
 
86
                        PopulateParameters();
 
87
                        return (ParameterInfo[])parameters.Clone();
 
88
                }
 
89
 
 
90
                private void PopulateParameters()
 
91
                {
 
92
                        if (parameters == null)
 
93
                        {
 
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++)
 
99
                                {
 
100
                                        int seq = module.Param.records[parameter].Sequence - 1;
 
101
                                        if (seq == -1)
 
102
                                        {
 
103
                                                returnParameter = new ParameterInfoImpl(this, seq, parameter);
 
104
                                        }
 
105
                                        else
 
106
                                        {
 
107
                                                parameters[seq] = new ParameterInfoImpl(this, seq, parameter);
 
108
                                        }
 
109
                                }
 
110
                                for (int i = 0; i < parameters.Length; i++)
 
111
                                {
 
112
                                        if (parameters[i] == null)
 
113
                                        {
 
114
                                                parameters[i] = new ParameterInfoImpl(this, i, -1);
 
115
                                        }
 
116
                                }
 
117
                                if (returnParameter == null)
 
118
                                {
 
119
                                        returnParameter = new ParameterInfoImpl(this, -1, -1);
 
120
                                }
 
121
                        }
 
122
                }
 
123
 
 
124
                internal override int ParameterCount
 
125
                {
 
126
                        get { return this.MethodSignature.GetParameterCount(); }
 
127
                }
 
128
 
 
129
                public override ParameterInfo ReturnParameter
 
130
                {
 
131
                        get
 
132
                        {
 
133
                                PopulateParameters();
 
134
                                return returnParameter;
 
135
                        }
 
136
                }
 
137
 
 
138
                public override Type ReturnType
 
139
                {
 
140
                        get
 
141
                        {
 
142
                                return this.ReturnParameter.ParameterType;
 
143
                        }
 
144
                }
 
145
 
 
146
                public override Type DeclaringType
 
147
                {
 
148
                        get { return declaringType.IsModulePseudoType ? null : declaringType; }
 
149
                }
 
150
 
 
151
                public override string Name
 
152
                {
 
153
                        get { return module.GetString(module.MethodDef.records[index].Name); }
 
154
                }
 
155
 
 
156
                public override int MetadataToken
 
157
                {
 
158
                        get { return (MethodDefTable.Index << 24) + index + 1; }
 
159
                }
 
160
 
 
161
                public override bool IsGenericMethodDefinition
 
162
                {
 
163
                        get
 
164
                        {
 
165
                                PopulateGenericArguments();
 
166
                                return typeArgs.Length > 0;
 
167
                        }
 
168
                }
 
169
 
 
170
                public override bool IsGenericMethod
 
171
                {
 
172
                        get { return IsGenericMethodDefinition; }
 
173
                }
 
174
 
 
175
                public override Type[] GetGenericArguments()
 
176
                {
 
177
                        PopulateGenericArguments();
 
178
                        return Util.Copy(typeArgs);
 
179
                }
 
180
 
 
181
                private void PopulateGenericArguments()
 
182
                {
 
183
                        if (typeArgs == null)
 
184
                        {
 
185
                                int token = this.MetadataToken;
 
186
                                int first = module.GenericParam.FindFirstByOwner(token);
 
187
                                if (first == -1)
 
188
                                {
 
189
                                        typeArgs = Type.EmptyTypes;
 
190
                                }
 
191
                                else
 
192
                                {
 
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++)
 
196
                                        {
 
197
                                                list.Add(new GenericTypeParameter(module, i));
 
198
                                        }
 
199
                                        typeArgs = list.ToArray();
 
200
                                }
 
201
                        }
 
202
                }
 
203
 
 
204
                internal override Type GetGenericMethodArgument(int index)
 
205
                {
 
206
                        PopulateGenericArguments();
 
207
                        return typeArgs[index];
 
208
                }
 
209
 
 
210
                internal override int GetGenericMethodArgumentCount()
 
211
                {
 
212
                        PopulateGenericArguments();
 
213
                        return typeArgs.Length;
 
214
                }
 
215
 
 
216
                public override MethodInfo GetGenericMethodDefinition()
 
217
                {
 
218
                        if (this.IsGenericMethodDefinition)
 
219
                        {
 
220
                                return this;
 
221
                        }
 
222
                        throw new InvalidOperationException();
 
223
                }
 
224
 
 
225
                public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
 
226
                {
 
227
                        return new GenericMethodInstance(declaringType, this, typeArguments);
 
228
                }
 
229
 
 
230
                public override Module Module
 
231
                {
 
232
                        get { return module; }
 
233
                }
 
234
 
 
235
                internal override MethodSignature MethodSignature
 
236
                {
 
237
                        get { return lazyMethodSignature ?? (lazyMethodSignature = MethodSignature.ReadSig(module, module.GetBlob(module.MethodDef.records[index].Signature), this)); }
 
238
                }
 
239
 
 
240
                internal override int ImportTo(Emit.ModuleBuilder module)
 
241
                {
 
242
                        return module.ImportMethodOrField(declaringType, this.Name, this.MethodSignature);
 
243
                }
 
244
 
 
245
                public override MethodInfo[] __GetMethodImpls()
 
246
                {
 
247
                        Type[] typeArgs = null;
 
248
                        List<MethodInfo> list = null;
 
249
                        foreach (int i in module.MethodImpl.Filter(declaringType.MetadataToken))
 
250
                        {
 
251
                                if (module.MethodImpl.records[i].MethodBody == this.MetadataToken)
 
252
                                {
 
253
                                        if (typeArgs == null)
 
254
                                        {
 
255
                                                typeArgs = declaringType.GetGenericArguments();
 
256
                                        }
 
257
                                        if (list == null)
 
258
                                        {
 
259
                                                list = new List<MethodInfo>();
 
260
                                        }
 
261
                                        list.Add((MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodDeclaration, typeArgs, null));
 
262
                                }
 
263
                        }
 
264
                        return Util.ToArray(list, Empty<MethodInfo>.Array);
 
265
                }
 
266
 
 
267
                internal override int GetCurrentToken()
 
268
                {
 
269
                        return this.MetadataToken;
 
270
                }
 
271
 
 
272
                internal override bool IsBaked
 
273
                {
 
274
                        get { return true; }
 
275
                }
 
276
        }
 
277
 
 
278
        sealed class ParameterInfoImpl : ParameterInfo
 
279
        {
 
280
                private readonly MethodDefImpl method;
 
281
                private readonly int position;
 
282
                private readonly int index;
 
283
 
 
284
                internal ParameterInfoImpl(MethodDefImpl method, int position, int index)
 
285
                {
 
286
                        this.method = method;
 
287
                        this.position = position;
 
288
                        this.index = index;
 
289
                }
 
290
 
 
291
                public override string Name
 
292
                {
 
293
                        get { return index == -1 ? null : ((ModuleReader)this.Module).GetString(this.Module.Param.records[index].Name); }
 
294
                }
 
295
 
 
296
                public override Type ParameterType
 
297
                {
 
298
                        get { return position == -1 ? method.MethodSignature.GetReturnType(method) : method.MethodSignature.GetParameterType(method, position); }
 
299
                }
 
300
 
 
301
                public override ParameterAttributes Attributes
 
302
                {
 
303
                        get { return index == -1 ? ParameterAttributes.None : (ParameterAttributes)this.Module.Param.records[index].Flags; }
 
304
                }
 
305
 
 
306
                public override int Position
 
307
                {
 
308
                        get { return position; }
 
309
                }
 
310
 
 
311
                public override object RawDefaultValue
 
312
                {
 
313
                        get
 
314
                        {
 
315
                                if ((this.Attributes & ParameterAttributes.HasDefault) != 0)
 
316
                                {
 
317
                                        return this.Module.Constant.GetRawConstantValue(this.Module, this.MetadataToken);
 
318
                                }
 
319
                                Universe universe = this.Module.universe;
 
320
                                if (this.ParameterType == universe.System_Decimal)
 
321
                                {
 
322
                                        Type attr = universe.System_Runtime_CompilerServices_DecimalConstantAttribute;
 
323
                                        if (attr != null)
 
324
                                        {
 
325
                                                foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(this, attr, false))
 
326
                                                {
 
327
                                                        IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
 
328
                                                        if (args.Count == 5)
 
329
                                                        {
 
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)
 
335
                                                                {
 
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);
 
337
                                                                }
 
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)
 
343
                                                                {
 
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);
 
345
                                                                }
 
346
                                                        }
 
347
                                                }
 
348
                                        }
 
349
                                }
 
350
                                if ((this.Attributes & ParameterAttributes.Optional) != 0)
 
351
                                {
 
352
                                        return Missing.Value;
 
353
                                }
 
354
                                return null;
 
355
                        }
 
356
                }
 
357
 
 
358
                public override CustomModifiers __GetCustomModifiers()
 
359
                {
 
360
                        return position == -1
 
361
                                ? method.MethodSignature.GetReturnTypeCustomModifiers(method)
 
362
                                : method.MethodSignature.GetParameterCustomModifiers(method, position);
 
363
                }
 
364
 
 
365
                public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
 
366
                {
 
367
                        return FieldMarshal.ReadFieldMarshal(this.Module, this.MetadataToken, out fieldMarshal);
 
368
                }
 
369
 
 
370
                public override MemberInfo Member
 
371
                {
 
372
                        get
 
373
                        {
 
374
                                // return the right ConstructorInfo wrapper
 
375
                                return method.Module.ResolveMethod(method.MetadataToken);
 
376
                        }
 
377
                }
 
378
 
 
379
                public override int MetadataToken
 
380
                {
 
381
                        get
 
382
                        {
 
383
                                // for parameters that don't have a row in the Param table, we return 0x08000000 (because index is -1 in that case),
 
384
                                // just like .NET
 
385
                                return (ParamTable.Index << 24) + index + 1;
 
386
                        }
 
387
                }
 
388
 
 
389
                internal override Module Module
 
390
                {
 
391
                        get { return method.Module; }
 
392
                }
 
393
        }
 
394
}