/// <summary>
 /// IsForeachScriptBlock: Returns true if:
 /// - command is 'Foreach-Object' (or alias)
 /// - parameter '-Parallel' is present
 /// </summary>
 /// <param name="cmdName"></param>
 /// <param name="scriptBlockParameterAst"></param>
 private bool IsForeachScriptBlock(string cmdName, CommandParameterAst scriptBlockParameterAst)
 {
     // 'pa' is the shortest unambiguous form for the '-Parallel' parameter
     return(s_foreachObjectCmdletNamesAndAliases.Contains(cmdName, StringComparer.OrdinalIgnoreCase) &&
            (scriptBlockParameterAst != null &&
             scriptBlockParameterAst.ParameterName.StartsWith("pa", StringComparison.OrdinalIgnoreCase)));
 }
Exemple #2
0
        private void AddParameter(CommandParameterAst commandParameterAst, bool isTrustedInput)
        {
            string nameSuffix;
            object argument;

            if (commandParameterAst.Argument != null)
            {
                var  arg                 = commandParameterAst.Argument;
                var  errorPos            = commandParameterAst.ErrorPosition;
                bool spaceAfterParameter = (errorPos.EndLineNumber != arg.Extent.StartLineNumber ||
                                            errorPos.EndColumnNumber != arg.Extent.StartColumnNumber);
                nameSuffix = spaceAfterParameter ? ": " : ":";

                argument = GetExpressionValue(commandParameterAst.Argument, isTrustedInput);
            }
            else
            {
                nameSuffix = string.Empty;
                argument   = null;
            }

            // first character in parameter name must be a dash
            _powershell.AddParameter(
                string.Format(CultureInfo.InvariantCulture, "-{0}{1}", commandParameterAst.ParameterName, nameSuffix),
                argument);
        }
        public object VisitCommandParameter(CommandParameterAst commandParameterAst)
        {
            var newArgument = VisitElement(commandParameterAst.Argument);

            return(new CommandParameterAst(commandParameterAst.Extent, commandParameterAst.ParameterName, newArgument,
                                           commandParameterAst.ErrorPosition));
        }
Exemple #4
0
            public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst)
            {
                CommandAst commandParentAst = commandParameterAst.Parent as CommandAst;

                if (commandParentAst != null &&
                    String.Equals(commandParentAst.GetCommandName(), "Import-DscResource", StringComparison.OrdinalIgnoreCase))
                {
                    // Resource can be specified by name, without a module.
                    if (String.Equals(commandParameterAst.ParameterName, "Name", StringComparison.OrdinalIgnoreCase))
                    {
                        ArrayLiteralAst arrayLiteralAst = commandParameterAst.Argument as ArrayLiteralAst;
                        if (arrayLiteralAst != null)
                        {
                            IEnumerable <string> resourceNames = arrayLiteralAst.Elements.OfType <StringConstantExpressionAst>().Select(x => x.Value);
                            foreach (string resourceName in resourceNames)
                            {
                            }
                        }
                    }
                    // Or with ModuleDefinition parameter
                    else if (String.Equals(commandParameterAst.ParameterName, "ModuleDefinition", StringComparison.OrdinalIgnoreCase))
                    {
                        ArrayLiteralAst arrayLiteralAst = commandParameterAst.Argument as ArrayLiteralAst;
                        if (arrayLiteralAst != null)
                        {
                            Modules.AddRange(arrayLiteralAst.Elements.OfType <StringConstantExpressionAst>().Select(x => x.Value));
                        }
                    }
                }
                return(base.VisitCommandParameter(commandParameterAst));
            }
        /// <summary>
        /// Condition on the parameter that must be satisfied for the error to be raised.
        /// </summary>
        /// <param name="CmdAst"></param>
        /// <param name="CeAst"></param>
        /// <returns></returns>
        public override bool ParameterCondition(CommandAst CmdAst, CommandElementAst CeAst)
        {
            if (CeAst is CommandParameterAst)
            {
                CommandParameterAst cmdParamAst = CeAst as CommandParameterAst;

                if (String.Equals(cmdParamAst.ParameterName, "computername", StringComparison.OrdinalIgnoreCase))
                {
                    Ast computerNameArgument = cmdParamAst.Argument;
                    if (computerNameArgument == null)
                    {
                        computerNameArgument = GetComputerNameArg(CmdAst, cmdParamAst.Extent.StartOffset);
                        if (computerNameArgument == null)
                        {
                            return(false);
                        }
                    }

                    var constExprAst = computerNameArgument as ConstantExpressionAst;
                    if (constExprAst != null)
                    {
                        return(!IsLocalhost(constExprAst));
                    }
                }
            }

            return(false);
        }
Exemple #6
0
        /// <summary>
        /// Condition on the parameter that must be satisfied for the error to be raised.
        /// </summary>
        /// <param name="CmdAst"></param>
        /// <param name="CeAst"></param>
        /// <returns></returns>
        public override bool ParameterCondition(CommandAst CmdAst, CommandElementAst CeAst)
        {
            if (CeAst is CommandParameterAst)
            {
                CommandParameterAst cmdParamAst = CeAst as CommandParameterAst;

                if (String.Equals(cmdParamAst.ParameterName, "computername", StringComparison.OrdinalIgnoreCase))
                {
                    List <string> localhostRepresentations = new List <string> {
                        "localhost", ".", "::1", "127.0.0.1"
                    };
                    Ast computerNameArgument = GetComputerNameArg(CmdAst, cmdParamAst.Extent.StartOffset);

                    if (null != computerNameArgument)
                    {
                        if (!localhostRepresentations.Contains(computerNameArgument.Extent.Text.ToLower()))
                        {
                            return(computerNameArgument is ConstantExpressionAst);
                        }

                        return(false);
                    }

                    if (null != cmdParamAst.Argument && !localhostRepresentations.Contains(cmdParamAst.Argument.ToString().Replace("\"", "").Replace("'", "").ToLower()))
                    {
                        return(cmdParamAst.Argument is ConstantExpressionAst);
                    }
                }
            }

            return(false);
        }
Exemple #7
0
        public ParameterSet(CommandAst commandAst)
        {
            Validation.CheckArgument(commandAst, $"{nameof(commandAst)} cannot be null.");

            var parameters            = new List <Parameter>();
            CommandParameterAst param = null;
            Ast arg = null;

            // Loop through all the parameters. The first element of CommandElements is the command name, so skip it.
            for (var i = 1; i < commandAst.CommandElements.Count(); ++i)
            {
                var elem = commandAst.CommandElements[i];

                if (elem is CommandParameterAst p)
                {
                    AddParameter(param, arg);
                    param = p;
                    arg   = null;
                }
                else if (AzPredictorConstants.ParameterIndicator == elem?.ToString().Trim().FirstOrDefault())
                {
                    // We have an incomplete command line such as
                    // `New-AzResourceGroup -Name ResourceGroup01 -Location WestUS -`
                    // We'll ignore the incomplete parameter.
                    AddParameter(param, arg);
                    param = null;
                    arg   = null;
                }
                else
                {
                    arg = elem;
                }
            }

            Validation.CheckInvariant((param != null) || (arg == null));

            AddParameter(param, arg);

            Parameters = parameters;

            void AddParameter(CommandParameterAst parameter, Ast parameterValue)
            {
                if (parameter != null)
                {
                    var value = parameterValue?.ToString();
                    if (value == null)
                    {
                        value = parameter.Argument?.ToString();
                    }

                    if (value != null)
                    {
                        value = CommandLineUtilities.UnescapePredictionText(value);
                    }

                    parameters.Add(new Parameter(parameter.ParameterName, value));
                }
            }
        }
Exemple #8
0
 public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     if (commandParameterAst.ToString().Contains(symbolRef.ScriptRegion.Text))
     {
         ValidateExtend(symbolRef.ScriptRegion.Text, commandParameterAst.ParameterName, commandParameterAst);
     }
     return(base.VisitCommandParameter(commandParameterAst));
 }
 /// <summary>
 /// IsJobScriptBlock: Returns true if:
 /// - command is 'Start-Job' or 'Start-ThreadJob' (or alias)
 /// - parameter name for this ScriptBlock not '-InitializationScript'
 /// </summary>
 /// <param name="cmdName"></param>
 /// <param name="scriptBlockParameterAst"></param>
 private bool IsJobScriptBlock(string cmdName, CommandParameterAst scriptBlockParameterAst)
 {
     // 'ini' is the shortest unambiguous form for the '-InitializationScript' parameter
     return((s_jobCmdletNamesAndAliases.Contains(cmdName, StringComparer.OrdinalIgnoreCase) ||
             s_threadJobCmdletNamesAndAliases.Contains(cmdName, StringComparer.OrdinalIgnoreCase)) &&
            !(scriptBlockParameterAst != null &&
              scriptBlockParameterAst.ParameterName.StartsWith("ini", StringComparison.OrdinalIgnoreCase)));
 }
 public virtual CommandElementAst VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     return(new CommandParameterAst(
                commandParameterAst.Extent,
                commandParameterAst.ParameterName,
                commandParameterAst.Argument?.Rewrite(this),
                commandParameterAst.ErrorPosition));
 }
Exemple #11
0
 /// <summary>
 /// Decides if the current function definition is a reference of the symbol being searched for.
 /// A reference of the symbol will be a of type SymbolType.Parameter and have the same name as the symbol
 /// </summary>
 /// <param name="commandParameterAst">A commandParameterAst in the script's AST</param>
 /// <returns>A visit action that continues the search for references</returns>
 public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     if (_symbolRef.SymbolType.Equals(SymbolType.Parameter) &&
         commandParameterAst.Extent.Text.Equals(_symbolRef.SymbolName, StringComparison.CurrentCultureIgnoreCase))
     {
         FoundReferences.Add(new SymbolReference(SymbolType.Parameter, commandParameterAst.Extent));
     }
     return(AstVisitAction.Continue);
 }
        private static bool IsParameterName(CommandElementAst ast, string name)
        {
            CommandParameterAst constantAst = ast as CommandParameterAst;

            if (constantAst == null)
            {
                return(false);
            }
            return(String.Equals(constantAst.ParameterName, name, StringComparison.OrdinalIgnoreCase));
        }
 public static CommandParameterAst Update(
     this CommandParameterAst ast,
     string parameterName   = null,
     ExpressionAst argument = null)
 {
     return(new CommandParameterAst(
                ast.Extent,
                parameterName ?? ast.ParameterName,
                argument?.Clone() ?? ast.Argument?.Clone(),
                ast.ErrorPosition));
 }
Exemple #14
0
        internal static SteppablePipeline GetSteppablePipeline(PipelineAst pipelineAst, CommandOrigin commandOrigin)
        {
            PipelineProcessor pipe = new PipelineProcessor();

            System.Management.Automation.ExecutionContext executionContextFromTLS = LocalPipeline.GetExecutionContextFromTLS();
            foreach (CommandAst ast in pipelineAst.PipelineElements.Cast <CommandAst>())
            {
                List <CommandParameterInternal> list = new List <CommandParameterInternal>();
                foreach (CommandElementAst ast2 in ast.CommandElements)
                {
                    CommandParameterAst commandParameterAst = ast2 as CommandParameterAst;
                    if (commandParameterAst != null)
                    {
                        list.Add(GetCommandParameter(commandParameterAst, executionContextFromTLS));
                    }
                    else
                    {
                        ExpressionAst expressionAst = (ExpressionAst)ast2;
                        object        obj2          = Compiler.GetExpressionValue(expressionAst, executionContextFromTLS, (IList)null);
                        bool          splatted      = (expressionAst is VariableExpressionAst) && ((VariableExpressionAst)expressionAst).Splatted;
                        list.Add(CommandParameterInternal.CreateArgument(expressionAst.Extent, obj2, splatted));
                    }
                }
                List <CommandRedirection> list2 = new List <CommandRedirection>();
                foreach (RedirectionAst ast5 in ast.Redirections)
                {
                    list2.Add(GetCommandRedirection(ast5, executionContextFromTLS));
                }
                CommandProcessorBase base2 = AddCommand(pipe, list.ToArray(), ast, list2.ToArray(), executionContextFromTLS);
                base2.Command.CommandOriginInternal      = commandOrigin;
                base2.CommandScope.ScopeOrigin           = commandOrigin;
                base2.Command.MyInvocation.CommandOrigin = commandOrigin;
                CallStackFrame[] frameArray = executionContextFromTLS.Debugger.GetCallStack().ToArray <CallStackFrame>();
                if ((frameArray.Length > 0) && Regex.IsMatch(frameArray[0].Position.Text, "GetSteppablePipeline", RegexOptions.IgnoreCase))
                {
                    InvocationInfo myInvocation = base2.Command.MyInvocation;
                    myInvocation.InvocationName = frameArray[0].InvocationInfo.InvocationName;
                    if (frameArray.Length > 1)
                    {
                        IScriptExtent position = frameArray[1].Position;
                        if ((position != null) && (position != PositionUtilities.EmptyExtent))
                        {
                            myInvocation.DisplayScriptPosition = position;
                        }
                    }
                }
                if ((executionContextFromTLS.CurrentCommandProcessor != null) && (executionContextFromTLS.CurrentCommandProcessor.CommandRuntime != null))
                {
                    base2.CommandRuntime.SetMergeFromRuntime(executionContextFromTLS.CurrentCommandProcessor.CommandRuntime);
                }
            }
            return(new SteppablePipeline(executionContextFromTLS, pipe));
        }
 /// <summary>
 /// Checks to see if this command parameter is the symbol we are looking for.
 /// </summary>
 /// <param name="commandParameterAst">A CommandParameterAst object in the script's AST</param>
 /// <returns>A decision to stop searching if the right symbol was found,
 /// or a decision to continue if it wasn't found</returns>
 public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     if (IsPositionInExtent(commandParameterAst.Extent))
     {
         FoundSymbolReference =
             new SymbolReference(
                 SymbolType.Parameter,
                 commandParameterAst.Extent);
         return(AstVisitAction.StopVisit);
     }
     return(AstVisitAction.Continue);
 }
        public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst)
        {
            Node expression = null;

            if (commandParameterAst.Argument != null)
            {
                expression = VisitSyntaxNode(commandParameterAst.Argument);
            }

            _currentNode = new Argument(commandParameterAst.ParameterName, expression);

            return(AstVisitAction.SkipChildren);
        }
Exemple #17
0
        private Dictionary <string, string> GetParameters(ReadOnlyCollection <CommandElementAst> commandElements)
        {
            Dictionary <string, string> dictionary = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
            bool   flag = false;
            string key  = null;
            int    num  = 0;

            foreach (CommandElementAst ast in commandElements)
            {
                if (!flag)
                {
                    flag = true;
                }
                else
                {
                    CommandParameterAst ast2 = ast as CommandParameterAst;
                    if (ast2 != null)
                    {
                        string parameterName = ast2.ParameterName;
                        if (ast2.Argument != null)
                        {
                            dictionary.Add(parameterName, ast2.Argument.ToString());
                            key = null;
                        }
                        else
                        {
                            key = parameterName;
                        }
                    }
                    else if (key != null)
                    {
                        ArrayExpressionAst ast3 = ast as ArrayExpressionAst;
                        if (ast3 != null)
                        {
                            dictionary.Add(key, ast3.SubExpression.ToString());
                        }
                        else
                        {
                            dictionary.Add(key, ast.ToString());
                        }
                        key = null;
                    }
                    else
                    {
                        dictionary.Add(num.ToString(CultureInfo.InvariantCulture), ast.ToString());
                        num++;
                    }
                }
            }
            return(dictionary);
        }
Exemple #18
0
        private static CommandParameterInternal GetCommandParameter(CommandParameterAst commandParameterAst, System.Management.Automation.ExecutionContext context)
        {
            ExpressionAst argument      = commandParameterAst.Argument;
            IScriptExtent errorPosition = commandParameterAst.ErrorPosition;

            if (argument == null)
            {
                return(CommandParameterInternal.CreateParameter(errorPosition, commandParameterAst.ParameterName, errorPosition.Text));
            }
            object obj2 = Compiler.GetExpressionValue(argument, context, (IList)null);
            bool   spaceAfterParameter = (errorPosition.EndLineNumber != argument.Extent.StartLineNumber) || (errorPosition.EndColumnNumber != argument.Extent.StartColumnNumber);

            return(CommandParameterInternal.CreateParameterWithArgument(errorPosition, commandParameterAst.ParameterName, errorPosition.Text, argument.Extent, obj2, spaceAfterParameter));
        }
        /// <summary>
        /// Condition on the parameter that must be satisfied for the error to be raised.
        /// </summary>
        /// <param name="CmdAst"></param>
        /// <param name="CeAst"></param>
        /// <returns></returns>
        public override bool ParameterCondition(CommandAst CmdAst, CommandElementAst CeAst)
        {
            if (CeAst is CommandParameterAst)
            {
                CommandParameterAst cmdParamAst = CeAst as CommandParameterAst;

                if (String.Equals(cmdParamAst.ParameterName, "computername", StringComparison.OrdinalIgnoreCase))
                {
                    return(cmdParamAst.Argument is ConstantExpressionAst || GetComputerNameArg(CmdAst, cmdParamAst.Extent.StartOffset) is ConstantExpressionAst);
                }
            }

            return(false);
        }
        public ParameterSet(CommandAst commandAst)
        {
            Validation.CheckArgument(commandAst, $"{nameof(commandAst)} cannot be null.");

            var parameters            = new List <Parameter>();
            var elements              = commandAst.CommandElements.Skip(1);
            CommandParameterAst param = null;
            Ast arg = null;

            foreach (Ast elem in elements)
            {
                if (elem is CommandParameterAst p)
                {
                    AddParameter(param, arg);
                    param = p;
                    arg   = null;
                }
                else if (AzPredictorConstants.ParameterIndicator == elem?.ToString().Trim().FirstOrDefault())
                {
                    // We have an incomplete command line such as
                    // `New-AzResourceGroup -Name ResourceGroup01 -Location WestUS -`
                    // We'll ignore the incomplete parameter.
                    AddParameter(param, arg);
                    param = null;
                    arg   = null;
                }
                else
                {
                    arg = elem;
                }
            }

            Validation.CheckInvariant((param != null) || (arg == null));

            AddParameter(param, arg);

            Parameters = parameters;

            void AddParameter(CommandParameterAst parameterName, Ast parameterValue)
            {
                if (parameterName != null)
                {
                    parameters.Add(new Parameter(parameterName.ParameterName, (parameterValue == null) ? null : CommandLineUtilities.UnescapePredictionText(parameterValue.ToString())));
                }
            }
        }
Exemple #21
0
        private void AddParameter(CommandParameterAst commandParameterAst)
        {
            string str;
            object expressionValue;

            if (commandParameterAst.Argument != null)
            {
                ExpressionAst argument      = commandParameterAst.Argument;
                IScriptExtent errorPosition = commandParameterAst.ErrorPosition;
                str             = ((errorPosition.EndLineNumber != argument.Extent.StartLineNumber) || (errorPosition.EndColumnNumber != argument.Extent.StartColumnNumber)) ? ": " : ":";
                expressionValue = this.GetExpressionValue(commandParameterAst.Argument);
            }
            else
            {
                str             = "";
                expressionValue = null;
            }
            this._powershell.AddParameter(string.Format(CultureInfo.InvariantCulture, "-{0}{1}", new object[] { commandParameterAst.ParameterName, str }), expressionValue);
        }
        private IEnumerable <CorrectionExtent> GetCorrectionExtent(CommandParameterAst commandParameterAst, string correctlyCaseName)
        {
            var description = string.Format(
                CultureInfo.CurrentCulture,
                Strings.UseCorrectCasingDescription,
                correctlyCaseName,
                correctlyCaseName);
            var cmdExtent  = commandParameterAst.Extent;
            var correction = new CorrectionExtent(
                cmdExtent.StartLineNumber,
                cmdExtent.EndLineNumber,
                // +1 because of the dash before the parameter name
                cmdExtent.StartColumnNumber + 1,
                // do not use EndColumnNumber property as it would not cover the case where the colon syntax: -ParameterName:$ParameterValue
                cmdExtent.StartColumnNumber + 1 + commandParameterAst.ParameterName.Length,
                correctlyCaseName,
                commandParameterAst.Extent.File,
                description);

            yield return(correction);
        }
Exemple #23
0
        private string GetDslInstanceName(string dslTypeName, IEnumerable <CommandElementAst> commandElements)
        {
            // try to guess dsl instance name - first string constant that is not named parameter value (or is value of 'name' parameter)
            bool lastElementIsUnknownParameter = false;
            int  num = 0;

            foreach (CommandElementAst elementAst in commandElements)
            {
                if (num++ == 0)
                {
                    continue;
                }
                if (elementAst is CommandParameterAst)
                {
                    CommandParameterAst commandParameterAst = (CommandParameterAst)elementAst;
                    lastElementIsUnknownParameter = commandParameterAst.ParameterName.ToLowerInvariant() != "name";
                    if (dslTypeName.StartsWith("PSDesiredStateConfiguration") && !lastElementIsUnknownParameter)
                    {
                        return(commandParameterAst.Argument.ToString());
                    }
                    continue;
                }
                if (elementAst is StringConstantExpressionAst && !lastElementIsUnknownParameter)
                {
                    return(((StringConstantExpressionAst)elementAst).Value);
                }
                if (elementAst is ExpandableStringExpressionAst && !lastElementIsUnknownParameter)
                {
                    return(((ExpandableStringExpressionAst)elementAst).Value);
                }
                if (elementAst is MemberExpressionAst && !lastElementIsUnknownParameter)
                {
                    return(((MemberExpressionAst)elementAst).Extent.Text);
                }

                lastElementIsUnknownParameter = false;
            }
            return(string.Empty);
        }
Exemple #24
0
        public override AstVisitAction VisitCommand(CommandAst commandAst)
        {
            object newParentObject;
            var    commandElements = commandAst.CommandElements;
            string dslInstanceName = this.DslNameGiver(commandElements, commandAst.Parent);

            if (dslInstanceName == null)
            {
                return(AstVisitAction.Continue);
            }

            string dslTypeName = ((StringConstantExpressionAst)commandElements[0]).Value;

            dslTypeName = dslTypeName.Replace("PSDesiredStateConfiguration\\", "");
            if (dslTypeName.ToLowerInvariant() == "configuration")
            {
                CommandParameterAst nameAst = (CommandParameterAst)commandAst.Find(ast => ast is CommandParameterAst && "name".Equals(((CommandParameterAst)ast).ParameterName.ToLowerInvariant()), false);
                newParentObject = this.ConfigurationAction(nameAst.Argument.ToString(), commandAst.Extent, this.GetCurrentNestingLevel(), this.GetCurrentParentObject());
            }
            else
            {
                newParentObject = this.DslAction(dslTypeName, dslInstanceName, commandAst.Extent, this.GetCurrentNestingLevel(), this.GetCurrentParentObject());
            }

            Ast body = commandAst.Find(ast => ast is CommandParameterAst && ("body".Equals(((CommandParameterAst)ast).ParameterName.ToLowerInvariant()) ||
                                                                             "value".Equals(((CommandParameterAst)ast).ParameterName.ToLowerInvariant())), false);

            if (body != null)
            {
                this.VisitChildren(body, newParentObject);
            }
            else
            {
                this.VisitChildren(commandElements[commandElements.Count - 1], newParentObject);
            }

            return(AstVisitAction.SkipChildren);
        }
 public object VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     return(false);
 }
Exemple #26
0
        /// <summary>
        /// Select the command argument that the cursor is at, or the previous/next Nth command arguments from the current cursor position.
        /// </summary>
        public static void SelectCommandArgument(ConsoleKeyInfo?key = null, object arg = null)
        {
            if (!TryGetArgAsInt(arg, out var numericArg, 0))
            {
                return;
            }

            _singleton.MaybeParseInput();

            int cursor = _singleton._current;
            int prev = -1, curr = -1, next = -1;
            var sbAsts    = _singleton._ast.FindAll(GetScriptBlockAst, searchNestedScriptBlocks: true).ToList();
            var arguments = new List <ExpressionAst>();

            // We start searching for command arguments from the most nested script block.
            for (int i = sbAsts.Count - 1; i >= 0; i--)
            {
                var sbAst   = sbAsts[i];
                var cmdAsts = sbAst.FindAll(ast => ast is CommandAst, searchNestedScriptBlocks: false);

                foreach (CommandAst cmdAst in cmdAsts)
                {
                    for (int j = 1; j < cmdAst.CommandElements.Count; j++)
                    {
                        var argument = cmdAst.CommandElements[j] switch
                        {
                            CommandParameterAst paramAst => paramAst.Argument,
                            ExpressionAst expAst => expAst,
                            _ => null,
                        };

                        if (argument is not null)
                        {
                            arguments.Add(argument);

                            int start = argument.Extent.StartOffset;
                            int end   = argument.Extent.EndOffset;

                            if (end <= cursor)
                            {
                                prev = arguments.Count - 1;
                            }
                            if (curr == -1 && start <= cursor && end > cursor)
                            {
                                curr = arguments.Count - 1;
                            }
                            else if (next == -1 && start > cursor)
                            {
                                next = arguments.Count - 1;
                            }
                        }
                    }
                }

                // Stop searching the outer script blocks if we find any command arguments within the current script block.
                if (arguments.Count > 0)
                {
                    break;
                }
            }

            // Simply return if we didn't find any command arguments.
            int count = arguments.Count;

            if (count == 0)
            {
                return;
            }

            if (prev == -1)
            {
                prev = count - 1;
            }
            if (next == -1)
            {
                next = 0;
            }
            if (curr == -1)
            {
                curr = numericArg > 0 ? prev : next;
            }

            int newStartCursor, newEndCursor;
            int selectCount = _singleton._visualSelectionCommandCount;

            // When an argument is already visually selected by the previous run of this function, the cursor would have past the selected argument.
            // In this case, if a user wants to move backward to an argument that is before the currently selected argument by having numericArg < 0,
            // we will need to adjust 'numericArg' to move to the expected argument.
            // Scenario:
            //   1) 'Alt+a' to select an argument;
            //   2) 'Alt+-' to make 'numericArg = -1';
            //   3) 'Alt+a' to select the argument that is right before the currently selected argument.
            if (count > 1 && numericArg < 0 && curr == next && selectCount > 0)
            {
                var prevArg = arguments[prev];
                if (_singleton._mark == prevArg.Extent.StartOffset && cursor == prevArg.Extent.EndOffset)
                {
                    numericArg--;
                }
            }

            while (true)
            {
                ExpressionAst targetAst = null;
                if (numericArg == 0)
                {
                    targetAst = arguments[curr];
                }
                else
                {
                    int index = curr + numericArg;
                    index     = index >= 0 ? index % count : (count + index % count) % count;
                    targetAst = arguments[index];
                }

                // Handle quoted-string arguments specially, by leaving the quotes out of the visual selection.
                StringConstantType?constantType = null;
                if (targetAst is StringConstantExpressionAst conString)
                {
                    constantType = conString.StringConstantType;
                }
                else if (targetAst is ExpandableStringExpressionAst expString)
                {
                    constantType = expString.StringConstantType;
                }

                int startOffsetAdjustment = 0, endOffsetAdjustment = 0;
                switch (constantType)
                {
                case StringConstantType.DoubleQuoted:
                case StringConstantType.SingleQuoted:
                    startOffsetAdjustment = endOffsetAdjustment = 1;
                    break;

                case StringConstantType.DoubleQuotedHereString:
                case StringConstantType.SingleQuotedHereString:
                    startOffsetAdjustment = 2;
                    endOffsetAdjustment   = 3;
                    break;

                default: break;
                }

                newStartCursor = targetAst.Extent.StartOffset + startOffsetAdjustment;
                newEndCursor   = targetAst.Extent.EndOffset - endOffsetAdjustment;

                // For quoted-string arguments, due to the special handling above, the cursor would always be
                // within the selected argument (cursor is placed at the ending quote), and thus when running
                // the 'SelectCommandArgument' action again, the same argument would be chosen.
                //
                // Below is how we detect this and move to the next argument when there is one:
                //  * the previous action was a visual selection command and the visual range was exactly
                //    what we are going to make. AND
                //  * count > 1, meaning that there are other arguments. AND
                //  * numericArg == 0. When 'numericArg' is not 0, the user is leaping among the available
                //    arguments, so it's possible that the same argument gets chosen.
                // In this case, we should select the next argument.
                if (numericArg == 0 && count > 1 && selectCount > 0 &&
                    _singleton._mark == newStartCursor && cursor == newEndCursor)
                {
                    curr = next;
                    continue;
                }

                break;
            }

            // Move cursor to the start of the argument.
            SetCursorPosition(newStartCursor);
            // Make the intended range visually selected.
            _singleton.VisualSelectionCommon(() => SetCursorPosition(newEndCursor), forceSetMark: true);


            // Get the script block AST's whose extent contains the cursor.
            bool GetScriptBlockAst(Ast ast)
            {
                if (ast is not ScriptBlockAst)
                {
                    return(false);
                }

                if (ast.Parent is null)
                {
                    return(true);
                }

                if (ast.Extent.StartOffset >= cursor)
                {
                    return(false);
                }

                // If the script block is closed, then we want the script block only if the cursor is within the script block.
                // Otherwise, if the script block is not completed, then we want the script block even if the cursor is at the end.
                int textLength = ast.Extent.Text.Length;

                return(ast.Extent.Text[textLength - 1] == '}'
                    ? ast.Extent.EndOffset - 1 > cursor
                    : ast.Extent.EndOffset >= cursor);
            }
        }
        /// <summary>
        /// Return true if mandatory parameters are used OR the cmdlet does not exist
        /// </summary>
        /// <param name="cmdAst"></param>
        /// <returns></returns>
        private bool MandatoryParameterExists(CommandAst cmdAst)
        {
            CommandInfo cmdInfo = null;
            List <ParameterMetadata>        mandParams = new List <ParameterMetadata>();
            IEnumerable <CommandElementAst> ceAsts     = null;
            bool returnValue = false;

            #region Predicates

            // Predicate to find ParameterAsts.
            Func <CommandElementAst, bool> foundParamASTs = delegate(CommandElementAst ceAst)
            {
                if (ceAst is CommandParameterAst)
                {
                    return(true);
                }
                return(false);
            };

            #endregion

            #region Compares parameter list and mandatory parameter list.

            cmdInfo = Helper.Instance.GetCommandInfo(cmdAst.GetCommandName());
            if (cmdInfo == null || (cmdInfo.CommandType != System.Management.Automation.CommandTypes.Cmdlet))
            {
                return(true);
            }

            // ignores if splatted variable is used
            if (Helper.Instance.HasSplattedVariable(cmdAst))
            {
                return(true);
            }

            // Gets parameters from command elements.
            ceAsts = cmdAst.CommandElements.Where <CommandElementAst>(foundParamASTs);

            // Gets mandatory parameters from cmdlet.
            // If cannot find any mandatory parameter, it's not necessary to do a further check for current cmdlet.
            try
            {
                int noOfParamSets = cmdInfo.ParameterSets.Count;
                foreach (ParameterMetadata pm in cmdInfo.Parameters.Values)
                {
                    int count = 0;

                    if (pm.Attributes.Count < noOfParamSets)
                    {
                        continue;
                    }

                    foreach (Attribute attr in pm.Attributes)
                    {
                        if (!(attr is ParameterAttribute))
                        {
                            continue;
                        }
                        if (((ParameterAttribute)attr).Mandatory)
                        {
                            count += 1;
                        }
                    }

                    if (count >= noOfParamSets)
                    {
                        mandParams.Add(pm);
                    }
                }
            }
            catch (Exception)
            {
                // For cases like cmd.exe. Also for runtime exception
                return(true);
            }

            if (mandParams.Count() == 0 || Helper.Instance.PositionalParameterUsed(cmdAst))
            {
                returnValue = true;
            }
            else
            {
                // Compares parameter list and mandatory parameter list.
                foreach (CommandElementAst ceAst in ceAsts)
                {
                    CommandParameterAst cpAst = (CommandParameterAst)ceAst;
                    if (mandParams.Count <ParameterMetadata>(item =>
                                                             item.Name.Equals(cpAst.ParameterName, StringComparison.OrdinalIgnoreCase)) > 0)
                    {
                        returnValue = true;
                        break;
                    }
                }
            }

            #endregion

            return(returnValue);
        }
Exemple #28
0
 public override object VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     script_.Write("-" + commandParameterAst.ParameterName);
     VisitElement(commandParameterAst.Argument);
     return(commandParameterAst);
 }
Exemple #29
0
 public override AstVisitAction VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     Console.WriteLine("Visited an CommandParameterAst.");
     Console.WriteLine("    " + commandParameterAst.ToString().Replace(Environment.NewLine, Environment.NewLine + "    "));
     return(AstVisitAction.Continue);
 }
Exemple #30
0
 public object VisitCommandParameter(CommandParameterAst commandParameterAst)
 {
     Console.WriteLine("Visited an CommandParameterAst.");
     return(commandParameterAst);
 }