/// <summary> /// Generates Diff results for each change that occurred from the ancestor to the changed /// </summary> /// <param name="ancestor"> /// The abstract syntax tree that the changed version originated from /// </param> /// <param name="changed">The abstract syntax tree that resulted from changing the ancestor</param> /// <returns>Changes between the ancestor and changed</returns> public static IEnumerable <Diff> Compare(SyntaxTree ancestor, SyntaxTree changed) { var offset = 0; //Tracks differences in indexes moving through the changed syntax tree foreach (var change in changed.GetChanges(ancestor)) { //Assumes that this list is sorted by place in file var origLength = change.Span.Length; var offsetChange = (change.NewText.Length - origLength); var chanStart = change.Span.Start + offset; var chanLength = origLength + offsetChange; offset += offsetChange; var d = new Diff { Ancestor = SpanDetails.Create(change.Span, ancestor), Changed = SpanDetails.Create(new TextSpan(chanStart, chanLength), changed) }; yield return(d); } }
internal static Conflict Create(List <DiffWithOrigin> potentialConflict, SyntaxTree ancestorTree, SyntaxTree localTree, SyntaxTree remoteTree) { var fllocal = FindStartEnd(potentialConflict.Where(c => c.Origin == DiffWithOrigin.OriginEnum.Local).Select(c => c.Diff)); var flremote = FindStartEnd(potentialConflict.Where(c => c.Origin == DiffWithOrigin.OriginEnum.Remote).Select(c => c.Diff)); var localStartOffset = fllocal.Item1.OffsetStart; var localEndOffset = fllocal.Item2.OffsetEnd; var remoteStartOffset = flremote.Item1.OffsetStart; var remoteEndOffset = flremote.Item2.OffsetEnd; var first = MinAncestorStart(fllocal.Item1, flremote.Item1).Ancestor.Span.Start; var last = MaxAncestorEnd(fllocal.Item2, flremote.Item2).Ancestor.Span.End; var con = new Conflict { Ancestor = SpanDetails.Create(first, last, ancestorTree), Local = SpanDetails.Create(first + localStartOffset, last + localEndOffset, localTree), Remote = SpanDetails.Create(first + remoteStartOffset, last + remoteEndOffset, remoteTree) }; return(con); }
private static InnerMethodConflict GetInnerMethodConflicts(MethodDeclarationSyntax ancestor, SpanDetails changed, SpanDetails removed, IEnumerable <MethodDeclarationSyntax> insertedMethods, InnerMethodConflict.Local type) { if (!TriviaCompare.IsSpanInNodeTrivia(removed.Span, removed.Node)) { return(null); } var change = changed.Node as MethodDeclarationSyntax; if (change == null) { return(null); } var moved = GetMovedMethod(insertedMethods, change); if (moved == null) { return(null); } var diffRes = Diff3.Compare(ancestor, moved, change); return(new InnerMethodConflict(ancestor, change, moved, diffRes, type)); }