public override void Process(AnalysisLayer layer, ref Reporting.Analysis analysis) { // Create the report and the analysis layer to report on. var report = new AnalysisReport(); report.Name = "Simplification Report"; // Perform various analysis operations. this.ProcessFrequentExpressions(layer, report); // Add our layers and report to the analysis result. if (report.Issues.Count > 0) layer.Reports.Add(report); }
private void ProcessFrequentExpressions(AnalysisLayer layer, AnalysisReport report) { // Perform analysis. var expressionTreeVisitor = new CalculateExpressionTreeVisitor(); layer.AstBuilder.CompilationUnit.AcceptVisitor(expressionTreeVisitor); // If there are no counts of this being an issue, don't create // an issue entry. if (expressionTreeVisitor.UniqueNodes.Count(x => x.Value.Count >= this.WarningLimit) == 0) return; var minCounts = expressionTreeVisitor.UniqueNodes.Where(x => x.Value.Count >= this.WarningLimit).Min(x => x.Value.Count); var maxCounts = expressionTreeVisitor.UniqueNodes.Where(x => x.Value.Count >= this.WarningLimit).Max(x => x.Value.Count); if (maxCounts == 0) return; // Write out issue analysis. var issue = new AnalysisIssue(); issue.ID = "W0001"; issue.Name = "Frequent expressions identified"; issue.Description = "The following frequent (occurring greater than " + this.WarningLimit + " times) expressions have been identified in the algorithm implementation."; foreach (var kv in expressionTreeVisitor.UniqueNodes) { foreach (var node in kv.Value.AstNodes) { var startTrackingInfo = node.Annotations.Where(x => x is StartTrackingInfo).Cast<StartTrackingInfo>().FirstOrDefault(); var endTrackingInfo = node.Annotations.Where(x => x is EndTrackingInfo).Cast<EndTrackingInfo>().FirstOrDefault(); if (startTrackingInfo == null || endTrackingInfo == null) continue; if (kv.Value.Count < this.WarningLimit) continue; var location = new AnalysisLocationHighlight(); location.Start = startTrackingInfo.CharacterPosition; location.End = endTrackingInfo.CharacterPosition; if (this.GradientMode == WarningGradientMode.Relative) { if (maxCounts - Math.Max(this.WarningLimit, minCounts) == 0) location.Importance = 100; else location.Importance = (int)Math.Round( (kv.Value.Count - Math.Max(this.WarningLimit, minCounts)) / (double)(maxCounts - Math.Max(this.WarningLimit, minCounts)) * 100); } else { var count = Math.Min(Math.Max(kv.Value.Count, this.WarningLimit), this.ErrorLimit); location.Importance = (int)(((count - this.WarningLimit) / (double)(this.ErrorLimit - this.WarningLimit)) * 100); } location.Message = "Occurs " + kv.Value.Count + " times"; issue.Locations.Add(location); } } issue.FlattenLocations(); if (issue.Locations.Count == 0) return; report.Issues.Add(issue); }