private static IReadOnlyDictionary <DocumentHandle, MethodsInDocument> GroupMethods(IEnumerable <KeyValuePair <DocumentHandle, MethodLineExtent> > methodExtents) { var builder = new Dictionary <DocumentHandle, ImmutableArray <MethodLineExtent> .Builder>(); foreach (var entry in methodExtents) { ImmutableArray <MethodLineExtent> .Builder existing; if (!builder.TryGetValue(entry.Key, out existing)) { builder[entry.Key] = existing = ImmutableArray.CreateBuilder <MethodLineExtent>(); } existing.Add(entry.Value); } var result = new Dictionary <DocumentHandle, MethodsInDocument>(builder.Count); foreach (var entry in builder) { var extents = entry.Value; Debug.Assert(extents.Count > 0); // sort by method handle: extents.Sort(MethodLineExtent.MethodComparer.Instance); // merge spans belonging to a single method: int j = 0; for (int i = 1; i < extents.Count; i++) { if (extents[i].Method == extents[j].Method) { extents[j] = new MethodLineExtent(extents[i].Method, Math.Min(extents[i].MinLine, extents[j].MinLine), Math.Max(extents[i].MaxLine, extents[j].MaxLine)); } else { j++; if (j < i) { extents[j] = extents[i]; } } } Debug.Assert(j < extents.Count); extents.Count = j + 1; var extentsByMethod = extents.ToImmutable(); // sort by start line: extents.Sort(MethodLineExtent.MinLineComparer.Instance); result.Add(entry.Key, new MethodsInDocument(extentsByMethod, PartitionToNonOverlappingSubsequences(extents))); } return(result); }
private ImmutableArray <MethodLineExtent> UpdateExtent(ImmutableArray <MethodLineExtent> extents, MethodLineExtent newExtent) { int index = extents.BinarySearch(newExtent, (x, y) => x.Method.CompareTo(y.Method)); Debug.Assert(index >= 0); return(extents.SetItem(index, newExtent)); }
public static MethodLineExtent Merge(MethodLineExtent left, MethodLineExtent right) { Debug.Assert(left.Method == right.Method); Debug.Assert(left.Version == right.Version); return(new MethodLineExtent(left.Method, left.Version, Math.Min(left.MinLine, right.MinLine), Math.Max(left.MaxLine, right.MaxLine))); }