Exemple #1
0
 static void TryAddExtension(LanguageProperties language, Action <IMethodOrProperty> methodFound, IMethodOrProperty ext, IReturnType resolvedType)
 {
     // now add the extension method if it fits the type
     if (MemberLookupHelper.IsApplicable(resolvedType, ext.Parameters[0].ReturnType, ext as IMethod))
     {
         IMethod method = ext as IMethod;
         if (method != null && method.TypeParameters.Count > 0)
         {
             IReturnType[] typeArguments = new IReturnType[method.TypeParameters.Count];
             MemberLookupHelper.InferTypeArgument(method.Parameters[0].ReturnType, resolvedType, typeArguments);
             for (int i = 0; i < typeArguments.Length; i++)
             {
                 if (typeArguments[i] != null)
                 {
                     ext            = (IMethod)ext.CreateSpecializedMember();
                     ext.ReturnType = ConstructedReturnType.TranslateType(ext.ReturnType, typeArguments, true);
                     for (int j = 0; j < ext.Parameters.Count; ++j)
                     {
                         ext.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(ext.Parameters[j].ReturnType, typeArguments, true);
                     }
                     break;
                 }
             }
         }
         methodFound(ext);
     }
 }
Exemple #2
0
        static bool IsConstructedConversionToGenericReturnType(IReturnType from, IReturnType to, IMethod allowGenericTargetsOnThisMethod)
        {
            // null could be passed when type arguments could not be resolved/inferred
            if (from == to)             // both are null or
            {
                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(true);
                }
                // applicability ignores constraints
//				foreach (IReturnType constraintType in typeParameter.Constraints) {
//					if (!ConversionExistsInternal(from, constraintType, allowGenericTargetsOnThisMethod)) {
//						return false;
//					}
//				}
                return(false);
            }

            // 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);
        }
Exemple #3
0
 /// <summary>
 /// Gets the type parameter that was passed to a certain base class.
 /// For example, when <paramref name="returnType"/> is Dictionary(of string, int)
 /// this method will return KeyValuePair(of string, int)
 /// </summary>
 public static IReturnType GetTypeParameterPassedToBaseClass(IReturnType parentType, IClass baseClass, int baseClassTypeParameterIndex)
 {
     foreach (IReturnType rt in GetTypeInheritanceTree(parentType))
     {
         ConstructedReturnType crt = rt.CastToConstructedReturnType();
         if (crt != null && baseClass.CompareTo(rt.GetUnderlyingClass()) == 0)
         {
             if (baseClassTypeParameterIndex < crt.TypeArguments.Count)
             {
                 return(crt.TypeArguments[baseClassTypeParameterIndex]);
             }
         }
     }
     return(null);
 }
Exemple #4
0
        /// <summary>
        /// Translates typeToTranslate using the type arguments from parentType;
        /// </summary>
        static IReturnType TranslateIfRequired(IReturnType parentType, IReturnType typeToTranslate)
        {
            if (typeToTranslate == null)
            {
                return(null);
            }
            ConstructedReturnType parentConstructedType = parentType.CastToConstructedReturnType();

            if (parentConstructedType != null)
            {
                return(ConstructedReturnType.TranslateType(typeToTranslate, parentConstructedType.TypeArguments, false));
            }
            else
            {
                return(typeToTranslate);
            }
        }
 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);
 }
Exemple #6
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 if (name == "dynamic")
         {
             writer.Write(DynamicRTCode);
         }
         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());
     }
 }