private string GetCommandName(CommandElementAst commandNameAst, bool isTrustedInput)
        {
            var    exprAst = commandNameAst as ExpressionAst;
            string commandName;

            if (exprAst != null)
            {
                var value = GetExpressionValue(exprAst, isTrustedInput);
                if (value == null)
                {
                    ScriptBlockToPowerShellChecker.ThrowError(
                        new ScriptBlockToPowerShellNotSupportedException(
                            "CantConvertWithScriptBlockInvocation", null, AutomationExceptions.CantConvertWithScriptBlockInvocation),
                        exprAst);
                }

                if (value is CommandInfo)
                {
                    commandName = ((CommandInfo)value).Name;
                }
                else
                {
                    commandName = value as string;
                }
            }
            else
            {
                // If this assertion fires, the command name is determined incorrectly.
                Diagnostics.Assert(commandNameAst is CommandParameterAst, "Unexpected element not handled correctly.");
                commandName = commandNameAst.Extent.Text;
            }

            if (string.IsNullOrWhiteSpace(commandName))
            {
                // TODO: could use a better error here
                throw new ScriptBlockToPowerShellNotSupportedException(
                          "CantConvertWithScriptBlockInvocation",
                          null,
                          AutomationExceptions.CantConvertWithScriptBlockInvocation);
            }

            return(commandName);
        }
        /// <summary>
        /// Checks to see if the command invocation is a dot
        /// in order to find a dot sourced file
        /// </summary>
        /// <param name="commandAst">A CommandAst object in the script's AST</param>
        /// <returns>A decision to stop searching if the right commandAst was found,
        /// or a decision to continue if it wasn't found</returns>
        public override AstVisitAction VisitCommand(CommandAst commandAst)
        {
            CommandElementAst commandElementAst = commandAst.CommandElements[0];

            if (commandAst.InvocationOperator.Equals(TokenKind.Dot))
            {
                string path = commandElementAst switch
                {
                    StringConstantExpressionAst stringConstantExpressionAst => stringConstantExpressionAst.Value,
                    ExpandableStringExpressionAst expandableStringExpressionAst => GetPathFromExpandableStringExpression(expandableStringExpressionAst),
                    _ => null,
                };
                if (!string.IsNullOrWhiteSpace(path))
                {
                    DotSourcedFiles.Add(PathUtils.NormalizePathSeparators(path));
                }
            }

            return(base.VisitCommand(commandAst));
        }
예제 #3
0
        /// <summary>
        /// Creates a Linq expression for a <see cref="CommandAst" /> representing
        /// the "with" command.
        /// </summary>
        /// <param name="commandAst">The AST to convert.</param>
        /// <param name="targetAst">The AST containing the target of the keyword.</param>
        /// <param name="bodyAst">The AST containing the body of the keyword.</param>
        /// <param name="visitor">The <see cref="CompileVisitor" /> requesting the expression.</param>
        /// <returns>An expression representing the command.</returns>
        protected override Expression ProcessObjectAndBody(
            CommandAst commandAst,
            CommandElementAst targetAst,
            ScriptBlockExpressionAst bodyAst,
            CompileVisitor visitor)
        {
            var disposeVar = Expression.Variable(typeof(IDisposable));

            return(visitor.NewBlock(() =>
                                    Expression.Block(
                                        typeof(void),
                                        new[] { disposeVar },
                                        Expression.Assign(
                                            disposeVar,
                                            Expression.Convert(
                                                targetAst.Compile(visitor),
                                                typeof(IDisposable))),
                                        Expression.TryFinally(
                                            bodyAst.ScriptBlock.EndBlock.Compile(visitor),
                                            Expression.Call(disposeVar, ReflectionCache.IDisposable_Dispose)))));
        }
        public static CommandAst As(
            this Ast source,
            AstType <CommandAst> targetType,
            string commandName,
            TokenKind invocationOperator,
            params CommandElementAst[] elements)
        {
            var extent      = GetExtentFromConstant(commandName, source.Extent);
            var newElements = new CommandElementAst[elements.Length + 1];

            for (int i = 0; i < elements.Length; i++)
            {
                newElements[i + 1] = elements[i];
            }

            newElements[0] = source.As(StringConstantExpression, commandName);
            return(new CommandAst(
                       extent,
                       newElements,
                       invocationOperator,
                       Enumerable.Empty <RedirectionAst>()));
        }
예제 #5
0
        CommandParameter ConvertCommandElementToCommandParameter(CommandElementAst commandElement)
        {
            if (commandElement is CommandParameterAst)
            {
                var commandParameterAst = commandElement as CommandParameterAst;
                return(new CommandParameter(commandParameterAst.ParameterName, commandParameterAst.Argument));
            }

            else if (commandElement is StringConstantExpressionAst)
            {
                var stringConstantExpressionAst = commandElement as StringConstantExpressionAst;
                return(new CommandParameter(null, stringConstantExpressionAst.Value));
            }

            else if (commandElement is ExpressionAst)
            {
                return(new CommandParameter(null, EvaluateAst(commandElement)));
            }

            else
            {
                throw new NotImplementedException();
            }
        }
예제 #6
0
        private ArmResourceName?GetResourceName()
        {
            if (CommandAst.CommandElements is null)
            {
                return(null);
            }

            string resourceNamespace = null;
            string type       = null;
            string apiVersion = null;

            int expect = 0;

            for (int i = 0; i < CommandAst.CommandElements.Count; i++)
            {
                CommandElementAst element = CommandAst.CommandElements[i];

                if (element is CommandParameterAst parameterAst)
                {
                    expect = 0;
                    if (parameterAst.ParameterName.Is(nameof(NewPSArmResourceCommand.Type)))
                    {
                        expect = 1;
                    }
                    else if (parameterAst.ParameterName.Is(nameof(NewPSArmResourceCommand.ApiVersion)))
                    {
                        expect = 2;
                    }
                    else if (parameterAst.ParameterName.Is(nameof(NewPSArmResourceCommand.Namespace)))
                    {
                        expect = 3;
                    }

                    continue;
                }

                switch (expect)
                {
                case 1:
                    if (element is StringConstantExpressionAst typeStrExpr)
                    {
                        type = typeStrExpr.Value;
                    }
                    break;

                case 2:
                    if (element is StringConstantExpressionAst apiVersionStrExpr)
                    {
                        apiVersion = apiVersionStrExpr.Value;
                    }
                    break;

                case 3:
                    if (element is StringConstantExpressionAst providerStrExpr)
                    {
                        resourceNamespace = providerStrExpr.Value;
                    }
                    break;
                }

                expect = 0;
            }

            if (resourceNamespace is null &&
                type is null &&
                apiVersion is null)
            {
                return(null);
            }

            return(new ArmResourceName(resourceNamespace, type, apiVersion));
        }
예제 #7
0
        /// <summary>
        /// AnalyzeScript: Analyzes the ast to check that cmdlets have help.
        /// </summary>
        /// <param name="ast">The script's ast</param>
        /// <param name="fileName">The name of the script</param>
        /// <returns>A List of diagnostic results of this rule</returns>
        public IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null)
            {
                throw new ArgumentNullException(Strings.NullAstErrorMessage);
            }

            DiagnosticRecords.Clear();
            this.fileName     = fileName;
            exportedFunctions = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            List <string> exportFunctionsCmdlet = Helper.Instance.CmdletNameAndAliases("export-modulemember");

            // find functions exported
            IEnumerable <Ast> cmdAsts = ast.FindAll(item => item is CommandAst &&
                                                    exportFunctionsCmdlet.Contains((item as CommandAst).GetCommandName(), StringComparer.OrdinalIgnoreCase), true);

            CommandInfo exportMM = Helper.Instance.GetCommandInfo("export-modulemember", CommandTypes.Cmdlet);

            // switch parameters
            IEnumerable <ParameterMetadata> switchParams = (exportMM != null) ? exportMM.Parameters.Values.Where <ParameterMetadata>(pm => pm.SwitchParameter) : Enumerable.Empty <ParameterMetadata>();

            if (exportMM == null)
            {
                return(DiagnosticRecords);
            }

            foreach (CommandAst cmdAst in cmdAsts)
            {
                if (cmdAst.CommandElements == null || cmdAst.CommandElements.Count < 2)
                {
                    continue;
                }

                int i = 1;

                while (i < cmdAst.CommandElements.Count)
                {
                    CommandElementAst ceAst   = cmdAst.CommandElements[i];
                    ExpressionAst     exprAst = null;

                    if (ceAst is CommandParameterAst)
                    {
                        var paramAst = ceAst as CommandParameterAst;
                        var param    = exportMM.ResolveParameter(paramAst.ParameterName);

                        if (param == null)
                        {
                            i += 1;
                            continue;
                        }

                        if (string.Equals(param.Name, "function", StringComparison.OrdinalIgnoreCase))
                        {
                            // checks for the case of -Function:"verb-nouns"
                            if (paramAst.Argument != null)
                            {
                                exprAst = paramAst.Argument;
                            }
                            // checks for the case of -Function "verb-nouns"
                            else if (i < cmdAst.CommandElements.Count - 1)
                            {
                                i      += 1;
                                exprAst = cmdAst.CommandElements[i] as ExpressionAst;
                            }
                        }
                        // some other parameter. we just checks whether the one after this is positional
                        else if (i < cmdAst.CommandElements.Count - 1)
                        {
                            // the next element is a parameter like -module so just move to that one
                            if (cmdAst.CommandElements[i + 1] is CommandParameterAst)
                            {
                                i += 1;
                                continue;
                            }

                            // not a switch parameter so the next element is definitely the argument to this parameter
                            if (paramAst.Argument == null && !switchParams.Contains(param))
                            {
                                // skips the next element
                                i += 1;
                            }

                            i += 1;
                            continue;
                        }
                    }
                    else if (ceAst is ExpressionAst)
                    {
                        exprAst = ceAst as ExpressionAst;
                    }

                    if (exprAst != null)
                    {
                        // One string so just add this to the list
                        if (exprAst is StringConstantExpressionAst)
                        {
                            exportedFunctions.Add((exprAst as StringConstantExpressionAst).Value);
                        }
                        // Array of the form "v-n", "v-n1"
                        else if (exprAst is ArrayLiteralAst)
                        {
                            exportedFunctions.UnionWith(Helper.Instance.GetStringsFromArrayLiteral(exprAst as ArrayLiteralAst));
                        }
                        // Array of the form @("v-n", "v-n1")
                        else if (exprAst is ArrayExpressionAst)
                        {
                            ArrayExpressionAst arrExAst = exprAst as ArrayExpressionAst;
                            if (arrExAst.SubExpression != null && arrExAst.SubExpression.Statements != null)
                            {
                                foreach (StatementAst stAst in arrExAst.SubExpression.Statements)
                                {
                                    if (stAst is PipelineAst)
                                    {
                                        PipelineAst pipeAst = stAst as PipelineAst;
                                        if (pipeAst.PipelineElements != null)
                                        {
                                            foreach (CommandBaseAst cmdBaseAst in pipeAst.PipelineElements)
                                            {
                                                if (cmdBaseAst is CommandExpressionAst)
                                                {
                                                    exportedFunctions.UnionWith(Helper.Instance.GetStringsFromArrayLiteral((cmdBaseAst as CommandExpressionAst).Expression as ArrayLiteralAst));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    i += 1;
                }
            }

            ast.Visit(this);

            return(DiagnosticRecords);
        }
예제 #8
0
 /// <summary>
 /// Creates a Linq expression for a <see cref="CommandAst" /> representing
 /// a custom command.
 /// </summary>
 /// <param name="commandAst">The AST to convert.</param>
 /// <param name="targetAst">The AST containing the target of the keyword.</param>
 /// <param name="bodyAst">The AST containing the body of the keyword.</param>
 /// <param name="visitor">The <see cref="CompileVisitor" /> requesting the expression.</param>
 /// <returns>An expression representing the command.</returns>
 protected abstract Expression ProcessObjectAndBody(
     CommandAst commandAst,
     CommandElementAst targetAst,
     ScriptBlockExpressionAst bodyAst,
     CompileVisitor visitor);
예제 #9
0
 public static MemberExpressionAst Member(ExpressionAst expression, CommandElementAst member, bool isStatic = false)
 => Current.Member(expression, member, isStatic);
예제 #10
0
 public static InvokeMemberExpressionAst InvokeMember(
     bool isStatic,
     ExpressionAst expression,
     CommandElementAst method,
     params ExpressionAst[] arguments)
 => Current.InvokeMember(isStatic, expression, method, arguments);
예제 #11
0
        private List <CompletionResult> GetResultForString(CompletionContext completionContext, ref int replacementIndex, ref int replacementLength, bool isQuotedString)
        {
            if (isQuotedString)
            {
                return(null);
            }
            Token tokenAtCursor = completionContext.TokenAtCursor;
            Ast   ast           = completionContext.RelatedAsts.Last <Ast>();
            List <CompletionResult>       list = null;
            ExpandableStringExpressionAst ast2 = ast as ExpandableStringExpressionAst;
            StringConstantExpressionAst   ast3 = ast as StringConstantExpressionAst;

            if ((ast3 != null) || (ast2 != null))
            {
                string             input = (ast3 != null) ? ast3.Value : ast2.Value;
                StringConstantType type  = (ast3 != null) ? ast3.StringConstantType : ast2.StringConstantType;
                string             str2  = null;
                if (type == StringConstantType.DoubleQuoted)
                {
                    Match match = Regex.Match(input, @"(\$[\w\d]+\.[\w\d\*]*)$");
                    if (match.Success)
                    {
                        str2 = match.Groups[1].Value;
                    }
                    else if ((match = Regex.Match(input, @"(\[[\w\d\.]+\]::[\w\d\*]*)$")).Success)
                    {
                        str2 = match.Groups[1].Value;
                    }
                }
                if (str2 != null)
                {
                    int num3;
                    int num4;
                    int offset = tokenAtCursor.Extent.StartScriptPosition.Offset;
                    int length = (this._cursorPosition.Offset - offset) - 1;
                    if (length >= input.Length)
                    {
                        length = input.Length;
                    }
                    CompletionAnalysis analysis = new CompletionAnalysis(this._ast, this._tokens, this._cursorPosition, this._options);
                    CompletionContext  context  = analysis.CreateCompletionContext(completionContext.ExecutionContext);
                    context.Helper = completionContext.Helper;
                    List <CompletionResult> list2 = analysis.GetResultHelper(context, out num3, out num4, true);
                    if ((list2 != null) && (list2.Count > 0))
                    {
                        list              = new List <CompletionResult>();
                        replacementIndex  = (offset + 1) + (length - str2.Length);
                        replacementLength = str2.Length;
                        string str3 = str2.Substring(0, num3);
                        foreach (CompletionResult result in list2)
                        {
                            string completionText = str3 + result.CompletionText;
                            if (result.ResultType.Equals(CompletionResultType.Property))
                            {
                                completionText = TokenKind.DollarParen.Text() + completionText + TokenKind.RParen.Text();
                            }
                            else if (result.ResultType.Equals(CompletionResultType.Method))
                            {
                                completionText = TokenKind.DollarParen.Text() + completionText;
                            }
                            completionText = completionText + "\"";
                            list.Add(new CompletionResult(completionText, result.ListItemText, result.ResultType, result.ToolTip));
                        }
                    }
                    return(list);
                }
                CommandElementAst stringAst = ast as CommandElementAst;
                string            str5      = CompletionCompleters.ConcatenateStringPathArguments(stringAst, string.Empty, completionContext);
                if (str5 == null)
                {
                    return(list);
                }
                completionContext.WordToComplete = str5;
                if ((ast.Parent is CommandAst) || (ast.Parent is CommandParameterAst))
                {
                    list              = CompletionCompleters.CompleteCommandArgument(completionContext);
                    replacementIndex  = completionContext.ReplacementIndex;
                    replacementLength = completionContext.ReplacementLength;
                    return(list);
                }
                list = new List <CompletionResult>(CompletionCompleters.CompleteFilename(completionContext));
                if (str5.IndexOf('-') != -1)
                {
                    List <CompletionResult> collection = CompletionCompleters.CompleteCommand(completionContext);
                    if ((collection != null) && (collection.Count > 0))
                    {
                        list.AddRange(collection);
                    }
                }
            }
            return(list);
        }
 /// <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)
 {
     return(CeAst is CommandParameterAst && String.Equals((CeAst as CommandParameterAst).ParameterName, "AsPlainText", StringComparison.OrdinalIgnoreCase));
 }
예제 #13
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 abstract bool ParameterCondition(CommandAst CmdAst, CommandElementAst CeAst);