Esempio n. 1
0
        internal void HandleEmptyArguments(object target)
        {
            //
            // *** registered empty handlers are called by the multi-parser
            //

            var definedEmptyHandlers      = Type.GetMethodsWith <EmptyAttribute>();
            var definedEmptyHandlersCount = definedEmptyHandlers.Count();

            Debug.Assert(definedEmptyHandlersCount <= 1);

            if (definedEmptyHandlersCount == 1)
            {
                var method = definedEmptyHandlers.First();

                VerifyMethodAndTarget(method, target);

                var obj = method.IsStatic ? null : target;

                // if it is a [Help] handler
                //
                if (method.HasAttribute <HelpAttribute>())
                {
                    var help = m_helpGenerator.GetHelp(this);

                    // method should execute because it was already passed validation
                    //
                    MethodInvoker.Invoke(method, obj, new[] { help });
                }
                else
                {
                    MethodInvoker.Invoke(method, obj, null);
                }

                // don't handle the default verb
                //
                return;
            }

            var defaultVerb = GetDefaultVerb();

            // if there is a default verb - execute it
            //
            if (defaultVerb != null)
            {
                // create an array of arguments that matches the method
                //
                var serviceProvider = CreateServiceProvider(target);
                var parameters      = ValuesFactory.CreateParameterValues(
                    defaultVerb,
                    target,
                    new Dictionary <string, string>(),
                    GetParameters(defaultVerb.MethodInfo),
                    serviceProvider);

                Execute(target, defaultVerb, parameters);
            }
        }
Esempio n. 2
0
        private int RunInternal(string[] args, object obj)
        {
            //
            // *** empty args are handled by the multi-parser
            //
            //

            Debug.Assert(args.Length > 0 && args.All(a => !string.IsNullOrEmpty(a)));

            // the first arg should be the verb, unless there is no verb and a default is used
            //
            var firstArg = args[0];

            if (HandleHelp(firstArg, obj))
            {
                return(MultiParser.ErrorCode);
            }

            var verb = firstArg;

            // a flag, in case there is no verb
            //
            var noVerb = false;

            // find the method by the given verb
            //
            var typeVerbs = GetVerbs()
                            .ToDictionary(v => v, v => GetParameters(v.MethodInfo).ToList());

            // arguments
            var notVerbs = args
                           .Where(a => a.StartsWith(ArgumentPrefixes))
                           .ToList();

            var globals = GetDefinedGlobals()
                          .Where(g => notVerbs.Any(a => a.Substring(1).StartsWith(g.Name.ToLowerInvariant())))
                          .ToList();

            var notVerbsNotGlobals = notVerbs
                                     .Where(a => globals.All(g => !a.Substring(1).StartsWith(g.Name.ToLowerInvariant())))
                                     .ToList();

            // find the method by name, parameter count and parameter names
            var methods = (
                from v in typeVerbs
                where v.Key.Names.Contains(verb.ToLowerInvariant())
                where v.Value.Count == notVerbs.Count
                select v
                ).ToList();

            Method method = SelectMethod(methods, notVerbs);

            // if arguments do not match parameter names, exclude globals
            methods = (
                from v in typeVerbs
                where v.Key.Names.Contains(verb.ToLowerInvariant())
                where v.Value.Count == notVerbsNotGlobals.Count
                select v
                ).ToList();

            if (method == null)
            {
                method = SelectMethod(methods, notVerbsNotGlobals);
            }

            // if arguments do not match parameters names, exclude optional parameters
            if (method == null)
            {
                const bool avoidOptionalParameters = false;
                method = SelectMethod(methods, notVerbsNotGlobals, avoidOptionalParameters);
            }

            // if arguments do not match parameter names, use only argument count (without globals)
            if (method == null)
            {
                method = methods.FirstOrDefault().Key;
            }

            // if nothing matches...
            if (method == null)
            {
                method = typeVerbs.FirstOrDefault(v => v.Key.Names.Contains(verb.ToLowerInvariant())).Key;
            }

            // if no method is found - a default must exist
            if (method == null)
            {
                // if there is a verb input but no method was found
                // AND
                // the first arg is not an input argument (doesn't start with "-" etc)
                //
                if (verb != null && !verb.StartsWith(ArgumentPrefixes))
                {
                    throw new VerbNotFoundException(verb);
                }

                method = typeVerbs.FirstOrDefault(v => v.Key.IsDefault).Key;

                // no default - error
                //
                if (method == null)
                {
                    throw new MissingDefaultVerbException();
                }

                noVerb = true;
            }

            // if there is a verb - skip the first arg
            //
            var inputArgs = MapArguments(noVerb ? args : args.Skip(1));

            HandleGlobals(inputArgs, obj);

            // a list of the available parameters
            //
            var paremetersList = GetParameters(method.MethodInfo);

            // a list of values, used when invoking the method
            //
            var parameterValues = ValuesFactory.CreateParameterValues(method, obj, inputArgs, paremetersList);

            ValidateVerbInput(method, parameterValues.Select(kvp => kvp.Value).ToList());

            // if some args weren't handled
            //
            if (inputArgs.Any())
            {
                throw new UnhandledParametersException(inputArgs);
            }

            return(Execute(obj, method, parameterValues));
        }