Пример #1
0
        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));
        }
Пример #2
0
 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));
 }
Пример #3
0
 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));
 }
Пример #4
0
        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);
        }