Example #1
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                string methodName = method.Attribute("name").Value + method.Attribute("signature").Value;
                methodName = ExtractMethodName(methodName, method.Parent.Parent.Attribute("name").Value);

                if (methodName.Contains("__") && lambdaMethodNameRegex.IsMatch(methodName))
                {
                    continue;
                }

                methodName = GetShortMethodName(methodName);

                var lines = method.Elements("lines")
                            .Elements("line");

                if (lines.Any())
                {
                    int firstLine = int.Parse(lines.First().Attribute("number").Value, CultureInfo.InvariantCulture);
                    int lastLine  = int.Parse(lines.Last().Attribute("number").Value, CultureInfo.InvariantCulture);

                    codeFile.AddCodeElement(new CodeElement(
                                                methodName,
                                                CodeElementType.Method,
                                                firstLine,
                                                lastLine,
                                                codeFile.CoverageQuota(firstLine, lastLine)));
                }
            }
        }
Example #2
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        /// <param name="numberOrLines">The number of lines in the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile, int numberOrLines)
        {
            var codeElements = new List <CodeElementBase>();

            foreach (var method in methodsOfFile)
            {
                var signature = method.Attribute("signature");

                if (signature == null)
                {
                    continue;
                }

                string methodName = signature.Value;
                int    lineNumber = int.Parse(method.Attribute("num").Value, CultureInfo.InvariantCulture);

                codeElements.Add(new CodeElementBase(methodName, lineNumber));

                var complexity = method.Attribute("complexity");

                if (complexity != null)
                {
                    var metrics = new List <Metric>()
                    {
                        new Metric(
                            ReportResources.CyclomaticComplexity,
                            ParserBase.CyclomaticComplexityUri,
                            MetricType.CodeQuality,
                            decimal.Parse(complexity.Value, CultureInfo.InvariantCulture),
                            MetricMergeOrder.LowerIsBetter)
                    };

                    var methodMetric = new MethodMetric(methodName, methodName, metrics)
                    {
                        Line = lineNumber
                    };

                    codeFile.AddMethodMetric(methodMetric);
                }
            }

            for (int i = 0; i < codeElements.Count; i++)
            {
                var codeElement = codeElements[i];

                int lastLine = numberOrLines;
                if (i < codeElements.Count - 1)
                {
                    lastLine = codeElements[i + 1].FirstLine - 1;
                }

                codeFile.AddCodeElement(new CodeElement(
                                            codeElement.Name,
                                            CodeElementType.Method,
                                            codeElement.FirstLine,
                                            lastLine,
                                            codeFile.CoverageQuota(codeElement.FirstLine, lastLine)));
            }
        }
Example #3
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                if (method.Attribute("skippedDueTo") != null ||
                    lambdaMethodNameRegex.IsMatch(method.Element("Name").Value))
                {
                    continue;
                }

                string methodName = ExtractMethodName(method.Element("Name").Value);
                methodName = methodName.Substring(methodName.LastIndexOf(':') + 1);

                CodeElementType type = CodeElementType.Method;

                if (method.HasAttributeWithValue("isGetter", "true") ||
                    method.HasAttributeWithValue("isSetter", "true"))
                {
                    type       = CodeElementType.Property;
                    methodName = methodName.Substring(4);
                }

                var seqpnts = method
                              .Elements("SequencePoints")
                              .Elements("SequencePoint")
                              .Select(seqpnt => new
                {
                    LineNumberStart = int.Parse(seqpnt.Attribute("sl").Value, CultureInfo.InvariantCulture),
                    LineNumberEnd   = seqpnt.Attribute("el") != null ? int.Parse(seqpnt.Attribute("el").Value, CultureInfo.InvariantCulture) : int.Parse(seqpnt.Attribute("sl").Value, CultureInfo.InvariantCulture)
                })
                              .ToArray();

                if (seqpnts.Length > 0)
                {
                    int firstLine = seqpnts.Min(s => s.LineNumberStart);
                    int lastLine  = seqpnts.Max(s => s.LineNumberEnd);

                    codeFile.AddCodeElement(new CodeElement(
                                                methodName,
                                                type,
                                                firstLine,
                                                lastLine,
                                                codeFile.CoverageQuota(firstLine, lastLine)));
                }
            }
        }
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                if (lambdaMethodNameRegex.IsMatch(method.Attribute("name").Value))
                {
                    continue;
                }

                string methodName = ExtractMethodName(method.Attribute("name").Value, method.Attribute("type_name").Value);

                CodeElementType type = CodeElementType.Method;

                if (methodName.StartsWith("get_", StringComparison.OrdinalIgnoreCase) ||
                    methodName.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
                {
                    type       = CodeElementType.Property;
                    methodName = methodName.Substring(4);
                }

                var seqpnts = method
                              .Elements("ranges")
                              .Elements("range")
                              .Where(l => l.Attribute("start_line").Value != "15732480")
                              .Select(l => new
                {
                    LineNumberStart = int.Parse(l.Attribute("start_line").Value, CultureInfo.InvariantCulture),
                    LineNumberEnd   = int.Parse(l.Attribute("end_line").Value, CultureInfo.InvariantCulture)
                })
                              .ToArray();

                if (seqpnts.Length > 0)
                {
                    int firstLine = seqpnts.Min(s => s.LineNumberStart);
                    int lastLine  = seqpnts.Max(s => s.LineNumberEnd);

                    codeFile.AddCodeElement(new CodeElement(
                                                methodName,
                                                type,
                                                firstLine,
                                                lastLine,
                                                codeFile.CoverageQuota(firstLine, lastLine)));
                }
            }
        }
Example #5
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="fileId">The id of the file.</param>
        /// <param name="methods">The methods.</param>
        private static void SetCodeElements(CodeFile codeFile, string fileId, IEnumerable <XElement> methods)
        {
            foreach (var method in methods)
            {
                string methodName = ExtractMethodName(method.Parent.Attribute("Name").Value, method.Attribute("Name").Value);

                if (lambdaMethodNameRegex.IsMatch(methodName))
                {
                    continue;
                }

                CodeElementType type = CodeElementType.Method;

                if (methodName.StartsWith("get_", StringComparison.OrdinalIgnoreCase) ||
                    methodName.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
                {
                    type       = CodeElementType.Property;
                    methodName = methodName.Substring(4);
                }

                var seqpnts = method
                              .Elements("Statement")
                              .Where(c => c.Attribute("FileIndex").Value == fileId)
                              .Select(c => new
                {
                    LineNumberStart = int.Parse(c.Attribute("Line").Value, CultureInfo.InvariantCulture),
                    LineNumberEnd   = int.Parse(c.Attribute("EndLine").Value, CultureInfo.InvariantCulture)
                })
                              .ToArray();

                if (seqpnts.Length > 0)
                {
                    int firstLine = seqpnts.Min(s => s.LineNumberStart);
                    int lastLine  = seqpnts.Max(s => s.LineNumberEnd);

                    codeFile.AddCodeElement(new CodeElement(
                                                methodName,
                                                type,
                                                seqpnts.Min(s => s.LineNumberStart),
                                                seqpnts.Max(s => s.LineNumberEnd),
                                                codeFile.CoverageQuota(firstLine, lastLine)));
                }
            }
        }
Example #6
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfClass">The methods of the class.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfClass)
        {
            foreach (var method in methodsOfClass)
            {
                string methodName = method.Attribute("name").Value;

                if (lambdaMethodNameRegex.IsMatch(methodName))
                {
                    continue;
                }

                CodeElementType type = CodeElementType.Method;

                if (methodName.StartsWith("get_", StringComparison.OrdinalIgnoreCase) ||
                    methodName.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
                {
                    type       = CodeElementType.Property;
                    methodName = methodName.Substring(4);
                }

                var seqpnts = method
                              .Elements("seqpnt")
                              .Where(seqpnt => seqpnt.Attribute("document").Value.Equals(codeFile.Path) && seqpnt.Attribute("line").Value != "16707566")
                              .Select(seqpnt => new
                {
                    LineNumberStart = int.Parse(seqpnt.Attribute("line").Value, CultureInfo.InvariantCulture),
                    LineNumberEnd   = int.Parse(seqpnt.Attribute("endline").Value, CultureInfo.InvariantCulture)
                })
                              .ToArray();

                if (seqpnts.Length > 0)
                {
                    int firstLine = seqpnts.Min(s => s.LineNumberStart);
                    int lastLine  = seqpnts.Max(s => s.LineNumberEnd);

                    codeFile.AddCodeElement(new CodeElement(
                                                methodName,
                                                type,
                                                firstLine,
                                                lastLine,
                                                codeFile.CoverageQuota(firstLine, lastLine)));
                }
            }
        }
Example #7
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        /// <param name="numberOrLines">The number of lines in the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile, int numberOrLines)
        {
            var codeElements = new List <CodeElementBase>();

            foreach (var method in methodsOfFile)
            {
                string methodName = method.Attribute("name").Value + method.Attribute("desc").Value;

                if (methodName.StartsWith("lambda$"))
                {
                    continue;
                }

                methodName = methodRegex.Replace(methodName, m => string.Format(CultureInfo.InvariantCulture, "{0}({1})", m.Groups["MethodName"].Value, m.Groups["Arguments"].Value));

                int lineNumber = int.Parse(method.Attribute("line")?.Value ?? "0", CultureInfo.InvariantCulture);

                codeElements.Add(new CodeElementBase(methodName, lineNumber));
            }

            codeElements.Sort((x, y) => x.FirstLine.CompareTo(y.FirstLine));
            for (int i = 0; i < codeElements.Count; i++)
            {
                var codeElement = codeElements[i];

                int lastLine = numberOrLines;
                if (i < codeElements.Count - 1)
                {
                    lastLine = codeElements[i + 1].FirstLine - 1;
                }

                codeFile.AddCodeElement(new CodeElement(
                                            codeElement.Name,
                                            CodeElementType.Method,
                                            codeElement.FirstLine,
                                            lastLine,
                                            codeFile.CoverageQuota(codeElement.FirstLine, lastLine)));
            }
        }
Example #8
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                string methodName = method.Attribute("name").Value;

                if (lambdaMethodNameRegex.IsMatch(methodName))
                {
                    continue;
                }

                CodeElementType type = CodeElementType.Method;

                if (methodName.StartsWith("get_", StringComparison.OrdinalIgnoreCase) ||
                    methodName.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
                {
                    type       = CodeElementType.Property;
                    methodName = methodName.Substring(4);
                }

                var lineNumbers = method
                                  .Elements("statement")
                                  .Select(l => int.Parse(l.Attribute("line").Value, CultureInfo.InvariantCulture))
                                  .ToArray();

                if (lineNumbers.Length > 0)
                {
                    int firstLine = lineNumbers.Min();
                    int lastLine  = lineNumbers.Max();

                    codeFile.AddCodeElement(new CodeElement(
                                                methodName,
                                                type,
                                                firstLine,
                                                lastLine,
                                                codeFile.CoverageQuota(firstLine, lastLine)));
                }
            }
        }
Example #9
0
        private void ProcessCoverage(Class @class, string fileName, string[] lines)
        {
            var codeElements     = new List <CodeElementBase>();
            int maxiumLineNumber = -1;
            var visitsByLine     = new Dictionary <int, int>();

            var branchesByLineNumber = new Dictionary <int, ICollection <Branch> >();

            foreach (var line in lines)
            {
                var match = lineCoverageRegex.Match(line);

                if (match.Success)
                {
                    int lineNumber = int.Parse(match.Groups["LineNumber"].Value, CultureInfo.InvariantCulture);
                    maxiumLineNumber = Math.Max(maxiumLineNumber, lineNumber);

                    string visitsText = match.Groups["Visits"].Value;

                    if (visitsText != "-")
                    {
                        int visits = 0;

                        if (visitsText != "#####" && visitsText != "=====")
                        {
                            visits = visitsText.ParseLargeInteger();
                        }

                        if (visitsByLine.ContainsKey(lineNumber))
                        {
                            visitsByLine[lineNumber] += visits;
                        }
                        else
                        {
                            visitsByLine[lineNumber] = visits;
                        }
                    }
                }
                else
                {
                    match = branchCoverageRegex.Match(line);

                    if (match.Success)
                    {
                        var branch = new Branch(
                            match.Groups["Visits"].Success ? match.Groups["Visits"].Value.ParseLargeInteger() : 0,
                            match.Groups["Number"].Value);

                        ICollection <Branch> branches = null;
                        if (branchesByLineNumber.TryGetValue(maxiumLineNumber, out branches))
                        {
                            HashSet <Branch> branchesHashset = (HashSet <Branch>)branches;
                            if (branchesHashset.Contains(branch))
                            {
                                // Not perfect for performance, but Hashset has no GetElement method
                                branchesHashset.First(b => b.Equals(branch)).BranchVisits += branch.BranchVisits;
                            }
                            else
                            {
                                branches.Add(branch);
                            }
                        }
                        else
                        {
                            branches = new HashSet <Branch>();
                            branches.Add(branch);

                            branchesByLineNumber.Add(maxiumLineNumber, branches);
                        }
                    }
                    else if (line.StartsWith("function "))
                    {
                        string name = line.Substring(9, line.IndexOf(' ', 9) - 9);

                        codeElements.Add(new CodeElementBase(name, maxiumLineNumber + 1));
                    }
                }
            }

            int[]             coverage        = new int[maxiumLineNumber + 1];
            LineVisitStatus[] lineVisitStatus = new LineVisitStatus[maxiumLineNumber + 1];

            for (int i = 0; i < coverage.Length; i++)
            {
                coverage[i] = -1;
            }

            foreach (var kv in visitsByLine)
            {
                coverage[kv.Key] = kv.Value;

                if (lineVisitStatus[kv.Key] != LineVisitStatus.Covered)
                {
                    bool partiallyCovered = false;

                    ICollection <Branch> branchesOfLine = null;

                    if (branchesByLineNumber.TryGetValue(kv.Key, out branchesOfLine))
                    {
                        partiallyCovered = branchesOfLine.Any(b => b.BranchVisits == 0);
                    }

                    LineVisitStatus statusOfLine = kv.Value > 0 ? (partiallyCovered ? LineVisitStatus.PartiallyCovered : LineVisitStatus.Covered) : LineVisitStatus.NotCovered;
                    lineVisitStatus[kv.Key] = (LineVisitStatus)Math.Max((int)lineVisitStatus[kv.Key], (int)statusOfLine);
                }
            }

            var codeFile = new CodeFile(fileName, coverage, lineVisitStatus, branchesByLineNumber);

            for (int i = 0; i < codeElements.Count; i++)
            {
                var codeElement = codeElements[i];

                int lastLine = maxiumLineNumber;
                if (i < codeElements.Count - 1)
                {
                    lastLine = codeElements[i + 1].FirstLine - 1;
                }

                codeFile.AddCodeElement(new CodeElement(
                                            codeElement.Name,
                                            CodeElementType.Method,
                                            codeElement.FirstLine,
                                            lastLine,
                                            codeFile.CoverageQuota(codeElement.FirstLine, lastLine)));
            }

            @class.AddFile(codeFile);
        }
Example #10
0
        private void ProcessClass(Class @class, string fileName, string[] lines, ref int currentLine)
        {
            var codeElements     = new List <CodeElementBase>();
            int maxiumLineNumber = -1;
            var visitsByLine     = new Dictionary <int, int>();

            var branchesByLineNumber = new Dictionary <int, ICollection <Branch> >();

            while (true)
            {
                string line = lines[currentLine];

                if (line == "end_of_record")
                {
                    break;
                }

                currentLine++;

                if (line.StartsWith("FN:"))
                {
                    line = line.Substring(3);
                    int    lineNumber = int.Parse(line.Substring(0, line.IndexOf(',')), CultureInfo.InvariantCulture);
                    string name       = line.Substring(line.IndexOf(',') + 1);
                    codeElements.Add(new CodeElementBase(name, lineNumber));
                }
                else if (line.StartsWith("BRDA:"))
                {
                    line = line.Substring(5);
                    string[] tokens     = line.Split(',');
                    int      lineNumber = int.Parse(tokens[0], CultureInfo.InvariantCulture);

                    var branch = new Branch(
                        "-".Equals(tokens[3]) ? 0 : int.Parse(tokens[3], CultureInfo.InvariantCulture),
                        $"{tokens[0]}_{tokens[1]}_{tokens[2]}");

                    ICollection <Branch> branches = null;
                    if (branchesByLineNumber.TryGetValue(lineNumber, out branches))
                    {
                        HashSet <Branch> branchesHashset = (HashSet <Branch>)branches;
                        if (branchesHashset.Contains(branch))
                        {
                            // Not perfect for performance, but Hashset has no GetElement method
                            branchesHashset.First(b => b.Equals(branch)).BranchVisits += branch.BranchVisits;
                        }
                        else
                        {
                            branches.Add(branch);
                        }
                    }
                    else
                    {
                        branches = new HashSet <Branch>();
                        branches.Add(branch);

                        branchesByLineNumber.Add(lineNumber, branches);
                    }
                }
                else if (line.StartsWith("DA:"))
                {
                    line = line.Substring(3);
                    int lineNumber = int.Parse(line.Substring(0, line.IndexOf(',')), CultureInfo.InvariantCulture);
                    int visits     = line.Substring(line.IndexOf(',') + 1).ParseLargeInteger();

                    maxiumLineNumber = Math.Max(maxiumLineNumber, lineNumber);

                    if (visitsByLine.ContainsKey(lineNumber))
                    {
                        visitsByLine[lineNumber] += visits;
                    }
                    else
                    {
                        visitsByLine[lineNumber] = visits;
                    }
                }
            }

            int[]             coverage        = new int[maxiumLineNumber + 1];
            LineVisitStatus[] lineVisitStatus = new LineVisitStatus[maxiumLineNumber + 1];

            for (int i = 0; i < coverage.Length; i++)
            {
                coverage[i] = -1;
            }

            foreach (var kv in visitsByLine)
            {
                coverage[kv.Key] = kv.Value;

                if (lineVisitStatus[kv.Key] != LineVisitStatus.Covered)
                {
                    bool partiallyCovered = false;

                    ICollection <Branch> branchesOfLine = null;

                    if (branchesByLineNumber.TryGetValue(kv.Key, out branchesOfLine))
                    {
                        partiallyCovered = branchesOfLine.Any(b => b.BranchVisits == 0);
                    }

                    LineVisitStatus statusOfLine = kv.Value > 0 ? (partiallyCovered ? LineVisitStatus.PartiallyCovered : LineVisitStatus.Covered) : LineVisitStatus.NotCovered;
                    lineVisitStatus[kv.Key] = (LineVisitStatus)Math.Max((int)lineVisitStatus[kv.Key], (int)statusOfLine);
                }
            }

            var codeFile = new CodeFile(fileName, coverage, lineVisitStatus, branchesByLineNumber);

            for (int i = 0; i < codeElements.Count; i++)
            {
                var codeElement = codeElements[i];

                int lastLine = maxiumLineNumber;
                if (i < codeElements.Count - 1)
                {
                    lastLine = codeElements[i + 1].FirstLine - 1;
                }

                codeFile.AddCodeElement(new CodeElement(
                                            codeElement.Name,
                                            CodeElementType.Method,
                                            codeElement.FirstLine,
                                            lastLine,
                                            codeFile.CoverageQuota(codeElement.FirstLine, lastLine)));
            }

            @class.AddFile(codeFile);
        }