/// <summary> /// Gets if <paramref name="t"/> is/contains a generic return type referring to a class type parameter. /// </summary> bool CheckReturnType(IReturnType t) { if (t == null) { return(false); } if (t.IsGenericReturnType) { return(t.CastToGenericReturnType().TypeParameter.Method == null); } else if (t.IsArrayReturnType) { return(CheckReturnType(t.CastToArrayReturnType().ArrayElementType)); } else if (t.IsConstructedReturnType) { foreach (IReturnType para in t.CastToConstructedReturnType().TypeArguments) { if (CheckReturnType(para)) { return(true); } } return(false); } else { return(false); } }
void WriteType(IReturnType rt) { if (rt == null) { writer.Write(NullRTReferenceCode); return; } if (rt.IsDefaultReturnType) { string name = rt.FullyQualifiedName; if (name == "System.Void") { writer.Write(VoidRTCode); } else { writer.Write(classIndices[new ClassNameTypeCountPair(rt)]); } } else if (rt.IsGenericReturnType) { GenericReturnType grt = rt.CastToGenericReturnType(); if (grt.TypeParameter.Method != null) { writer.Write(MethodGenericRTCode); } else { writer.Write(TypeGenericRTCode); } writer.Write(grt.TypeParameter.Index); } else if (rt.IsArrayReturnType) { writer.Write(ArrayRTCode); writer.Write(rt.CastToArrayReturnType().ArrayDimensions); WriteType(rt.CastToArrayReturnType().ArrayElementType); } else if (rt.IsConstructedReturnType) { ConstructedReturnType crt = rt.CastToConstructedReturnType(); writer.Write(ConstructedRTCode); WriteType(crt.UnboundType); writer.Write((byte)crt.TypeArguments.Count); foreach (IReturnType typeArgument in crt.TypeArguments) { WriteType(typeArgument); } } else if (rt.IsDecoratingReturnType <PointerReturnType>()) { writer.Write(PointerRTCode); WriteType(rt.CastToDecoratingReturnType <PointerReturnType>().BaseType); } else { writer.Write(NullRTReferenceCode); LoggingService.Warn("Unknown return type: " + rt.ToString()); } }
static bool IsConstructedConversionToGenericReturnType(IReturnType from, IReturnType to, IMethod allowGenericTargetsOnThisMethod) { // null could be passed when type arguments could not be resolved/inferred if (from == null && to == null) { return(true); } if (from == null || to == null) { return(false); } if (from.Equals(to)) { return(true); } if (allowGenericTargetsOnThisMethod == null) { return(false); } if (to.IsGenericReturnType) { ITypeParameter typeParameter = to.CastToGenericReturnType().TypeParameter; if (typeParameter.Method != allowGenericTargetsOnThisMethod) { return(false); } foreach (IReturnType constraintType in typeParameter.Constraints) { if (!ConversionExistsInternal(from, constraintType, allowGenericTargetsOnThisMethod)) { return(false); } } return(true); } // for conversions like from IEnumerable<string> to IEnumerable<T>, where T is a GenericReturnType ConstructedReturnType cFrom = from.CastToConstructedReturnType(); ConstructedReturnType cTo = to.CastToConstructedReturnType(); if (cFrom != null && cTo != null) { if (cFrom.FullyQualifiedName == cTo.FullyQualifiedName && cFrom.TypeArguments.Count == cTo.TypeArguments.Count) { for (int i = 0; i < cFrom.TypeArguments.Count; i++) { if (!IsConstructedConversionToGenericReturnType(cFrom.TypeArguments[i], cTo.TypeArguments[i], allowGenericTargetsOnThisMethod)) { return(false); } } return(true); } } return(false); }
public override bool Equals(object o) { IReturnType rt = o as IReturnType; if (rt == null || !rt.IsGenericReturnType) { return(false); } return(_typeParameter.Equals(rt.CastToGenericReturnType()._typeParameter)); }
public override bool Equals(IReturnType rt) { if (rt == null || !rt.IsGenericReturnType) { return(false); } GenericReturnType grt = rt.CastToGenericReturnType(); if ((typeParameter.Method == null) != (grt.typeParameter.Method == null)) { return(false); } return(typeParameter.Index == grt.typeParameter.Index); }
TP GetTPForType(IReturnType t) { if (t == null) { return(null); } GenericReturnType grt = t.CastToGenericReturnType(); if (grt != null) { return(typeParameters.FirstOrDefault(tp => tp.TypeParameter.Equals(grt.TypeParameter))); } return(null); }
public virtual GenericReturnType CastToGenericReturnType() { IReturnType baseType = BaseType; GenericReturnType temp; if (baseType != null && TryEnter()) { temp = baseType.CastToGenericReturnType(); } else { throw new InvalidCastException("Cannot cast " + ToString() + " to expected type."); } _busy = false; return(temp); }
/// <summary> /// Gets whether this type parameter occurs in the specified return type. /// </summary> public bool OccursIn(IReturnType rt) { ArrayReturnType art = rt.CastToArrayReturnType(); if (art != null) { return OccursIn(art.ArrayElementType); } ConstructedReturnType crt = rt.CastToConstructedReturnType(); if (crt != null) { return crt.TypeArguments.Any(ta => OccursIn(ta)); } GenericReturnType grt = rt.CastToGenericReturnType(); if (grt != null) { return this.TypeParameter.Equals(grt.TypeParameter); } return false; }
bool CheckReturnType(IReturnType t) { if (t.IsGenericReturnType) { return t.CastToGenericReturnType().TypeParameter.Method == null; } else if (t.IsArrayReturnType) { return CheckReturnType(t.CastToArrayReturnType().ArrayElementType); } else if (t.IsConstructedReturnType) { foreach (IReturnType para in t.CastToConstructedReturnType().TypeArguments) { if (para != null) { if (CheckReturnType(para)) return true; } } return false; } else { return false; } }
static bool IsApplicable(IReturnType argument, IReturnType expected) { if (argument == null) // TODO: Use NullReturnType instead of no return type { return(true); // "null" can be passed for any argument } if (expected.IsGenericReturnType) { foreach (IReturnType constraint in expected.CastToGenericReturnType().TypeParameter.Constraints) { if (!ConversionExists(argument, constraint)) { return(false); } } } return(ConversionExists(argument, expected)); }
public static IReturnType TranslateType(IReturnType input, IList <IReturnType> typeParameters, bool convertForMethod) { if (input == null || typeParameters == null || typeParameters.Count == 0) { return(input); // nothing to do when there are no type parameters specified } if (input.IsGenericReturnType) { GenericReturnType rt = input.CastToGenericReturnType(); if (convertForMethod ? (rt.TypeParameter.Method != null) : (rt.TypeParameter.Method == null)) { if (rt.TypeParameter.Index < typeParameters.Count) { IReturnType newType = typeParameters[rt.TypeParameter.Index]; if (newType != null) { return(newType); } } } } else if (input.IsArrayReturnType) { ArrayReturnType arInput = input.CastToArrayReturnType(); IReturnType e = arInput.ArrayElementType; IReturnType t = TranslateType(e, typeParameters, convertForMethod); if (e != t && t != null) { return(new ArrayReturnType(arInput.ProjectContent, t, arInput.ArrayDimensions)); } } else if (input.IsConstructedReturnType) { ConstructedReturnType cinput = input.CastToConstructedReturnType(); List <IReturnType> para = new List <IReturnType>(cinput.TypeArguments.Count); foreach (IReturnType argument in cinput.TypeArguments) { para.Add(TranslateType(argument, typeParameters, convertForMethod)); } return(new ConstructedReturnType(cinput.UnboundType, para)); } return(input); }
/// <summary> /// Gets whether this type parameter occurs in the specified return type. /// </summary> public bool OccursIn(IReturnType rt) { ArrayReturnType art = rt.CastToArrayReturnType(); if (art != null) { return(OccursIn(art.ArrayElementType)); } ConstructedReturnType crt = rt.CastToConstructedReturnType(); if (crt != null) { return(crt.TypeArguments.Any(ta => OccursIn(ta))); } GenericReturnType grt = rt.CastToGenericReturnType(); if (grt != null) { return(this.TypeParameter.Equals(grt.TypeParameter)); } return(false); }
void WriteType(IReturnType rt) { if (rt == null) { writer.Write(NullRTReferenceCode); return; } if (rt.IsDefaultReturnType) { string name = rt.FullyQualifiedName; if (name == "System.Void") { writer.Write(VoidRTCode); } else { writer.Write(classIndices[new ClassNameTypeCountPair(rt)]); } } else if (rt.IsGenericReturnType) { GenericReturnType grt = rt.CastToGenericReturnType(); if (grt.TypeParameter.Method != null) { writer.Write(MethodGenericRTCode); } else { writer.Write(TypeGenericRTCode); } writer.Write(grt.TypeParameter.Index); } else if (rt.IsArrayReturnType) { writer.Write(ArrayRTCode); writer.Write(rt.CastToArrayReturnType().ArrayDimensions); WriteType(rt.CastToArrayReturnType().ArrayElementType); } else if (rt.IsConstructedReturnType) { ConstructedReturnType crt = rt.CastToConstructedReturnType(); writer.Write(ConstructedRTCode); WriteType(crt.UnboundType); writer.Write((byte)crt.TypeArguments.Count); foreach (IReturnType typeArgument in crt.TypeArguments) { WriteType(typeArgument); } } else if (rt.IsDecoratingReturnType<PointerReturnType>()) { writer.Write(PointerRTCode); WriteType(rt.CastToDecoratingReturnType<PointerReturnType>().BaseType); } else { writer.Write(NullRTReferenceCode); LoggingService.Warn("Unknown return type: " + rt.ToString()); } }
/// <summary> /// Infers type arguments specified by passing expectedArgument as parameter where passedArgument /// was expected. The resulting type arguments are written to outputArray. /// Returns false when expectedArgument and passedArgument are incompatible, otherwise true /// is returned (true is used both for successful inferring and other kind of errors). /// </summary> /// <remarks> /// The C# spec (§ 25.6.4) has a bug: it says that type inference works if the passedArgument is IEnumerable{T} /// and the expectedArgument is an array; passedArgument and expectedArgument must be swapped here. /// </remarks> public static bool InferTypeArgument(IReturnType expectedArgument, IReturnType passedArgument, IReturnType[] outputArray) { if (expectedArgument == null) { return(true); } if (passedArgument == null || passedArgument == NullReturnType.Instance) { return(true); } if (passedArgument.IsArrayReturnType) { IReturnType passedArrayElementType = passedArgument.CastToArrayReturnType().ArrayElementType; if (expectedArgument.IsArrayReturnType && expectedArgument.CastToArrayReturnType().ArrayDimensions == passedArgument.CastToArrayReturnType().ArrayDimensions) { return(InferTypeArgument(expectedArgument.CastToArrayReturnType().ArrayElementType, passedArrayElementType, outputArray)); } else if (expectedArgument.IsConstructedReturnType) { switch (expectedArgument.FullyQualifiedName) { case "System.Collections.Generic.IList": case "System.Collections.Generic.ICollection": case "System.Collections.Generic.IEnumerable": return(InferTypeArgument(expectedArgument.CastToConstructedReturnType().TypeArguments[0], passedArrayElementType, outputArray)); } } // If P is an array type, and A is not an array type of the same rank, // or an instantiation of IList<>, ICollection<>, or IEnumerable<>, then // type inference fails for the generic method. return(false); } if (expectedArgument.IsGenericReturnType) { GenericReturnType methodTP = expectedArgument.CastToGenericReturnType(); if (methodTP.TypeParameter.Method != null) { if (methodTP.TypeParameter.Index < outputArray.Length) { outputArray[methodTP.TypeParameter.Index] = passedArgument; } return(true); } } if (expectedArgument.IsConstructedReturnType) { // The spec for this case is quite complex. // For our purposes, we can simplify enourmously: if (!passedArgument.IsConstructedReturnType) { return(false); } IList <IReturnType> expectedTA = expectedArgument.CastToConstructedReturnType().TypeArguments; IList <IReturnType> passedTA = passedArgument.CastToConstructedReturnType().TypeArguments; int count = Math.Min(expectedTA.Count, passedTA.Count); for (int i = 0; i < count; i++) { InferTypeArgument(expectedTA[i], passedTA[i], outputArray); } } return(true); }
static bool IsApplicable(IReturnType argument, IReturnType expected) { if (argument == null) // TODO: Use NullReturnType instead of no return type return true; // "null" can be passed for any argument if (expected.IsGenericReturnType) { foreach (IReturnType constraint in expected.CastToGenericReturnType().TypeParameter.Constraints) { if (!ConversionExists(argument, constraint)) { return false; } } } return ConversionExists(argument, expected); }
TP GetTPForType(IReturnType t) { if (t == null) return null; GenericReturnType grt = t.CastToGenericReturnType(); if (grt != null) { return typeParameters.FirstOrDefault(tp => tp.TypeParameter.Equals(grt.TypeParameter)); } return null; }
/// <summary> /// Infers type arguments specified by passing expectedArgument as parameter where passedArgument /// was expected. The resulting type arguments are written to outputArray. /// Returns false when expectedArgument and passedArgument are incompatible, otherwise true /// is returned (true is used both for successful inferring and other kind of errors). /// </summary> public static bool InferTypeArgument(IReturnType expectedArgument, IReturnType passedArgument, IReturnType[] outputArray) { if (expectedArgument == null) return true; if (passedArgument == null) return true; // TODO: NullTypeReference if (expectedArgument.IsArrayReturnType) { IReturnType expectedArrayElementType = expectedArgument.CastToArrayReturnType().ArrayElementType; if (passedArgument.IsArrayReturnType && expectedArgument.CastToArrayReturnType().ArrayDimensions == passedArgument.CastToArrayReturnType().ArrayDimensions) { return InferTypeArgument(expectedArrayElementType, passedArgument.CastToArrayReturnType().ArrayElementType, outputArray); } else if (passedArgument.IsConstructedReturnType) { switch (passedArgument.FullyQualifiedName) { case "System.Collections.Generic.IList": case "System.Collections.Generic.ICollection": case "System.Collections.Generic.IEnumerable": return InferTypeArgument(expectedArrayElementType, passedArgument.CastToConstructedReturnType().TypeArguments[0], outputArray); } } // If P is an array type, and A is not an array type of the same rank, // or an instantiation of IList<>, ICollection<>, or IEnumerable<>, then // type inference fails for the generic method. return false; } if (expectedArgument.IsGenericReturnType) { GenericReturnType methodTP = expectedArgument.CastToGenericReturnType(); if (methodTP.TypeParameter.Method != null) { if (methodTP.TypeParameter.Index < outputArray.Length) { outputArray[methodTP.TypeParameter.Index] = passedArgument; } return true; } } if (expectedArgument.IsConstructedReturnType) { // The spec for this case is quite complex. // For our purposes, we can simplify enourmously: if (!passedArgument.IsConstructedReturnType) return false; IList<IReturnType> expectedTA = expectedArgument.CastToConstructedReturnType().TypeArguments; IList<IReturnType> passedTA = passedArgument.CastToConstructedReturnType().TypeArguments; int count = Math.Min(expectedTA.Count, passedTA.Count); for (int i = 0; i < count; i++) { InferTypeArgument(expectedTA[i], passedTA[i], outputArray); } } return true; }
public static IReturnType TranslateType(IReturnType input, IList<IReturnType> typeParameters, bool convertForMethod) { if (typeParameters == null || typeParameters.Count == 0) { return input; // nothing to do when there are no type parameters specified } if (input.IsGenericReturnType) { GenericReturnType rt = input.CastToGenericReturnType(); if (convertForMethod ? (rt.TypeParameter.Method != null) : (rt.TypeParameter.Method == null)) { if (rt.TypeParameter.Index < typeParameters.Count) { IReturnType newType = typeParameters[rt.TypeParameter.Index]; if (newType != null) { return newType; } } } } else if (input.IsArrayReturnType) { ArrayReturnType arInput = input.CastToArrayReturnType(); IReturnType e = arInput.ArrayElementType; IReturnType t = TranslateType(e, typeParameters, convertForMethod); if (e != t && t != null) return new ArrayReturnType(arInput.ProjectContent, t, arInput.ArrayDimensions); } else if (input.IsConstructedReturnType) { ConstructedReturnType cinput = input.CastToConstructedReturnType(); List<IReturnType> para = new List<IReturnType>(cinput.TypeArguments.Count); foreach (IReturnType argument in cinput.TypeArguments) { para.Add(TranslateType(argument, typeParameters, convertForMethod)); } return new ConstructedReturnType(cinput.UnboundType, para); } return input; }