/// <summary> /// Analyzes the given ast to find violations. /// </summary> /// <param name="ast">AST to be analyzed. This should be non-null</param> /// <param name="fileName">Name of file that corresponds to the input AST.</param> /// <returns>A an enumerable type containing the violations</returns> public override IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException("ast"); } // TODO Should have the following option // * no-empty-lines-after var diagnosticRecords = new List <DiagnosticRecord>(); if (!Enable) { return(diagnosticRecords); } var tokens = Helper.Instance.Tokens; // Ignore open braces that are part of arguments to a command // * E.g. get-process | % { "blah } // In the above case even if OnSameLine == false, we should not // flag the open brace as it would move the brace to the next line // and will invalidate the command var tokenOps = new TokenOperations(tokens, ast); tokensToIgnore = new HashSet <Token>(tokenOps.GetOpenBracesInCommandElements()); // Ignore open braces that are part of a one line if-else statement // E.g. $x = if ($true) { "blah" } else { "blah blah" } if (IgnoreOneLineBlock) { foreach (var pair in tokenOps.GetBracePairsOnSameLine()) { tokensToIgnore.Add(pair.Item1); } } foreach (var violationFinder in violationFinders) { diagnosticRecords.AddRange(violationFinder(tokens, ast, fileName)); } return(diagnosticRecords); }
/// <summary> /// Analyzes the given ast to find violations. /// </summary> /// <param name="ast">AST to be analyzed. This should be non-null</param> /// <param name="fileName">Name of file that corresponds to the input AST.</param> /// <returns>A an enumerable type containing the violations</returns> public override IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException("ast"); } if (!Enable) { return(Enumerable.Empty <DiagnosticRecord>()); } // TODO Should have the following options // * no-empty-lines-before var tokens = Helper.Instance.Tokens; var diagnosticRecords = new List <DiagnosticRecord>(); var curlyStack = new Stack <Tuple <Token, int> >(); // TODO move part common with PlaceOpenBrace to one place var tokenOps = new TokenOperations(tokens, ast); tokensToIgnore = new HashSet <Token>(tokenOps.GetCloseBracesInCommandElements()); // Ignore close braces that are part of a one line if-else statement // E.g. $x = if ($true) { "blah" } else { "blah blah" } if (IgnoreOneLineBlock) { foreach (var pair in tokenOps.GetBracePairsOnSameLine()) { tokensToIgnore.Add(pair.Item2); } } for (int k = 0; k < tokens.Length; k++) { var token = tokens[k]; if (token.Kind == TokenKind.LCurly || token.Kind == TokenKind.AtCurly) { curlyStack.Push(new Tuple <Token, int>(token, k)); continue; } if (token.Kind == TokenKind.RCurly) { if (curlyStack.Count > 0) { var openBraceToken = curlyStack.Peek().Item1; var openBracePos = curlyStack.Pop().Item2; // Ignore if a one line hashtable if (openBraceToken.Kind == TokenKind.AtCurly && openBraceToken.Extent.StartLineNumber == token.Extent.StartLineNumber) { continue; } foreach (var violationFinder in violationFinders) { AddToDiagnosticRecords( violationFinder(tokens, k, openBracePos, fileName), ref diagnosticRecords); } } else { break; } } } return(diagnosticRecords); }