public override bool CanAssist(RichCommandLineContext context)
        {
            Providers.Clear();
            Providers.AddRange(standardProviders);

            CommandLineArgument targetArgument = null;

            if (context.PreviousNonWhitespaceToken != null && ArgParser.IsDashSpecifiedArgumentIdentifier(context.PreviousNonWhitespaceToken.Value))
            {
                var candidate = context.PreviousNonWhitespaceToken.Value.Substring(1);
                targetArgument = (from a in Definition.AllGlobalAndActionArguments where a.IsMatch(candidate) select a).SingleOrDefault();
            }

            if (targetArgument != null)
            {
                foreach (var assistant in targetArgument.Metadata.Metas <ArgContextualAssistant>())
                {
                    var dynamicProvider = assistant.GetContextAssistProvider(Definition);
                    Providers.Add(dynamicProvider);
                }
            }

            foreach (var provider in Providers)
            {
                if (provider is PowerArgsContextAwareAssistant)
                {
                    (provider as PowerArgsContextAwareAssistant).TargetArgument = targetArgument;
                }
            }

            var ret = base.CanAssist(context);

            return(ret);
        }
        public static CommandLineArgument FindContextualArgument(FindContextualArgumentArgs args)
        {
            args.Definition = PassThroughOrTryGetAmbientDefinition(args.Definition);

            string currentTokenArgumentNameValue = null;

            if (args.PreviousToken != null && ArgParser.IsDashSpecifiedArgumentIdentifier(args.PreviousToken))
            {
                currentTokenArgumentNameValue = args.PreviousToken.Substring(1);
            }
            else if (args.PreviousToken != null && args.PreviousToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = args.PreviousToken.Substring(1);
            }
            else
            {
                // strange behavior outside of this method where we need to look back one if the current token has a non whitespace value
                var targetPosition = string.IsNullOrWhiteSpace(args.CurrentToken) ? args.CurrentTokenIndex : args.CurrentTokenIndex - 1;
                if (targetPosition < 0)
                {
                    return(null);
                }
                var positionArg = args.ActionContext == null?
                                  args.Definition.Arguments.Where(a => a.Position == targetPosition).FirstOrDefault() :
                                      args.ActionContext.Arguments.Where(a => a.Position == targetPosition).FirstOrDefault();

                var argsArray = Args.Convert(args.CommandLine);

                if (positionArg == null)
                {
                    return(positionArg);
                }

                for (var i = 0; i < Math.Min(argsArray.Length, targetPosition + 1); i++)
                {
                    // positional args must occur before any named args
                    if (argsArray[i].StartsWith("/") || Regex.IsMatch(argsArray[i], @"^-[^\d]"))
                    {
                        return(null);
                    }
                }

                return(positionArg);
            }

            CommandLineArgument currentTokenArgument = null;

            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = args.Definition.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();

                if (currentTokenArgument == null && args.ActionContext != null)
                {
                    currentTokenArgument = args.ActionContext.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue) && arg.ArgumentType != typeof(bool)).SingleOrDefault();
                }
            }
            return(currentTokenArgument);
        }
示例#3
0
        public bool TryComplete(TabCompletionContext context, out string completion)
        {
            var fixedUpCandidate = context.CompletionCandidate;

            if (ArgParser.IsDashSpecifiedArgumentIdentifier(fixedUpCandidate))
            {
                fixedUpCandidate = fixedUpCandidate.Substring(1);
            }
            else if (fixedUpCandidate.StartsWith("/"))
            {
                fixedUpCandidate = fixedUpCandidate.Substring(1);
            }
            else
            {
                completion = null;
                return(false);
            }

            var match = definition.Arguments.Where(arg => arg.IsMatch(fixedUpCandidate)).SingleOrDefault();

            if (match == null)
            {
                foreach (var action in definition.Actions)
                {
                    match = action.Arguments.Where(arg => arg.IsMatch(fixedUpCandidate)).SingleOrDefault();
                    if (match != null)
                    {
                        break;
                    }
                }
            }

            if (match == null)
            {
                completion = null;
                return(false);
            }

            if (match != argument)
            {
                completion = null;
                return(false);
            }

            return(TryComplete(new ArgumentAwareTabCompletionContext()
            {
                InnerContext = context,
                Argument = argument
            }
                               , out completion));
        }
示例#4
0
        private ArgAction ParseInternal(Type t, string[] input)
        {
            ArgShortcut.RegisterShortcuts(t);
            ValidateArgScaffold(t);

            var context = new ArgHook.HookContext();

            context.Args        = Activator.CreateInstance(t);
            context.CmdLineArgs = input;

            t.RunBeforeParse(context);
            var specifiedActionProperty = FindSpecifiedAction(t, ref context.CmdLineArgs);

            context.ParserData = ArgParser.Parse(context.CmdLineArgs);
            PopulateProperties(context);

            if (specifiedActionProperty != null)
            {
                var actionPropertyValue = Activator.CreateInstance(specifiedActionProperty.PropertyType);
                var toRestore           = context.Args;
                context.Args = actionPropertyValue;
                PopulateProperties(context);
                context.Args = toRestore;
                specifiedActionProperty.SetValue(context.Args, actionPropertyValue, null);
            }

            if (context.ParserData.ImplicitParameters.Count > 0)
            {
                throw new UnexpectedArgException("Unexpected unnamed argument: " + context.ParserData.ImplicitParameters.First().Value);
            }

            if (context.ParserData.ExplicitParameters.Count > 0)
            {
                throw new UnexpectedArgException("Unexpected named argument: " + context.ParserData.ExplicitParameters.First().Key);
            }

            return(new ArgAction()
            {
                Value = context.Args,
                ActionArgs = specifiedActionProperty != null?specifiedActionProperty.GetValue(context.Args, null) : null,
                                 ActionArgsProperty = specifiedActionProperty
            });
        }
        /// <summary>
        /// A helper that detects the argument represented by the current token given a definition.
        /// </summary>
        /// <param name="contextualAction">An action to inspect for a match if the current token does not match a global argument.  Pass null to only check global arguments.</param>
        /// <param name="currentToken">The token to inspect.  If you pass null you will get null back.</param>
        /// <param name="expectMatchingArg">This will be set to true if the current token starts with a '-' or a '/' meaning that the token was an argument indicator, even if it didn't match an argument in the definition.</param>
        /// <param name="def">The definition to inspect.  If null, the ambient definition will be used.  If there is no ambient definition and null is passed then this method throws a NullReferenceException.</param>
        /// <returns>An argument that is matched by the given token or null if there was no match</returns>
        public static CommandLineArgument FindCurrentTokenArgument(CommandLineAction contextualAction, string currentToken, out bool expectMatchingArg, CommandLineArgumentsDefinition def = null)
        {
            def = PassThroughOrTryGetAmbientDefinition(def);

            if (currentToken == null)
            {
                expectMatchingArg = false;
                return(null);
            }

            string currentTokenArgumentNameValue = null;

            expectMatchingArg = false;
            if (ArgParser.IsDashSpecifiedArgumentIdentifier(currentToken))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg             = true;
            }
            else if (currentToken.StartsWith("/"))
            {
                currentTokenArgumentNameValue = currentToken.Substring(1);
                expectMatchingArg             = true;
            }

            CommandLineArgument currentTokenArgument = null;

            if (currentTokenArgumentNameValue != null)
            {
                currentTokenArgument = def.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();

                if (currentTokenArgument == null && contextualAction != null)
                {
                    currentTokenArgument = contextualAction.Arguments.Where(arg => arg.IsMatch(currentTokenArgumentNameValue)).SingleOrDefault();
                }
            }
            return(currentTokenArgument);
        }
        /// <summary>
        /// If the current argument is a boolean and it is specified on the command line then
        /// this hook sets the IsNonInteractive flag on the current argument definition.
        /// </summary>
        /// <param name="context"></param>
        public override void BeforeParse(ArgHook.HookContext context)
        {
            if (context.CurrentArgument.ArgumentType != typeof(bool))
            {
                throw new InvalidArgDefinitionException(GetType().Name + " can only be used on boolean arguments");
            }

            for (int i = 0; i < context.CmdLineArgs.Length; i++)
            {
                var    arg = context.CmdLineArgs[i];
                string key;

                if (ArgParser.TryParseKey(arg, out key))
                {
                    var nextArg = i == context.CmdLineArgs.Length - 1 ? "" : context.CmdLineArgs[i + 1].ToLower();

                    // TODO - Find a better way to detect explicit 'false'
                    if (context.CurrentArgument.IsMatch(key) && nextArg != "false" && nextArg != "0")
                    {
                        context.Definition.IsNonInteractive = true;
                    }
                }
            }
        }
示例#7
0
        private ArgAction ParseInternal(CommandLineArgumentsDefinition definition, string[] input)
        {
            // TODO - Validation should be consistently done against the definition, not against the raw type
            if (definition.ArgumentScaffoldType != null)
            {
                ValidateArgScaffold(definition.ArgumentScaffoldType);
            }

            var context = ArgHook.HookContext.Current;

            context.Definition = definition;
            _ambientDefinition = definition;

            definition.Validate(context);

            if (definition.ArgumentScaffoldType != null)
            {
                context.Args = Activator.CreateInstance(definition.ArgumentScaffoldType);
            }
            context.CmdLineArgs = input;

            context.RunBeforeParse();
            context.ParserData = ArgParser.Parse(definition, context.CmdLineArgs);

            var actionToken = context.CmdLineArgs.FirstOrDefault();
            var actionQuery = context.Definition.Actions.Where(a => a.IsMatch(actionToken));

            if (actionQuery.Count() == 1)
            {
                context.SpecifiedAction = actionQuery.First();
            }
            else if (actionQuery.Count() > 1)
            {
                throw new InvalidArgDefinitionException("There are multiple actions that match argument '" + actionToken + "'");
            }

            context.RunBeforePopulateProperties();
            CommandLineArgument.PopulateArguments(context.Definition.Arguments, context);
            context.Definition.SetPropertyValues(context.Args);

            object actionArgs = null;

            object[] actionParameters = null;

            if (context.SpecifiedAction == null && context.Definition.Actions.Count > 0)
            {
                if (context.CmdLineArgs.FirstOrDefault() == null)
                {
                    throw new MissingArgException("No action was specified");
                }
                else
                {
                    throw new UnknownActionArgException(string.Format("Unknown action: '{0}'", context.CmdLineArgs.FirstOrDefault()));
                }
            }
            else if (context.SpecifiedAction != null)
            {
                PropertyInfo actionProp = null;
                if (context.Definition.ArgumentScaffoldType != null)
                {
                    actionProp = ArgAction.GetActionProperty(context.Definition.ArgumentScaffoldType);
                }

                if (actionProp != null)
                {
                    actionProp.SetValue(context.Args, context.SpecifiedAction.Aliases.First(), null);
                }

                context.ParserData.ImplicitParameters.Remove(0);
                CommandLineArgument.PopulateArguments(context.SpecifiedAction.Arguments, context);
            }

            context.RunAfterPopulateProperties();

            if (context.SpecifiedAction != null)
            {
                actionArgs = context.SpecifiedAction.PopulateArguments(context.Args, ref actionParameters);
            }

            if (context.Definition.Metadata.HasMeta <AllowUnexpectedArgs>() == false)
            {
                if (context.ParserData.ImplicitParameters.Count > 0)
                {
                    throw new UnexpectedArgException("Unexpected unnamed argument: " + context.ParserData.ImplicitParameters.First().Value);
                }

                if (context.ParserData.ExplicitParameters.Count > 0)
                {
                    throw new UnexpectedArgException("Unexpected named argument: " + context.ParserData.ExplicitParameters.First().Key);
                }
            }
            else
            {
                definition.UnexpectedExplicitArguments = context.ParserData.ExplicitParameters;
                definition.UnexpectedImplicitArguments = context.ParserData.ImplicitParameters;
            }


            if (definition.ArgumentScaffoldType != null)
            {
                if (AmbientArgs.ContainsKey(definition.ArgumentScaffoldType))
                {
                    AmbientArgs[definition.ArgumentScaffoldType] = context.Args;
                }
                else
                {
                    AmbientArgs.Add(definition.ArgumentScaffoldType, context.Args);
                }
            }

            PropertyInfo actionArgsPropertyInfo = null;

            if (context.SpecifiedAction != null)
            {
                if (context.SpecifiedAction.Source is PropertyInfo)
                {
                    actionArgsPropertyInfo = context.SpecifiedAction.Source as PropertyInfo;
                }
                else if (context.SpecifiedAction.Source is MethodInfo)
                {
                    actionArgsPropertyInfo = new ArgActionMethodVirtualProperty(context.SpecifiedAction.Source as MethodInfo);
                }
            }

            return(new ArgAction()
            {
                Value = context.Args,
                ActionArgs = actionArgs,
                ActionParameters = actionParameters,
                ActionArgsProperty = actionArgsPropertyInfo,
                ActionArgsMethod = context.SpecifiedAction != null ? context.SpecifiedAction.ActionMethod : null,
                Definition = context.Definition,
                Context = context,
            });
        }