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