2 Copyright (C) 2009-2012 Jeroen Frijters
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.
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:
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.
25 using System.Collections.Generic;
27 using IKVM.Reflection.Metadata;
29 namespace IKVM.Reflection.Reader
31 abstract class TypeParameterType : TypeInfo
33 public sealed override string AssemblyQualifiedName
38 public sealed override bool IsValueType
40 get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
43 public sealed override Type BaseType
47 foreach (Type type in GetGenericParameterConstraints())
49 if (!type.IsInterface && !type.IsGenericParameter)
54 return this.IsValueType ? this.Module.universe.System_ValueType : this.Module.universe.System_Object;
58 public override Type[] __GetDeclaredInterfaces()
60 List<Type> list = new List<Type>();
61 foreach (Type type in GetGenericParameterConstraints())
68 return list.ToArray();
71 public sealed override TypeAttributes Attributes
73 get { return TypeAttributes.Public; }
76 public sealed override string FullName
81 public sealed override string ToString()
86 public sealed override bool IsGenericParameter
91 public sealed override bool __ContainsMissingType
95 bool freeList = false;
98 foreach (Type type in GetGenericParameterConstraints())
100 if (type.__IsMissing)
104 else if (type.IsConstructedGenericType || type.HasElementType || type.__IsFunctionPointer)
106 // if a constructed type contains generic parameters,
107 // it might contain this type parameter again and
108 // to prevent infinite recurssion, we keep a thread local
109 // list of type parameters we've already processed
110 if (type.ContainsGenericParameters)
112 if (containsMissingTypeHack == null)
115 containsMissingTypeHack = new List<Type>();
117 else if (containsMissingTypeHack.Contains(this))
121 containsMissingTypeHack.Add(this);
123 if (type.__ContainsMissingType)
135 containsMissingTypeHack = null;
142 private static List<Type> containsMissingTypeHack;
145 sealed class UnboundGenericMethodParameter : TypeParameterType
147 private static readonly DummyModule module = new DummyModule();
148 private readonly int position;
150 private sealed class DummyModule : NonPEModule
152 internal DummyModule()
153 : base(new Universe())
157 protected override Exception NotSupportedException()
159 return new InvalidOperationException();
162 protected override Exception ArgumentOutOfRangeException()
164 return new InvalidOperationException();
167 public override bool Equals(object obj)
169 throw new InvalidOperationException();
172 public override int GetHashCode()
174 throw new InvalidOperationException();
177 public override string ToString()
179 throw new InvalidOperationException();
182 public override int MDStreamVersion
184 get { throw new InvalidOperationException(); }
187 public override Assembly Assembly
189 get { throw new InvalidOperationException(); }
192 internal override Type FindType(TypeName typeName)
194 throw new InvalidOperationException();
197 internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
199 throw new InvalidOperationException();
202 internal override void GetTypesImpl(List<Type> list)
204 throw new InvalidOperationException();
207 public override string FullyQualifiedName
209 get { throw new InvalidOperationException(); }
212 public override string Name
214 get { throw new InvalidOperationException(); }
217 public override Guid ModuleVersionId
219 get { throw new InvalidOperationException(); }
222 public override string ScopeName
224 get { throw new InvalidOperationException(); }
228 internal static Type Make(int position)
230 return module.universe.CanonicalizeType(new UnboundGenericMethodParameter(position));
233 private UnboundGenericMethodParameter(int position)
235 this.position = position;
238 public override bool Equals(object obj)
240 UnboundGenericMethodParameter other = obj as UnboundGenericMethodParameter;
241 return other != null && other.position == position;
244 public override int GetHashCode()
249 public override string Namespace
251 get { throw new InvalidOperationException(); }
254 public override string Name
256 get { throw new InvalidOperationException(); }
259 public override int MetadataToken
261 get { throw new InvalidOperationException(); }
264 public override Module Module
266 get { return module; }
269 public override int GenericParameterPosition
271 get { return position; }
274 public override Type DeclaringType
279 public override MethodBase DeclaringMethod
281 get { throw new InvalidOperationException(); }
284 public override Type[] GetGenericParameterConstraints()
286 throw new InvalidOperationException();
289 public override GenericParameterAttributes GenericParameterAttributes
291 get { throw new InvalidOperationException(); }
294 internal override Type BindTypeParameters(IGenericBinder binder)
296 return binder.BindMethodParameter(this);
299 internal override bool IsBaked
301 get { throw new InvalidOperationException(); }
305 sealed class GenericTypeParameter : TypeParameterType
307 private readonly ModuleReader module;
308 private readonly int index;
310 internal GenericTypeParameter(ModuleReader module, int index)
312 this.module = module;
316 public override bool Equals(object obj)
318 return base.Equals(obj);
321 public override int GetHashCode()
323 return base.GetHashCode();
326 public override string Namespace
328 get { return DeclaringType.Namespace; }
331 public override string Name
333 get { return module.GetString(module.GenericParam.records[index].Name); }
336 public override Module Module
338 get { return module; }
341 public override int MetadataToken
343 get { return (GenericParamTable.Index << 24) + index + 1; }
346 public override int GenericParameterPosition
348 get { return module.GenericParam.records[index].Number; }
351 public override Type DeclaringType
355 int owner = module.GenericParam.records[index].Owner;
356 return (owner >> 24) == TypeDefTable.Index ? module.ResolveType(owner) : null;
360 public override MethodBase DeclaringMethod
364 int owner = module.GenericParam.records[index].Owner;
365 return (owner >> 24) == MethodDefTable.Index ? module.ResolveMethod(owner) : null;
369 public override Type[] GetGenericParameterConstraints()
371 IGenericContext context = (this.DeclaringMethod as IGenericContext) ?? this.DeclaringType;
372 List<Type> list = new List<Type>();
373 foreach (int i in module.GenericParamConstraint.Filter(this.MetadataToken))
375 list.Add(module.ResolveType(module.GenericParamConstraint.records[i].Constraint, context));
377 return list.ToArray();
380 public override GenericParameterAttributes GenericParameterAttributes
382 get { return (GenericParameterAttributes)module.GenericParam.records[index].Flags; }
385 internal override Type BindTypeParameters(IGenericBinder binder)
387 int owner = module.GenericParam.records[index].Owner;
388 if ((owner >> 24) == MethodDefTable.Index)
390 return binder.BindMethodParameter(this);
394 return binder.BindTypeParameter(this);
398 internal override bool IsBaked