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);
        }
Ejemplo n.º 2
0
 public abstract void Process(AnalysisLayer layer, ref Reporting.Analysis analysis);
        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);
        }