mirror of https://github.com/icsharpcode/ILSpy.git
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							525 lines
						
					
					
						
							19 KiB
						
					
					
				
			
		
		
	
	
							525 lines
						
					
					
						
							19 KiB
						
					
					
				// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team | 
						|
//  | 
						|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this | 
						|
// software and associated documentation files (the "Software"), to deal in the Software | 
						|
// without restriction, including without limitation the rights to use, copy, modify, merge, | 
						|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons | 
						|
// to whom the Software is furnished to do so, subject to the following conditions: | 
						|
//  | 
						|
// The above copyright notice and this permission notice shall be included in all copies or | 
						|
// substantial portions of the Software. | 
						|
//  | 
						|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | 
						|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | 
						|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE | 
						|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | 
						|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
						|
// DEALINGS IN THE SOFTWARE. | 
						|
 | 
						|
using System; | 
						|
using System.Collections.Generic; | 
						|
using System.Collections.ObjectModel; | 
						|
using System.Linq; | 
						|
using Mono.Cecil; | 
						|
 | 
						|
namespace ICSharpCode.Decompiler.TypeSystem | 
						|
{ | 
						|
	public static class TypesHierarchyHelpers | 
						|
	{ | 
						|
		public static bool IsBaseType(TypeDefinition baseType, TypeDefinition derivedType, bool resolveTypeArguments) | 
						|
		{ | 
						|
			if (resolveTypeArguments) | 
						|
				return BaseTypes(derivedType).Any(t => t.Item == baseType); | 
						|
			else { | 
						|
				var comparableBaseType = baseType.Resolve(); | 
						|
				if (comparableBaseType == null) | 
						|
					return false; | 
						|
				while (derivedType.BaseType != null) { | 
						|
					var resolvedBaseType = derivedType.BaseType.Resolve(); | 
						|
					if (resolvedBaseType == null) | 
						|
						return false; | 
						|
					if (comparableBaseType == resolvedBaseType) | 
						|
						return true; | 
						|
					derivedType = resolvedBaseType; | 
						|
				} | 
						|
				return false; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determines whether one method overrides or hides another method. | 
						|
		/// </summary> | 
						|
		/// <param name="parentMethod">The method declared in a base type.</param> | 
						|
		/// <param name="childMethod">The method declared in a derived type.</param> | 
						|
		/// <returns>true if <paramref name="childMethod"/> hides or overrides <paramref name="parentMethod"/>, | 
						|
		/// otherwise false.</returns> | 
						|
		public static bool IsBaseMethod(MethodDefinition parentMethod, MethodDefinition childMethod) | 
						|
		{ | 
						|
			if (parentMethod == null) | 
						|
				throw new ArgumentNullException(nameof(parentMethod)); | 
						|
			if (childMethod == null) | 
						|
				throw new ArgumentNullException(nameof(childMethod)); | 
						|
 | 
						|
			if (parentMethod.Name != childMethod.Name) | 
						|
				return false; | 
						|
 | 
						|
			if (parentMethod.HasParameters || childMethod.HasParameters) | 
						|
				if (!parentMethod.HasParameters || !childMethod.HasParameters || parentMethod.Parameters.Count != childMethod.Parameters.Count) | 
						|
					return false; | 
						|
 | 
						|
			return FindBaseMethods(childMethod).Any(m => m == parentMethod);// || (parentMethod.HasGenericParameters && m.); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determines whether a property overrides or hides another property. | 
						|
		/// </summary> | 
						|
		/// <param name="parentProperty">The property declared in a base type.</param> | 
						|
		/// <param name="childProperty">The property declared in a derived type.</param> | 
						|
		/// <returns>true if the <paramref name="childProperty"/> hides or overrides <paramref name="parentProperty"/>, | 
						|
		/// otherwise false.</returns> | 
						|
		public static bool IsBaseProperty(PropertyDefinition parentProperty, PropertyDefinition childProperty) | 
						|
		{ | 
						|
			if (parentProperty == null) | 
						|
				throw new ArgumentNullException(nameof(parentProperty)); | 
						|
			if (childProperty == null) | 
						|
				throw new ArgumentNullException(nameof(childProperty)); | 
						|
 | 
						|
			if (parentProperty.Name != childProperty.Name) | 
						|
				return false; | 
						|
 | 
						|
			if (parentProperty.HasParameters || childProperty.HasParameters) | 
						|
				if (!parentProperty.HasParameters || !childProperty.HasParameters || parentProperty.Parameters.Count != childProperty.Parameters.Count) | 
						|
					return false; | 
						|
 | 
						|
			return FindBaseProperties(childProperty).Any(m => m == parentProperty); | 
						|
		} | 
						|
 | 
						|
		public static bool IsBaseEvent(EventDefinition parentEvent, EventDefinition childEvent) | 
						|
		{ | 
						|
			if (parentEvent.Name != childEvent.Name) | 
						|
				return false; | 
						|
 | 
						|
			return FindBaseEvents(childEvent).Any(m => m == parentEvent); | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Finds all methods from base types overridden or hidden by the specified method. | 
						|
		/// </summary> | 
						|
		/// <param name="method">The method which overrides or hides methods from base types.</param> | 
						|
		/// <returns>Methods overriden or hidden by the specified method.</returns> | 
						|
		public static IEnumerable<MethodDefinition> FindBaseMethods(MethodDefinition method) | 
						|
		{ | 
						|
			if (method == null) | 
						|
				throw new ArgumentNullException(nameof(method)); | 
						|
 | 
						|
			var typeContext = CreateGenericContext(method.DeclaringType); | 
						|
			var gMethod = typeContext.ApplyTo(method); | 
						|
 | 
						|
			foreach (var baseType in BaseTypes(method.DeclaringType)) | 
						|
				foreach (var baseMethod in baseType.Item.Methods) | 
						|
					if (MatchMethod(baseType.ApplyTo(baseMethod), gMethod) && IsVisibleFromDerived(baseMethod, method.DeclaringType)) { | 
						|
						yield return baseMethod; | 
						|
						if (baseMethod.IsNewSlot == baseMethod.IsVirtual) | 
						|
							yield break; | 
						|
					} | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Finds all properties from base types overridden or hidden by the specified property. | 
						|
		/// </summary> | 
						|
		/// <param name="property">The property which overrides or hides properties from base types.</param> | 
						|
		/// <returns>Properties overriden or hidden by the specified property.</returns> | 
						|
		public static IEnumerable<PropertyDefinition> FindBaseProperties(PropertyDefinition property) | 
						|
		{ | 
						|
			if (property == null) | 
						|
				throw new ArgumentNullException(nameof(property)); | 
						|
 | 
						|
			if ((property.GetMethod ?? property.SetMethod).HasOverrides) | 
						|
				yield break; | 
						|
 | 
						|
			var typeContext = CreateGenericContext(property.DeclaringType); | 
						|
			var gProperty = typeContext.ApplyTo(property); | 
						|
			bool isIndexer = property.IsIndexer(); | 
						|
 | 
						|
			foreach (var baseType in BaseTypes(property.DeclaringType)) | 
						|
				foreach (var baseProperty in baseType.Item.Properties) | 
						|
					if (MatchProperty(baseType.ApplyTo(baseProperty), gProperty) | 
						|
							&& IsVisibleFromDerived(baseProperty, property.DeclaringType)) { | 
						|
						if (isIndexer != baseProperty.IsIndexer()) | 
						|
							continue; | 
						|
						yield return baseProperty; | 
						|
						var anyPropertyAccessor = baseProperty.GetMethod ?? baseProperty.SetMethod; | 
						|
						if (anyPropertyAccessor.IsNewSlot == anyPropertyAccessor.IsVirtual) | 
						|
							yield break; | 
						|
					} | 
						|
		} | 
						|
 | 
						|
		public static IEnumerable<EventDefinition> FindBaseEvents(EventDefinition eventDef) | 
						|
		{ | 
						|
			if (eventDef == null) | 
						|
				throw new ArgumentNullException(nameof(eventDef)); | 
						|
 | 
						|
			var typeContext = CreateGenericContext(eventDef.DeclaringType); | 
						|
			var gEvent = typeContext.ApplyTo(eventDef); | 
						|
 | 
						|
			foreach (var baseType in BaseTypes(eventDef.DeclaringType)) | 
						|
				foreach (var baseEvent in baseType.Item.Events) | 
						|
					if (MatchEvent(baseType.ApplyTo(baseEvent), gEvent) && IsVisibleFromDerived(baseEvent, eventDef.DeclaringType)) { | 
						|
						yield return baseEvent; | 
						|
						var anyEventAccessor = baseEvent.AddMethod ?? baseEvent.RemoveMethod; | 
						|
						if (anyEventAccessor.IsNewSlot == anyEventAccessor.IsVirtual) | 
						|
							yield break; | 
						|
					} | 
						|
 | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determinates whether member of the base type is visible from a derived type. | 
						|
		/// </summary> | 
						|
		/// <param name="baseMember">The member which visibility is checked.</param> | 
						|
		/// <param name="derivedType">The derived type.</param> | 
						|
		/// <returns>true if the member is visible from derived type, othewise false.</returns> | 
						|
		public static bool IsVisibleFromDerived(IMemberDefinition baseMember, TypeDefinition derivedType) | 
						|
		{ | 
						|
			if (baseMember == null) | 
						|
				throw new ArgumentNullException(nameof(baseMember)); | 
						|
			if (derivedType == null) | 
						|
				throw new ArgumentNullException(nameof(derivedType)); | 
						|
 | 
						|
			MethodAttributes attrs = GetAccessAttributes(baseMember) & MethodAttributes.MemberAccessMask; | 
						|
			if (attrs == MethodAttributes.Private) | 
						|
				return false; | 
						|
 | 
						|
			if (baseMember.DeclaringType.Module == derivedType.Module) | 
						|
				return true; | 
						|
 | 
						|
			if (attrs == MethodAttributes.Assembly || attrs == MethodAttributes.FamANDAssem) { | 
						|
				var derivedTypeAsm = derivedType.Module.Assembly; | 
						|
				var asm = baseMember.DeclaringType.Module.Assembly; | 
						|
 | 
						|
				if (asm.HasCustomAttributes) { | 
						|
					var attributes = asm.CustomAttributes | 
						|
						.Where(attr => attr.AttributeType.FullName == "System.Runtime.CompilerServices.InternalsVisibleToAttribute"); | 
						|
					foreach (var attribute in attributes) { | 
						|
						string assemblyName = attribute.ConstructorArguments[0].Value as string; | 
						|
						assemblyName = assemblyName.Split(',')[0]; // strip off any public key info | 
						|
						if (assemblyName == derivedTypeAsm.Name.Name) | 
						|
							return true; | 
						|
					} | 
						|
				} | 
						|
 | 
						|
				return false; | 
						|
			} | 
						|
 | 
						|
			return true; | 
						|
		} | 
						|
 | 
						|
		private static MethodAttributes GetAccessAttributes(IMemberDefinition member) | 
						|
		{ | 
						|
			var fld = member as FieldDefinition; | 
						|
			if (fld != null) | 
						|
				return (MethodAttributes)fld.Attributes; | 
						|
 | 
						|
			var method = member as MethodDefinition; | 
						|
			if (method != null) | 
						|
				return method.Attributes; | 
						|
 | 
						|
			var prop = member as PropertyDefinition; | 
						|
			if (prop != null) { | 
						|
				return (prop.GetMethod ?? prop.SetMethod).Attributes; | 
						|
		} | 
						|
 | 
						|
			var evnt = member as EventDefinition; | 
						|
			if (evnt != null) { | 
						|
				return (evnt.AddMethod ?? evnt.RemoveMethod).Attributes; | 
						|
			} | 
						|
 | 
						|
			var nestedType = member as TypeDefinition; | 
						|
			if (nestedType != null) { | 
						|
				if (nestedType.IsNestedPrivate) | 
						|
					return MethodAttributes.Private; | 
						|
				if (nestedType.IsNestedAssembly || nestedType.IsNestedFamilyAndAssembly) | 
						|
					return MethodAttributes.Assembly; | 
						|
				return MethodAttributes.Public; | 
						|
			} | 
						|
 | 
						|
			throw new NotSupportedException(); | 
						|
		} | 
						|
 | 
						|
		private static bool MatchMethod(GenericContext<MethodDefinition> candidate, GenericContext<MethodDefinition> method) | 
						|
		{ | 
						|
			var mCandidate = candidate.Item; | 
						|
			var mMethod = method.Item; | 
						|
			if (mCandidate.Name != mMethod.Name) | 
						|
				return false; | 
						|
 | 
						|
			if (mCandidate.HasOverrides) | 
						|
				return false; | 
						|
 | 
						|
			if (mCandidate.IsSpecialName != method.Item.IsSpecialName) | 
						|
				return false; | 
						|
 | 
						|
			if (mCandidate.HasGenericParameters || mMethod.HasGenericParameters) { | 
						|
				if (!mCandidate.HasGenericParameters || !mMethod.HasGenericParameters || mCandidate.GenericParameters.Count != mMethod.GenericParameters.Count) | 
						|
					return false; | 
						|
			} | 
						|
 | 
						|
			if (mCandidate.HasParameters || mMethod.HasParameters) { | 
						|
				if (!mCandidate.HasParameters || !mMethod.HasParameters || mCandidate.Parameters.Count != mMethod.Parameters.Count) | 
						|
					return false; | 
						|
 | 
						|
				for (int index = 0; index < mCandidate.Parameters.Count; index++) { | 
						|
					if (!MatchParameters(candidate.ApplyTo(mCandidate.Parameters[index]), method.ApplyTo(mMethod.Parameters[index]))) | 
						|
						return false; | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			return true; | 
						|
		} | 
						|
 | 
						|
		public static bool MatchInterfaceMethod(MethodDefinition candidate, MethodDefinition method, TypeReference interfaceContextType) | 
						|
		{ | 
						|
			var candidateContext = CreateGenericContext(candidate.DeclaringType); | 
						|
			var gCandidate = candidateContext.ApplyTo(candidate); | 
						|
 | 
						|
			if (interfaceContextType is GenericInstanceType) { | 
						|
				var methodContext = new GenericContext<TypeDefinition>(interfaceContextType.Resolve(), ((GenericInstanceType)interfaceContextType).GenericArguments); | 
						|
				var gMethod = methodContext.ApplyTo(method); | 
						|
				return MatchMethod(gCandidate, gMethod); | 
						|
			} else { | 
						|
				var methodContext = CreateGenericContext(interfaceContextType.Resolve()); | 
						|
				var gMethod = candidateContext.ApplyTo(method); | 
						|
				return MatchMethod(gCandidate, gMethod); | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		private static bool MatchProperty(GenericContext<PropertyDefinition> candidate, GenericContext<PropertyDefinition> property) | 
						|
		{ | 
						|
			var mCandidate = candidate.Item; | 
						|
			var mProperty = property.Item; | 
						|
			if (mCandidate.Name != mProperty.Name) | 
						|
				return false; | 
						|
 | 
						|
			if ((mCandidate.GetMethod ?? mCandidate.SetMethod).HasOverrides) | 
						|
				return false; | 
						|
 | 
						|
			if (mCandidate.HasParameters || mProperty.HasParameters) { | 
						|
				if (!mCandidate.HasParameters || !mProperty.HasParameters || mCandidate.Parameters.Count != mProperty.Parameters.Count) | 
						|
					return false; | 
						|
 | 
						|
				for (int index = 0; index < mCandidate.Parameters.Count; index++) { | 
						|
					if (!MatchParameters(candidate.ApplyTo(mCandidate.Parameters[index]), property.ApplyTo(mProperty.Parameters[index]))) | 
						|
						return false; | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			return true; | 
						|
		} | 
						|
 | 
						|
		private static bool MatchEvent(GenericContext<EventDefinition> candidate, GenericContext<EventDefinition> ev) | 
						|
		{ | 
						|
			var mCandidate = candidate.Item; | 
						|
			var mEvent = ev.Item; | 
						|
			if (mCandidate.Name != mEvent.Name) | 
						|
				return false; | 
						|
 | 
						|
			if ((mCandidate.AddMethod ?? mCandidate.RemoveMethod).HasOverrides) | 
						|
				return false; | 
						|
 | 
						|
			if (!IsSameType(candidate.ResolveWithContext(mCandidate.EventType), ev.ResolveWithContext(mEvent.EventType))) | 
						|
				return false; | 
						|
 | 
						|
			return true; | 
						|
		} | 
						|
 | 
						|
		private static bool MatchParameters(GenericContext<ParameterDefinition> baseParameterType, GenericContext<ParameterDefinition> parameterType) | 
						|
		{ | 
						|
			if (baseParameterType.Item.IsIn != parameterType.Item.IsIn || | 
						|
					baseParameterType.Item.IsOut != parameterType.Item.IsOut) | 
						|
				return false; | 
						|
			var baseParam = baseParameterType.ResolveWithContext(baseParameterType.Item.ParameterType); | 
						|
			var param = parameterType.ResolveWithContext(parameterType.Item.ParameterType); | 
						|
			return IsSameType(baseParam, param); | 
						|
		} | 
						|
 | 
						|
		private static bool IsSameType(TypeReference tr1, TypeReference tr2) | 
						|
		{ | 
						|
			if (tr1 == tr2) | 
						|
				return true; | 
						|
			if (tr1 == null || tr2 == null) | 
						|
				return false; | 
						|
 | 
						|
			if (tr1.GetType() != tr2.GetType()) | 
						|
				return false; | 
						|
 | 
						|
			if (tr1.Name == tr2.Name && tr1.FullName == tr2.FullName) | 
						|
				return true; | 
						|
 | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		private static IEnumerable<GenericContext<TypeDefinition>> BaseTypes(TypeDefinition type) | 
						|
		{ | 
						|
			return BaseTypes(CreateGenericContext(type)); | 
						|
		} | 
						|
 | 
						|
		private static IEnumerable<GenericContext<TypeDefinition>> BaseTypes(GenericContext<TypeDefinition> type) | 
						|
		{ | 
						|
			while (type.Item.BaseType != null) { | 
						|
				var baseType = type.Item.BaseType; | 
						|
				var genericBaseType = baseType as GenericInstanceType; | 
						|
				if (genericBaseType != null) { | 
						|
					type = new GenericContext<TypeDefinition>(genericBaseType.ResolveOrThrow(), | 
						|
						genericBaseType.GenericArguments.Select(t => type.ResolveWithContext(t))); | 
						|
				} else | 
						|
					type = new GenericContext<TypeDefinition>(baseType.ResolveOrThrow()); | 
						|
				yield return type; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		private static GenericContext<TypeDefinition> CreateGenericContext(TypeDefinition type) | 
						|
		{ | 
						|
			return type.HasGenericParameters | 
						|
				? new GenericContext<TypeDefinition>(type, type.GenericParameters) | 
						|
				: new GenericContext<TypeDefinition>(type); | 
						|
		} | 
						|
 | 
						|
		struct GenericContext<T> where T : class | 
						|
		{ | 
						|
			private static readonly ReadOnlyCollection<TypeReference> Empty = new ReadOnlyCollection<TypeReference>(new List<TypeReference>()); | 
						|
			private static readonly GenericParameter UnresolvedGenericTypeParameter = | 
						|
				new DummyGenericParameterProvider(false).DummyParameter; | 
						|
			private static readonly GenericParameter UnresolvedGenericMethodParameter = | 
						|
				new DummyGenericParameterProvider(true).DummyParameter; | 
						|
 | 
						|
			public readonly T Item; | 
						|
			public readonly ReadOnlyCollection<TypeReference> TypeArguments; | 
						|
 | 
						|
			public GenericContext(T item) | 
						|
			{ | 
						|
				if (item == null) | 
						|
					throw new ArgumentNullException(nameof(item)); | 
						|
 | 
						|
				Item = item; | 
						|
				TypeArguments = Empty; | 
						|
			} | 
						|
 | 
						|
			public GenericContext(T item, IEnumerable<TypeReference> typeArguments) | 
						|
			{ | 
						|
				if (item == null) | 
						|
					throw new ArgumentNullException(nameof(item)); | 
						|
 | 
						|
				Item = item; | 
						|
				var list = new List<TypeReference>(); | 
						|
				foreach (var arg in typeArguments) { | 
						|
					var resolved = arg != null ? arg.Resolve() : arg; | 
						|
					list.Add(resolved != null ? resolved : arg); | 
						|
				} | 
						|
				TypeArguments = new ReadOnlyCollection<TypeReference>(list); | 
						|
			} | 
						|
 | 
						|
			private GenericContext(T item, ReadOnlyCollection<TypeReference> typeArguments) | 
						|
			{ | 
						|
				Item = item; | 
						|
				TypeArguments = typeArguments; | 
						|
			} | 
						|
 | 
						|
			public TypeReference ResolveWithContext(TypeReference type) | 
						|
			{ | 
						|
				var genericParameter = type as GenericParameter; | 
						|
				if (genericParameter != null) | 
						|
					if (genericParameter.Owner.GenericParameterType == GenericParameterType.Type) | 
						|
					return this.TypeArguments[genericParameter.Position]; | 
						|
					else | 
						|
						return genericParameter.Owner.GenericParameterType == GenericParameterType.Type | 
						|
							? UnresolvedGenericTypeParameter : UnresolvedGenericMethodParameter; | 
						|
				var typeSpecification = type as TypeSpecification; | 
						|
				if (typeSpecification != null) { | 
						|
					var resolvedElementType = ResolveWithContext(typeSpecification.ElementType); | 
						|
					return ReplaceElementType(typeSpecification, resolvedElementType); | 
						|
				} | 
						|
				return type.ResolveOrThrow(); | 
						|
			} | 
						|
 | 
						|
			private TypeReference ReplaceElementType(TypeSpecification ts, TypeReference newElementType) | 
						|
			{ | 
						|
				var arrayType = ts as Mono.Cecil.ArrayType; | 
						|
				if (arrayType != null) { | 
						|
					if (newElementType == arrayType.ElementType) | 
						|
						return arrayType; | 
						|
					var newArrayType = new Mono.Cecil.ArrayType(newElementType, arrayType.Rank); | 
						|
					for (int dimension = 0; dimension < arrayType.Rank; dimension++) | 
						|
						newArrayType.Dimensions[dimension] = arrayType.Dimensions[dimension]; | 
						|
					return newArrayType; | 
						|
				} | 
						|
				var byReferenceType = ts as Mono.Cecil.ByReferenceType; | 
						|
				if (byReferenceType != null) { | 
						|
					return new Mono.Cecil.ByReferenceType(newElementType); | 
						|
			} | 
						|
				// TODO: should we throw an exception instead calling Resolve method? | 
						|
				return ts.ResolveOrThrow(); | 
						|
			} | 
						|
 | 
						|
			public GenericContext<T2> ApplyTo<T2>(T2 item) where T2 : class | 
						|
			{ | 
						|
				return new GenericContext<T2>(item, this.TypeArguments); | 
						|
			} | 
						|
 | 
						|
			private class DummyGenericParameterProvider : IGenericParameterProvider | 
						|
			{ | 
						|
				readonly Mono.Cecil.GenericParameterType type; | 
						|
				readonly Mono.Collections.Generic.Collection<GenericParameter> parameters; | 
						|
 | 
						|
				public DummyGenericParameterProvider(bool methodTypeParameter) | 
						|
				{ | 
						|
					type = methodTypeParameter ? Mono.Cecil.GenericParameterType.Method : | 
						|
						Mono.Cecil.GenericParameterType.Type; | 
						|
					parameters = new Mono.Collections.Generic.Collection<GenericParameter>(1); | 
						|
					parameters.Add(new GenericParameter(this)); | 
						|
		} | 
						|
 | 
						|
				public GenericParameter DummyParameter | 
						|
				{ | 
						|
					get { return parameters[0]; } | 
						|
	} | 
						|
 | 
						|
				bool IGenericParameterProvider.HasGenericParameters | 
						|
				{ | 
						|
					get { throw new NotImplementedException(); } | 
						|
				} | 
						|
 | 
						|
				bool IGenericParameterProvider.IsDefinition | 
						|
				{ | 
						|
					get { throw new NotImplementedException(); } | 
						|
				} | 
						|
 | 
						|
				ModuleDefinition IGenericParameterProvider.Module | 
						|
				{ | 
						|
					get { throw new NotImplementedException(); } | 
						|
				} | 
						|
 | 
						|
				Mono.Collections.Generic.Collection<GenericParameter> IGenericParameterProvider.GenericParameters | 
						|
				{ | 
						|
					get { return parameters; } | 
						|
				} | 
						|
 | 
						|
				GenericParameterType IGenericParameterProvider.GenericParameterType | 
						|
				{ | 
						|
					get { return type; } | 
						|
				} | 
						|
 | 
						|
				MetadataToken IMetadataTokenProvider.MetadataToken | 
						|
				{ | 
						|
					get | 
						|
					{ | 
						|
						throw new NotImplementedException(); | 
						|
					} | 
						|
					set | 
						|
					{ | 
						|
						throw new NotImplementedException(); | 
						|
					} | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
	} | 
						|
}
 | 
						|
 |