/// <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 = Helper.Instance.GetExportedFunction(ast); ast.Visit(this); return(DiagnosticRecords); }
/// <summary> /// AnalyzeScript: Checks that objects return in a cmdlet have their types declared in OutputType Attribute /// </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; _classes = ast.FindAll(item => item is TypeDefinitionAst && ((item as TypeDefinitionAst).IsClass), true).Cast <TypeDefinitionAst>(); ast.Visit(this); return(DiagnosticRecords); }
/// <summary> /// AnalyzeScript: Analyzes the ast to check that Write-Verbose is called at least once in every cmdlet or script. /// <param name="ast">The script's ast</param> /// <param name="fileName">The script's file name</param> /// </summary> public IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException(Strings.NullAstErrorMessage); } ClearList(); this.AddNames(new List <string>() { "Configuration", "Workflow" }); DiagnosticRecords.Clear(); this.fileName = fileName; //We only check that advanced functions should have Write-Verbose ast.Visit(this); return(DiagnosticRecords); }
/// <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); }