示例#1
0
 /// <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);
     }
 }
示例#2
0
 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);
        }
示例#4
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
			/// <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));
 }
示例#11
0
 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);
 }
示例#12
0
            /// <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);
		}
示例#16
0
		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;
		}