Fix null sessions in HttpContextWrapper.Session
[mono.git] / mcs / class / IKVM.Reflection / FieldInfo.cs
1 /*
2   Copyright (C) 2009-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.Diagnostics;
27
28 namespace IKVM.Reflection
29 {
30         public abstract class FieldInfo : MemberInfo
31         {
32                 // prevent external subclasses
33                 internal FieldInfo()
34                 {
35                 }
36
37                 public sealed override MemberTypes MemberType
38                 {
39                         get { return MemberTypes.Field; }
40                 }
41
42                 public abstract FieldAttributes Attributes { get; }
43                 public abstract void __GetDataFromRVA(byte[] data, int offset, int length);
44                 public abstract int __FieldRVA { get; }
45                 public abstract Object GetRawConstantValue();
46                 internal abstract FieldSignature FieldSignature { get; }
47
48                 public Type FieldType
49                 {
50                         get { return this.FieldSignature.FieldType; }
51                 }
52
53                 public CustomModifiers __GetCustomModifiers()
54                 {
55                         return this.FieldSignature.GetCustomModifiers();
56                 }
57
58                 public Type[] GetOptionalCustomModifiers()
59                 {
60                         return __GetCustomModifiers().GetOptional();
61                 }
62
63                 public Type[] GetRequiredCustomModifiers()
64                 {
65                         return __GetCustomModifiers().GetRequired();
66                 }
67
68                 public bool IsStatic
69                 {
70                         get { return (Attributes & FieldAttributes.Static) != 0; }
71                 }
72
73                 public bool IsLiteral
74                 {
75                         get { return (Attributes & FieldAttributes.Literal) != 0; }
76                 }
77
78                 public bool IsInitOnly
79                 {
80                         get { return (Attributes & FieldAttributes.InitOnly) != 0; }
81                 }
82
83                 public bool IsNotSerialized
84                 {
85                         get { return (Attributes & FieldAttributes.NotSerialized) != 0; }
86                 }
87
88                 public bool IsSpecialName
89                 {
90                         get { return (Attributes & FieldAttributes.SpecialName) != 0; }
91                 }
92
93                 public bool IsPublic
94                 {
95                         get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; }
96                 }
97
98                 public bool IsPrivate
99                 {
100                         get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; }
101                 }
102
103                 public bool IsFamily
104                 {
105                         get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; }
106                 }
107
108                 public bool IsFamilyOrAssembly
109                 {
110                         get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; }
111                 }
112
113                 public bool IsAssembly
114                 {
115                         get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; }
116                 }
117
118                 public bool IsFamilyAndAssembly
119                 {
120                         get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; }
121                 }
122
123                 public bool IsPinvokeImpl
124                 {
125                         get { return (Attributes & FieldAttributes.PinvokeImpl) != 0; }
126                 }
127
128                 public virtual FieldInfo __GetFieldOnTypeDefinition()
129                 {
130                         return this;
131                 }
132
133                 public abstract bool __TryGetFieldOffset(out int offset);
134
135                 public bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
136                 {
137                         return FieldMarshal.ReadFieldMarshal(this.Module, GetCurrentToken(), out fieldMarshal);
138                 }
139
140                 internal abstract int ImportTo(Emit.ModuleBuilder module);
141
142                 internal virtual FieldInfo BindTypeParameters(Type type)
143                 {
144                         return new GenericFieldInstance(this.DeclaringType.BindTypeParameters(type), this);
145                 }
146
147                 internal sealed override bool BindingFlagsMatch(BindingFlags flags)
148                 {
149                         return BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic)
150                                 && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static, BindingFlags.Instance);
151                 }
152
153                 internal sealed override bool BindingFlagsMatchInherited(BindingFlags flags)
154                 {
155                         return (Attributes & FieldAttributes.FieldAccessMask) > FieldAttributes.Private
156                                 && BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic)
157                                 && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance);
158                 }
159
160                 internal sealed override MemberInfo SetReflectedType(Type type)
161                 {
162                         return new FieldInfoWithReflectedType(type, this);
163                 }
164
165                 internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
166                 {
167                         Module module = this.Module;
168                         List<CustomAttributeData> list = new List<CustomAttributeData>();
169                         if (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_MarshalAsAttribute))
170                         {
171                                 FieldMarshal spec;
172                                 if (__TryGetFieldMarshal(out spec))
173                                 {
174                                         list.Add(CustomAttributeData.CreateMarshalAsPseudoCustomAttribute(module, spec));
175                                 }
176                         }
177                         if (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_FieldOffsetAttribute))
178                         {
179                                 int offset;
180                                 if (__TryGetFieldOffset(out offset))
181                                 {
182                                         list.Add(CustomAttributeData.CreateFieldOffsetPseudoCustomAttribute(module, offset));
183                                 }
184                         }
185                         return list;
186                 }
187         }
188
189         sealed class FieldInfoWithReflectedType : FieldInfo
190         {
191                 private readonly Type reflectedType;
192                 private readonly FieldInfo field;
193
194                 internal FieldInfoWithReflectedType(Type reflectedType, FieldInfo field)
195                 {
196                         Debug.Assert(reflectedType != field.DeclaringType);
197                         this.reflectedType = reflectedType;
198                         this.field = field;
199                 }
200
201                 public override FieldAttributes Attributes
202                 {
203                         get { return field.Attributes; }
204                 }
205
206                 public override void __GetDataFromRVA(byte[] data, int offset, int length)
207                 {
208                         field.__GetDataFromRVA(data, offset, length);
209                 }
210
211                 public override int __FieldRVA
212                 {
213                         get { return field.__FieldRVA; }
214                 }
215
216                 public override bool __TryGetFieldOffset(out int offset)
217                 {
218                         return field.__TryGetFieldOffset(out offset);
219                 }
220
221                 public override Object GetRawConstantValue()
222                 {
223                         return field.GetRawConstantValue();
224                 }
225
226                 internal override FieldSignature FieldSignature
227                 {
228                         get { return field.FieldSignature; }
229                 }
230
231                 public override FieldInfo __GetFieldOnTypeDefinition()
232                 {
233                         return field.__GetFieldOnTypeDefinition();
234                 }
235
236                 internal override int ImportTo(Emit.ModuleBuilder module)
237                 {
238                         return field.ImportTo(module);
239                 }
240
241                 internal override FieldInfo BindTypeParameters(Type type)
242                 {
243                         return field.BindTypeParameters(type);
244                 }
245
246                 public override bool __IsMissing
247                 {
248                         get { return field.__IsMissing; }
249                 }
250
251                 public override Type DeclaringType
252                 {
253                         get { return field.DeclaringType; }
254                 }
255
256                 public override Type ReflectedType
257                 {
258                         get { return reflectedType; }
259                 }
260
261                 public override bool Equals(object obj)
262                 {
263                         FieldInfoWithReflectedType other = obj as FieldInfoWithReflectedType;
264                         return other != null
265                                 && other.reflectedType == reflectedType
266                                 && other.field == field;
267                 }
268
269                 public override int GetHashCode()
270                 {
271                         return reflectedType.GetHashCode() ^ field.GetHashCode();
272                 }
273
274                 public override int MetadataToken
275                 {
276                         get { return field.MetadataToken; }
277                 }
278
279                 public override Module Module
280                 {
281                         get { return field.Module; }
282                 }
283
284                 public override string Name
285                 {
286                         get { return field.Name; }
287                 }
288
289                 public override string ToString()
290                 {
291                         return field.ToString();
292                 }
293
294                 internal override int GetCurrentToken()
295                 {
296                         return field.GetCurrentToken();
297                 }
298
299                 internal override bool IsBaked
300                 {
301                         get { return field.IsBaked; }
302                 }
303         }
304 }