Merge pull request #237 from knocte/master
[mono.git] / mcs / class / IKVM.Reflection / Reader / GenericTypeParameter.cs
1 /*
2   Copyright (C) 2009 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Text;
27 using IKVM.Reflection.Metadata;
28
29 namespace IKVM.Reflection.Reader
30 {
31         abstract class TypeParameterType : Type
32         {
33                 public sealed override string AssemblyQualifiedName
34                 {
35                         get { return null; }
36                 }
37
38                 public sealed override bool IsValueType
39                 {
40                         get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
41                 }
42
43                 public sealed override Type BaseType
44                 {
45                         get
46                         {
47                                 foreach (Type type in GetGenericParameterConstraints())
48                                 {
49                                         if (!type.IsInterface && !type.IsGenericParameter)
50                                         {
51                                                 return type;
52                                         }
53                                 }
54                                 return this.IsValueType ? this.Module.universe.System_ValueType : this.Module.universe.System_Object;
55                         }
56                 }
57
58                 public override Type[] __GetDeclaredInterfaces()
59                 {
60                         List<Type> list = new List<Type>();
61                         foreach (Type type in GetGenericParameterConstraints())
62                         {
63                                 if (type.IsInterface)
64                                 {
65                                         list.Add(type);
66                                 }
67                         }
68                         return list.ToArray();
69                 }
70
71                 public sealed override TypeAttributes Attributes
72                 {
73                         get { return TypeAttributes.Public; }
74                 }
75
76                 public sealed override string FullName
77                 {
78                         get { return null; }
79                 }
80
81                 public sealed override string ToString()
82                 {
83                         return this.Name;
84                 }
85
86                 public sealed override bool IsGenericParameter
87                 {
88                         get { return true; }
89                 }
90         }
91
92         sealed class UnboundGenericMethodParameter : TypeParameterType
93         {
94                 private static readonly DummyModule module = new DummyModule();
95                 private readonly int position;
96
97                 private sealed class DummyModule : NonPEModule
98                 {
99                         internal DummyModule()
100                                 : base(new Universe())
101                         {
102                         }
103
104                         protected override Exception NotSupportedException()
105                         {
106                                 return new InvalidOperationException();
107                         }
108
109                         protected override Exception ArgumentOutOfRangeException()
110                         {
111                                 return new InvalidOperationException();
112                         }
113
114                         public override bool Equals(object obj)
115                         {
116                                 throw new InvalidOperationException();
117                         }
118
119                         public override int GetHashCode()
120                         {
121                                 throw new InvalidOperationException();
122                         }
123
124                         public override string ToString()
125                         {
126                                 throw new InvalidOperationException();
127                         }
128
129                         public override int MDStreamVersion
130                         {
131                                 get { throw new InvalidOperationException(); }
132                         }
133
134                         public override Assembly Assembly
135                         {
136                                 get { throw new InvalidOperationException(); }
137                         }
138
139                         internal override Type FindType(TypeName typeName)
140                         {
141                                 throw new InvalidOperationException();
142                         }
143
144                         internal override void GetTypesImpl(List<Type> list)
145                         {
146                                 throw new InvalidOperationException();
147                         }
148
149                         public override string FullyQualifiedName
150                         {
151                                 get { throw new InvalidOperationException(); }
152                         }
153
154                         public override string Name
155                         {
156                                 get { throw new InvalidOperationException(); }
157                         }
158
159                         public override Guid ModuleVersionId
160                         {
161                                 get { throw new InvalidOperationException(); }
162                         }
163
164                         public override string ScopeName
165                         {
166                                 get { throw new InvalidOperationException(); }
167                         }
168                 }
169
170                 internal static Type Make(int position)
171                 {
172                         return module.universe.CanonicalizeType(new UnboundGenericMethodParameter(position));
173                 }
174
175                 private UnboundGenericMethodParameter(int position)
176                 {
177                         this.position = position;
178                 }
179
180                 public override bool Equals(object obj)
181                 {
182                         UnboundGenericMethodParameter other = obj as UnboundGenericMethodParameter;
183                         return other != null && other.position == position;
184                 }
185
186                 public override int GetHashCode()
187                 {
188                         return position;
189                 }
190
191                 public override string Namespace
192                 {
193                         get { throw new InvalidOperationException(); }
194                 }
195
196                 public override string Name
197                 {
198                         get { throw new InvalidOperationException(); }
199                 }
200
201                 public override int MetadataToken
202                 {
203                         get { throw new InvalidOperationException(); }
204                 }
205
206                 public override Module Module
207                 {
208                         get { return module; }
209                 }
210
211                 public override int GenericParameterPosition
212                 {
213                         get { return position; }
214                 }
215
216                 public override Type DeclaringType
217                 {
218                         get { return null; }
219                 }
220
221                 public override MethodBase DeclaringMethod
222                 {
223                         get { throw new InvalidOperationException(); }
224                 }
225
226                 public override Type[] GetGenericParameterConstraints()
227                 {
228                         throw new InvalidOperationException();
229                 }
230
231                 public override GenericParameterAttributes GenericParameterAttributes
232                 {
233                         get { throw new InvalidOperationException(); }
234                 }
235
236                 internal override Type BindTypeParameters(IGenericBinder binder)
237                 {
238                         return binder.BindMethodParameter(this);
239                 }
240         }
241
242         sealed class GenericTypeParameter : TypeParameterType
243         {
244                 private readonly ModuleReader module;
245                 private readonly int index;
246
247                 internal GenericTypeParameter(ModuleReader module, int index)
248                 {
249                         this.module = module;
250                         this.index = index;
251                 }
252
253                 public override bool Equals(object obj)
254                 {
255                         return base.Equals(obj);
256                 }
257
258                 public override int GetHashCode()
259                 {
260                         return base.GetHashCode();
261                 }
262
263                 public override string Namespace
264                 {
265                         get { return DeclaringType.Namespace; }
266                 }
267
268                 public override string Name
269                 {
270                         get { return module.GetString(module.GenericParam.records[index].Name); }
271                 }
272
273                 public override Module Module
274                 {
275                         get { return module; }
276                 }
277
278                 public override int MetadataToken
279                 {
280                         get { return (GenericParamTable.Index << 24) + index + 1; }
281                 }
282
283                 public override int GenericParameterPosition
284                 {
285                         get { return module.GenericParam.records[index].Number; }
286                 }
287
288                 public override Type DeclaringType
289                 {
290                         get
291                         {
292                                 int owner = module.GenericParam.records[index].Owner;
293                                 return (owner >> 24) == TypeDefTable.Index ? module.ResolveType(owner) : null;
294                         }
295                 }
296
297                 public override MethodBase DeclaringMethod
298                 {
299                         get
300                         {
301                                 int owner = module.GenericParam.records[index].Owner;
302                                 return (owner >> 24) == MethodDefTable.Index ? module.ResolveMethod(owner) : null;
303                         }
304                 }
305
306                 public override Type[] GetGenericParameterConstraints()
307                 {
308                         IGenericContext context = (this.DeclaringMethod as IGenericContext) ?? this.DeclaringType;
309                         List<Type> list = new List<Type>();
310                         foreach (int i in module.GenericParamConstraint.Filter(this.MetadataToken))
311                         {
312                                 list.Add(module.ResolveType(module.GenericParamConstraint.records[i].Constraint, context));
313                         }
314                         return list.ToArray();
315                 }
316
317                 public override GenericParameterAttributes GenericParameterAttributes
318                 {
319                         get { return (GenericParameterAttributes)module.GenericParam.records[index].Flags; }
320                 }
321
322                 internal override Type BindTypeParameters(IGenericBinder binder)
323                 {
324                         int owner = module.GenericParam.records[index].Owner;
325                         if ((owner >> 24) == MethodDefTable.Index)
326                         {
327                                 return binder.BindMethodParameter(this);
328                         }
329                         else
330                         {
331                                 return binder.BindTypeParameter(this);
332                         }
333                 }
334         }
335 }