Example #1
0
        bool ImplicitConversion(Type from, Type to)
        {
            IType from2 = from.ToTypeReference().Resolve(mscorlib);
            IType to2   = to.ToTypeReference().Resolve(mscorlib);

            return(conversions.ImplicitConversion(from2, to2));
        }
 bool IsConstraintConvertible(IType typeArg, IType constraintType)
 {
     // TODO: this isn't exactly correct; not all kinds of implicit conversions are allowed here
     return(conversions.ImplicitConversion(typeArg, constraintType));
 }
Example #3
0
        Conversion ImplicitConversion(Type from, Type to)
        {
            IType from2 = compilation.FindType(from);
            IType to2   = compilation.FindType(to);

            return(conversions.ImplicitConversion(from2, to2));
        }
Example #4
0
 public override Conversion IsValid(IType[] parameterTypes, IType returnType, Conversions conversions)
 {
     Assert.AreEqual(expectedParameterTypes, parameterTypes);
     return(conversions.ImplicitConversion(inferredReturnType, returnType));
 }
			public override Conversion IsValid(IType[] parameterTypes, IType returnType, Conversions conversions)
			{
				return conversions.ImplicitConversion(inferredReturnType, returnType);
			}
Example #6
0
 public override Conversion IsValid(IType[] parameterTypes, IType returnType, Conversions conversions)
 {
     return(conversions.ImplicitConversion(inferredReturnType, returnType));
 }
Example #7
0
        void CheckApplicability(Candidate candidate)
        {
            // C# 4.0 spec: §7.5.3.1 Applicable function member

            // Test whether parameters were mapped the correct number of arguments:
            int[] argumentCountPerParameter = new int[candidate.ParameterTypes.Length];
            foreach (int parameterIndex in candidate.ArgumentToParameterMap)
            {
                if (parameterIndex >= 0)
                {
                    argumentCountPerParameter[parameterIndex]++;
                }
            }
            for (int i = 0; i < argumentCountPerParameter.Length; i++)
            {
                if (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1)
                {
                    continue;                     // any number of arguments is fine for the params-array
                }
                if (argumentCountPerParameter[i] == 0)
                {
                    if (candidate.Parameters[i].IsOptional)
                    {
                        candidate.HasUnmappedOptionalParameters = true;
                    }
                    else
                    {
                        candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);
                    }
                }
                else if (argumentCountPerParameter[i] > 1)
                {
                    candidate.AddError(OverloadResolutionErrors.MultipleArgumentsForSingleParameter);
                }
            }

            candidate.ArgumentConversions = new Conversion[arguments.Length];
            // Test whether argument passing mode matches the parameter passing mode
            for (int i = 0; i < arguments.Length; i++)
            {
                int parameterIndex = candidate.ArgumentToParameterMap[i];
                if (parameterIndex < 0)
                {
                    continue;
                }

                ByReferenceResolveResult brrr = arguments[i] as ByReferenceResolveResult;
                if (brrr != null)
                {
                    if ((brrr.IsOut && !candidate.Parameters[parameterIndex].IsOut) || (brrr.IsRef && !candidate.Parameters[parameterIndex].IsRef))
                    {
                        candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
                    }
                }
                else
                {
                    if (candidate.Parameters[parameterIndex].IsOut || candidate.Parameters[parameterIndex].IsRef)
                    {
                        candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
                    }
                }
                IType      parameterType = candidate.ParameterTypes[parameterIndex];
                Conversion c             = conversions.ImplicitConversion(arguments[i], parameterType);
                candidate.ArgumentConversions[i] = c;
                if (IsExtensionMethodInvocation && parameterIndex == 0)
                {
                    // First parameter to extension method must be an identity, reference or boxing conversion
                    if (!(c == Conversion.IdentityConversion || c == Conversion.ImplicitReferenceConversion || c == Conversion.BoxingConversion))
                    {
                        candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
                    }
                }
                else
                {
                    if (!c.IsValid)
                    {
                        candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
                    }
                }
            }
        }
Example #8
0
        IList <IType> FindTypesInBounds(IList <IType> lowerBounds, IList <IType> upperBounds)
        {
            // If there's only a single type; return that single type.
            // If both inputs are empty, return the empty list.
            if (lowerBounds.Count == 0 && upperBounds.Count <= 1)
            {
                return(upperBounds);
            }
            if (upperBounds.Count == 0 && lowerBounds.Count <= 1)
            {
                return(lowerBounds);
            }
            if (nestingLevel > maxNestingLevel)
            {
                return(EmptyList <IType> .Instance);
            }

            // Finds a type X so that "LB <: X <: UB"
            Log("FindTypesInBound, LowerBounds=", lowerBounds);
            Log("FindTypesInBound, UpperBounds=", upperBounds);
            Debug.Indent();

            // First try the Fixing algorithm from the C# spec (§7.5.2.11)
            List <IType> candidateTypes = lowerBounds.Union(upperBounds)
                                          .Where(c => lowerBounds.All(b => conversions.ImplicitConversion(b, c)))
                                          .Where(c => upperBounds.All(b => conversions.ImplicitConversion(c, b)))
                                          .ToList(); // evaluate the query only once

            candidateTypes = candidateTypes.Where(
                c => candidateTypes.All(o => conversions.ImplicitConversion(c, o))
                ).ToList();
            // If the specified algorithm produces a single candidate, we return
            // that candidate.
            // We also return the whole candidate list if we're not using the improved
            // algorithm.
            if (candidateTypes.Count == 1 || !(algorithm == TypeInferenceAlgorithm.Improved || algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults))
            {
                return(candidateTypes);
            }
            candidateTypes.Clear();

            // Now try the improved algorithm
            List <ITypeDefinition> candidateTypeDefinitions;

            if (lowerBounds.Count > 0)
            {
                // Find candidates by using the lower bounds:
                var hashSet = new HashSet <ITypeDefinition>(lowerBounds[0].GetAllBaseTypeDefinitions(context));
                for (int i = 1; i < lowerBounds.Count; i++)
                {
                    hashSet.IntersectWith(lowerBounds[i].GetAllBaseTypeDefinitions(context));
                }
                candidateTypeDefinitions = hashSet.ToList();
            }
            else
            {
                // Find candidates by looking at all classes in the project:
                candidateTypeDefinitions = context.GetAllClasses().ToList();
            }

            // Now filter out candidates that violate the upper bounds:
            foreach (IType ub in upperBounds)
            {
                ITypeDefinition ubDef = ub.GetDefinition();
                if (ubDef != null)
                {
                    candidateTypeDefinitions.RemoveAll(c => !c.IsDerivedFrom(ubDef, context));
                }
            }

            foreach (ITypeDefinition candidateDef in candidateTypeDefinitions)
            {
                // determine the type parameters for the candidate:
                IType candidate;
                if (candidateDef.TypeParameterCount == 0)
                {
                    candidate = candidateDef;
                }
                else
                {
                    Log("Inferring arguments for candidate type definition: " + candidateDef);
                    bool    success;
                    IType[] result = InferTypeArgumentsFromBounds(
                        candidateDef.TypeParameters,
                        new ParameterizedType(candidateDef, candidateDef.TypeParameters.SafeCast <ITypeParameter, IType>()),
                        lowerBounds, upperBounds,
                        out success);
                    if (success)
                    {
                        candidate = new ParameterizedType(candidateDef, result);
                    }
                    else
                    {
                        Log("Inference failed; ignoring candidate");
                        continue;
                    }
                }
                Log("Candidate type: " + candidate);

                if (lowerBounds.Count > 0)
                {
                    // if there were lower bounds, we aim for the most specific candidate:

                    // if this candidate isn't made redundant by an existing, more specific candidate:
                    if (!candidateTypes.Any(c => c.GetDefinition().IsDerivedFrom(candidateDef, context)))
                    {
                        // remove all existing candidates made redundant by this candidate:
                        candidateTypes.RemoveAll(c => candidateDef.IsDerivedFrom(c.GetDefinition(), context));
                        // add new candidate
                        candidateTypes.Add(candidate);
                    }
                }
                else
                {
                    // if there only were upper bounds, we aim for the least specific candidate:

                    // if this candidate isn't made redundant by an existing, less specific candidate:
                    if (!candidateTypes.Any(c => candidateDef.IsDerivedFrom(c.GetDefinition(), context)))
                    {
                        // remove all existing candidates made redundant by this candidate:
                        candidateTypes.RemoveAll(c => c.GetDefinition().IsDerivedFrom(candidateDef, context));
                        // add new candidate
                        candidateTypes.Add(candidate);
                    }
                }
            }
            Debug.Unindent();
            return(candidateTypes);
        }
Example #9
0
			public override Conversion IsValid(IType[] parameterTypes, IType returnType, Conversions conversions)
			{
				Assert.AreEqual(expectedParameterTypes, parameterTypes);
				return conversions.ImplicitConversion(inferredReturnType, returnType);
			}
Example #10
0
		internal static bool IsEligibleExtensionMethod(ICompilation compilation, Conversions conversions, IType targetType, IMethod method, bool useTypeInference, out IType[] outInferredTypes)
		{
			outInferredTypes = null;
			if (targetType == null)
				return true;
			if (method.Parameters.Count == 0)
				return false;
			IType thisParameterType = method.Parameters[0].Type;
			if (useTypeInference && method.TypeParameters.Count > 0) {
				// We need to infer type arguments from targetType:
				TypeInference ti = new TypeInference(compilation, conversions);
				ResolveResult[] arguments = { new ResolveResult(targetType) };
				IType[] parameterTypes = { method.Parameters[0].Type };
				bool success;
				var inferredTypes = ti.InferTypeArguments(method.TypeParameters, arguments, parameterTypes, out success);
				var substitution = new TypeParameterSubstitution(null, inferredTypes);
				// Validate that the types that could be inferred (aren't unknown) satisfy the constraints:
				bool hasInferredTypes = false;
				for (int i = 0; i < inferredTypes.Length; i++) {
					if (inferredTypes[i].Kind != TypeKind.Unknown && inferredTypes[i].Kind != TypeKind.UnboundTypeArgument) {
						hasInferredTypes = true;
						if (!OverloadResolution.ValidateConstraints(method.TypeParameters[i], inferredTypes[i], substitution, conversions))
							return false;
					} else {
						inferredTypes[i] = method.TypeParameters[i]; // do not substitute types that could not be inferred
					}
				}
				if (hasInferredTypes)
					outInferredTypes = inferredTypes;
				thisParameterType = thisParameterType.AcceptVisitor(substitution);
			}
			Conversion c = conversions.ImplicitConversion(targetType, thisParameterType);
			return c.IsValid && (c.IsIdentityConversion || c.IsReferenceConversion || c.IsBoxingConversion);
		}