public static Backtrace FromLines(Codebase owner, List <string> lines, int startLine, int endLine) { var header = lines[0]; var subHeader = lines[1]; var headerNumbers = Regex.Matches(header, "(?<number>^-\\s*\\d+)|(?<number>\\d+)( |\\))") // first number must capture negative sign if exists. .Cast <Match>() .Select(x => x.Groups["number"].Value.Replace(" ", "")) .Select(x => Convert.ToInt32(x)) .ToList(); var subHeaderNumberMatches = Regex.Matches(subHeader, "(?<number>^-\\s*\\d+)|(?<number>\\d+)( |\\))"); //var subHeaderNumbers = Regex.Matches(subHeader, "(?<number>^-\\s*\\d+)|(?<number>\\d+)( |\\))") // first number must capture negative sign if exists. var subHeaderNumbers = subHeaderNumberMatches .Cast <Match>() .Select(x => x.Groups["number"].Value.Replace(" ", "")) .Select(x => Convert.ToInt32(x)) .ToList(); var bytesDelta = headerNumbers[0]; var newBytes = headerNumbers[1]; var oldBytes = headerNumbers[2]; var countDelta = subHeaderNumbers[0]; var newCount = subHeaderNumbers[1]; var oldCount = subHeaderNumbers[2]; var result = new Backtrace { TotalLeak = bytesDelta, Count = countDelta, Owner = owner, Lines = new List <LineOfCode>(), StartLine = startLine, EndLine = endLine }; var justLines = lines.Skip(2).Where(x => x.Trim() != string.Empty).ToList(); LineOfCode prevLine = null; foreach (var lineStr in justLines) { var line = owner.GetLine(lineStr); line.Leaks.AddOrGet(result); // Add leak to line's leaks line.Function.Leaks.AddOrGet(result); // Add leak to line's function's leak line.Scope.Leaks.AddOrGet(result); // Add leak to line's scope's leak if (line.SourceFile != null) { line.SourceFile.Leaks.AddOrGet(result); // Add leak to line's file's leaks } line.Module.Leaks.AddOrGet(result); // Add leak to line's module's leaks result.Lines.Add(line); // Add line to leak // Connect and update calls to and called from if (prevLine != null) { line.CallsTo.AddOrGet(prevLine); // Line calls prevLine line.Function.CallsTo.AddOrGet(prevLine.Function); // Line's function calls prevLine's function line.Module.CallsTo.AddOrGet(prevLine.Module); // Line's module calls prevLine's module if (line.SourceFile != null && prevLine.SourceFile != null) { line.SourceFile.CallsTo.AddOrGet(prevLine.SourceFile); // Line's file calls prevLine's file prevLine.SourceFile.CalledFrom.AddOrGet(line.SourceFile); // PrevLine's file is called from line's file } prevLine.CalledFrom.AddOrGet(line); // PrevLine is called from line prevLine.Function.CalledFrom.AddOrGet(line.Function); // PrevLine's function is called from line's function prevLine.Module.CalledFrom.AddOrGet(line.Module); // PrevLine's module is called from line's module } prevLine = line; } return(result); }
// Add new backtrace public void AddBacktrace(List <string> lines, int startLine, int endLine) { var newTrace = Backtrace.FromLines(this, lines, startLine, endLine); Leaks.Add(newTrace); }