示例#1
0
        /// <summary>
        ///     Parses the given set of tokens based on the rules specified by the <see cref="Command"/>.
        /// </summary>
        /// <param name="tokens">Token strings to parse.</param>
        /// <returns>A <see cref="ParseResult" /> instance.</returns>
        public ParseResult Parse(IEnumerable <string> tokens)
        {
            DebugOutput.Write("Tokens passed", tokens);

            IReadOnlyList <string> tokenList = tokens.ToList();

            // Creates a ParseRun instance, which specifies the sequence of commands specified and
            // the tokens and any options and arguments that apply to the specified commands.
            ParseRun run = CreateRun(tokenList);

            // Extract out just the option and argument objects from their respective run collections.
            // We want to pass these to parser style methods that only need to deal with the Option
            // and Argument objects and not have to deal with the 'run' aspects. See some of the calls
            // to protected methods from this method.
            IReadOnlyList <Option>   justOptions   = run.Options.Select(o => o.Option).ToList();
            IReadOnlyList <Argument> justArguments = run.Arguments.Select(a => a.Argument).ToList();

            // Even though the caller can define the grouping, the parser style can override it based
            // on the available options and arguments. See the UnixArgStyle class for an example.
            Grouping = ArgStyle.GetGrouping(Grouping, justOptions, justArguments);

            // Validate all the available options based on the parser style rules.
            // See the UnixArgStyle for an example.
            ArgStyle.ValidateDefinedOptions(justOptions);

            // Identify all tokens as options or arguments. Identified option details are stored in
            // the Option instance itself. Identified arguments are returned from the method.
            List <string> specifiedArguments =
                ArgStyle.IdentifyTokens(run.Tokens, run.Options, Grouping).ToList();

            // Get the groups that match the specified options and arguments.
            IReadOnlyList <int> matchingGroups = GetMatchingGroups(run, specifiedArguments);

            // If no groups match, we cannot proceed, so throw a parser exception.
            if (matchingGroups.Count == 0)
            {
                throw new ParserException(-1, "The specified arguments and options are invalid.");
            }

            // Trim the argument and option runs to those that contain the matcing groups.
            TrimRunsToMatchingGroups(run, matchingGroups);

            //TODO: Come back to this later
            //if (ConfigReader != null)
            //    specifiedArguments = ConfigReader.Run(specifiedArguments, Options);

            // Process the specified options and arguments, and resolve their values.
            ProcessOptions(run.Options);
            ProcessArguments(specifiedArguments, run.Arguments);

            var parseResult = new ParseResult(run);

            // Runs the custom validator, if it is assigned.
            CommandCustomValidator customCommandValidator = parseResult.Command.CustomValidator;
            string validationError = customCommandValidator?.Invoke(parseResult.Arguments, parseResult.Options);

            if (validationError != null)
            {
                throw new ValidationException(validationError, null, null);
            }

            return(parseResult);
        }
示例#2
0
        /// <inheritdoc/>
        public MethodBuilder Define()
        {
            if (this.methodBuilder != null)
            {
                return(this.methodBuilder);
            }

            int parmCount = this.parms.Count;

            Type[] parameterTypes = new Type[parmCount];
            for (int i = 0; i < parmCount; i++)
            {
                parameterTypes[i] = this.parms[i].ParameterType;
            }

            this.methodBuilder = this.defineMethod(
                this.methodName,
                this.Attributes,
                this.callingConvention,
                this.returnType,
                null,
                null,
                parameterTypes,
                null,
                null);

            if (this.genericParameterBuilders != null)
            {
                this.genericParameters = this.methodBuilder.DefineGenericParameters(
                    this.genericParameterBuilders.Select(g => g.ParameterName).ToArray());

                for (int i = 0; i < this.genericParameterBuilders.Count; i++)
                {
                    this.genericParameterBuilders[i].Build(this.genericParameters[i]);
                }
            }

            int parmIndex = 0;

            foreach (var parm in this.parms)
            {
                var paramBuilder = this.methodBuilder
                                   .DefineParameter(++parmIndex, parm.Attributes, parm.ParameterName);

                parm.CustomAttributes.SetCustomAttributes(a => paramBuilder.SetCustomAttribute(a));
            }

            this.customAttributes.SetCustomAttributes(a => this.methodBuilder.SetCustomAttribute(a));

            DebugOutput.WriteLine("");
            DebugOutput.WriteLine("=======================================");
            DebugOutput.Write($"New Method {this.methodBuilder.Name}");
            if (this.methodBuilder.IsGenericMethodDefinition == true)
            {
                DebugOutput.Write($"<{string.Join(", ", this.methodBuilder.GetGenericArguments().Select(t => t.Name))}>");
            }

            DebugOutput.WriteLine($"({string.Join(", ", this.parms.Select(p => $"{p.Attributes} {p.ParameterType} {p.ParameterName}"))})");
            DebugOutput.WriteLine("Calling Convention: {0}", this.methodBuilder.CallingConvention);
            DebugOutput.WriteLine("Attributes: {0}", this.Attributes);
            DebugOutput.WriteLine("");

            return(this.methodBuilder);
        }