Add info to the manual page on MONO_DNS
[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 MethodInfo MakeGenericMethod(params Type[] typeArguments)
132                 {
133                         return new GenericMethodInstance(declaringType, method, typeArguments);
134                 }
135
136                 public override bool IsGenericMethod
137                 {
138                         get { return method.IsGenericMethod; }
139                 }
140
141                 public override bool IsGenericMethodDefinition
142                 {
143                         get { return method.IsGenericMethodDefinition && methodArgs == null; }
144                 }
145
146                 public override bool ContainsGenericParameters
147                 {
148                         get
149                         {
150                                 if (declaringType.ContainsGenericParameters)
151                                 {
152                                         return true;
153                                 }
154                                 if (methodArgs != null)
155                                 {
156                                         foreach (Type type in methodArgs)
157                                         {
158                                                 if (type.ContainsGenericParameters)
159                                                 {
160                                                         return true;
161                                                 }
162                                         }
163                                 }
164                                 return false;
165                         }
166                 }
167
168                 public override MethodInfo GetGenericMethodDefinition()
169                 {
170                         if (this.IsGenericMethod)
171                         {
172                                 if (this.IsGenericMethodDefinition)
173                                 {
174                                         return this;
175                                 }
176                                 else if (declaringType.IsGenericTypeInstance)
177                                 {
178                                         return new GenericMethodInstance(declaringType, method, null);
179                                 }
180                                 else
181                                 {
182                                         return method;
183                                 }
184                         }
185                         throw new InvalidOperationException();
186                 }
187
188                 public override MethodBase __GetMethodOnTypeDefinition()
189                 {
190                         return method;
191                 }
192
193                 public override Type[] GetGenericArguments()
194                 {
195                         if (methodArgs == null)
196                         {
197                                 return method.GetGenericArguments();
198                         }
199                         else
200                         {
201                                 return (Type[])methodArgs.Clone();
202                         }
203                 }
204
205                 internal override Type GetGenericMethodArgument(int index)
206                 {
207                         if (methodArgs == null)
208                         {
209                                 return method.GetGenericMethodArgument(index);
210                         }
211                         else
212                         {
213                                 return methodArgs[index];
214                         }
215                 }
216
217                 internal override int GetGenericMethodArgumentCount()
218                 {
219                         return method.GetGenericMethodArgumentCount();
220                 }
221
222                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
223                 {
224                         return method.GetCustomAttributesData(attributeType);
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                                 Writer.ByteBuffer spec = new Writer.ByteBuffer(10);
241                                 Signature.WriteMethodSpec(module, spec, methodArgs);
242                                 Metadata.MethodSpecTable.Record rec = new Metadata.MethodSpecTable.Record();
243                                 Emit.MethodBuilder mb = method as Emit.MethodBuilder;
244                                 if (mb != null && mb.ModuleBuilder == module && !declaringType.IsGenericType)
245                                 {
246                                         rec.Method = mb.MetadataToken;
247                                 }
248                                 else
249                                 {
250                                         rec.Method = module.ImportMember(GetGenericMethodDefinition());
251                                 }
252                                 rec.Instantiation = module.Blobs.Add(spec);
253                                 return 0x2B000000 | module.MethodSpec.FindOrAddRecord(rec);
254                         }
255                 }
256
257                 internal override MethodSignature MethodSignature
258                 {
259                         get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); }
260                 }
261
262                 internal override MethodBase BindTypeParameters(Type type)
263                 {
264                         System.Diagnostics.Debug.Assert(methodArgs == null);
265                         return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null);
266                 }
267
268                 internal override bool HasThis
269                 {
270                         get { return method.HasThis; }
271                 }
272         }
273
274         sealed class GenericFieldInstance : FieldInfo
275         {
276                 private readonly Type declaringType;
277                 private readonly FieldInfo field;
278
279                 internal GenericFieldInstance(Type declaringType, FieldInfo field)
280                 {
281                         this.declaringType = declaringType;
282                         this.field = field;
283                 }
284
285                 public override bool Equals(object obj)
286                 {
287                         GenericFieldInstance other = obj as GenericFieldInstance;
288                         return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field);
289                 }
290
291                 public override int GetHashCode()
292                 {
293                         return declaringType.GetHashCode() * 3 ^ field.GetHashCode();
294                 }
295
296                 public override FieldAttributes Attributes
297                 {
298                         get { return field.Attributes; }
299                 }
300
301                 public override string Name
302                 {
303                         get { return field.Name; }
304                 }
305
306                 public override Type DeclaringType
307                 {
308                         get { return declaringType; }
309                 }
310
311                 public override Module Module
312                 {
313                         get { return declaringType.Module; }
314                 }
315
316                 public override int MetadataToken
317                 {
318                         get { return field.MetadataToken; }
319                 }
320
321                 public override object GetRawConstantValue()
322                 {
323                         return field.GetRawConstantValue();
324                 }
325
326                 public override void __GetDataFromRVA(byte[] data, int offset, int length)
327                 {
328                         field.__GetDataFromRVA(data, offset, length);
329                 }
330
331                 public override int __FieldRVA
332                 {
333                         get { return field.__FieldRVA; }
334                 }
335
336                 public override FieldInfo __GetFieldOnTypeDefinition()
337                 {
338                         return field;
339                 }
340
341                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
342                 {
343                         return field.GetCustomAttributesData(attributeType);
344                 }
345
346                 internal override FieldSignature FieldSignature
347                 {
348                         get { return field.FieldSignature.ExpandTypeParameters(declaringType); }
349                 }
350
351                 internal override int ImportTo(Emit.ModuleBuilder module)
352                 {
353                         return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature);
354                 }
355
356                 internal override FieldInfo BindTypeParameters(Type type)
357                 {
358                         return new GenericFieldInstance(declaringType.BindTypeParameters(type), field);
359                 }
360         }
361
362         sealed class GenericParameterInfoImpl : ParameterInfo
363         {
364                 private readonly GenericMethodInstance method;
365                 private readonly ParameterInfo parameterInfo;
366
367                 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)
368                 {
369                         this.method = method;
370                         this.parameterInfo = parameterInfo;
371                 }
372
373                 public override string Name
374                 {
375                         get { return parameterInfo.Name; }
376                 }
377
378                 public override Type ParameterType
379                 {
380                         get { return parameterInfo.ParameterType.BindTypeParameters(method); }
381                 }
382
383                 public override ParameterAttributes Attributes
384                 {
385                         get { return parameterInfo.Attributes; }
386                 }
387
388                 public override int Position
389                 {
390                         get { return parameterInfo.Position; }
391                 }
392
393                 public override object RawDefaultValue
394                 {
395                         get { return parameterInfo.RawDefaultValue; }
396                 }
397
398                 public override Type[] GetOptionalCustomModifiers()
399                 {
400                         Type[] modifiers = parameterInfo.GetOptionalCustomModifiers();
401                         Type.InplaceBindTypeParameters(method, modifiers);
402                         return modifiers;
403                 }
404
405                 public override Type[] GetRequiredCustomModifiers()
406                 {
407                         Type[] modifiers = parameterInfo.GetRequiredCustomModifiers();
408                         Type.InplaceBindTypeParameters(method, modifiers);
409                         return modifiers;
410                 }
411
412                 public override MemberInfo Member
413                 {
414                         get { return method; }
415                 }
416
417                 public override int MetadataToken
418                 {
419                         get { return parameterInfo.MetadataToken; }
420                 }
421
422                 internal override Module Module
423                 {
424                         get { return method.Module; }
425                 }
426         }
427
428         sealed class GenericPropertyInfo : PropertyInfo
429         {
430                 private readonly Type typeInstance;
431                 private readonly PropertyInfo property;
432
433                 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property)
434                 {
435                         this.typeInstance = typeInstance;
436                         this.property = property;
437                 }
438
439                 public override bool Equals(object obj)
440                 {
441                         GenericPropertyInfo other = obj as GenericPropertyInfo;
442                         return other != null && other.typeInstance == typeInstance && other.property == property;
443                 }
444
445                 public override int GetHashCode()
446                 {
447                         return typeInstance.GetHashCode() * 537 + property.GetHashCode();
448                 }
449
450                 public override PropertyAttributes Attributes
451                 {
452                         get { return property.Attributes; }
453                 }
454
455                 public override bool CanRead
456                 {
457                         get { return property.CanRead; }
458                 }
459
460                 public override bool CanWrite
461                 {
462                         get { return property.CanWrite; }
463                 }
464
465                 private MethodInfo Wrap(MethodInfo method)
466                 {
467                         if (method == null)
468                         {
469                                 return null;
470                         }
471                         return new GenericMethodInstance(typeInstance, method, null);
472                 }
473
474                 public override MethodInfo GetGetMethod(bool nonPublic)
475                 {
476                         return Wrap(property.GetGetMethod(nonPublic));
477                 }
478
479                 public override MethodInfo GetSetMethod(bool nonPublic)
480                 {
481                         return Wrap(property.GetSetMethod(nonPublic));
482                 }
483
484                 public override MethodInfo[] GetAccessors(bool nonPublic)
485                 {
486                         MethodInfo[] accessors = property.GetAccessors(nonPublic);
487                         for (int i = 0; i < accessors.Length; i++)
488                         {
489                                 accessors[i] = Wrap(accessors[i]);
490                         }
491                         return accessors;
492                 }
493
494                 public override object GetRawConstantValue()
495                 {
496                         return property.GetRawConstantValue();
497                 }
498
499                 internal override bool IsPublic
500                 {
501                         get { return property.IsPublic; }
502                 }
503
504                 internal override bool IsStatic
505                 {
506                         get { return property.IsStatic; }
507                 }
508
509                 internal override PropertySignature PropertySignature
510                 {
511                         get { return property.PropertySignature.ExpandTypeParameters(typeInstance); }
512                 }
513
514                 public override string Name
515                 {
516                         get { return property.Name; }
517                 }
518
519                 public override Type DeclaringType
520                 {
521                         get { return typeInstance; }
522                 }
523
524                 public override Module Module
525                 {
526                         get { return typeInstance.Module; }
527                 }
528
529                 public override int MetadataToken
530                 {
531                         get { return property.MetadataToken; }
532                 }
533
534                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
535                 {
536                         return property.GetCustomAttributesData(attributeType);
537                 }
538
539                 internal override PropertyInfo BindTypeParameters(Type type)
540                 {
541                         return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property);
542                 }
543         }
544
545         sealed class GenericEventInfo : EventInfo
546         {
547                 private readonly Type typeInstance;
548                 private readonly EventInfo eventInfo;
549
550                 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo)
551                 {
552                         this.typeInstance = typeInstance;
553                         this.eventInfo = eventInfo;
554                 }
555
556                 public override bool Equals(object obj)
557                 {
558                         GenericEventInfo other = obj as GenericEventInfo;
559                         return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo;
560                 }
561
562                 public override int GetHashCode()
563                 {
564                         return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode();
565                 }
566
567                 public override EventAttributes Attributes
568                 {
569                         get { return eventInfo.Attributes; }
570                 }
571
572                 private MethodInfo Wrap(MethodInfo method)
573                 {
574                         if (method == null)
575                         {
576                                 return null;
577                         }
578                         return new GenericMethodInstance(typeInstance, method, null);
579                 }
580
581                 public override MethodInfo GetAddMethod(bool nonPublic)
582                 {
583                         return Wrap(eventInfo.GetAddMethod(nonPublic));
584                 }
585
586                 public override MethodInfo GetRaiseMethod(bool nonPublic)
587                 {
588                         return Wrap(eventInfo.GetRaiseMethod(nonPublic));
589                 }
590
591                 public override MethodInfo GetRemoveMethod(bool nonPublic)
592                 {
593                         return Wrap(eventInfo.GetRemoveMethod(nonPublic));
594                 }
595
596                 public override MethodInfo[] GetOtherMethods(bool nonPublic)
597                 {
598                         MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic);
599                         for (int i = 0; i < others.Length; i++)
600                         {
601                                 others[i] = Wrap(others[i]);
602                         }
603                         return others;
604                 }
605
606                 public override MethodInfo[] __GetMethods()
607                 {
608                         MethodInfo[] others = eventInfo.__GetMethods();
609                         for (int i = 0; i < others.Length; i++)
610                         {
611                                 others[i] = Wrap(others[i]);
612                         }
613                         return others;
614                 }
615
616                 public override Type EventHandlerType
617                 {
618                         get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); }
619                 }
620
621                 public override string Name
622                 {
623                         get { return eventInfo.Name; }
624                 }
625
626                 public override Type DeclaringType
627                 {
628                         get { return typeInstance; }
629                 }
630
631                 public override Module Module
632                 {
633                         get { return eventInfo.Module; }
634                 }
635
636                 public override int MetadataToken
637                 {
638                         get { return eventInfo.MetadataToken; }
639                 }
640
641                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
642                 {
643                         return eventInfo.GetCustomAttributesData(attributeType);
644                 }
645
646                 internal override EventInfo BindTypeParameters(Type type)
647                 {
648                         return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo);
649                 }
650
651                 internal override bool IsPublic
652                 {
653                         get { return eventInfo.IsPublic; }
654                 }
655
656                 internal override bool IsStatic
657                 {
658                         get { return eventInfo.IsStatic; }
659                 }
660         }
661 }