Improved error messages so that it becomes clear where configuration errors come...
[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.IsGenericTypeInstance)
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 IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
228                 {
229                         return method.GetCustomAttributesData(attributeType);
230                 }
231
232                 internal override MethodInfo GetMethodOnTypeDefinition()
233                 {
234                         return method.GetMethodOnTypeDefinition();
235                 }
236
237                 internal override int ImportTo(Emit.ModuleBuilder module)
238                 {
239                         if (methodArgs == null)
240                         {
241                                 return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature);
242                         }
243                         else
244                         {
245                                 Writer.ByteBuffer spec = new Writer.ByteBuffer(10);
246                                 Signature.WriteMethodSpec(module, spec, methodArgs);
247                                 Metadata.MethodSpecTable.Record rec = new Metadata.MethodSpecTable.Record();
248                                 Emit.MethodBuilder mb = method as Emit.MethodBuilder;
249                                 if (mb != null && mb.ModuleBuilder == module && !declaringType.IsGenericType)
250                                 {
251                                         rec.Method = mb.MetadataToken;
252                                 }
253                                 else
254                                 {
255                                         rec.Method = module.ImportMember(GetGenericMethodDefinition());
256                                 }
257                                 rec.Instantiation = module.Blobs.Add(spec);
258                                 return 0x2B000000 | module.MethodSpec.FindOrAddRecord(rec);
259                         }
260                 }
261
262                 internal override MethodSignature MethodSignature
263                 {
264                         get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); }
265                 }
266
267                 internal override MethodBase BindTypeParameters(Type type)
268                 {
269                         System.Diagnostics.Debug.Assert(methodArgs == null);
270                         return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null);
271                 }
272
273                 internal override bool HasThis
274                 {
275                         get { return method.HasThis; }
276                 }
277
278                 public override MethodInfo[] __GetMethodImpls()
279                 {
280                         MethodInfo[] methods = method.__GetMethodImpls();
281                         for (int i = 0; i < methods.Length; i++)
282                         {
283                                 methods[i] = (MethodInfo)methods[i].BindTypeParameters(declaringType);
284                         }
285                         return methods;
286                 }
287         }
288
289         sealed class GenericFieldInstance : FieldInfo
290         {
291                 private readonly Type declaringType;
292                 private readonly FieldInfo field;
293
294                 internal GenericFieldInstance(Type declaringType, FieldInfo field)
295                 {
296                         this.declaringType = declaringType;
297                         this.field = field;
298                 }
299
300                 public override bool Equals(object obj)
301                 {
302                         GenericFieldInstance other = obj as GenericFieldInstance;
303                         return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field);
304                 }
305
306                 public override int GetHashCode()
307                 {
308                         return declaringType.GetHashCode() * 3 ^ field.GetHashCode();
309                 }
310
311                 public override FieldAttributes Attributes
312                 {
313                         get { return field.Attributes; }
314                 }
315
316                 public override string Name
317                 {
318                         get { return field.Name; }
319                 }
320
321                 public override Type DeclaringType
322                 {
323                         get { return declaringType; }
324                 }
325
326                 public override Module Module
327                 {
328                         get { return declaringType.Module; }
329                 }
330
331                 public override int MetadataToken
332                 {
333                         get { return field.MetadataToken; }
334                 }
335
336                 public override object GetRawConstantValue()
337                 {
338                         return field.GetRawConstantValue();
339                 }
340
341                 public override void __GetDataFromRVA(byte[] data, int offset, int length)
342                 {
343                         field.__GetDataFromRVA(data, offset, length);
344                 }
345
346                 public override int __FieldRVA
347                 {
348                         get { return field.__FieldRVA; }
349                 }
350
351                 public override FieldInfo __GetFieldOnTypeDefinition()
352                 {
353                         return field;
354                 }
355
356                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
357                 {
358                         return field.GetCustomAttributesData(attributeType);
359                 }
360
361                 internal override FieldSignature FieldSignature
362                 {
363                         get { return field.FieldSignature.ExpandTypeParameters(declaringType); }
364                 }
365
366                 internal override int ImportTo(Emit.ModuleBuilder module)
367                 {
368                         return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature);
369                 }
370
371                 internal override FieldInfo BindTypeParameters(Type type)
372                 {
373                         return new GenericFieldInstance(declaringType.BindTypeParameters(type), field);
374                 }
375         }
376
377         sealed class GenericParameterInfoImpl : ParameterInfo
378         {
379                 private readonly GenericMethodInstance method;
380                 private readonly ParameterInfo parameterInfo;
381
382                 internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo)
383                 {
384                         this.method = method;
385                         this.parameterInfo = parameterInfo;
386                 }
387
388                 public override string Name
389                 {
390                         get { return parameterInfo.Name; }
391                 }
392
393                 public override Type ParameterType
394                 {
395                         get { return parameterInfo.ParameterType.BindTypeParameters(method); }
396                 }
397
398                 public override ParameterAttributes Attributes
399                 {
400                         get { return parameterInfo.Attributes; }
401                 }
402
403                 public override int Position
404                 {
405                         get { return parameterInfo.Position; }
406                 }
407
408                 public override object RawDefaultValue
409                 {
410                         get { return parameterInfo.RawDefaultValue; }
411                 }
412
413                 public override CustomModifiers __GetCustomModifiers()
414                 {
415                         return parameterInfo.__GetCustomModifiers().Bind(method);
416                 }
417
418                 public override MemberInfo Member
419                 {
420                         get { return method; }
421                 }
422
423                 public override int MetadataToken
424                 {
425                         get { return parameterInfo.MetadataToken; }
426                 }
427
428                 internal override Module Module
429                 {
430                         get { return method.Module; }
431                 }
432         }
433
434         sealed class GenericPropertyInfo : PropertyInfo
435         {
436                 private readonly Type typeInstance;
437                 private readonly PropertyInfo property;
438
439                 internal GenericPropertyInfo(Type typeInstance, PropertyInfo property)
440                 {
441                         this.typeInstance = typeInstance;
442                         this.property = property;
443                 }
444
445                 public override bool Equals(object obj)
446                 {
447                         GenericPropertyInfo other = obj as GenericPropertyInfo;
448                         return other != null && other.typeInstance == typeInstance && other.property == property;
449                 }
450
451                 public override int GetHashCode()
452                 {
453                         return typeInstance.GetHashCode() * 537 + property.GetHashCode();
454                 }
455
456                 public override PropertyAttributes Attributes
457                 {
458                         get { return property.Attributes; }
459                 }
460
461                 public override bool CanRead
462                 {
463                         get { return property.CanRead; }
464                 }
465
466                 public override bool CanWrite
467                 {
468                         get { return property.CanWrite; }
469                 }
470
471                 private MethodInfo Wrap(MethodInfo method)
472                 {
473                         if (method == null)
474                         {
475                                 return null;
476                         }
477                         return new GenericMethodInstance(typeInstance, method, null);
478                 }
479
480                 public override MethodInfo GetGetMethod(bool nonPublic)
481                 {
482                         return Wrap(property.GetGetMethod(nonPublic));
483                 }
484
485                 public override MethodInfo GetSetMethod(bool nonPublic)
486                 {
487                         return Wrap(property.GetSetMethod(nonPublic));
488                 }
489
490                 public override MethodInfo[] GetAccessors(bool nonPublic)
491                 {
492                         MethodInfo[] accessors = property.GetAccessors(nonPublic);
493                         for (int i = 0; i < accessors.Length; i++)
494                         {
495                                 accessors[i] = Wrap(accessors[i]);
496                         }
497                         return accessors;
498                 }
499
500                 public override object GetRawConstantValue()
501                 {
502                         return property.GetRawConstantValue();
503                 }
504
505                 internal override bool IsPublic
506                 {
507                         get { return property.IsPublic; }
508                 }
509
510                 internal override bool IsNonPrivate
511                 {
512                         get { return property.IsNonPrivate; }
513                 }
514
515                 internal override bool IsStatic
516                 {
517                         get { return property.IsStatic; }
518                 }
519
520                 internal override PropertySignature PropertySignature
521                 {
522                         get { return property.PropertySignature.ExpandTypeParameters(typeInstance); }
523                 }
524
525                 public override string Name
526                 {
527                         get { return property.Name; }
528                 }
529
530                 public override Type DeclaringType
531                 {
532                         get { return typeInstance; }
533                 }
534
535                 public override Module Module
536                 {
537                         get { return typeInstance.Module; }
538                 }
539
540                 public override int MetadataToken
541                 {
542                         get { return property.MetadataToken; }
543                 }
544
545                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
546                 {
547                         return property.GetCustomAttributesData(attributeType);
548                 }
549
550                 internal override PropertyInfo BindTypeParameters(Type type)
551                 {
552                         return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property);
553                 }
554         }
555
556         sealed class GenericEventInfo : EventInfo
557         {
558                 private readonly Type typeInstance;
559                 private readonly EventInfo eventInfo;
560
561                 internal GenericEventInfo(Type typeInstance, EventInfo eventInfo)
562                 {
563                         this.typeInstance = typeInstance;
564                         this.eventInfo = eventInfo;
565                 }
566
567                 public override bool Equals(object obj)
568                 {
569                         GenericEventInfo other = obj as GenericEventInfo;
570                         return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo;
571                 }
572
573                 public override int GetHashCode()
574                 {
575                         return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode();
576                 }
577
578                 public override EventAttributes Attributes
579                 {
580                         get { return eventInfo.Attributes; }
581                 }
582
583                 private MethodInfo Wrap(MethodInfo method)
584                 {
585                         if (method == null)
586                         {
587                                 return null;
588                         }
589                         return new GenericMethodInstance(typeInstance, method, null);
590                 }
591
592                 public override MethodInfo GetAddMethod(bool nonPublic)
593                 {
594                         return Wrap(eventInfo.GetAddMethod(nonPublic));
595                 }
596
597                 public override MethodInfo GetRaiseMethod(bool nonPublic)
598                 {
599                         return Wrap(eventInfo.GetRaiseMethod(nonPublic));
600                 }
601
602                 public override MethodInfo GetRemoveMethod(bool nonPublic)
603                 {
604                         return Wrap(eventInfo.GetRemoveMethod(nonPublic));
605                 }
606
607                 public override MethodInfo[] GetOtherMethods(bool nonPublic)
608                 {
609                         MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic);
610                         for (int i = 0; i < others.Length; i++)
611                         {
612                                 others[i] = Wrap(others[i]);
613                         }
614                         return others;
615                 }
616
617                 public override MethodInfo[] __GetMethods()
618                 {
619                         MethodInfo[] others = eventInfo.__GetMethods();
620                         for (int i = 0; i < others.Length; i++)
621                         {
622                                 others[i] = Wrap(others[i]);
623                         }
624                         return others;
625                 }
626
627                 public override Type EventHandlerType
628                 {
629                         get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); }
630                 }
631
632                 public override string Name
633                 {
634                         get { return eventInfo.Name; }
635                 }
636
637                 public override Type DeclaringType
638                 {
639                         get { return typeInstance; }
640                 }
641
642                 public override Module Module
643                 {
644                         get { return eventInfo.Module; }
645                 }
646
647                 public override int MetadataToken
648                 {
649                         get { return eventInfo.MetadataToken; }
650                 }
651
652                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
653                 {
654                         return eventInfo.GetCustomAttributesData(attributeType);
655                 }
656
657                 internal override EventInfo BindTypeParameters(Type type)
658                 {
659                         return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo);
660                 }
661
662                 internal override bool IsPublic
663                 {
664                         get { return eventInfo.IsPublic; }
665                 }
666
667                 internal override bool IsNonPrivate
668                 {
669                         get { return eventInfo.IsNonPrivate; }
670                 }
671
672                 internal override bool IsStatic
673                 {
674                         get { return eventInfo.IsStatic; }
675                 }
676         }
677 }