do not check order sequence if option /order was not used
[mono.git] / mcs / class / IKVM.Reflection / GenericWrappers.cs
1 /*
2   Copyright (C) 2009, 2010 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
28 namespace IKVM.Reflection
29 {
30         // this represents both generic method instantiations and non-generic methods on generic type instantations
31         // (this means that it can be a generic method declaration as well as a generic method instance)
32         sealed class GenericMethodInstance : MethodInfo
33         {
34                 private readonly Type declaringType;
35                 private readonly MethodInfo method;
36                 private readonly Type[] methodArgs;
37                 private MethodSignature lazyMethodSignature;
38
39                 internal GenericMethodInstance(Type declaringType, MethodInfo method, Type[] methodArgs)
40                 {
41                         System.Diagnostics.Debug.Assert(!(method is GenericMethodInstance));
42                         this.declaringType = declaringType;
43                         this.method = method;
44                         this.methodArgs = methodArgs;
45                 }
46
47                 public override bool Equals(object obj)
48                 {
49                         GenericMethodInstance other = obj as GenericMethodInstance;
50                         return other != null
51                                 && other.method.Equals(method)
52                                 && other.declaringType.Equals(declaringType)
53                                 && Util.ArrayEquals(other.methodArgs, methodArgs);
54                 }
55
56                 public override int GetHashCode()
57                 {
58                         return declaringType.GetHashCode() * 33 ^ method.GetHashCode() ^ Util.GetHashCode(methodArgs);
59                 }
60
61                 public override Type ReturnType
62                 {
63                         get { return method.ReturnType.BindTypeParameters(this); }
64                 }
65
66                 public override ParameterInfo ReturnParameter
67                 {
68                         get { return new GenericParameterInfoImpl(this, method.ReturnParameter); }
69                 }
70
71                 public override ParameterInfo[] GetParameters()
72                 {
73                         ParameterInfo[] parameters = method.GetParameters();
74                         for (int i = 0; i < parameters.Length; i++)
75                         {
76                                 parameters[i] = new GenericParameterInfoImpl(this, parameters[i]);
77                         }
78                         return parameters;
79                 }
80
81                 internal override int ParameterCount
82                 {
83                         get { return method.ParameterCount; }
84                 }
85
86                 public override CallingConventions CallingConvention
87                 {
88                         get { return method.CallingConvention; }
89                 }
90
91                 public override MethodAttributes Attributes
92                 {
93                         get { return method.Attributes; }
94                 }
95
96                 public override MethodImplAttributes GetMethodImplementationFlags()
97                 {
98                         return method.GetMethodImplementationFlags();
99                 }
100
101                 public override string Name
102                 {
103                         get { return method.Name; }
104                 }
105
106                 public override Type DeclaringType
107                 {
108                         get { return declaringType.IsModulePseudoType ? null : declaringType; }
109                 }
110
111                 public override Module Module
112                 {
113                         get { return method.Module; }
114                 }
115
116                 public override int MetadataToken
117                 {
118                         get { return method.MetadataToken; }
119                 }
120
121                 public override MethodBody GetMethodBody()
122                 {
123                         IKVM.Reflection.Reader.MethodDefImpl md = method as IKVM.Reflection.Reader.MethodDefImpl;
124                         if (md != null)
125                         {
126                                 return md.GetMethodBody(this);
127                         }
128                         throw new NotSupportedException();
129                 }
130
131                 public override int __MethodRVA
132                 {
133                         get { return method.__MethodRVA; }
134                 }
135
136                 public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
137                 {
138                         return new GenericMethodInstance(declaringType, method, typeArguments);
139                 }
140
141                 public override bool IsGenericMethod
142                 {
143                         get { return method.IsGenericMethod; }
144                 }
145
146                 public override bool IsGenericMethodDefinition
147                 {
148                         get { return method.IsGenericMethodDefinition && methodArgs == null; }
149                 }
150
151                 public override bool ContainsGenericParameters
152                 {
153                         get
154                         {
155                                 if (declaringType.ContainsGenericParameters)
156                                 {
157                                         return true;
158                                 }
159                                 if (methodArgs != null)
160                                 {
161                                         foreach (Type type in methodArgs)
162                                         {
163                                                 if (type.ContainsGenericParameters)
164                                                 {
165                                                         return true;
166                                                 }
167                                         }
168                                 }
169                                 return false;
170                         }
171                 }
172
173                 public override MethodInfo GetGenericMethodDefinition()
174                 {
175                         if (this.IsGenericMethod)
176                         {
177                                 if (this.IsGenericMethodDefinition)
178                                 {
179                                         return this;
180                                 }
181                                 else if (declaringType.IsConstructedGenericType)
182                                 {
183                                         return new GenericMethodInstance(declaringType, method, null);
184                                 }
185                                 else
186                                 {
187                                         return method;
188                                 }
189                         }
190                         throw new InvalidOperationException();
191                 }
192
193                 public override MethodBase __GetMethodOnTypeDefinition()
194                 {
195                         return method;
196                 }
197
198                 public override Type[] GetGenericArguments()
199                 {
200                         if (methodArgs == null)
201                         {
202                                 return method.GetGenericArguments();
203                         }
204                         else
205                         {
206                                 return (Type[])methodArgs.Clone();
207                         }
208                 }
209
210                 internal override Type GetGenericMethodArgument(int index)
211                 {
212                         if (methodArgs == null)
213                         {
214                                 return method.GetGenericMethodArgument(index);
215                         }
216                         else
217                         {
218                                 return methodArgs[index];
219                         }
220                 }
221
222                 internal override int GetGenericMethodArgumentCount()
223                 {
224                         return method.GetGenericMethodArgumentCount();
225                 }
226
227                 internal override MethodInfo GetMethodOnTypeDefinition()
228                 {
229                         return method.GetMethodOnTypeDefinition();
230                 }
231
232                 internal override int ImportTo(Emit.ModuleBuilder module)
233                 {
234                         if (methodArgs == null)
235                         {
236                                 return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature);
237                         }
238                         else
239                         {
240                                 return module.ImportMethodSpec(declaringType, method, methodArgs);
241                         }
242                 }
243
244                 internal override MethodSignature MethodSignature
245                 {
246                         get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); }
247                 }
248
249                 internal override MethodBase BindTypeParameters(Type type)
250                 {
251                         System.Diagnostics.Debug.Assert(methodArgs == null);
252                         return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null);
253                 }
254
255                 internal override bool HasThis
256                 {
257                         get { return method.HasThis; }
258                 }
259
260                 public override MethodInfo[] __GetMethodImpls()
261                 {
262                         MethodInfo[] methods = method.__GetMethodImpls();
263                         for (int i = 0; i < methods.Length; i++)
264                         {
265                                 methods[i] = (MethodInfo)methods[i].BindTypeParameters(declaringType);
266                         }
267                         return methods;
268                 }
269
270                 internal override int GetCurrentToken()
271                 {
272                         return method.GetCurrentToken();
273                 }
274
275                 internal override bool IsBaked
276                 {
277                         get { return method.IsBaked; }
278                 }
279         }
280
281         sealed class GenericFieldInstance : FieldInfo
282         {
283                 private readonly Type declaringType;
284                 private readonly FieldInfo field;
285
286                 internal GenericFieldInstance(Type declaringType, FieldInfo field)
287                 {
288                         this.declaringType = declaringType;
289                         this.field = field;
290                 }
291
292                 public override bool Equals(object obj)
293                 {
294                         GenericFieldInstance other = obj as GenericFieldInstance;
295                         return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field);
296                 }
297
298                 public override int GetHashCode()
299                 {
300                         return declaringType.GetHashCode() * 3 ^ field.GetHashCode();
301                 }
302
303                 public override FieldAttributes Attributes
304                 {
305                         get { return field.Attributes; }
306                 }
307
308                 public override string Name
309                 {
310                         get { return field.Name; }
311                 }
312
313                 public override Type DeclaringType
314                 {
315                         get { return declaringType; }
316                 }
317
318                 public override Module Module
319                 {
320                         get { return declaringType.Module; }
321                 }
322
323                 public override int MetadataToken
324                 {
325                         get { return field.MetadataToken; }
326                 }
327
328                 public override object GetRawConstantValue()
329                 {
330                         return field.GetRawConstantValue();
331                 }
332
333                 public override void __GetDataFromRVA(byte[] data, int offset, int length)
334                 {
335                         field.__GetDataFromRVA(data, offset, length);
336                 }
337
338                 public override int __FieldRVA
339                 {
340                         get { return field.__FieldRVA; }
341                 }
342
343                 public override bool __TryGetFieldOffset(out int offset)
344                 {
345                         return field.__TryGetFieldOffset(out offset);
346                 }
347
348                 public override FieldInfo __GetFieldOnTypeDefinition()
349                 {
350                         return field;
351                 }
352
353                 internal override FieldSignature FieldSignature
354                 {
355                         get { return field.FieldSignature.ExpandTypeParameters(declaringType); }
356                 }
357
358                 internal override int ImportTo(Emit.ModuleBuilder module)
359                 {
360                         return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature);
361                 }
362
363                 internal override FieldInfo BindTypeParameters(Type type)
364                 {
365                         return new GenericFieldInstance(declaringType.BindTypeParameters(type), field);
366                 }
367
368                 internal override int GetCurrentToken()
369                 {
370                         return field.GetCurrentToken();
371                 }
372
373                 internal override bool IsBaked
374                 {
375                         get { return field.IsBaked; }
376                 }
377         }
378
379         sealed class GenericParameterInfoImpl : ParameterInfo
380         {
381                 private readonly GenericMethodInstance method;
382                 private readonly ParameterInfo parameterInfo;
383
384                 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)
385                 {
386                         this.method = method;
387                         this.parameterInfo = parameterInfo;
388                 }
389
390                 public override string Name
391                 {
392                         get { return parameterInfo.Name; }
393                 }
394
395                 public override Type ParameterType
396                 {
397                         get { return parameterInfo.ParameterType.BindTypeParameters(method); }
398                 }
399
400                 public override ParameterAttributes Attributes
401                 {
402                         get { return parameterInfo.Attributes; }
403                 }
404
405                 public override int Position
406                 {
407                         get { return parameterInfo.Position; }
408                 }
409
410                 public override object RawDefaultValue
411                 {
412                         get { return parameterInfo.RawDefaultValue; }
413                 }
414
415                 public override CustomModifiers __GetCustomModifiers()
416                 {
417                         return parameterInfo.__GetCustomModifiers().Bind(method);
418                 }
419
420                 public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
421                 {
422                         return parameterInfo.__TryGetFieldMarshal(out fieldMarshal);
423                 }
424
425                 public override MemberInfo Member
426                 {
427                         get { return method; }
428                 }
429
430                 public override int MetadataToken
431                 {
432                         get { return parameterInfo.MetadataToken; }
433                 }
434
435                 internal override Module Module
436                 {
437                         get { return method.Module; }
438                 }
439         }
440
441         sealed class GenericPropertyInfo : PropertyInfo
442         {
443                 private readonly Type typeInstance;
444                 private readonly PropertyInfo property;
445
446                 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property)
447                 {
448                         this.typeInstance = typeInstance;
449                         this.property = property;
450                 }
451
452                 public override bool Equals(object obj)
453                 {
454                         GenericPropertyInfo other = obj as GenericPropertyInfo;
455                         return other != null && other.typeInstance == typeInstance && other.property == property;
456                 }
457
458                 public override int GetHashCode()
459                 {
460                         return typeInstance.GetHashCode() * 537 + property.GetHashCode();
461                 }
462
463                 public override PropertyAttributes Attributes
464                 {
465                         get { return property.Attributes; }
466                 }
467
468                 public override bool CanRead
469                 {
470                         get { return property.CanRead; }
471                 }
472
473                 public override bool CanWrite
474                 {
475                         get { return property.CanWrite; }
476                 }
477
478                 private MethodInfo Wrap(MethodInfo method)
479                 {
480                         if (method == null)
481                         {
482                                 return null;
483                         }
484                         return new GenericMethodInstance(typeInstance, method, null);
485                 }
486
487                 public override MethodInfo GetGetMethod(bool nonPublic)
488                 {
489                         return Wrap(property.GetGetMethod(nonPublic));
490                 }
491
492                 public override MethodInfo GetSetMethod(bool nonPublic)
493                 {
494                         return Wrap(property.GetSetMethod(nonPublic));
495                 }
496
497                 public override MethodInfo[] GetAccessors(bool nonPublic)
498                 {
499                         MethodInfo[] accessors = property.GetAccessors(nonPublic);
500                         for (int i = 0; i < accessors.Length; i++)
501                         {
502                                 accessors[i] = Wrap(accessors[i]);
503                         }
504                         return accessors;
505                 }
506
507                 public override object GetRawConstantValue()
508                 {
509                         return property.GetRawConstantValue();
510                 }
511
512                 internal override bool IsPublic
513                 {
514                         get { return property.IsPublic; }
515                 }
516
517                 internal override bool IsNonPrivate
518                 {
519                         get { return property.IsNonPrivate; }
520                 }
521
522                 internal override bool IsStatic
523                 {
524                         get { return property.IsStatic; }
525                 }
526
527                 internal override PropertySignature PropertySignature
528                 {
529                         get { return property.PropertySignature.ExpandTypeParameters(typeInstance); }
530                 }
531
532                 public override string Name
533                 {
534                         get { return property.Name; }
535                 }
536
537                 public override Type DeclaringType
538                 {
539                         get { return typeInstance; }
540                 }
541
542                 public override Module Module
543                 {
544                         get { return typeInstance.Module; }
545                 }
546
547                 public override int MetadataToken
548                 {
549                         get { return property.MetadataToken; }
550                 }
551
552                 internal override PropertyInfo BindTypeParameters(Type type)
553                 {
554                         return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property);
555                 }
556
557                 internal override bool IsBaked
558                 {
559                         get { return property.IsBaked; }
560                 }
561
562                 internal override int GetCurrentToken()
563                 {
564                         return property.GetCurrentToken();
565                 }
566         }
567
568         sealed class GenericEventInfo : EventInfo
569         {
570                 private readonly Type typeInstance;
571                 private readonly EventInfo eventInfo;
572
573                 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo)
574                 {
575                         this.typeInstance = typeInstance;
576                         this.eventInfo = eventInfo;
577                 }
578
579                 public override bool Equals(object obj)
580                 {
581                         GenericEventInfo other = obj as GenericEventInfo;
582                         return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo;
583                 }
584
585                 public override int GetHashCode()
586                 {
587                         return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode();
588                 }
589
590                 public override EventAttributes Attributes
591                 {
592                         get { return eventInfo.Attributes; }
593                 }
594
595                 private MethodInfo Wrap(MethodInfo method)
596                 {
597                         if (method == null)
598                         {
599                                 return null;
600                         }
601                         return new GenericMethodInstance(typeInstance, method, null);
602                 }
603
604                 public override MethodInfo GetAddMethod(bool nonPublic)
605                 {
606                         return Wrap(eventInfo.GetAddMethod(nonPublic));
607                 }
608
609                 public override MethodInfo GetRaiseMethod(bool nonPublic)
610                 {
611                         return Wrap(eventInfo.GetRaiseMethod(nonPublic));
612                 }
613
614                 public override MethodInfo GetRemoveMethod(bool nonPublic)
615                 {
616                         return Wrap(eventInfo.GetRemoveMethod(nonPublic));
617                 }
618
619                 public override MethodInfo[] GetOtherMethods(bool nonPublic)
620                 {
621                         MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic);
622                         for (int i = 0; i < others.Length; i++)
623                         {
624                                 others[i] = Wrap(others[i]);
625                         }
626                         return others;
627                 }
628
629                 public override MethodInfo[] __GetMethods()
630                 {
631                         MethodInfo[] others = eventInfo.__GetMethods();
632                         for (int i = 0; i < others.Length; i++)
633                         {
634                                 others[i] = Wrap(others[i]);
635                         }
636                         return others;
637                 }
638
639                 public override Type EventHandlerType
640                 {
641                         get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); }
642                 }
643
644                 public override string Name
645                 {
646                         get { return eventInfo.Name; }
647                 }
648
649                 public override Type DeclaringType
650                 {
651                         get { return typeInstance; }
652                 }
653
654                 public override Module Module
655                 {
656                         get { return eventInfo.Module; }
657                 }
658
659                 public override int MetadataToken
660                 {
661                         get { return eventInfo.MetadataToken; }
662                 }
663
664                 internal override EventInfo BindTypeParameters(Type type)
665                 {
666                         return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo);
667                 }
668
669                 internal override bool IsPublic
670                 {
671                         get { return eventInfo.IsPublic; }
672                 }
673
674                 internal override bool IsNonPrivate
675                 {
676                         get { return eventInfo.IsNonPrivate; }
677                 }
678
679                 internal override bool IsStatic
680                 {
681                         get { return eventInfo.IsStatic; }
682                 }
683
684                 internal override bool IsBaked
685                 {
686                         get { return eventInfo.IsBaked; }
687                 }
688
689                 internal override int GetCurrentToken()
690                 {
691                         return eventInfo.GetCurrentToken();
692                 }
693         }
694 }