Skip to content

Fix severity filtering while invoking script analyzer #480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 29, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 82 additions & 91 deletions Engine/ScriptAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,64 @@ private IEnumerable<DiagnosticRecord> AnalyzeFile(string filePath)
return this.AnalyzeSyntaxTree(scriptAst, scriptTokens, filePath);
}

private bool IsSeverityAllowed(IEnumerable<uint> allowedSeverities, IRule rule)
{
return severity == null
|| (allowedSeverities != null
&& rule != null
&& HasGetSeverity(rule)
&& allowedSeverities.Contains((uint)rule.GetSeverity()));
}

IEnumerable<uint> GetAllowedSeveritiesInInt()
{
return severity != null
? severity.Select(item => (uint)Enum.Parse(typeof(DiagnosticSeverity), item, true))
: null;
}

bool HasMethod<T>(T obj, string methodName)
{
var type = obj.GetType();
return type.GetMethod(methodName) != null;
}

bool HasGetSeverity<T>(T obj)
{
return HasMethod<T>(obj, "GetSeverity");
}

bool IsRuleAllowed(IRule rule)
{
IEnumerable<uint> allowedSeverities = GetAllowedSeveritiesInInt();
bool includeRegexMatch = false;
bool excludeRegexMatch = false;
foreach (Regex include in includeRegexList)
{
if (include.IsMatch(rule.GetName()))
{
includeRegexMatch = true;
break;
}
}

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

bool helpRule = String.Equals(rule.GetName(), "PSUseUTF8EncodingForHelpFile", StringComparison.OrdinalIgnoreCase);
bool includeSeverity = IsSeverityAllowed(allowedSeverities, rule);

return (includeRule == null || includeRegexMatch)
&& (excludeRule == null || !excludeRegexMatch)
&& IsSeverityAllowed(allowedSeverities, rule);
}

/// <summary>
/// Analyzes the syntax tree of a script file that has already been parsed.
/// </summary>
Expand Down Expand Up @@ -1373,42 +1431,20 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(

Helper.Instance.Tokens = scriptTokens;
}

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

if (this.ScriptRules != null)
{
var tasks = this.ScriptRules.Select(scriptRule => Task.Factory.StartNew(() =>
{
bool includeRegexMatch = false;
bool excludeRegexMatch = false;
var allowedRules = this.ScriptRules.Where(IsRuleAllowed);

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;
}
}

bool helpRule = String.Equals(scriptRule.GetName(), "PSUseUTF8EncodingForHelpFile", StringComparison.OrdinalIgnoreCase);

if ((includeRule == null || includeRegexMatch) && (excludeRule == null || !excludeRegexMatch))
if (allowedRules.Any())
{
var tasks = allowedRules.Select(scriptRule => Task.Factory.StartNew(() =>
{
bool helpRule = String.Equals(scriptRule.GetName(), "PSUseUTF8EncodingForHelpFile", StringComparison.OrdinalIgnoreCase);
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
Expand Down Expand Up @@ -1442,26 +1478,26 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(
}

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

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

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

if (data != null)
{
this.outputWriter.WriteVerbose(data[0] as string);
if (data.Count == 2)
if (data != null)
{
this.outputWriter.WriteError(data[1] as ErrorRecord);
this.outputWriter.WriteVerbose(data[0] as string);
if (data.Count == 2)
{
this.outputWriter.WriteError(data[1] as ErrorRecord);
}
}
}
}
Expand All @@ -1475,25 +1511,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(
{
foreach (ITokenRule tokenRule in this.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))
if (IsRuleAllowed(tokenRule))
{
this.outputWriter.WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, tokenRule.GetName()));

Expand Down Expand Up @@ -1592,24 +1610,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(
// Run all DSC Rules
foreach (IDSCResourceRule dscResourceRule in this.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))
if (IsRuleAllowed(dscResourceRule))
{
this.outputWriter.WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, dscResourceRule.GetName()));

Expand Down Expand Up @@ -1646,8 +1647,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(

foreach (ExternalRule exRule in this.ExternalRules)
{
if ((includeRule == null || includeRule.Contains(exRule.GetName(), StringComparer.OrdinalIgnoreCase)) &&
(excludeRule == null || !excludeRule.Contains(exRule.GetName(), StringComparer.OrdinalIgnoreCase)))
if (IsRuleAllowed(exRule))
{
string ruleName = string.Format(CultureInfo.CurrentCulture, "{0}\\{1}", exRule.GetSourceName(), exRule.GetName());
this.outputWriter.WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, ruleName));
Expand Down Expand Up @@ -1676,15 +1676,6 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(
// Need to reverse the concurrentbag to ensure that results are sorted in the increasing order of line numbers
IEnumerable<DiagnosticRecord> diagnosticsList = diagnostics.Reverse();

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

return this.suppressedOnly ?
suppressed.OfType<DiagnosticRecord>() :
diagnosticsList;
Expand Down