public void TypeParameterPassedToBaseClassSameClass()
		{
			IReturnType[] stringArr = { msc.SystemTypes.String };
			IReturnType rrt = new ConstructedReturnType(EnumerableClass.DefaultReturnType, stringArr);
			IReturnType res = MemberLookupHelper.GetTypeParameterPassedToBaseClass(rrt, EnumerableClass, 0);
			Assert.AreEqual("System.String", res.FullyQualifiedName);
		}
Esempio n. 2
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);
     }
 }
Esempio n. 3
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);
        }
Esempio n. 5
0
		public void TypeParameterPassedToBaseClassTestDictionary()
		{
			IReturnType[] stringInt = { msc.SystemTypes.String, msc.SystemTypes.Int32 };
			IReturnType rrt = new ConstructedReturnType(DictionaryRT, stringInt);
			IReturnType res = MemberLookupHelper.GetTypeParameterPassedToBaseClass(rrt, EnumerableClass, 0);
			Assert.AreEqual("System.Collections.Generic.KeyValuePair", res.FullyQualifiedName);
			ConstructedReturnType resc = res.CastToConstructedReturnType();
			Assert.AreEqual("System.String", resc.TypeArguments[0].FullyQualifiedName);
			Assert.AreEqual("System.Int32", resc.TypeArguments[1].FullyQualifiedName);
		}
 /// <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);
 }
Esempio n. 7
0
        /// <summary>
        /// Gets the common base type of a and b.
        /// </summary>
        public static IReturnType GetCommonType(IProjectContent projectContent, IReturnType a, IReturnType b)
        {
            if (projectContent == null)
            {
                throw new ArgumentNullException("projectContent");
            }
            if (a == null)
            {
                return(b);
            }
            if (b == null)
            {
                return(a);
            }
            if (ConversionExists(a, b))
            {
                return(b);
            }
            if (ConversionExists(b, a))
            {
                return(a);
            }
            IClass c = a.GetUnderlyingClass();

            if (c != null)
            {
                foreach (IClass baseClass in c.ClassInheritanceTree)
                {
                    IReturnType baseType = baseClass.DefaultReturnType;
                    if (baseClass.TypeParameters.Count > 0)
                    {
                        IReturnType[] typeArguments = new IReturnType[baseClass.TypeParameters.Count];
                        for (int i = 0; i < typeArguments.Length; i++)
                        {
                            typeArguments[i] = GetTypeParameterPassedToBaseClass(a, baseClass, i);
                        }
                        baseType = new ConstructedReturnType(baseType, typeArguments);
                    }
                    if (ConversionExists(b, baseType))
                    {
                        return(baseType);
                    }
                }
            }
            return(projectContent.SystemTypes.Object);
        }
Esempio n. 8
0
 static void TryAddExtension(LanguageProperties language, ArrayList res, IMethodOrProperty ext, IReturnType resolvedType)
 {
     // accept only extension methods
     if (!ext.IsExtensionMethod)
     {
         return;
     }
     // don't add extension if method with that name already exists
     // but allow overloading extension methods
     foreach (IMember member in res)
     {
         IMethodOrProperty p = member as IMethodOrProperty;
         if (p != null && p.IsExtensionMethod)
         {
             continue;
         }
         if (language.NameComparer.Equals(member.Name, ext.Name))
         {
             return;
         }
     }
     // now add the extension method if it fits the type
     if (MemberLookupHelper.ConversionExists(resolvedType, ext.Parameters[0].ReturnType))
     {
         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.Clone();
                     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;
                 }
             }
         }
         res.Add(ext);
     }
 }
        /// <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);
            }
        }
Esempio n. 10
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)
        {
            if (!parentType.IsConstructedReturnType)
            {
                return(null);
            }
            ConstructedReturnType returnType = parentType.CastToConstructedReturnType();
            IClass c = returnType.GetUnderlyingClass();

            if (c == null)
            {
                return(null);
            }
            if (baseClass.CompareTo(c) == 0)
            {
                if (baseClassTypeParameterIndex >= returnType.TypeArguments.Count)
                {
                    return(null);
                }
                return(returnType.TypeArguments[baseClassTypeParameterIndex]);
            }
            foreach (IReturnType baseType in c.BaseTypes)
            {
                if (baseClass.CompareTo(baseType.GetUnderlyingClass()) == 0)
                {
                    if (!baseType.IsConstructedReturnType)
                    {
                        return(null);
                    }
                    ConstructedReturnType baseTypeCRT = baseType.CastToConstructedReturnType();
                    if (baseClassTypeParameterIndex >= baseTypeCRT.TypeArguments.Count)
                    {
                        return(null);
                    }
                    IReturnType result = baseTypeCRT.TypeArguments[baseClassTypeParameterIndex];
                    if (returnType.TypeArguments != null)
                    {
                        result = ConstructedReturnType.TranslateType(result, returnType.TypeArguments, false);
                    }
                    return(result);
                }
            }
            return(null);
        }
Esempio n. 11
0
 static IReturnType[][] ExpandParametersAndSubstitute(IList <IMethodOrProperty> list,
                                                      IReturnType[] arguments,
                                                      int maxScore, int[] ranking, bool[] needToExpand,
                                                      out IReturnType[][] inferredTypeParameters)
 {
     IReturnType[][] expandedParameters = new IReturnType[list.Count][];
     inferredTypeParameters = new IReturnType[list.Count][];
     for (int i = 0; i < ranking.Length; i++)
     {
         if (ranking[i] == maxScore)
         {
             IList <IParameter> parameters     = list[i].Parameters;
             IReturnType[]      typeParameters = (list[i] is IMethod) ? InferTypeArguments((IMethod)list[i], arguments) : null;
             inferredTypeParameters[i] = typeParameters;
             IReturnType paramsType = null;
             expandedParameters[i] = new IReturnType[arguments.Length];
             for (int j = 0; j < arguments.Length; j++)
             {
                 if (j < parameters.Count)
                 {
                     IParameter parameter = parameters[j];
                     if (parameter.IsParams && needToExpand[i])
                     {
                         if (parameter.ReturnType.IsArrayReturnType)
                         {
                             paramsType = parameter.ReturnType.CastToArrayReturnType().ArrayElementType;
                             paramsType = ConstructedReturnType.TranslateType(paramsType, typeParameters, true);
                         }
                         expandedParameters[i][j] = paramsType;
                     }
                     else
                     {
                         expandedParameters[i][j] = ConstructedReturnType.TranslateType(parameter.ReturnType, typeParameters, true);
                     }
                 }
                 else
                 {
                     expandedParameters[i][j] = paramsType;
                 }
             }
         }
     }
     return(expandedParameters);
 }
Esempio n. 12
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);
 }
Esempio n. 13
0
 static void ApplyInferredTypeParameters(IList <IMethod> list, IReturnType[][] inferredTypeParameters)
 {
     if (inferredTypeParameters == null)
     {
         return;
     }
     for (int i = 0; i < list.Count; i++)
     {
         IReturnType[] inferred = inferredTypeParameters[i];
         if (inferred != null && inferred.Length > 0)
         {
             IMethod m = (IMethod)list[i].Clone();
             m.ReturnType = ConstructedReturnType.TranslateType(m.ReturnType, inferred, true);
             for (int j = 0; j < m.Parameters.Count; ++j)
             {
                 m.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(m.Parameters[j].ReturnType, inferred, true);
             }
             list[i] = m;
         }
     }
 }
Esempio n. 14
0
		public static IReturnType CreateReturnType(AST.TypeReference reference, IClass callingClass,
		                                           IMethodOrProperty callingMember, int caretLine, int caretColumn,
		                                           IProjectContent projectContent)
		{
			System.Diagnostics.Debug.Assert(projectContent != null);
			if (reference == null) {
				return GetDefaultReturnType(projectContent);
			}
			if (reference is AST.ArrayTypeReference) {
				AST.ArrayTypeReference arr = (AST.ArrayTypeReference)reference;
				return new ArrayReturnType(projectContent,
				                           CreateReturnType(arr.ElementType, callingClass, callingMember,
				                                            caretLine, caretColumn, projectContent),
				                           (arr.Rank != null) ? (int)arr.Rank.Value : 1);
			} else if (reference is AST.SimpleTypeReference) {
				string name = ((AST.SimpleTypeReference)reference).Name;
				IReturnType rt;
				int typeParameterCount = (reference is AST.GenericTypeReference) ? ((AST.GenericTypeReference)reference).GenericArguments.Count : 0;
				if (name == "duck")
					rt = new BooResolver.DuckClass(new DefaultCompilationUnit(projectContent)).DefaultReturnType;
				else if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name))
					rt = new GetClassReturnType(projectContent, BooAmbience.ReverseTypeConversionTable[name], typeParameterCount);
				else if (callingClass == null)
					rt = new GetClassReturnType(projectContent, name, typeParameterCount);
				else
					rt = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn,
					                               name, typeParameterCount);
				if (typeParameterCount > 0) {
					AST.TypeReferenceCollection arguments = ((AST.GenericTypeReference)reference).GenericArguments;
					// GenericTypeReference derives from SimpleTypeReference
					IReturnType[] typeArguments = new IReturnType[arguments.Count];
					for (int i = 0; i < typeArguments.Length; i++) {
						typeArguments[i] = CreateReturnType(arguments[i], callingClass, callingMember, caretLine, caretColumn,
						                                    projectContent);
					}
					rt = new ConstructedReturnType(rt, typeArguments);
				}
				return rt;
			} else if (reference is AST.CallableTypeReference) {
				AST.CallableTypeReference ctr = (AST.CallableTypeReference)reference;
				AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(new DefaultCompilationUnit(projectContent));
				if (ctr.ReturnType != null) {
					amrt.MethodReturnType = CreateReturnType(ctr.ReturnType, callingClass, callingMember, caretLine, caretColumn, projectContent);
				}
				amrt.MethodParameters = new List<IParameter>();
				AddParameters(ctr.Parameters, amrt.MethodParameters, callingMember, callingClass ?? new DefaultClass(new DefaultCompilationUnit(projectContent), "__Dummy"));
				return amrt;
			} else {
				throw new NotSupportedException("unknown reference type: " + reference.ToString());
			}
		}
Esempio n. 15
0
		public void TypeParameterPassedToBaseClassTestGenericClassDerivingFromList()
		{
			DefaultClass listDerivingClass = CreateGenericClassDerivingFromList();
			
			ConstructedReturnType testType = new ConstructedReturnType(listDerivingClass.DefaultReturnType,
			                                                           new IReturnType[] { msc.SystemTypes.String });
			
			IReturnType res = MemberLookupHelper.GetTypeParameterPassedToBaseClass(testType,
			                                                                       EnumerableClass, 0);
			Assert.AreEqual("System.String", res.FullyQualifiedName);
		}
		/// <summary>
		/// Gets the common base type of a and b.
		/// </summary>
		public static IReturnType GetCommonType(IProjectContent projectContent, IReturnType a, IReturnType b)
		{
			if (projectContent == null)
				throw new ArgumentNullException("projectContent");
			if (a == null) return b;
			if (b == null) return a;
			if (ConversionExists(a, b))
				return b;
			if (ConversionExists(b, a))
				return a;
			IClass c = a.GetUnderlyingClass();
			if (c != null) {
				foreach (IClass baseClass in c.ClassInheritanceTree) {
					IReturnType baseType = baseClass.DefaultReturnType;
					if (baseClass.TypeParameters.Count > 0) {
						IReturnType[] typeArguments = new IReturnType[baseClass.TypeParameters.Count];
						for (int i = 0; i < typeArguments.Length; i++) {
							typeArguments[i] = GetTypeParameterPassedToBaseClass(a, baseClass, i);
						}
						baseType = new ConstructedReturnType(baseType, typeArguments);
					}
					if (ConversionExists(b, baseType))
						return baseType;
				}
			}
			return projectContent.SystemTypes.Object;
		}
Esempio n. 17
0
        /// <summary>
        /// Assigns a ranking score to each method in the <paramref name="list"/>.
        /// </summary>
        /// <param name="list">Link with the methods to check.<br/>
        /// <b>Generic methods in the input type are replaced by methods with have the types substituted!</b>
        /// </param>
        /// <param name="typeParameters">List with the type parameters passed to the method.
        /// Can be null (=no type parameters)</param>
        /// <param name="arguments">The types of the arguments passed to the method.
        /// A null return type means any argument type is allowed.</param>
        /// <param name="allowAdditionalArguments">Specifies whether the method can have
        /// more parameters than specified here. Useful for method insight scenarios.</param>
        /// <param name="acceptableMatch">Out parameter that is true when the best ranked
        /// method is acceptable for a method call (no invalid casts)</param>
        /// <returns>Integer array. Each value in the array </returns>
        public static int[] RankOverloads(IList <IMethod> list,
                                          IReturnType[] typeParameters,
                                          IReturnType[] arguments,
                                          bool allowAdditionalArguments,
                                          out bool acceptableMatch)
        {
            acceptableMatch = false;
            if (list.Count == 0)
            {
                return new int[] {}
            }
            ;

            List <IMethodOrProperty> l2 = new List <IMethodOrProperty>(list.Count);

            IReturnType[][] inferredTypeParameters;
            // See ECMA-334, § 14.3

            // If type parameters are specified, remove all methods from the list that do not
            // use the specified number of parameters.
            if (typeParameters != null && typeParameters.Length > 0)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    IMethod m = list[i];
                    if (m.TypeParameters.Count == typeParameters.Length)
                    {
                        m            = (IMethod)m.Clone();
                        m.ReturnType = ConstructedReturnType.TranslateType(m.ReturnType, typeParameters, true);
                        for (int j = 0; j < m.Parameters.Count; ++j)
                        {
                            m.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(m.Parameters[j].ReturnType, typeParameters, true);
                        }
                        list[i] = m;
                        l2.Add(m);
                    }
                }

                int[] innerRanking = RankOverloads(l2, arguments, allowAdditionalArguments, out acceptableMatch, out inferredTypeParameters);

                int[] ranking    = new int[list.Count];
                int   innerIndex = 0;
                for (int i = 0; i < ranking.Length; i++)
                {
                    if (list[i].TypeParameters.Count == typeParameters.Length)
                    {
                        ranking[i] = innerRanking[innerIndex++];
                    }
                    else
                    {
                        ranking[i] = 0;
                    }
                }
                return(ranking);
            }
            else
            {
                // Note that when there are no type parameters, methods having type parameters
                // are not removed, since the type inference process might be able to infer the
                // type arguments.
                foreach (IMethod m in list)
                {
                    l2.Add(m);
                }

                int[] ranking = RankOverloads(l2, arguments, allowAdditionalArguments, out acceptableMatch, out inferredTypeParameters);
                ApplyInferredTypeParameters(list, inferredTypeParameters);
                return(ranking);
            }
        }