/// <summary> /// Adds a candidate to overload resolution. /// </summary> /// <param name="member">The candidate member to add.</param> /// <param name="additionalErrors">Additional errors that apply to the candidate. /// This is used to represent errors during member lookup (e.g. OverloadResolutionErrors.Inaccessible) /// in overload resolution.</param> /// <returns>The errors that prevent the member from being applicable, if any. /// Note: this method does not return errors that do not affect applicability.</returns> public OverloadResolutionErrors AddCandidate(IParameterizedMember member, OverloadResolutionErrors additionalErrors) { if (member == null) { throw new ArgumentNullException("member"); } Candidate c = new Candidate(member, false); c.AddError(additionalErrors); if (CalculateCandidate(c)) { //candidates.Add(c); } if (this.AllowExpandingParams && member.Parameters.Count > 0 && member.Parameters[member.Parameters.Count - 1].IsParams) { Candidate expandedCandidate = new Candidate(member, true); expandedCandidate.AddError(additionalErrors); // consider expanded form only if it isn't obviously wrong if (CalculateCandidate(expandedCandidate)) { //candidates.Add(expandedCandidate); if (expandedCandidate.ErrorCount < c.ErrorCount) { return(expandedCandidate.Errors); } } } return(c.Errors); }
/// <summary> /// Returns whether a candidate with the given errors is still considered to be applicable. /// </summary> public static bool IsApplicable(OverloadResolutionErrors errors) { const OverloadResolutionErrors errorsThatDoNotMatterForApplicability = OverloadResolutionErrors.AmbiguousMatch | OverloadResolutionErrors.MethodConstraintsNotSatisfied; return((errors & ~errorsThatDoNotMatterForApplicability) == OverloadResolutionErrors.None); }
public void AddError(OverloadResolutionErrors newError) { this.Errors |= newError; if (!IsApplicable(newError)) { this.ErrorCount++; } }
internal void LogCandidateAddingResult(string text, IParameterizedMember method, OverloadResolutionErrors errors) { #if DEBUG Log.WriteLine(string.Format("{0} {1} = {2}{3}", text, method, errors == OverloadResolutionErrors.None ? "Success" : errors.ToString(), this.BestCandidate == method ? " (best candidate so far)" : this.BestCandidateAmbiguousWith == method ? " (ambiguous)" : "" )); #endif }
/// <summary> /// Adds all candidates from the method lists. /// /// This method implements the logic that causes applicable methods in derived types to hide /// all methods in base types. /// </summary> /// <param name="methodLists">The methods, grouped by declaring type. Base types must come first in the list.</param> public void AddMethodLists(IList <MethodListWithDeclaringType> methodLists) { if (methodLists == null) { throw new ArgumentNullException("methodLists"); } // Base types come first, so go through the list backwards (derived types first) bool[] isHiddenByDerivedType; if (methodLists.Count > 1) { isHiddenByDerivedType = new bool[methodLists.Count]; } else { isHiddenByDerivedType = null; } for (int i = methodLists.Count - 1; i >= 0; i--) { if (isHiddenByDerivedType != null && isHiddenByDerivedType[i]) { Log.WriteLine(" Skipping methods in {0} because they are hidden by an applicable method in a derived type", methodLists[i].DeclaringType); continue; } MethodListWithDeclaringType methodList = methodLists[i]; bool foundApplicableCandidateInCurrentList = false; for (int j = 0; j < methodList.Count; j++) { IParameterizedMember method = methodList[j]; Log.Indent(); OverloadResolutionErrors errors = AddCandidate(method); Log.Unindent(); LogCandidateAddingResult(" Candidate", method, errors); foundApplicableCandidateInCurrentList |= IsApplicable(errors); } if (foundApplicableCandidateInCurrentList && i > 0) { foreach (IType baseType in methodList.DeclaringType.GetAllBaseTypes()) { for (int j = 0; j < i; j++) { if (!isHiddenByDerivedType[j] && baseType.Equals(methodLists[j].DeclaringType)) { isHiddenByDerivedType[j] = true; } } } } } }
public InvocationResolveResult(ResolveResult targetResult, OverloadResolution or, ITypeResolveContext context) : base( or.IsExtensionMethodInvocation ? null : targetResult, or.GetBestCandidateWithSubstitutedTypeArguments(), context) { this.OverloadResolutionErrors = or.BestCandidateErrors; this.argumentToParameterMap = or.GetArgumentToParameterMap(); this.Arguments = or.GetArgumentsWithConversions(); this.IsExtensionMethodInvocation = or.IsExtensionMethodInvocation; this.IsExpandedForm = or.BestCandidateIsExpandedForm; this.IsLiftedOperatorInvocation = or.BestCandidate is OverloadResolution.ILiftedOperator; }
public CSharpInvocationResolveResult( ResolveResult targetResult, IParameterizedMember member, IList<ResolveResult> arguments, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isDelegateInvocation = false, IList<int> argumentToParameterMap = null) : base(targetResult, member, arguments) { this.OverloadResolutionErrors = overloadResolutionErrors; this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExpandedForm = isExpandedForm; this.IsDelegateInvocation = isDelegateInvocation; this.argumentToParameterMap = argumentToParameterMap; }
public CppInvocationResolveResult( ResolveResult targetResult, IParameterizedMember member, IList <ResolveResult> arguments, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isDelegateInvocation = false, IList <int> argumentToParameterMap = null) : base(targetResult, member, arguments) { this.OverloadResolutionErrors = overloadResolutionErrors; this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExpandedForm = isExpandedForm; this.IsDelegateInvocation = isDelegateInvocation; this.argumentToParameterMap = argumentToParameterMap; }
public InvocationResolveResult( ResolveResult targetResult, IParameterizedMember member, IType returnType, IList <ResolveResult> arguments, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isLiftedOperatorInvocation = false, bool isDelegateInvocation = false, IList <int> argumentToParameterMap = null) : base(targetResult, member, returnType) { this.OverloadResolutionErrors = overloadResolutionErrors; this.Arguments = arguments ?? EmptyList <ResolveResult> .Instance; this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExpandedForm = isExpandedForm; this.IsLiftedOperatorInvocation = isLiftedOperatorInvocation; this.IsDelegateInvocation = isDelegateInvocation; this.argumentToParameterMap = argumentToParameterMap; }
public CSharpInvocationResolveResult( ResolveResult targetResult, IParameterizedMember member, IList <ResolveResult> arguments, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isDelegateInvocation = false, IReadOnlyList <int> argumentToParameterMap = null, IList <ResolveResult> initializerStatements = null, IType returnTypeOverride = null ) : base(targetResult, member, arguments, initializerStatements, returnTypeOverride) { this.OverloadResolutionErrors = overloadResolutionErrors; this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExpandedForm = isExpandedForm; this.IsDelegateInvocation = isDelegateInvocation; this.argumentToParameterMap = argumentToParameterMap; }
public InvocationResolveResult( ResolveResult targetResult, IParameterizedMember member, IType returnType, IList<ResolveResult> arguments, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isLiftedOperatorInvocation = false, bool isDelegateInvocation = false, IList<int> argumentToParameterMap = null) : base(targetResult, member, returnType) { this.OverloadResolutionErrors = overloadResolutionErrors; this.Arguments = arguments ?? EmptyList<ResolveResult>.Instance; this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExpandedForm = isExpandedForm; this.IsLiftedOperatorInvocation = isLiftedOperatorInvocation; this.IsDelegateInvocation = isDelegateInvocation; this.argumentToParameterMap = argumentToParameterMap; }
public CSharpInvocationResolveResult( ResolveResult targetResult, IParameterizedMember member, IList<ResolveResult> arguments, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isDelegateInvocation = false, IList<int> argumentToParameterMap = null, IList<ResolveResult> initializerStatements = null, IType returnTypeOverride = null, bool isConditionallyRemoved = false ) : base(targetResult, member, arguments, initializerStatements, returnTypeOverride, isConditionallyRemoved) { this.OverloadResolutionErrors = overloadResolutionErrors; this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExpandedForm = isExpandedForm; this.IsDelegateInvocation = isDelegateInvocation; this.argumentToParameterMap = argumentToParameterMap; }
public Invocation(Expression targetResult, IParameterizedMember member, IList <Expression> arguments, OverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None, bool isExtensionMethodInvocation = false, bool isExpandedForm = false, bool isDelegateInvocation = false, IList <int> argumentToParameterMap = null, IList <Expression> initializerStatements = null, IType returnTypeOverride = null) { this.ResolvedType = returnTypeOverride ?? MemberExpressionStatement.ComputeType(member); _resolved = true; this.targetResult = targetResult; this.member = member; this.RArguments = arguments ?? EmptyList <AST.Expression> .Instance; this.InitializerStatements = initializerStatements ?? EmptyList <AST.Expression> .Instance; this.OverloadResolutionErrors = overloadResolutionErrors; this.IsExtensionMethodInvocation = isExtensionMethodInvocation; this.IsExpandedForm = isExpandedForm; this.IsDelegateInvocation = isDelegateInvocation; this.argumentToParameterMap = argumentToParameterMap; eclass = ExprClass.Value; }
internal void LogCandidateAddingResult(string text, IParameterizedMember method, OverloadResolutionErrors errors) { #if DEBUG StringBuilder b = new StringBuilder(text); b.Append(' '); b.Append(method); b.Append(" = "); if (errors == OverloadResolutionErrors.None) { b.Append("Success"); } else { b.Append(errors); } if (this.BestCandidate == method) { b.Append(" (best candidate so far)"); } else if (this.BestCandidateAmbiguousWith == method) { b.Append(" (ambiguous)"); } Log.WriteLine(b.ToString()); #endif }
/// <summary> /// Returns whether a candidate with the given errors is still considered to be applicable. /// </summary> public static bool IsApplicable(OverloadResolutionErrors errors) { const OverloadResolutionErrors errorsThatDoNotMatterForApplicability = OverloadResolutionErrors.AmbiguousMatch | OverloadResolutionErrors.MethodConstraintsNotSatisfied; return (errors & ~errorsThatDoNotMatterForApplicability) == OverloadResolutionErrors.None; }
public OverloadResolution PerformOverloadResolution(ITypeResolveContext context, ResolveResult[] arguments, string[] argumentNames = null, bool allowExtensionMethods = true, bool allowExpandingParams = true, Conversions conversions = null) { Log.WriteLine("Performing overload resolution for " + this); Log.WriteCollection(" Arguments: ", arguments); var typeArgumentArray = this.TypeArguments.ToArray(); OverloadResolution or = new OverloadResolution(context, arguments, argumentNames, typeArgumentArray, conversions); or.AllowExpandingParams = allowExpandingParams; or.AddMethodLists(methodLists); if (allowExtensionMethods && !or.FoundApplicableCandidate) { // No applicable match found, so let's try extension methods. var extensionMethods = this.GetExtensionMethods(); if (extensionMethods.Count > 0) { Log.WriteLine("No candidate is applicable, trying {0} extension methods groups...", extensionMethods.Count); ResolveResult[] extArguments = new ResolveResult[arguments.Length + 1]; extArguments[0] = new ResolveResult(this.TargetType); arguments.CopyTo(extArguments, 1); string[] extArgumentNames = null; if (argumentNames != null) { extArgumentNames = new string[argumentNames.Length + 1]; argumentNames.CopyTo(extArgumentNames, 1); } var extOr = new OverloadResolution(context, extArguments, extArgumentNames, typeArgumentArray, conversions); extOr.AllowExpandingParams = allowExpandingParams; extOr.IsExtensionMethodInvocation = true; foreach (var g in extensionMethods) { foreach (var method in g) { Log.Indent(); OverloadResolutionErrors errors = extOr.AddCandidate(method); Log.Unindent(); or.LogCandidateAddingResult(" Extension", method, errors); } if (extOr.FoundApplicableCandidate) { break; } } // For the lack of a better comparison function (the one within OverloadResolution // cannot be used as it depends on the argument set): if (extOr.FoundApplicableCandidate || or.BestCandidate == null) { // Consider an extension method result better than the normal result only // if it's applicable; or if there is no normal result. or = extOr; } } } Log.WriteLine("Overload resolution finished, best candidate is {0}.", or.GetBestCandidateWithSubstitutedTypeArguments()); return(or); }
public OverloadResolutionErrors AddCandidate(IParameterizedMember member, OverloadResolutionErrors additionalErrors) { if (member == null) throw new ArgumentNullException("member"); Candidate c = new Candidate(member, false); if (additionalErrors != OverloadResolutionErrors.None) c.AddError(additionalErrors); if (CalculateCandidate(c)) { //candidates.Add(c); } if (this.AllowExpandingParams && member.Parameters.Count > 0 && member.Parameters[member.Parameters.Count - 1].IsParams) { Candidate expandedCandidate = new Candidate(member, true); if (additionalErrors != OverloadResolutionErrors.None) expandedCandidate.AddError(additionalErrors); // consider expanded form only if it isn't obviously wrong if (CalculateCandidate(expandedCandidate)) { //candidates.Add(expandedCandidate); if (expandedCandidate.ErrorCount < c.ErrorCount) return expandedCandidate.Errors; } } return c.Errors; }
public static bool IsApplicable(OverloadResolutionErrors errors) { return (errors & ~OverloadResolutionErrors.AmbiguousMatch) == OverloadResolutionErrors.None; }
public void AddError(OverloadResolutionErrors newError) { this.Errors |= newError; this.ErrorCount++; }
public void AddError(OverloadResolutionErrors newError) { this.Errors |= newError; if (!IsApplicable(newError)) this.ErrorCount++; }
/// <summary> /// Returns whether a candidate with the given errors is still considered to be applicable. /// </summary> public static bool IsApplicable(OverloadResolutionErrors errors) { const OverloadResolutionErrors errorsThatDoNotMatterForApplicability = OverloadResolutionErrors.AmbiguousMatch; return (errors & ~errorsThatDoNotMatterForApplicability) == OverloadResolutionErrors.None; }
internal void LogCandidateAddingResult(string text, IParameterizedMember method, OverloadResolutionErrors errors) { #if DEBUG StringBuilder b = new StringBuilder(text); b.Append(' '); b.Append(method); b.Append(" = "); if (errors == OverloadResolutionErrors.None) b.Append("Success"); else b.Append(errors); if (this.BestCandidate == method) { b.Append(" (best candidate so far)"); } else if (this.BestCandidateAmbiguousWith == method) { b.Append(" (ambiguous)"); } Log.WriteLine(b.ToString()); #endif }
public static bool IsApplicable(OverloadResolutionErrors errors) { return((errors & ~OverloadResolutionErrors.AmbiguousMatch) == OverloadResolutionErrors.None); }
public void ReportOverloadErrors(OverloadResolutionErrors errors, Location l) { //if ((errors & OverloadResolutionErrors.WrongNumberOfTypeArguments) != 0) // rc.Report.Error(0,l, "The method {0} has wrong number of type arguments, {1} type arguments expected.", bc.); }