コード例 #1
0
        /// <summary>
        /// Tries to retrieve the name of the given type associated with this
        /// argument.  If no such name of that type exists, returns null.
        /// </summary>
        /// <param name="nameType">The type of name to retrieve.</param>
        /// <returns>The given name, or null if no such name exists.</returns>
        public string GetName(ArgumentNameType nameType)
        {
            switch (nameType)
            {
            case ArgumentNameType.ShortName:
                return(ShortName);

            case ArgumentNameType.LongName:
                return(LongName);

            default:
                throw new ArgumentOutOfRangeException(nameof(nameType));
            }
        }
コード例 #2
0
        private IEnumerable <string> GetNamedArgumentCompletions(ArgumentNameType nameType, IReadOnlyList <string> tokens, int indexOfTokenToComplete, string namedArgumentAfterPrefix, object inProgressParsedObject)
        {
            Func <IEnumerable <string> > emptyCompletions = Enumerable.Empty <string>;

            var separatorIndex = namedArgumentAfterPrefix.IndexOfAny(ArgumentTerminatorsAndSeparators.ToArray());

            if (separatorIndex < 0)
            {
                return(ArgumentSet.NamedArguments
                       .Select(namedArg => namedArg.GetName(nameType))
                       .Where(argName => argName != null)
                       .OrderBy(argName => argName, StringComparerToUse)
                       .Where(candidateName => candidateName.StartsWith(namedArgumentAfterPrefix, StringComparisonToUse)));
            }

            var separator = namedArgumentAfterPrefix[separatorIndex];

            if (!ArgumentSet.Attribute.ArgumentValueSeparators.Contains(separator))
            {
                return(emptyCompletions());
            }

            var name  = namedArgumentAfterPrefix.Substring(0, separatorIndex);
            var value = namedArgumentAfterPrefix.Substring(separatorIndex + 1);

            if (!ArgumentSet.TryGetNamedArgument(nameType, name, out ArgumentDefinition arg))
            {
                return(emptyCompletions());
            }

            var parseState = new ArgumentParser(ArgumentSet, arg, _options, /*destination=*/ null);

            return(parseState
                   .GetCompletions(tokens, indexOfTokenToComplete, value, inProgressParsedObject)
                   .Select(completion => string.Concat(name, separator.ToString(), completion)));
        }
コード例 #3
0
        private IReadOnlyDictionary <string, ArgumentDefinition> GetNamedArgumentDictionary(ArgumentNameType nameType)
        {
            switch (nameType)
            {
            case ArgumentNameType.ShortName:
                return(_namedArgumentsByShortName);

            case ArgumentNameType.LongName:
                return(_namedArgumentsByLongName);

            default:
                throw new ArgumentOutOfRangeException(nameof(nameType));
            }
        }
コード例 #4
0
        /// <summary>
        /// Try to look up a named argument by short or long name.
        /// </summary>
        /// <param name="nameType">Type of name to look up.</param>
        /// <param name="name">Name to look up.</param>
        /// <param name="arg">On success, receives the named argument.</param>
        /// <returns>True on success; false otherwise.</returns>
        public bool TryGetNamedArgument(ArgumentNameType nameType, string name, out ArgumentDefinition arg)
        {
            var dict = GetNamedArgumentDictionary(nameType);

            return(dict.TryGetValue(name, out arg));
        }
コード例 #5
0
        /// <summary>
        /// Enumerates named arguments of the given type.
        /// </summary>
        /// <param name="nameType">Type of name to look up.</param>
        /// <returns>Enumeration.</returns>
        public IEnumerable <string> GetArgumentNames(ArgumentNameType nameType)
        {
            var dict = GetNamedArgumentDictionary(nameType);

            return(dict.Keys);
        }
コード例 #6
0
        private ArgumentSetParseResult TryParseNamedArgument(
            string argument,
            string argumentPrefix,
            ArgumentNameType namedArgType,
            out IReadOnlyList <ArgumentAndValue> parsedArgs)
        {
            var prefixLength = argumentPrefix.Length;

            Debug.Assert(argument.Length >= prefixLength);

            // Figure out where the argument name ends.
            var endIndex = argument.IndexOfAny(ArgumentSet.Attribute.ArgumentValueSeparators, prefixLength);

            // Special case: check for '+' and '-' for booleans.
            if (endIndex < 0 && argument.Length > argumentPrefix.Length)
            {
                var lastArgumentChar = argument[argument.Length - 1];
                if (ArgumentNameTerminators.Any(t => lastArgumentChar.Equals(t)))
                {
                    endIndex = argument.Length - 1;
                }
            }

            // If we don't have a separator or terminator, then consume the full string.
            if (endIndex < 0)
            {
                endIndex = argument.Length;
            }

            // Extract the argument name(s), separate from the prefix
            // or optional argument value.
            var options = argument.Substring(prefixLength, endIndex - prefixLength);

            // Extract the option argument (a.k.a. value), if there is one.
            string optionArgument = null;

            if (argument.Length > prefixLength + options.Length)
            {
                // If there's an argument value separator, then extract the value after the separator.
                if (ArgumentSet.Attribute.ArgumentValueSeparators.Any(sep => argument[prefixLength + options.Length] == sep))
                {
                    optionArgument = argument.Substring(prefixLength + options.Length + 1);
                }

                // Otherwise, it might be a terminator; extract the rest of the string.
                else
                {
                    optionArgument = argument.Substring(prefixLength + options.Length);
                }
            }

            // Now try to figure out how many names are present.
            if (namedArgType == ArgumentNameType.ShortName &&
                (ArgumentSet.Attribute.AllowMultipleShortNamesInOneToken || ArgumentSet.Attribute.AllowElidingSeparatorAfterShortName))
            {
                Debug.Assert(ArgumentSet.Attribute.ShortNamesAreOneCharacterLong);

                // Since short names are one character long, we parse them one at a
                // time, preparing for multiple arguments in this one token.
                var args = new List <ArgumentAndValue>();
                for (var index = 0; index < options.Length; ++index)
                {
                    // Try parsing it as a short name; bail immediately if we find an invalid
                    // one.
                    var possibleShortName = new string(options[index], 1);
                    if (!ArgumentSet.TryGetNamedArgument(ArgumentNameType.ShortName, possibleShortName, out ArgumentDefinition arg))
                    {
                        parsedArgs = null;
                        return(ArgumentSetParseResult.UnknownNamedArgument(namedArgType, possibleShortName));
                    }

                    // If this parsed as a short name that takes a required option argument,
                    // and we didn't see an option argument, and we allow mushing together
                    // short names and their option arguments, then try parsing the rest of
                    // this token as an option argument.
                    var lastChar = index == options.Length - 1;
                    if (arg.RequiresOptionArgumentEx(_options) &&
                        ArgumentSet.Attribute.AllowElidingSeparatorAfterShortName &&
                        optionArgument == null &&
                        !lastChar)
                    {
                        optionArgument = options.Substring(index + 1);
                        index          = options.Length - 1;
                        lastChar       = true;
                    }

                    if (!ArgumentSet.Attribute.AllowMultipleShortNamesInOneToken &&
                        args.Count > 0)
                    {
                        parsedArgs = null;
                        return(ArgumentSetParseResult.UnknownNamedArgument());
                    }

                    args.Add(new ArgumentAndValue
                    {
                        Arg   = arg,
                        Value = lastChar ? optionArgument : null
                    });
                }

                // Special case: if no arguments were found, return an error.
                if (args.Count == 0)
                {
                    parsedArgs = null;
                    return(ArgumentSetParseResult.FailedParsing);
                }

                parsedArgs = args;
            }
            else
            {
                // Try to look up the argument by name.
                if (!ArgumentSet.TryGetNamedArgument(namedArgType, options, out ArgumentDefinition arg))
                {
                    parsedArgs = null;
                    return(ArgumentSetParseResult.UnknownNamedArgument(namedArgType, options));
                }

                parsedArgs = new[]
                {
                    new ArgumentAndValue
                    {
                        Arg   = arg,
                        Value = optionArgument
                    }
                };
            }

            var lastArg = parsedArgs.GetLastOrDefault();
            var lastArgTakesRestOfLine = lastArg?.Arg.TakesRestOfLine ?? false;

            // If the last named argument we saw in this token required an
            // option argument to go with it, then yield that information
            // so it can be used by the caller (e.g. in completion generation).
            if (lastArg != null &&
                lastArg.Arg.RequiresOptionArgumentEx(_options) &&
                string.IsNullOrEmpty(lastArg.Value))
            {
                return(ArgumentSetParseResult.RequiresOptionArgument(lastArg.Arg));
            }

            return(ArgumentSetParseResult.Ready(lastArg?.Arg));
        }