Merged into single file, added assertions
[mono.git] / mcs / class / IKVM.Reflection / Missing.cs
1 /*
2   Copyright (C) 2011-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.Runtime.InteropServices;
27
28 namespace IKVM.Reflection
29 {
30         [Serializable]
31         public sealed class MissingAssemblyException : InvalidOperationException
32         {
33                 [NonSerialized]
34                 private readonly MissingAssembly assembly;
35
36                 internal MissingAssemblyException(MissingAssembly assembly)
37                         : base("Assembly '" + assembly.FullName + "' is a missing assembly and does not support the requested operation.")
38                 {
39                         this.assembly = assembly;
40                 }
41
42                 private MissingAssemblyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
43                         : base(info, context)
44                 {
45                 }
46
47                 public Assembly Assembly
48                 {
49                         get { return assembly; }
50                 }
51         }
52
53         [Serializable]
54         public sealed class MissingModuleException : InvalidOperationException
55         {
56                 [NonSerialized]
57                 private readonly MissingModule module;
58
59                 internal MissingModuleException(MissingModule module)
60                         : base("Module from missing assembly '" + module.Assembly.FullName + "' does not support the requested operation.")
61                 {
62                         this.module = module;
63                 }
64
65                 private MissingModuleException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
66                         : base(info, context)
67                 {
68                 }
69
70                 public Module Module
71                 {
72                         get { return module; }
73                 }
74         }
75
76         [Serializable]
77         public sealed class MissingMemberException : InvalidOperationException
78         {
79                 [NonSerialized]
80                 private readonly MemberInfo member;
81
82                 internal MissingMemberException(MemberInfo member)
83                         : base("Member '" + member + "' is a missing member and does not support the requested operation.")
84                 {
85                         this.member = member;
86                 }
87
88                 private MissingMemberException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
89                         : base(info, context)
90                 {
91                 }
92
93                 public MemberInfo MemberInfo
94                 {
95                         get { return member; }
96                 }
97         }
98
99         public struct MissingGenericMethodBuilder
100         {
101                 private readonly MissingMethod method;
102
103                 public MissingGenericMethodBuilder(Type declaringType, CallingConventions callingConvention, string name, int genericParameterCount)
104                 {
105                         method = new MissingMethod(declaringType, name, new MethodSignature(null, null, new PackedCustomModifiers(), callingConvention, genericParameterCount));
106                 }
107
108                 public Type[] GetGenericArguments()
109                 {
110                         return method.GetGenericArguments();
111                 }
112
113                 public void SetSignature(Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
114                 {
115                         method.signature = new MethodSignature(
116                                 returnType ?? method.Module.universe.System_Void,
117                                 Util.Copy(parameterTypes),
118                                 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, parameterTypes.Length),
119                                 method.signature.CallingConvention,
120                                 method.signature.GenericParameterCount);
121                 }
122
123                 [Obsolete("Please use SetSignature(Type, CustomModifiers, Type[], CustomModifiers[]) instead.")]
124                 public void SetSignature(Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
125                 {
126                         method.signature = new MethodSignature(
127                                 returnType ?? method.Module.universe.System_Void,
128                                 Util.Copy(parameterTypes),
129                                 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, parameterTypes.Length),
130                                 method.signature.CallingConvention,
131                                 method.signature.GenericParameterCount);
132                 }
133
134                 public MethodInfo Finish()
135                 {
136                         return method;
137                 }
138         }
139
140         sealed class MissingAssembly : Assembly
141         {
142                 private readonly MissingModule module;
143
144                 internal MissingAssembly(Universe universe, string name)
145                         : base(universe)
146                 {
147                         module = new MissingModule(this);
148                         this.fullName = name;
149                 }
150
151                 public override Type[] GetTypes()
152                 {
153                         throw new MissingAssemblyException(this);
154                 }
155
156                 public override AssemblyName GetName()
157                 {
158                         return new AssemblyName(fullName);
159                 }
160
161                 public override string ImageRuntimeVersion
162                 {
163                         get { throw new MissingAssemblyException(this); }
164                 }
165
166                 public override Module ManifestModule
167                 {
168                         get { return module; }
169                 }
170
171                 public override MethodInfo EntryPoint
172                 {
173                         get { throw new MissingAssemblyException(this); }
174                 }
175
176                 public override string Location
177                 {
178                         get { throw new MissingAssemblyException(this); }
179                 }
180
181                 public override AssemblyName[] GetReferencedAssemblies()
182                 {
183                         throw new MissingAssemblyException(this);
184                 }
185
186                 public override Module[] GetModules(bool getResourceModules)
187                 {
188                         throw new MissingAssemblyException(this);
189                 }
190
191                 public override Module[] GetLoadedModules(bool getResourceModules)
192                 {
193                         throw new MissingAssemblyException(this);
194                 }
195
196                 public override Module GetModule(string name)
197                 {
198                         throw new MissingAssemblyException(this);
199                 }
200
201                 public override string[] GetManifestResourceNames()
202                 {
203                         throw new MissingAssemblyException(this);
204                 }
205
206                 public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
207                 {
208                         throw new MissingAssemblyException(this);
209                 }
210
211                 public override System.IO.Stream GetManifestResourceStream(string resourceName)
212                 {
213                         throw new MissingAssemblyException(this);
214                 }
215
216                 public override bool __IsMissing
217                 {
218                         get { return true; }
219                 }
220
221                 internal override Type FindType(TypeName typeName)
222                 {
223                         return null;
224                 }
225
226                 internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
227                 {
228                         return null;
229                 }
230
231                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
232                 {
233                         throw new MissingAssemblyException(this);
234                 }
235         }
236
237         sealed class MissingModule : NonPEModule
238         {
239                 private readonly MissingAssembly assembly;
240
241                 internal MissingModule(MissingAssembly assembly)
242                         : base(assembly.universe)
243                 {
244                         this.assembly = assembly;
245                 }
246
247                 public override int MDStreamVersion
248                 {
249                         get { throw new MissingModuleException(this); }
250                 }
251
252                 public override Assembly Assembly
253                 {
254                         get { return assembly; }
255                 }
256
257                 public override string FullyQualifiedName
258                 {
259                         get { throw new MissingModuleException(this); }
260                 }
261
262                 public override string Name
263                 {
264                         get { throw new MissingModuleException(this); }
265                 }
266
267                 public override Guid ModuleVersionId
268                 {
269                         get { throw new MissingModuleException(this); }
270                 }
271
272                 public override string ScopeName
273                 {
274                         get { throw new MissingModuleException(this); }
275                 }
276
277                 internal override Type FindType(TypeName typeName)
278                 {
279                         return null;
280                 }
281
282                 internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
283                 {
284                         return null;
285                 }
286
287                 internal override void GetTypesImpl(System.Collections.Generic.List<Type> list)
288                 {
289                         throw new MissingModuleException(this);
290                 }
291
292                 public override void __GetDataDirectoryEntry(int index, out int rva, out int length)
293                 {
294                         throw new MissingModuleException(this);
295                 }
296
297                 public override IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security)
298                 {
299                         throw new MissingModuleException(this);
300                 }
301
302                 public override long __RelativeVirtualAddressToFileOffset(int rva)
303                 {
304                         throw new MissingModuleException(this);
305                 }
306
307                 public override __StandAloneMethodSig __ResolveStandAloneMethodSig(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
308                 {
309                         throw new MissingModuleException(this);
310                 }
311
312                 public override int __Subsystem
313                 {
314                         get { throw new MissingModuleException(this); }
315                 }
316
317                 internal override void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
318                 {
319                         throw new MissingModuleException(this);
320                 }
321
322                 public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
323                 {
324                         throw new MissingModuleException(this);
325                 }
326
327                 public override bool __IsMissing
328                 {
329                         get { return true; }
330                 }
331
332                 protected override Exception InvalidOperationException()
333                 {
334                         return new MissingModuleException(this);
335                 }
336
337                 protected override Exception NotSupportedException()
338                 {
339                         return new MissingModuleException(this);
340                 }
341
342                 protected override Exception ArgumentOutOfRangeException()
343                 {
344                         return new MissingModuleException(this);
345                 }
346         }
347
348         sealed class MissingType : Type
349         {
350                 private readonly Module module;
351                 private readonly Type declaringType;
352                 private readonly string ns;
353                 private readonly string name;
354                 private Type[] typeArgs;
355                 private int token;
356
357                 internal MissingType(Module module, Type declaringType, string ns, string name)
358                 {
359                         this.module = module;
360                         this.declaringType = declaringType;
361                         this.ns = ns;
362                         this.name = name;
363                         MarkEnumOrValueType(ns, name);
364                 }
365
366                 internal override MethodBase FindMethod(string name, MethodSignature signature)
367                 {
368                         MethodInfo method = new MissingMethod(this, name, signature);
369                         if (name == ".ctor")
370                         {
371                                 return new ConstructorInfoImpl(method);
372                         }
373                         return method;
374                 }
375
376                 internal override FieldInfo FindField(string name, FieldSignature signature)
377                 {
378                         return new MissingField(this, name, signature);
379                 }
380
381                 internal override Type FindNestedType(TypeName name)
382                 {
383                         return null;
384                 }
385
386                 internal override Type FindNestedTypeIgnoreCase(TypeName lowerCaseName)
387                 {
388                         return null;
389                 }
390
391                 public override bool __IsMissing
392                 {
393                         get { return true; }
394                 }
395
396                 public override Type DeclaringType
397                 {
398                         get { return declaringType; }
399                 }
400
401                 public override string __Name
402                 {
403                         get { return name; }
404                 }
405
406                 public override string __Namespace
407                 {
408                         get { return ns; }
409                 }
410
411                 public override string Name
412                 {
413                         get { return TypeNameParser.Escape(name); }
414                 }
415
416                 public override string FullName
417                 {
418                         get { return GetFullName(); }
419                 }
420
421                 public override Module Module
422                 {
423                         get { return module; }
424                 }
425
426                 public override int MetadataToken
427                 {
428                         get { return token; }
429                 }
430
431                 public override bool IsValueType
432                 {
433                         get
434                         {
435                                 switch (typeFlags & (TypeFlags.ValueType | TypeFlags.NotValueType))
436                                 {
437                                         case TypeFlags.ValueType:
438                                                 return true;
439                                         case TypeFlags.NotValueType:
440                                                 return false;
441                                         default:
442                                                 if (module.universe.ResolveMissingTypeIsValueType(this))
443                                                 {
444                                                         typeFlags |= TypeFlags.ValueType;
445                                                 }
446                                                 else
447                                                 {
448                                                         typeFlags |= TypeFlags.NotValueType;
449                                                 }
450                                                 return (typeFlags & TypeFlags.ValueType) != 0;
451                                 }
452                         }
453                 }
454
455                 public override Type BaseType
456                 {
457                         get { throw new MissingMemberException(this); }
458                 }
459
460                 public override TypeAttributes Attributes
461                 {
462                         get { throw new MissingMemberException(this); }
463                 }
464
465                 public override Type[] __GetDeclaredTypes()
466                 {
467                         throw new MissingMemberException(this);
468                 }
469
470                 public override Type[] __GetDeclaredInterfaces()
471                 {
472                         throw new MissingMemberException(this);
473                 }
474
475                 public override MethodBase[] __GetDeclaredMethods()
476                 {
477                         throw new MissingMemberException(this);
478                 }
479
480                 public override __MethodImplMap __GetMethodImplMap()
481                 {
482                         throw new MissingMemberException(this);
483                 }
484
485                 public override FieldInfo[] __GetDeclaredFields()
486                 {
487                         throw new MissingMemberException(this);
488                 }
489
490                 public override EventInfo[] __GetDeclaredEvents()
491                 {
492                         throw new MissingMemberException(this);
493                 }
494
495                 public override PropertyInfo[] __GetDeclaredProperties()
496                 {
497                         throw new MissingMemberException(this);
498                 }
499
500                 public override CustomModifiers __GetCustomModifiers()
501                 {
502                         throw new MissingMemberException(this);
503                 }
504
505                 public override Type[] GetGenericArguments()
506                 {
507                         throw new MissingMemberException(this);
508                 }
509
510                 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
511                 {
512                         throw new MissingMemberException(this);
513                 }
514
515                 public override StructLayoutAttribute StructLayoutAttribute
516                 {
517                         get { throw new MissingMemberException(this); }
518                 }
519
520                 public override bool IsGenericType
521                 {
522                         get { throw new MissingMemberException(this); }
523                 }
524
525                 public override bool IsGenericTypeDefinition
526                 {
527                         get { throw new MissingMemberException(this); }
528                 }
529
530                 internal override Type GetGenericTypeArgument(int index)
531                 {
532                         if (typeArgs == null)
533                         {
534                                 typeArgs = new Type[index + 1];
535                         }
536                         else if (typeArgs.Length <= index)
537                         {
538                                 Array.Resize(ref typeArgs, index + 1);
539                         }
540                         return typeArgs[index] ?? (typeArgs[index] = new MissingTypeParameter(this, index));
541                 }
542
543                 internal override Type BindTypeParameters(IGenericBinder binder)
544                 {
545                         return this;
546                 }
547
548                 internal override Type SetMetadataTokenForMissing(int token)
549                 {
550                         this.token = token;
551                         return this;
552                 }
553
554                 internal override bool IsBaked
555                 {
556                         get { throw new MissingMemberException(this); }
557                 }
558         }
559
560         sealed class MissingTypeParameter : IKVM.Reflection.Reader.TypeParameterType
561         {
562                 private readonly MemberInfo owner;
563                 private readonly int index;
564
565                 internal MissingTypeParameter(MemberInfo owner, int index)
566                 {
567                         this.owner = owner;
568                         this.index = index;
569                 }
570
571                 public override Module Module
572                 {
573                         get { return owner.Module; }
574                 }
575
576                 public override string Name
577                 {
578                         get { return null; }
579                 }
580
581                 public override int GenericParameterPosition
582                 {
583                         get { return index; }
584                 }
585
586                 public override MethodBase DeclaringMethod
587                 {
588                         get { return owner as MethodBase; }
589                 }
590
591                 public override Type DeclaringType
592                 {
593                         get { return owner as Type; }
594                 }
595
596                 internal override Type BindTypeParameters(IGenericBinder binder)
597                 {
598                         if (owner is MethodBase)
599                         {
600                                 return binder.BindMethodParameter(this);
601                         }
602                         else
603                         {
604                                 return binder.BindTypeParameter(this);
605                         }
606                 }
607
608                 internal override bool IsBaked
609                 {
610                         get { return owner.IsBaked; }
611                 }
612         }
613
614         sealed class MissingMethod : MethodInfo
615         {
616                 private readonly Type declaringType;
617                 private readonly string name;
618                 internal MethodSignature signature;
619                 private MethodInfo forwarder;
620                 private Type[] typeArgs;
621
622                 internal MissingMethod(Type declaringType, string name, MethodSignature signature)
623                 {
624                         this.declaringType = declaringType;
625                         this.name = name;
626                         this.signature = signature;
627                 }
628
629                 private MethodInfo Forwarder
630                 {
631                         get
632                         {
633                                 MethodInfo method = TryGetForwarder();
634                                 if (method == null)
635                                 {
636                                         throw new MissingMemberException(this);
637                                 }
638                                 return method;
639                         }
640                 }
641
642                 private MethodInfo TryGetForwarder()
643                 {
644                         if (forwarder == null && !declaringType.__IsMissing)
645                         {
646                                 MethodBase mb = declaringType.FindMethod(name, signature);
647                                 ConstructorInfo ci = mb as ConstructorInfo;
648                                 if (ci != null)
649                                 {
650                                         forwarder = ci.GetMethodInfo();
651                                 }
652                                 else
653                                 {
654                                         forwarder = (MethodInfo)mb;
655                                 }
656                         }
657                         return forwarder;
658                 }
659
660                 public override bool __IsMissing
661                 {
662                         get { return TryGetForwarder() == null; }
663                 }
664
665                 public override Type ReturnType
666                 {
667                         get { return signature.GetReturnType(this); }
668                 }
669
670                 public override ParameterInfo ReturnParameter
671                 {
672                         get { return new ParameterInfoImpl(this, -1); }
673                 }
674
675                 internal override MethodSignature MethodSignature
676                 {
677                         get { return signature; }
678                 }
679
680                 internal override int ParameterCount
681                 {
682                         get { return signature.GetParameterCount(); }
683                 }
684
685                 private sealed class ParameterInfoImpl : ParameterInfo
686                 {
687                         private readonly MissingMethod method;
688                         private readonly int index;
689
690                         internal ParameterInfoImpl(MissingMethod method, int index)
691                         {
692                                 this.method = method;
693                                 this.index = index;
694                         }
695
696                         private ParameterInfo Forwarder
697                         {
698                                 get { return index == -1 ? method.Forwarder.ReturnParameter : method.Forwarder.GetParameters()[index]; }
699                         }
700
701                         public override string Name
702                         {
703                                 get { return Forwarder.Name; }
704                         }
705
706                         public override Type ParameterType
707                         {
708                                 get { return index == -1 ? method.signature.GetReturnType(method) : method.signature.GetParameterType(method, index); }
709                         }
710
711                         public override ParameterAttributes Attributes
712                         {
713                                 get { return Forwarder.Attributes; }
714                         }
715
716                         public override int Position
717                         {
718                                 get { return index; }
719                         }
720
721                         public override object RawDefaultValue
722                         {
723                                 get { return Forwarder.RawDefaultValue; }
724                         }
725
726                         public override CustomModifiers __GetCustomModifiers()
727                         {
728                                 return index == -1
729                                         ? method.signature.GetReturnTypeCustomModifiers(method)
730                                         : method.signature.GetParameterCustomModifiers(method, index);
731                         }
732
733                         public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
734                         {
735                                 return Forwarder.__TryGetFieldMarshal(out fieldMarshal);
736                         }
737
738                         public override MemberInfo Member
739                         {
740                                 get { return method; }
741                         }
742
743                         public override int MetadataToken
744                         {
745                                 get { return Forwarder.MetadataToken; }
746                         }
747
748                         internal override Module Module
749                         {
750                                 get { return method.Module; }
751                         }
752
753                         public override string ToString()
754                         {
755                                 return Forwarder.ToString();
756                         }
757                 }
758
759                 public override ParameterInfo[] GetParameters()
760                 {
761                         ParameterInfo[] parameters = new ParameterInfo[signature.GetParameterCount()];
762                         for (int i = 0; i < parameters.Length; i++)
763                         {
764                                 parameters[i] = new ParameterInfoImpl(this, i);
765                         }
766                         return parameters;
767                 }
768
769                 public override MethodAttributes Attributes
770                 {
771                         get { return Forwarder.Attributes; }
772                 }
773
774                 public override MethodImplAttributes GetMethodImplementationFlags()
775                 {
776                         return Forwarder.GetMethodImplementationFlags();
777                 }
778
779                 public override MethodBody GetMethodBody()
780                 {
781                         return Forwarder.GetMethodBody();
782                 }
783
784                 public override int __MethodRVA
785                 {
786                         get { return Forwarder.__MethodRVA; }
787                 }
788
789                 public override CallingConventions CallingConvention
790                 {
791                         get { return signature.CallingConvention; }
792                 }
793
794                 internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module)
795                 {
796                         MethodInfo method = TryGetForwarder();
797                         if (method != null)
798                         {
799                                 return method.ImportTo(module);
800                         }
801                         return module.ImportMethodOrField(declaringType, this.Name, this.MethodSignature);
802                 }
803
804                 public override string Name
805                 {
806                         get { return name; }
807                 }
808
809                 public override Type DeclaringType
810                 {
811                         get { return declaringType.IsModulePseudoType ? null : declaringType; }
812                 }
813
814                 public override Module Module
815                 {
816                         get { return declaringType.Module; }
817                 }
818
819                 public override bool Equals(object obj)
820                 {
821                         MissingMethod other = obj as MissingMethod;
822                         return other != null
823                                 && other.declaringType == declaringType
824                                 && other.name == name
825                                 && other.signature.Equals(signature);
826                 }
827
828                 public override int GetHashCode()
829                 {
830                         return declaringType.GetHashCode() ^ name.GetHashCode() ^ signature.GetHashCode();
831                 }
832
833                 internal override MethodBase BindTypeParameters(Type type)
834                 {
835                         MethodInfo forwarder = TryGetForwarder();
836                         if (forwarder != null)
837                         {
838                                 return forwarder.BindTypeParameters(type);
839                         }
840                         return new GenericMethodInstance(type, this, null);
841                 }
842
843                 public override bool ContainsGenericParameters
844                 {
845                         get { return Forwarder.ContainsGenericParameters; }
846                 }
847
848                 public override Type[] GetGenericArguments()
849                 {
850                         MethodInfo method = TryGetForwarder();
851                         if (method != null)
852                         {
853                                 return Forwarder.GetGenericArguments();
854                         }
855                         if (typeArgs == null)
856                         {
857                                 typeArgs = new Type[signature.GenericParameterCount];
858                                 for (int i = 0; i < typeArgs.Length; i++)
859                                 {
860                                         typeArgs[i] = new MissingTypeParameter(this, i);
861                                 }
862                         }
863                         return Util.Copy(typeArgs);
864                 }
865
866                 internal override Type GetGenericMethodArgument(int index)
867                 {
868                         return GetGenericArguments()[index];
869                 }
870
871                 internal override int GetGenericMethodArgumentCount()
872                 {
873                         return Forwarder.GetGenericMethodArgumentCount();
874                 }
875
876                 public override MethodInfo GetGenericMethodDefinition()
877                 {
878                         return Forwarder.GetGenericMethodDefinition();
879                 }
880
881                 internal override MethodInfo GetMethodOnTypeDefinition()
882                 {
883                         return Forwarder.GetMethodOnTypeDefinition();
884                 }
885
886                 internal override bool HasThis
887                 {
888                         get { return (signature.CallingConvention & (CallingConventions.HasThis | CallingConventions.ExplicitThis)) == CallingConventions.HasThis; }
889                 }
890
891                 public override bool IsGenericMethod
892                 {
893                         get { return IsGenericMethodDefinition; }
894                 }
895
896                 public override bool IsGenericMethodDefinition
897                 {
898                         get { return signature.GenericParameterCount != 0; }
899                 }
900
901                 public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
902                 {
903                         MethodInfo method = TryGetForwarder();
904                         if (method != null)
905                         {
906                                 return method.MakeGenericMethod(typeArguments);
907                         }
908                         return new GenericMethodInstance(declaringType, this, typeArguments);
909                 }
910
911                 public override int MetadataToken
912                 {
913                         get { return Forwarder.MetadataToken; }
914                 }
915
916                 internal override int GetCurrentToken()
917                 {
918                         return Forwarder.GetCurrentToken();
919                 }
920
921                 internal override bool IsBaked
922                 {
923                         get { return Forwarder.IsBaked; }
924                 }
925         }
926
927         sealed class MissingField : FieldInfo
928         {
929                 private readonly Type declaringType;
930                 private readonly string name;
931                 private readonly FieldSignature signature;
932                 private FieldInfo forwarder;
933
934                 internal MissingField(Type declaringType, string name, FieldSignature signature)
935                 {
936                         this.declaringType = declaringType;
937                         this.name = name;
938                         this.signature = signature;
939                 }
940
941                 private FieldInfo Forwarder
942                 {
943                         get
944                         {
945                                 FieldInfo field = TryGetForwarder();
946                                 if (field == null)
947                                 {
948                                         throw new MissingMemberException(this);
949                                 }
950                                 return field;
951                         }
952                 }
953
954                 private FieldInfo TryGetForwarder()
955                 {
956                         if (forwarder == null && !declaringType.__IsMissing)
957                         {
958                                 forwarder = declaringType.FindField(name, signature);
959                         }
960                         return forwarder;
961                 }
962
963                 public override bool __IsMissing
964                 {
965                         get { return TryGetForwarder() == null; }
966                 }
967
968                 public override FieldAttributes Attributes
969                 {
970                         get { return Forwarder.Attributes; }
971                 }
972
973                 public override void __GetDataFromRVA(byte[] data, int offset, int length)
974                 {
975                         Forwarder.__GetDataFromRVA(data, offset, length);
976                 }
977
978                 public override int __FieldRVA
979                 {
980                         get { return Forwarder.__FieldRVA; }
981                 }
982
983                 public override bool __TryGetFieldOffset(out int offset)
984                 {
985                         return Forwarder.__TryGetFieldOffset(out offset);
986                 }
987
988                 public override object GetRawConstantValue()
989                 {
990                         return Forwarder.GetRawConstantValue();
991                 }
992
993                 internal override FieldSignature FieldSignature
994                 {
995                         get { return signature; }
996                 }
997
998                 internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module)
999                 {
1000                         FieldInfo field = TryGetForwarder();
1001                         if (field != null)
1002                         {
1003                                 return field.ImportTo(module);
1004                         }
1005                         return module.ImportMethodOrField(declaringType, this.Name, this.FieldSignature);
1006                 }
1007
1008                 public override string Name
1009                 {
1010                         get { return name; }
1011                 }
1012
1013                 public override Type DeclaringType
1014                 {
1015                         get { return declaringType.IsModulePseudoType ? null : declaringType; }
1016                 }
1017
1018                 public override Module Module
1019                 {
1020                         get { return declaringType.Module; }
1021                 }
1022
1023                 internal override FieldInfo BindTypeParameters(Type type)
1024                 {
1025                         FieldInfo forwarder = TryGetForwarder();
1026                         if (forwarder != null)
1027                         {
1028                                 return forwarder.BindTypeParameters(type);
1029                         }
1030                         return new GenericFieldInstance(type, this);
1031                 }
1032
1033                 public override int MetadataToken
1034                 {
1035                         get { return Forwarder.MetadataToken; }
1036                 }
1037
1038                 public override bool Equals(object obj)
1039                 {
1040                         MissingField other = obj as MissingField;
1041                         return other != null
1042                                 && other.declaringType == declaringType
1043                                 && other.name == name
1044                                 && other.signature.Equals(signature);
1045                 }
1046
1047                 public override int GetHashCode()
1048                 {
1049                         return declaringType.GetHashCode() ^ name.GetHashCode() ^ signature.GetHashCode();
1050                 }
1051
1052                 public override string ToString()
1053                 {
1054                         return this.FieldType.Name + " " + this.Name;
1055                 }
1056
1057                 internal override int GetCurrentToken()
1058                 {
1059                         return Forwarder.GetCurrentToken();
1060                 }
1061
1062                 internal override bool IsBaked
1063                 {
1064                         get { return Forwarder.IsBaked; }
1065                 }
1066         }
1067
1068         // NOTE this is currently only used by CustomAttributeData (because there is no other way to refer to a property)
1069         sealed class MissingProperty : PropertyInfo
1070         {
1071                 private readonly Type declaringType;
1072                 private readonly string name;
1073                 private readonly PropertySignature signature;
1074
1075                 internal MissingProperty(Type declaringType, string name, PropertySignature signature)
1076                 {
1077                         this.declaringType = declaringType;
1078                         this.name = name;
1079                         this.signature = signature;
1080                 }
1081
1082                 public override PropertyAttributes Attributes
1083                 {
1084                         get { throw new MissingMemberException(this); }
1085                 }
1086
1087                 public override bool CanRead
1088                 {
1089                         get { throw new MissingMemberException(this); }
1090                 }
1091
1092                 public override bool CanWrite
1093                 {
1094                         get { throw new MissingMemberException(this); }
1095                 }
1096
1097                 public override MethodInfo GetGetMethod(bool nonPublic)
1098                 {
1099                         throw new MissingMemberException(this);
1100                 }
1101
1102                 public override MethodInfo GetSetMethod(bool nonPublic)
1103                 {
1104                         throw new MissingMemberException(this);
1105                 }
1106
1107                 public override MethodInfo[] GetAccessors(bool nonPublic)
1108                 {
1109                         throw new MissingMemberException(this);
1110                 }
1111
1112                 public override object GetRawConstantValue()
1113                 {
1114                         throw new MissingMemberException(this);
1115                 }
1116
1117                 internal override bool IsPublic
1118                 {
1119                         get { throw new MissingMemberException(this); }
1120                 }
1121
1122                 internal override bool IsNonPrivate
1123                 {
1124                         get { throw new MissingMemberException(this); }
1125                 }
1126
1127                 internal override bool IsStatic
1128                 {
1129                         get { throw new MissingMemberException(this); }
1130                 }
1131
1132                 internal override PropertySignature PropertySignature
1133                 {
1134                         get { return signature; }
1135                 }
1136
1137                 public override string Name
1138                 {
1139                         get { return name; }
1140                 }
1141
1142                 public override Type DeclaringType
1143                 {
1144                         get { return declaringType; }
1145                 }
1146
1147                 public override Module Module
1148                 {
1149                         get { return declaringType.Module; }
1150                 }
1151
1152                 internal override bool IsBaked
1153                 {
1154                         get { return declaringType.IsBaked; }
1155                 }
1156
1157                 internal override int GetCurrentToken()
1158                 {
1159                         throw new MissingMemberException(this);
1160                 }
1161         }
1162 }