Beispiel #1
0
 public FunctionDefinitionAst(IScriptExtent extent, bool isFilter, bool isWorkflow, string name, IEnumerable<ParameterAst> parameters, ScriptBlockAst body) : base(extent)
 {
     if (string.IsNullOrEmpty(name))
     {
         throw PSTraceSource.NewArgumentNullException("name");
     }
     if (body == null)
     {
         throw PSTraceSource.NewArgumentNullException("body");
     }
     if (isFilter && isWorkflow)
     {
         throw PSTraceSource.NewArgumentException("isFilter");
     }
     this.IsFilter = isFilter;
     this.IsWorkflow = isWorkflow;
     this.Name = name;
     if ((parameters != null) && parameters.Any<ParameterAst>())
     {
         this.Parameters = new ReadOnlyCollection<ParameterAst>(parameters.ToArray<ParameterAst>());
         base.SetParents((IEnumerable<Ast>) this.Parameters);
     }
     this.Body = body;
     base.SetParent(body);
 }
        /// <summary>
        /// Parse the runbook content
        /// </summary>
        /// <param name="content"></param>
        public void Parse(string content)
        {
            if (_tokens == null || _scriptBlock == null)
                IsDirty = true;

            if (!IsDirty)
                return;

            _scriptBlock = System.Management.Automation.Language.Parser.ParseInput(content, out _tokens, out _parseErrors);

            if (_parseErrors != null && _parseErrors.Length > 0)
            {
                _currentlyHasParseErrors = true;
                OnParseError?.Invoke(this, new ParseErrorEventArgs(_parseErrors));
            }
            else if (_currentlyHasParseErrors)
            {
                _currentlyHasParseErrors = false;
                OnClearParseErrors?.Invoke(this, new EventArgs());
            }

            // Analyze the code too
            if (SettingsService.CurrentSettings.EnableCodeAnalysis && !string.IsNullOrEmpty(content) && IsDirty)
            {
                Task.Run(() =>
                {
                    var records = AnalyzerService.Analyze(_scriptBlock, _tokens);//ScriptAnalyzer.Instance.AnalyzeSyntaxTree(_scriptBlock, _tokens, string.Empty);

                    if (SettingsService.CurrentSettings.EnableCodeAnalysis)
                    {// && (_cachedRecords == null || _cachedRecords.Count() != records.Count()))
                        Execute.OnUIThread(() => { OnAnalysisCompleted?.Invoke(this, new AnalysisEventArgs(records)); });
                    }
                });
            }
        }
Beispiel #3
0
 internal Command(ScriptBlockAst scriptBlockAst, bool useLocalScope = false)
     : this()
 {
     this.ScriptBlockAst = scriptBlockAst;
     this.UseLocalScope = useLocalScope;
     IsScript = false;
 }
Beispiel #4
0
        public static bool TryParsePartialInput(string input, out ScriptBlockAst scriptBlock,
            out string lastControlStmt)
        {
            scriptBlock = null;
            lastControlStmt = "";
            var parseTree = Parse(input, true);
            if (parseTree.Status.Equals(ParseTreeStatus.Parsed))
            {
                scriptBlock = new AstBuilder(Grammar, parseTree).BuildScriptBlockAst(parseTree.Root);
                return true;
            }
            // if we're here we only partially parsed, because Parse would have thrown on error
            var reversedTokens = parseTree.Tokens.Reverse<Token>();
            foreach (var token in reversedTokens)
            {
                if (token.KeyTerm != null &&
                    ControlStatementKeywords.Contains(token.KeyTerm.Text, StringComparer.InvariantCultureIgnoreCase))
                {
                    lastControlStmt = token.KeyTerm.Text;
                    break;
                }
            }

            return false;
        }
 public ScriptBlockExpressionAst(IScriptExtent extent, ScriptBlockAst scriptBlock) : base(extent)
 {
     if (scriptBlock == null)
     {
         throw PSTraceSource.NewArgumentNullException("scriptBlock");
     }
     this.ScriptBlock = scriptBlock;
     base.SetParent(scriptBlock);
 }
Beispiel #6
0
 public FunctionDefinitionAst(IScriptExtent extent, bool isFilter, bool isWorkflow, string name, IEnumerable<ParameterAst> parameters, ScriptBlockAst body)
     : base(extent)
 {
     this.IsFilter = isFilter;
     this.IsWorkflow = isWorkflow;
     this.Name = name;
     this.Parameters = parameters.ToReadOnlyCollection();
     this.Body = body;
 }
Beispiel #7
0
 internal static void CheckAst(Parser parser, ScriptBlockAst ast)
 {
     SemanticChecks semanticChecker = new SemanticChecks(parser);
     semanticChecker._scopeStack.Push(ast);
     ast.InternalVisit(semanticChecker);
     semanticChecker._scopeStack.Pop();
     Diagnostics.Assert(semanticChecker._memberScopeStack.Count == 0, "Unbalanced push/pop of member scope stack");
     Diagnostics.Assert(semanticChecker._scopeStack.Count == 0, "Unbalanced push/pop of scope stack");
 }
Beispiel #8
0
    public System.Object VisitScriptBlock(System.Management.Automation.Language.ScriptBlockAst scriptBlockAst)
    {
        IScriptExtent mappedExtent = MapExtent(scriptBlockAst.Extent);

        ParamBlockAst mappedParamBlock = scriptBlockAst.ParamBlock == null ? null : (ParamBlockAst)VisitParamBlock(scriptBlockAst.ParamBlock);

        NamedBlockAst mappedBeginBlock        = scriptBlockAst.BeginBlock == null ? null : (NamedBlockAst)VisitNamedBlock(scriptBlockAst.BeginBlock);
        NamedBlockAst mappedProcessBlock      = scriptBlockAst.ProcessBlock == null ? null : (NamedBlockAst)VisitNamedBlock(scriptBlockAst.ProcessBlock);
        NamedBlockAst mappedEndBlock          = scriptBlockAst.EndBlock == null ? null : (NamedBlockAst)VisitNamedBlock(scriptBlockAst.EndBlock);
        NamedBlockAst mappedDynamicParamBlock = scriptBlockAst.DynamicParamBlock == null ? null : (NamedBlockAst)VisitNamedBlock(scriptBlockAst.DynamicParamBlock);

        return(new ScriptBlockAst(mappedExtent, mappedParamBlock, mappedBeginBlock, mappedProcessBlock, mappedEndBlock, mappedDynamicParamBlock));
    }
Beispiel #9
0
        internal static void ResolveSymbols(Parser parser, ScriptBlockAst scriptBlockAst)
        {
            Diagnostics.Assert(scriptBlockAst.Parent == null, "Can only resolve starting from the root");

            var usingState = scriptBlockAst.UsingStatements.Count > 0
                ? new TypeResolutionState(TypeOps.GetNamespacesForTypeResolutionState(scriptBlockAst.UsingStatements), TypeResolutionState.emptyAssemblies)
                : TypeResolutionState.GetDefaultUsingState(null);
            var resolver = new SymbolResolver(parser, usingState);

            resolver._symbolTable.EnterScope(scriptBlockAst, ScopeType.ScriptBlock);
            scriptBlockAst.Visit(resolver);
            resolver._symbolTable.LeaveScope();

            Diagnostics.Assert(resolver._symbolTable._scopes.Count == 0, "Somebody missed removing a scope");
        }
Beispiel #10
0
 internal static void DefineWorkflows(ExecutionContext context, ScriptBlockAst scriptBlockAst)
 {
     try
     {
         foreach (WorkflowInfo info in Utils.GetAstToWorkflowConverterAndEnsureWorkflowModuleLoaded(context).CompileWorkflows(scriptBlockAst, null))
         {
             context.EngineSessionState.SetWorkflowRaw(info, context.EngineSessionState.CurrentScope.ScopeOrigin);
         }
     }
     catch (Exception exception)
     {
         CommandProcessorBase.CheckForSevereException(exception);
         RuntimeException exception2 = exception as RuntimeException;
         if (exception2 == null)
         {
             throw ExceptionHandlingOps.ConvertToRuntimeException(exception, scriptBlockAst.Extent);
         }
         InterpreterError.UpdateExceptionErrorRecordPosition(exception2, scriptBlockAst.Extent);
         throw;
     }
 }
Beispiel #11
0
 public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     this._currentBlock = this._entryBlock;
     if (scriptBlockAst.DynamicParamBlock != null)
     {
         scriptBlockAst.DynamicParamBlock.Accept(this);
     }
     if (scriptBlockAst.BeginBlock != null)
     {
         scriptBlockAst.BeginBlock.Accept(this);
     }
     if (scriptBlockAst.ProcessBlock != null)
     {
         scriptBlockAst.ProcessBlock.Accept(this);
     }
     if (scriptBlockAst.EndBlock != null)
     {
         scriptBlockAst.EndBlock.Accept(this);
     }
     this._currentBlock.FlowsTo(this._exitBlock);
     return(null);
 }
Beispiel #12
0
 public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     throw PSTraceSource.NewArgumentException("ast");
 }
 public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     this.ReportError(scriptBlockAst, () => ParserStrings.ScriptBlockNotSupportedInDataSection, new object[0]);
     return(AstVisitAction.Continue);
 }
Beispiel #14
0
 public override AstVisitAction VisitScriptBlock(ScriptBlockAst ast)
 {
     return(Check(ast));
 }
Beispiel #15
0
 public virtual AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     return AstVisitAction.Continue;
 }
Beispiel #16
0
 public static IEnumerable<DiagnosticRecord> Analyze(ScriptBlockAst scriptBlock, Token[] tokens)
 {
     return ScriptAnalyzer.Instance.AnalyzeSyntaxTree(scriptBlock, tokens, string.Empty);
 }
Beispiel #17
0
        public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
        {
            var funcDefn = scriptBlockAst.Parent as FunctionDefinitionAst;
            var funcName = (funcDefn != null) ? funcDefn.Name : "<ScriptBlock>";

            var rootForDefiningTypesAndUsings = scriptBlockAst.Find(ast => ast is TypeDefinitionAst || ast is UsingStatementAst, true) != null
                ? scriptBlockAst
                : null;

            if (scriptBlockAst.DynamicParamBlock != null)
            {
                _dynamicParamBlockLambda = CompileNamedBlock(scriptBlockAst.DynamicParamBlock, funcName + "<DynamicParam>", rootForDefiningTypesAndUsings);
                rootForDefiningTypesAndUsings = null;
            }

            // Skip param block - nothing to generate, defaults get generated when generating parameter metadata.

            if (scriptBlockAst.BeginBlock != null)
            {
                _beginBlockLambda = CompileNamedBlock(scriptBlockAst.BeginBlock, funcName + "<Begin>", rootForDefiningTypesAndUsings);
                rootForDefiningTypesAndUsings = null;
            }
            if (scriptBlockAst.ProcessBlock != null)
            {
                var processFuncName = funcName;
                if (!scriptBlockAst.ProcessBlock.Unnamed)
                {
                    processFuncName = funcName + "<Process>";
                }
                _processBlockLambda = CompileNamedBlock(scriptBlockAst.ProcessBlock, processFuncName, rootForDefiningTypesAndUsings);
                rootForDefiningTypesAndUsings = null;
            }
            if (scriptBlockAst.EndBlock != null)
            {
                if (!scriptBlockAst.EndBlock.Unnamed)
                {
                    funcName = funcName + "<End>";
                }
                _endBlockLambda = CompileNamedBlock(scriptBlockAst.EndBlock, funcName, rootForDefiningTypesAndUsings);
            }

            return null;
        }
Beispiel #18
0
 public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     this._currentBlock = this._entryBlock;
     if (scriptBlockAst.DynamicParamBlock != null)
     {
         scriptBlockAst.DynamicParamBlock.Accept(this);
     }
     if (scriptBlockAst.BeginBlock != null)
     {
         scriptBlockAst.BeginBlock.Accept(this);
     }
     if (scriptBlockAst.ProcessBlock != null)
     {
         scriptBlockAst.ProcessBlock.Accept(this);
     }
     if (scriptBlockAst.EndBlock != null)
     {
         scriptBlockAst.EndBlock.Accept(this);
     }
     this._currentBlock.FlowsTo(this._exitBlock);
     return null;
 }
Beispiel #19
0
        public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
        {
            try
            {
                scriptBlockAst.EndBlock.Visit(this);
            }
            catch (ReturnException e)
            {
                _pipelineCommandRuntime.WriteObject(e.Value);
            }

            return AstVisitAction.SkipChildren;
        }
Beispiel #20
0
 private static Ast GetLastAstAtCursor(ScriptBlockAst scriptBlockAst, IScriptPosition cursorPosition)
 {
     var asts = AstSearcher.FindAll(scriptBlockAst, ast => IsCursorRightAfterExtent(cursorPosition, ast.Extent), searchNestedScriptBlocks: true);
     return asts.LastOrDefault();
 }
        /// <summary>
        /// Analyzes a single script file.
        /// </summary>
        /// <param name="filePath">The path to the file ot analyze</param>
        private void AnalyzeFile(string filePath)
        {
            Token[] tokens = null;
            ParseError[] errors = null;
            ConcurrentBag<DiagnosticRecord> diagnostics = new ConcurrentBag<DiagnosticRecord>();
            ConcurrentBag<SuppressedRecord> suppressed = new ConcurrentBag<SuppressedRecord>();
            BlockingCollection<List<object>> verboseOrErrors = new BlockingCollection<List<object>>();

            // Use a List of KVP rather than dictionary, since for a script containing inline functions with same signature, keys clash
            List<KeyValuePair<CommandInfo, IScriptExtent>> cmdInfoTable = new List<KeyValuePair<CommandInfo, IScriptExtent>>();

            //Check wild card input for the Include/ExcludeRules and create regex match patterns
            includeRegexList = new List<Regex>();
            excludeRegexList = new List<Regex>();
            if (includeRule != null)
            {
                foreach (string rule in includeRule)
                {
                    Regex includeRegex = new Regex(String.Format("^{0}$", Regex.Escape(rule).Replace(@"\*", ".*")), RegexOptions.IgnoreCase);
                    includeRegexList.Add(includeRegex);
                }
            }
            if (excludeRule != null)
            {
                foreach (string rule in excludeRule)
                {
                    Regex excludeRegex = new Regex(String.Format("^{0}$", Regex.Escape(rule).Replace(@"\*", ".*")), RegexOptions.IgnoreCase);
                    excludeRegexList.Add(excludeRegex);
                }
            }

            //Parse the file
            if (File.Exists(filePath))
            {
                ast = Parser.ParseFile(filePath, out tokens, out errors);
            }
            else
            {
                ThrowTerminatingError(new ErrorRecord(new FileNotFoundException(),
                    string.Format(CultureInfo.CurrentCulture, Strings.InvalidPath, filePath),
                    ErrorCategory.InvalidArgument, filePath));
            }

            if (errors != null && errors.Length > 0)
            {
                foreach (ParseError error in errors)
                {
                    string parseErrorMessage = String.Format(CultureInfo.CurrentCulture, Strings.ParserErrorFormat, error.Extent.File, error.Message.TrimEnd('.'), error.Extent.StartLineNumber, error.Extent.StartColumnNumber);
                    WriteError(new ErrorRecord(new ParseException(parseErrorMessage), parseErrorMessage, ErrorCategory.ParserError, error.ErrorId));
                }
            }

            if (errors.Length > 10)
            {
                string manyParseErrorMessage = String.Format(CultureInfo.CurrentCulture, Strings.ParserErrorMessage, System.IO.Path.GetFileName(filePath));
                WriteError(new ErrorRecord(new ParseException(manyParseErrorMessage), manyParseErrorMessage, ErrorCategory.ParserError, filePath));

                return;
            }

            ruleSuppressions = Helper.Instance.GetRuleSuppression(ast);

            foreach (List<RuleSuppression> ruleSuppressionsList in ruleSuppressions.Values)
            {
                foreach (RuleSuppression ruleSuppression in ruleSuppressionsList)
                {
                    if (!String.IsNullOrWhiteSpace(ruleSuppression.Error))
                    {
                        WriteError(new ErrorRecord(new ArgumentException(ruleSuppression.Error), ruleSuppression.Error, ErrorCategory.InvalidArgument, ruleSuppression));
                    }
                }
            }

            #region Run VariableAnalysis
            try
            {
                Helper.Instance.InitializeVariableAnalysis(ast);
            }
            catch { }
            #endregion

            Helper.Instance.Tokens = tokens;

            #region Run ScriptRules
            //Trim down to the leaf element of the filePath and pass it to Diagnostic Record
            string fileName = System.IO.Path.GetFileName(filePath);

            if (ScriptAnalyzer.Instance.ScriptRules != null)
            {
                var tasks = ScriptAnalyzer.Instance.ScriptRules.Select(scriptRule => Task.Factory.StartNew(() =>
                    {
                        bool includeRegexMatch = false;
                        bool excludeRegexMatch = false;

                        foreach (Regex include in includeRegexList)
                        {
                            if (include.IsMatch(scriptRule.GetName()))
                            {
                                includeRegexMatch = true;
                                break;
                            }
                        }

                        foreach (Regex exclude in excludeRegexList)
                        {
                            if (exclude.IsMatch(scriptRule.GetName()))
                            {
                                excludeRegexMatch = true;
                                break;
                            }
                        }

                        if ((includeRule == null || includeRegexMatch) && (excludeRule == null || !excludeRegexMatch))
                        {
                            List<object> result = new List<object>();

                            result.Add(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, scriptRule.GetName()));

                            // Ensure that any unhandled errors from Rules are converted to non-terminating errors
                            // We want the Engine to continue functioning even if one or more Rules throws an exception
                            try
                            {
                                var records = Helper.Instance.SuppressRule(scriptRule.GetName(), ruleSuppressions, scriptRule.AnalyzeScript(ast, ast.Extent.File).ToList());
                                foreach (var record in records.Item2)
                                {
                                    diagnostics.Add(record);
                                }
                                foreach (var suppressedRec in records.Item1)
                                {
                                    suppressed.Add(suppressedRec);
                                }
                            }
                            catch (Exception scriptRuleException)
                            {
                                result.Add(new ErrorRecord(scriptRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, ast.Extent.File));
                            }

                            verboseOrErrors.Add(result);
                        }
                }));

                Task.Factory.ContinueWhenAll(tasks.ToArray(), t => verboseOrErrors.CompleteAdding());

                while (!verboseOrErrors.IsCompleted)
                {
                    List<object> data = null;
                    try
                    {
                        data = verboseOrErrors.Take();
                    }
                    catch (InvalidOperationException) { }

                    if (data != null)
                    {
                        WriteVerbose(data[0] as string);
                        if (data.Count == 2)
                        {
                            WriteError(data[1] as ErrorRecord);
                        }
                    }
                }
            }

            #endregion

            #region Run Token Rules

            if (ScriptAnalyzer.Instance.TokenRules != null)
            {
                foreach (ITokenRule tokenRule in ScriptAnalyzer.Instance.TokenRules)
                {
                    bool includeRegexMatch = false;
                    bool excludeRegexMatch = false;
                    foreach (Regex include in includeRegexList)
                    {
                        if (include.IsMatch(tokenRule.GetName()))
                        {
                            includeRegexMatch = true;
                            break;
                        }
                    }
                    foreach (Regex exclude in excludeRegexList)
                    {
                        if (exclude.IsMatch(tokenRule.GetName()))
                        {
                            excludeRegexMatch = true;
                            break;
                        }
                    }
                    if ((includeRule == null || includeRegexMatch) && (excludeRule == null || !excludeRegexMatch))
                    {
                        WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, tokenRule.GetName()));

                        // Ensure that any unhandled errors from Rules are converted to non-terminating errors
                        // We want the Engine to continue functioning even if one or more Rules throws an exception
                        try
                        {
                            var records = Helper.Instance.SuppressRule(tokenRule.GetName(), ruleSuppressions, tokenRule.AnalyzeTokens(tokens, filePath).ToList());
                            foreach (var record in records.Item2)
                            {
                                diagnostics.Add(record);
                            }
                            foreach (var suppressedRec in records.Item1)
                            {
                                suppressed.Add(suppressedRec);
                            }
                        }
                        catch (Exception tokenRuleException)
                        {
                            WriteError(new ErrorRecord(tokenRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, fileName));
                        }
                    }
                }
            }

            #endregion

            #region DSC Resource Rules
            if (ScriptAnalyzer.Instance.DSCResourceRules != null)
            {
                // Invoke AnalyzeDSCClass only if the ast is a class based resource
                if (Helper.Instance.IsDscResourceClassBased(ast))
                {
                    // Run DSC Class rule
                    foreach (IDSCResourceRule dscResourceRule in ScriptAnalyzer.Instance.DSCResourceRules)
                    {
                        bool includeRegexMatch = false;
                        bool excludeRegexMatch = false;

                        foreach (Regex include in includeRegexList)
                        {
                            if (include.IsMatch(dscResourceRule.GetName()))
                            {
                                includeRegexMatch = true;
                                break;
                            }
                        }

                        foreach (Regex exclude in excludeRegexList)
                        {
                            if (exclude.IsMatch(dscResourceRule.GetName()))
                            {
                                excludeRegexMatch = true;
                                break;
                            }
                        }

                        if ((includeRule == null || includeRegexMatch) && (excludeRule == null || excludeRegexMatch))
                        {
                            WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, dscResourceRule.GetName()));

                            // Ensure that any unhandled errors from Rules are converted to non-terminating errors
                            // We want the Engine to continue functioning even if one or more Rules throws an exception
                            try
                            {
                                var records = Helper.Instance.SuppressRule(dscResourceRule.GetName(), ruleSuppressions, dscResourceRule.AnalyzeDSCClass(ast, filePath).ToList());
                                foreach (var record in records.Item2)
                                {
                                    diagnostics.Add(record);
                                }
                                foreach (var suppressedRec in records.Item1)
                                {
                                    suppressed.Add(suppressedRec);
                                }
                            }
                            catch (Exception dscResourceRuleException)
                            {
                                WriteError(new ErrorRecord(dscResourceRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, filePath));
                            }
                        }
                    }
                }

                // Check if the supplied artifact is indeed part of the DSC resource
                if (Helper.Instance.IsDscResourceModule(filePath))
                {
                    // Run all DSC Rules
                    foreach (IDSCResourceRule dscResourceRule in ScriptAnalyzer.Instance.DSCResourceRules)
                    {
                        bool includeRegexMatch = false;
                        bool excludeRegexMatch = false;
                        foreach (Regex include in includeRegexList)
                        {
                            if (include.IsMatch(dscResourceRule.GetName()))
                            {
                                includeRegexMatch = true;
                                break;
                            }
                        }
                        foreach (Regex exclude in excludeRegexList)
                        {
                            if (exclude.IsMatch(dscResourceRule.GetName()))
                            {
                                excludeRegexMatch = true;
                            }
                        }
                        if ((includeRule == null || includeRegexMatch) && (excludeRule == null || !excludeRegexMatch))
                        {
                            WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, dscResourceRule.GetName()));

                            // Ensure that any unhandled errors from Rules are converted to non-terminating errors
                            // We want the Engine to continue functioning even if one or more Rules throws an exception
                            try
                            {
                                var records = Helper.Instance.SuppressRule(dscResourceRule.GetName(), ruleSuppressions, dscResourceRule.AnalyzeDSCResource(ast, filePath).ToList());
                                foreach (var record in records.Item2)
                                {
                                    diagnostics.Add(record);
                                }
                                foreach (var suppressedRec in records.Item1)
                                {
                                    suppressed.Add(suppressedRec);
                                }
                            }
                            catch (Exception dscResourceRuleException)
                            {
                                WriteError(new ErrorRecord(dscResourceRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, filePath));
                            }
                        }
                    }

                }
            }
            #endregion

            #region Run External Rules

            if (ScriptAnalyzer.Instance.ExternalRules != null)
            {
                List<ExternalRule> exRules = new List<ExternalRule>();

                foreach (ExternalRule exRule in ScriptAnalyzer.Instance.ExternalRules)
                {
                    if ((includeRule == null || includeRule.Contains(exRule.GetName(), StringComparer.OrdinalIgnoreCase)) &&
                        (excludeRule == null || !excludeRule.Contains(exRule.GetName(), StringComparer.OrdinalIgnoreCase)))
                    {
                        string ruleName = string.Format(CultureInfo.CurrentCulture, "{0}\\{1}", exRule.GetSourceName(), exRule.GetName());
                        WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, ruleName));

                        // Ensure that any unhandled errors from Rules are converted to non-terminating errors
                        // We want the Engine to continue functioning even if one or more Rules throws an exception
                        try
                        {
                            exRules.Add(exRule);
                        }
                        catch (Exception externalRuleException)
                        {
                            WriteError(new ErrorRecord(externalRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, fileName));
                        }
                    }
                }

                foreach (var record in ScriptAnalyzer.Instance.GetExternalRecord(ast, tokens, exRules.ToArray(), this, fileName))
                {
                    diagnostics.Add(record);
                }
            }

            #endregion

            IEnumerable<DiagnosticRecord> diagnosticsList = diagnostics;

            if (severity != null)
            {
                var diagSeverity = severity.Select(item => Enum.Parse(typeof(DiagnosticSeverity), item, true));
                diagnosticsList = diagnostics.Where(item => diagSeverity.Contains(item.Severity));
            }

            //Output through loggers
            foreach (ILogger logger in ScriptAnalyzer.Instance.Loggers)
            {
                if (SuppressedOnly)
                {
                    foreach (DiagnosticRecord suppressRecord in suppressed)
                    {
                        logger.LogObject(suppressRecord, this);
                    }
                }
                else
                {
                    foreach (DiagnosticRecord diagnostic in diagnosticsList)
                    {
                        logger.LogObject(diagnostic, this);
                    }
                }
            }
        }
 public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     this.ReportError(scriptBlockAst, () => ParserStrings.ScriptBlockNotSupportedInDataSection, new object[0]);
     return AstVisitAction.Continue;
 }
 public FunctionDefinitionAst(IScriptExtent extent, bool isFilter, bool isWorkflow, string name, IEnumerable <ParameterAst> parameters, ScriptBlockAst body) : base(extent)
 {
     if (string.IsNullOrEmpty(name))
     {
         throw PSTraceSource.NewArgumentNullException("name");
     }
     if (body == null)
     {
         throw PSTraceSource.NewArgumentNullException("body");
     }
     if (isFilter && isWorkflow)
     {
         throw PSTraceSource.NewArgumentException("isFilter");
     }
     this.IsFilter   = isFilter;
     this.IsWorkflow = isWorkflow;
     this.Name       = name;
     if ((parameters != null) && parameters.Any <ParameterAst>())
     {
         this.Parameters = new ReadOnlyCollection <ParameterAst>(parameters.ToArray <ParameterAst>());
         base.SetParents((IEnumerable <Ast>) this.Parameters);
     }
     this.Body = body;
     base.SetParent(body);
 }
Beispiel #24
0
        private void GenerateTypesAndUsings(ScriptBlockAst rootForDefiningTypesAndUsings, List<Expression> exprs)
        {
            // We don't postpone load assemblies, import modules from 'using' to the moment, when enclosed scriptblock is executed.
            // We do loading, when root of the script is compiled.
            // This allow us to avoid creating 10 different classes in this situation:
            // 1..10 | % { class C {} }
            // But it's possible that we are loading something from the codepaths that we never execute.

            // If Parent of rootForDefiningTypesAndUsings is not null, then we already defined all types, when Visit a parent ScriptBlock
            if (rootForDefiningTypesAndUsings.Parent == null)
            {
                if (rootForDefiningTypesAndUsings.UsingStatements.Any())
                {
                    bool allUsingsAreNamespaces = rootForDefiningTypesAndUsings.UsingStatements.All(us => us.UsingStatementKind == UsingStatementKind.Namespace);
                    GenerateLoadUsings(rootForDefiningTypesAndUsings.UsingStatements, allUsingsAreNamespaces, exprs);
                }

                TypeDefinitionAst[] typeAsts =
                    rootForDefiningTypesAndUsings.FindAll(ast => ast is TypeDefinitionAst, true)
                        .Cast<TypeDefinitionAst>()
                        .ToArray();

                if (typeAsts.Length > 0)
                {
                    var assembly = DefinePowerShellTypes(rootForDefiningTypesAndUsings, typeAsts);
                    exprs.Add(Expression.Call(CachedReflectionInfo.TypeOps_SetAssemblyDefiningPSTypes,
                        _functionContext, Expression.Constant(assembly)));

                    exprs.Add(Expression.Call(CachedReflectionInfo.TypeOps_InitPowerShellTypesAtRuntime,
                        Expression.Constant(typeAsts)));
                }
            }

            Dictionary<string, TypeDefinitionAst> typesToAddToScope =
                rootForDefiningTypesAndUsings.FindAll(ast => ast is TypeDefinitionAst, false)
                    .Cast<TypeDefinitionAst>()
                    .ToDictionary(type => type.Name);
            if (typesToAddToScope.Count > 0)
            {
                exprs.Add(Expression.Call(CachedReflectionInfo.TypeOps_AddPowerShellTypesToTheScope,
                    Expression.Constant(typesToAddToScope), _executionContextParameter));
            }
        }
Beispiel #25
0
        private Expression<Action<FunctionContext>> CompileSingleLambda(ReadOnlyCollection<StatementAst> statements,
                                             ReadOnlyCollection<TrapStatementAst> traps,
                                             string funcName,
                                             IScriptExtent entryExtent,
                                             IScriptExtent exitExtent,
                                             ScriptBlockAst rootForDefiningTypesAndUsings)
        {
            _currentFunctionName = funcName;

            _loopTargets.Clear();

            _returnTarget = Expression.Label("returnTarget");
            var exprs = new List<Expression>();
            var temps = new List<ParameterExpression>();

            GenerateFunctionProlog(exprs, temps, entryExtent);

            if (rootForDefiningTypesAndUsings != null)
            {
                GenerateTypesAndUsings(rootForDefiningTypesAndUsings, exprs);
            }

            var actualBodyExprs = new List<Expression>();

            if (CompilingMemberFunction)
            {
                temps.Add(_returnPipe);
            }

            CompileStatementListWithTraps(statements, traps, actualBodyExprs, temps);

            exprs.AddRange(actualBodyExprs);

            // We always add the return label even if it's unused - that way it doesn't matter what the last
            // expression is in the body - the full body will always have void type.
            exprs.Add(Expression.Label(_returnTarget));

            GenerateFunctionEpilog(exprs, exitExtent);

            temps.Add(LocalVariablesParameter);
            Expression body = Expression.Block(temps, exprs);

            // A return from a normal block is just that - a simple return (no exception).
            // A return from a trap turns into an exception because the trap is compiled into a different lambda, yet
            // the return from the trap must return from the function containing the trap.  So we wrap the full
            // body of regular begin/process/end blocks with a try/catch so a return from the trap returns
            // to the right place.  We can avoid also avoid generating the catch if we know there aren't any traps.
            if (!_compilingTrap &&
                ((traps != null && traps.Count > 0)
                || statements.Any(stmt => AstSearcher.Contains(stmt, ast => ast is TrapStatementAst, searchNestedScriptBlocks: false))))
            {
                body = Expression.Block(
                    new[] { _executionContextParameter },
                    Expression.TryCatchFinally(
                        body,
                        Expression.Call(
                            Expression.Field(_executionContextParameter, CachedReflectionInfo.ExecutionContext_Debugger),
                            CachedReflectionInfo.Debugger_ExitScriptFunction),
                        Expression.Catch(typeof(ReturnException), ExpressionCache.Empty)));
            }
            else
            {
                // Either no traps, or we're compiling a trap - either way don't catch the ReturnException.
                body = Expression.Block(
                    new[] { _executionContextParameter },
                    Expression.TryFinally(
                        body,
                        Expression.Call(
                            Expression.Field(_executionContextParameter, CachedReflectionInfo.ExecutionContext_Debugger),
                            CachedReflectionInfo.Debugger_ExitScriptFunction)));
            }

            return Expression.Lambda<Action<FunctionContext>>(body, funcName, new[] { _functionContext });
        }
Beispiel #26
0
        internal static void ResolveSymbols(Parser parser, ScriptBlockAst scriptBlockAst)
        {
            Diagnostics.Assert(scriptBlockAst.Parent == null, "Can only resolve starting from the root");

            var usingState = scriptBlockAst.UsingStatements.Count > 0
                ? new TypeResolutionState(TypeOps.GetNamespacesForTypeResolutionState(scriptBlockAst.UsingStatements), TypeResolutionState.emptyAssemblies)
                : TypeResolutionState.GetDefaultUsingState(null);
            var resolver = new SymbolResolver(parser, usingState);
            resolver._symbolTable.EnterScope(scriptBlockAst, ScopeType.ScriptBlock);
            scriptBlockAst.Visit(resolver);
            resolver._symbolTable.LeaveScope();

            Diagnostics.Assert(resolver._symbolTable._scopes.Count == 0, "Somebody missed removing a scope");
        }
 public ScriptBlockExpressionAst(IScriptExtent extent, ScriptBlockAst scriptBlock)
     : base(extent)
 {
     this.ScriptBlock = scriptBlock;
 }
Beispiel #28
0
        public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
        {
            try
            {
                scriptBlockAst.EndBlock.Visit(this);
            }
            catch (ReturnException)
            {
            }

            return AstVisitAction.SkipChildren;
        }
        /// <summary>
        /// Visit script block
        /// </summary>
        /// <param name="scriptBlockAst"></param>
        /// <returns></returns>
        public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
        {
            if (scriptBlockAst == null) return null;

            _currentBlock = _entryBlock;

            if (scriptBlockAst.DynamicParamBlock != null)
            {
                scriptBlockAst.DynamicParamBlock.Visit(this.Decorator);
            }

            if (scriptBlockAst.BeginBlock != null)
            {
                scriptBlockAst.BeginBlock.Visit(this.Decorator);
            }
            if (scriptBlockAst.ProcessBlock != null)
            {
                scriptBlockAst.ProcessBlock.Visit(this.Decorator);
            }
            if (scriptBlockAst.EndBlock != null)
            {
                scriptBlockAst.EndBlock.Visit(this.Decorator);
            }

            _currentBlock.FlowsTo(_exitBlock);

            return null;
        }
Beispiel #30
0
 internal Command(ScriptBlockAst scriptBlockAst)
     : this()
 {
     this.ScriptBlockAst = scriptBlockAst;
     IsScript = false;
 }
 /// <summary/>
 public virtual object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     return _decorated.VisitScriptBlock(scriptBlockAst);
 }
        /// <summary>
        /// Finds all references (not including aliases) in a script for the given symbol
        /// </summary>
        /// <param name="scriptAst">The abstract syntax tree of the given script</param>
        /// <param name="foundSymbol">The symbol that we are looking for referneces of</param>
        /// <param name="needsAliases">If this reference search needs aliases.
        /// This should always be false and used for occurence requests</param>
        /// <returns>A collection of SymbolReference objects that are refrences to the symbolRefrence
        /// not including aliases</returns>
        public static IEnumerable<SymbolReference> FindReferencesOfSymbol(
            ScriptBlockAst scriptAst, 
            SymbolReference foundSymbol, 
            bool needsAliases)
        {
            FindReferencesVisitor referencesVisitor =
                new FindReferencesVisitor(foundSymbol);
            scriptAst.Visit(referencesVisitor);

            return referencesVisitor.FoundReferences;
        }
Beispiel #33
0
 public FunctionDefinitionAst(IScriptExtent extent, bool isFilter, bool isWorkflow, string name, IEnumerable <ParameterAst> parameters, ScriptBlockAst body)
     : base(extent)
 {
     this.IsFilter   = isFilter;
     this.IsWorkflow = isWorkflow;
     this.Name       = name;
     this.Parameters = parameters.ToReadOnlyCollection();
     this.Body       = body;
 }
Beispiel #34
0
        internal static void CheckAst(Parser parser, ScriptBlockAst ast)
        {
            SemanticChecks visitor = new SemanticChecks(parser);

            ast.InternalVisit(visitor);
        }
Beispiel #35
0
 public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     return(AutomationNull.Value);
 }
Beispiel #36
0
 /// <summary/>
 public virtual object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     return(null);
 }
        internal static PowerShell Convert(ScriptBlockAst body,
                                           ReadOnlyCollection<ParameterAst> functionParameters,
                                           bool isTrustedInput,
                                           ExecutionContext context,
                                           Dictionary<string, object> variables,
                                           bool filterNonUsingVariables,
                                           bool? createLocalScope,
                                           object[] args)
        {
            ExecutionContext.CheckStackDepth();

            if (args == null)
            {
                args = Utils.EmptyArray<object>();
            }

            // Perform validations on the ScriptBlock.  GetSimplePipeline can allow for more than one
            // pipeline if the first parameter is true, but Invoke-Command doesn't yet support multiple
            // pipelines in a PowerShell (it just grabs the last command directly.)  The rest of this
            // code properly supports multiple pipelines, so it should just work to change the false to true
            // if/when Invoke-Command can support multiple pipelines.
            string errorId;
            string errorMsg;
            body.GetSimplePipeline(true, out errorId, out errorMsg);
            if (errorId != null)
            {
                throw new ScriptBlockToPowerShellNotSupportedException(errorId, null, errorMsg);
            }

            var checker = new ScriptBlockToPowerShellChecker { ScriptBeingConverted = body };
            if (functionParameters != null)
            {
                foreach (var parameter in functionParameters)
                {
                    parameter.InternalVisit(checker);
                }
            }
            body.InternalVisit(checker);

            // When the context is null (or they haven't supplied any variables), throw, but only if we really need the
            // context (basically, if we have some variable reference to resolve).
            if (context == null && (checker.HasUsingExpr || checker.UsesParameter) && (variables == null))
            {
                throw new PSInvalidOperationException(AutomationExceptions.CantConvertScriptBlockWithNoContext);
            }

            try
            {
                var converter = new ScriptBlockToPowerShellConverter { _context = context, _createLocalScope = createLocalScope };

                if (checker.HasUsingExpr)
                {
                    converter._usingValueMap = GetUsingValues(body, isTrustedInput, context, variables, filterNonUsingVariables).Item1;
                }

                if (checker.UsesParameter)
                {
                    // If any parameters are used, we create a new scope and bind the parameters.

                    var newScope = context.EngineSessionState.NewScope(false);
                    context.EngineSessionState.CurrentScope = newScope;
                    context.EngineSessionState.CurrentScope.ScopeOrigin = CommandOrigin.Internal;

                    var locals =
                        MutableTuple.MakeTuple(Compiler.DottedLocalsTupleType, Compiler.DottedLocalsNameIndexMap);

                    // Get the parameter metadata for the script block. 
                    // If 'functionParameters' is not null, then the ScriptBlockAst is actually the body of a FunctionDefinitionAst, and it doesn't have a ParamBlock.
                    // If 'functionParameters' is null, then the ScriptBlockAst may have parameters defined in its ParamBlock.
                    bool usesCmdletBinding = false;
                    var parameters = functionParameters != null
                                         ? Compiler.GetParameterMetaData(functionParameters, true, ref usesCmdletBinding)
                                         : ((IParameterMetadataProvider)body).GetParameterMetadata(true, ref usesCmdletBinding);
                    object[] remainingArgs = ScriptBlock.BindArgumentsForScriptblockInvoke(
                        (RuntimeDefinedParameter[])parameters.Data, args, context, false, null, locals);
                    locals.SetAutomaticVariable(AutomaticVariable.Args, remainingArgs, context);
                    newScope.LocalsTuple = locals;
                }

                foreach (var pipeline in body.EndBlock.Statements.OfType<PipelineAst>())
                {
                    converter._powershell.AddStatement();
                    converter.ConvertPipeline(pipeline, isTrustedInput);
                }
                return converter._powershell;
            }
            finally
            {
                if (checker.UsesParameter)
                {
                    context.EngineSessionState.RemoveScope(context.EngineSessionState.CurrentScope);
                }
            }
        }
Beispiel #38
0
 public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     return false;
 }
        /// <summary>
        /// Check if the given UsingExpression is in a different scope from the previous UsingExpression that we analyzed.
        /// </summary>
        /// <remarks>
        /// Note that the value of <paramref name="usingExpr"/> is retrieved by calling 'UsingExpressionAstSearcher.FindAllUsingExpressionExceptForWorkflow'.
        /// So <paramref name="usingExpr"/> is guaranteed not inside a workflow.
        /// </remarks>
        /// <param name="usingExpr">The UsingExpression to analyze</param>
        /// <param name="topLevelParent">The top level Ast, should be either ScriptBlockAst or FunctionDefinitionAst</param>
        /// <param name="sbClosestToPreviousUsingExpr">The ScriptBlockAst that represents the scope of the previously analyzed UsingExpressions</param>
        private static bool HasUsingExpressionsInDifferentScopes(UsingExpressionAst usingExpr, Ast topLevelParent, ref ScriptBlockAst sbClosestToPreviousUsingExpr)
        {
            Diagnostics.Assert(topLevelParent is ScriptBlockAst || topLevelParent is FunctionDefinitionAst,
                "the top level parent should be either a ScriptBlockAst or FunctionDefinitionAst");

            // Scan up the parents of a UsingExpression to check if it's in a nested function/filter/ScriptBlock
            Ast current = usingExpr;
            do
            {
                current = current.Parent;

                var sbAst = current as ScriptBlockAst;
                if (sbAst != null)
                {
                    // We find the closest parent ScriptBlockAst of the current UsingExpression, which represents the scope
                    // that the current UsingExpression is in.

                    if (sbClosestToPreviousUsingExpr == null)
                    {
                        // The current UsingExpression is the first one to be analyzed.
                        sbClosestToPreviousUsingExpr = sbAst;
                        return false;
                    }

                    if (sbAst == sbClosestToPreviousUsingExpr)
                    {
                        // The current UsingExpression is in the same scope as the previous UsingExpression we analyzed.
                        return false;
                    }

                    // The current UsingExpression is in a different scope from the previous UsingExpression we analyzed.
                    return true;
                }

                var funcAst = current as FunctionDefinitionAst;
                if (funcAst != null)
                {
                    // The parent chain of the current UsingExpression reaches a FunctionDefinitionAst, then the UsingExpression 
                    // must be in 'Parameters' property of this FunctionDefinitionAst.
                    // In this case, the 'Body' of this FunctionDefinitionAst represents the scope that the UsingExpression is in.

                    if (sbClosestToPreviousUsingExpr == null)
                    {
                        // The current UsingExpression is the first one to be analyzed.
                        sbClosestToPreviousUsingExpr = funcAst.Body;
                        return false;
                    }

                    if (funcAst.Body == sbClosestToPreviousUsingExpr)
                    {
                        // The current UsingExpression is in the same scope as the previous UsingExpression we analyzed.
                        return false;
                    }

                    // The current UsingExpression is in a different scope from the previous UsingExpression we analyzed.
                    return true;
                }
            } while (current != topLevelParent);

            Diagnostics.Assert(false, "Unreachable Code. Top level parent is eitehr ScriptBlockAst or FunctionDefinitionAst, so it should return within the loop for sure.");
            // I don't think it's reachable, but if it happens, just assume there are UsingExpressions in different scopes.
            return true;
        }
Beispiel #40
0
        public override AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
        {
            try
            {
                scriptBlockAst.EndBlock.Visit(this);
            }
            catch (ReturnException e)
            {
                // if the exception was a return excpetion, also write the returnResult, if existing
                if (PSObject.Unwrap(e.Value) != null)
                {
                    _pipelineCommandRuntime.WriteObject(e.Value, true);
                }
            }

            return AstVisitAction.SkipChildren;
        }
Beispiel #41
0
        private Expression<Action<FunctionContext>> CompileNamedBlock(NamedBlockAst namedBlockAst, string funcName, ScriptBlockAst rootForDefiningTypes)
        {
            IScriptExtent entryExtent = null;
            IScriptExtent exitExtent = null;
            if (namedBlockAst.Unnamed)
            {
                // Get extent from the function or scriptblock expression parent, if any.
                var scriptBlock = (ScriptBlockAst)namedBlockAst.Parent;
                if (scriptBlock.Parent != null && scriptBlock.Extent is InternalScriptExtent)
                {
                    // We must have curlies at the start/end.
                    var scriptExtent = (InternalScriptExtent)scriptBlock.Extent;
                    entryExtent = new InternalScriptExtent(scriptExtent.PositionHelper, scriptExtent.StartOffset, scriptExtent.StartOffset + 1);
                    exitExtent = new InternalScriptExtent(scriptExtent.PositionHelper, scriptExtent.EndOffset - 1, scriptExtent.EndOffset);
                }
            }
            else
            {
                entryExtent = namedBlockAst.OpenCurlyExtent;
                exitExtent = namedBlockAst.CloseCurlyExtent;
            }

            return CompileSingleLambda(namedBlockAst.Statements, namedBlockAst.Traps, funcName, entryExtent, exitExtent, rootForDefiningTypes);
        }
Beispiel #42
0
 /// <summary/>
 public virtual AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     return(AstVisitAction.Continue);
 }
Beispiel #43
0
 /// <summary/>
 public virtual AstVisitAction VisitScriptBlock(ScriptBlockAst scriptBlockAst) => DefaultVisit(scriptBlockAst);
Beispiel #44
0
 public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
 {
     return(false);
 }
Beispiel #45
0
 public ScriptBlockExpressionAst(IScriptExtent extent, ScriptBlockAst scriptBlock)
     : base(extent)
 {
     this.ScriptBlock = scriptBlock;
 }