/// <summary> /// Use the generic argument providers to specialize a type /// </summary> /// <param name="type">The type to resolve</param> /// <param name="declaringType">The declaring type as a generic argument provider</param> /// <param name="method">The method as a generic argument provider</param> /// <returns></returns> public static IType GetType(IType type, IGenericArgumentProvider declaringType, IGenericArgumentProvider method) { ITypeReference itr = type as ITypeReference; if (itr != null) { if (itr.GenericType == null) { // The parameter is directly a non-generic type reference return(itr); } else { // The parameter is a reference to a generic type. Build an array of types of the // generic arguments by recursion IType[] ita = new IType[itr.GenericArguments.Count]; for (int i = 0; i < ita.Length; i++) { ita[i] = GetType(itr.GenericArguments[i], declaringType, method); } // Build the specialization (the 'instance') of the generic type ITypeReference itr2 = new XTypeInstanceReference(); itr2.GenericType = itr.GenericType; itr2.GenericArguments.AddRange(ita); ((ISettableTypeDeclaration)itr2).Declaration = itr.Resolve(); return(itr2); } } // Check to see if the parameter is an array IArrayType iat = type as IArrayType; if (iat != null) { // The parameter is an array type. Build an array type and recurse to get its element type IArrayType iat2 = new XArrayType(); iat2.ElementType = GetType(iat.ElementType, declaringType, method); iat2.DotNetType = iat.DotNetType; return(iat2); } // Check to see if the parameter is a pointer IPointerType ipt = type as IPointerType; if (ipt != null) { // The parameter is a pointer type. Build a pointer type and recurse to set its element type IPointerType ipt2 = new XPointerType(); ipt2.ElementType = GetType(ipt.ElementType, declaringType, method); return(ipt2); } // Check to see if the parameter is a reference IReferenceType irt = type as IReferenceType; if (irt != null) { // The parameter is a reference type. Build a reference type and recurse // to set its element type IReferenceType irt2 = new XReferenceType(); irt2.ElementType = GetType(irt.ElementType, declaringType, method); return(irt2); } // Check to see if the parameter has an optional modifier IOptionalModifier iom = type as IOptionalModifier; if (iom != null) { // The parameter has an optional modifier. Build an optional modifier type and recurse // to set its element type IOptionalModifier iom2 = new XOptionalModifier(); iom2.Modifier = (ITypeReference)GetType(iom.Modifier, declaringType, method); iom2.ElementType = GetType(iom.ElementType, declaringType, method); return(iom2); } // Check to see if the parameter has an required modifier IRequiredModifier irm = type as IRequiredModifier; if (irm != null) { // The parameter has a required modifier. Build a required modifier type and recurse // to set its element type IRequiredModifier irm2 = new XRequiredModifier(); irm2.Modifier = (ITypeReference)GetType(irm.Modifier, declaringType, method); irm2.ElementType = GetType(irm.ElementType, declaringType, method); return(irm2); } // Deal with generic parameters IGenericParameter igp = type as IGenericParameter; IMethodReference imr; if (igp != null) { itr = igp.Owner as ITypeReference; imr = igp.Owner as IMethodReference; ; if (itr == null && imr == null) { throw new NotSupportedException("A generic parameter must be owned by a method or type"); } if (itr == null) { if (method != null) { // Get the parameter type from the method instance return(method.GenericArguments[igp.Position]); } else { return(igp); } } else { if (declaringType != null) { // Get the parameter type from the declaring type return(declaringType.GenericArguments[igp.Position]); } else { return(igp); } } } // The only thing left is that the parameter is a generic argument IGenericArgument iga = type as IGenericArgument; if (iga == null) { throw new NotSupportedException("Unable to get the parameters type"); } IType it = iga.Resolve(); if (it == null || !(it is IGenericArgument) || (it is IGenericParameter)) { itr = iga.Owner as ITypeReference; imr = iga.Owner as IMethodReference; if (itr == null && imr == null) { throw new NotSupportedException(); } if (itr == null) { if (method != null) { IGenericArgument iga2 = new XGenericArgument(); iga2.Owner = method; iga2.Position = iga.Position; return(iga2); } else { return(iga); } } else { IGenericArgument iga2 = new XGenericArgument(); iga2.Owner = declaringType; iga2.Position = iga.Position; return(iga2); } } // Recurse return(GetType(it, declaringType, method)); }
private void WriteGenericParameterConstraintList(IGenericArgumentProvider provider, IFormatter formatter) { ITypeCollection genericArguments = provider.GenericArguments; if (genericArguments.Count > 0) { for (int i = 0; i < genericArguments.Count; i++) { IGenericParameter parameter = genericArguments[i] as IGenericParameter; if ((parameter != null) && (parameter.Constraints.Count > 0)) { formatter.Write(" "); formatter.WriteKeyword("where"); formatter.Write(" "); formatter.Write(parameter.Name); formatter.Write(":"); formatter.Write(" "); for (int j = 0; j < parameter.Constraints.Count; j++) { if (j != 0) { formatter.Write(", "); } IType constraint = (IType)parameter.Constraints[j]; this.WriteGenericParameterConstraint(constraint, formatter); } } } } }