コード例 #1
0
        public bool HasParameterErrors => _parameterErrors.Any(p => p != null);                 // Are there any parameter errors?

        public OverloadMatch(IOverload option, InstanceAnonymousTypeLinker typeArgLinker, ParseInfo parseInfo, DocRange inferenceErrorRange)
        {
            Option               = option;
            _parseInfo           = parseInfo;
            _inferenceErrorRange = inferenceErrorRange;
            _parameterErrors     = new OverloadMatchError[option.Parameters.Length];

            if (typeArgLinker != null)
            {
                TypeArgLinker = typeArgLinker;
                TypeArgs      = typeArgLinker.TypeArgsFromAnonymousTypes(option.GenericTypes);
            }
            else
            {
                TypeArgLinker = new InstanceAnonymousTypeLinker();
                TypeArgs      = new CodeType[option.TypeArgCount];
            }
        }
コード例 #2
0
        private OverloadMatch MatchOverload(IOverload option, PickyParameter[] inputParameters, List <ParameterValue> context)
        {
            PickyParameter lastPicky = null;

            // If the generics were provided ('_genericsProvided'), get the type linker from the option.
            OverloadMatch match = new OverloadMatch(option, _genericsProvided ? option.GetTypeLinker(_generics) : null, _parseInfo, _targetRange);

            match.OrderedParameters = new PickyParameter[option.Parameters.Length];

            // Check type arg count.
            if (_genericsProvided && _generics.Length != option.TypeArgCount)
            {
                match.IncorrectTypeArgCount(_parseInfo.TranslateInfo, _targetRange);
            }

            // Iterate through the option's parameters.
            for (int i = 0; i < inputParameters.Length; i++)
            {
                // Out of range
                if (i >= option.Parameters.Length)
                {
                    if (i == option.Parameters.Length)
                    {
                        match.Error(string.Format(_errorMessages.BadParameterCount, inputParameters.Length), _targetRange);
                    }
                    continue;
                }
                // Non-picky
                else if (inputParameters[i].ParameterOrdered(option.Parameters[i]))
                {
                    // If the picky parameters end but there is an additional picky parameter, throw a syntax error.
                    if (lastPicky != null && inputParameters[i].Name == null)
                    {
                        match.Error($"Named argument '{lastPicky.Name}' is used out-of-position but is followed by an unnamed argument", lastPicky.NameRange);
                    }
                    else
                    {
                        match.OrderedParameters[i] = inputParameters[i];

                        // If _genericsFilled is false, get context-inferred type arguments.
                        if (!_genericsProvided)
                        {
                            ExtractInferredGenerics(match, option.Parameters[i].GetCodeType(_parseInfo.TranslateInfo), inputParameters[i].Value.Type());
                        }

                        // Next contextual parameter
                        if (i == inputParameters.Length - 1 && i < option.Parameters.Length - 1)
                        {
                            match.LastContextualParameterIndex = i + 1;
                        }
                    }
                }
                else // Picky
                {
                    // Picky parameter ends.
                    lastPicky = inputParameters[i];

                    // Set relevant picky parameter.
                    bool nameFound = false;
                    for (int p = 0; p < option.Parameters.Length && !nameFound; p++)
                    {
                        if (inputParameters[i].Name == option.Parameters[p].Name)
                        {
                            // A matching parameter was found.
                            match.OrderedParameters[p] = inputParameters[i];
                            nameFound = true;

                            // If _genericsFilled is false, get context-inferred type arguments.
                            if (!_genericsProvided)
                            {
                                ExtractInferredGenerics(match, option.Parameters[p].GetCodeType(_parseInfo.TranslateInfo), inputParameters[i].Value.Type());
                            }
                        }
                    }

                    // If the named argument's name is not found, throw an error.
                    if (!nameFound)
                    {
                        match.Error($"Named argument '{lastPicky.Name}' does not exist in the function '{option.GetLabel(_parseInfo.TranslateInfo, LabelInfo.OverloadError)}'.", inputParameters[i].NameRange);
                    }
                }
            }

            // Compare parameter types.
            match.UpdateAllParameters();

            // Make sure every type arg was accounted for.
            if (!_genericsProvided && !match.TypeArgLinkerCompleted)
            {
                match.InferSuccessful = false;
            }

            // Get the missing parameters.
            match.GetMissingParameters(_errorMessages, context, _targetRange, CallRange);

            return(match);
        }