private FunctionCallInfo CheckConstraintsAndReturn(OverloadCompatibility compatibility, CallLocation location) { if (RespectsAllConstraints(compatibility.Substitutions)) { return(new FunctionCallInfo(AfterSubstitution(compatibility), compatibility.Substitutions)); } errors.Add(new CallArgumentsViolateParametersConstraints(location.File, location.Line, location.CallString)); return(new FunctionCallInfo(new ErrorSignature(new UndefinedType()), ImmutableHashSet <Substitution> .Empty)); }
private FunctionCallInfo CouldNotFindMatchingOverload(CallLocation location) { errors.Add(new NoMatchingOverloadForCall(location.File, location.Line, location.CallString)); return(new FunctionCallInfo(new ErrorSignature(new UndefinedType()), ImmutableHashSet <Substitution> .Empty)); }
private FunctionCallInfo AmbiguousFunctionCall(CallLocation location) { errors.Add(new CouldNotResolveAmbiguousFunctionCall(location.File, location.Line, location.CallString)); return(new FunctionCallInfo(new ErrorSignature(new UndefinedType()), ImmutableHashSet <Substitution> .Empty)); }
private FunctionCallInfo BindFunctionCallCore(IReadOnlyList <Callable> overloads, IReadOnlyList <IType> argumentsTypes, IReadOnlyList <IType> explicitTypeArguments, bool isPoly, CallLocation location) { //check for use of undefined function/overload if (overloads.None()) { errors.Add(new UseOfUndeclaredFunction(location.File, location.Line, location.CallString)); return(new FunctionCallInfo(new ErrorSignature(new UndefinedType()), ImmutableHashSet <Substitution> .Empty)); } //check for calls that use undefined arguments if (argumentsTypes.Any(x => x is UndefinedType) || explicitTypeArguments.Any(x => x is UndefinedType)) { return(new FunctionCallInfo(new ErrorSignature(new UndefinedType()), ImmutableHashSet <Substitution> .Empty)); } if (isPoly) { var overloadsInfo = getCompatibility(true); var possibleAtRuntime = overloadsInfo.Where(x => x.IsCompatible()).Select(x => new FunctionCallInfo(AfterSubstitution(x), x.Substitutions)).ToList(); if (possibleAtRuntime.One()) { return(possibleAtRuntime.First()); } if (possibleAtRuntime.None()) { return(CouldNotFindMatchingOverload(location)); } return(getDispatcherOrErrorSignature()); FunctionCallInfo getDispatcherOrErrorSignature() { return(possibleAtRuntime.AllHaveSame(x => x.Callable.ReturnType) ? new FunctionCallInfo(new Dispatcher(possibleAtRuntime.ToImmutableArray()), ImmutableHashSet <Substitution> .Empty) : new FunctionCallInfo(new ErrorSignature(new UndefinedType()), ImmutableHashSet <Substitution> .Empty)); } } else { var overloadsInfo = getCompatibility(false); var compatibleOverloads = overloadsInfo.Where(x => x.IsCompatible()).ToList(); if (compatibleOverloads.One()) { return(checkConstraintsAndReturn(compatibleOverloads.First())); } if (compatibleOverloads.None()) { return(CouldNotFindMatchingOverload(location)); } return(resolve()); FunctionCallInfo resolve() { var perfectMatches = compatibleOverloads.Where(IsPerfectCompatibility).ToImmutableArray(); return(perfectMatches.One() ? checkConstraintsAndReturn(perfectMatches.First()) : AmbiguousFunctionCall(location)); } } FunctionCallInfo checkConstraintsAndReturn(OverloadCompatibility x) => CheckConstraintsAndReturn(x, location); IEnumerable <OverloadCompatibility> getCompatibility(bool poly) => GetOverloadsCompatibilityInfo(explicitTypeArguments: explicitTypeArguments, argumentsTypes: argumentsTypes, overloads: overloads, isPoly: poly); }