Skip to content

Commit 9f2ee6b

Browse files
committed
There was a long standing problem where the ignoreWhitespace flag was not passed down into the subpiece diff building. This fixes that but while fixing that it was noticed that the parent doesnt reflect in this case that the child has a change. I updated it so the child diffing passing a result to the parent so we always show that changes are there.
1 parent 44360dd commit 9f2ee6b

3 files changed

Lines changed: 115 additions & 75 deletions

File tree

DiffPlex/DiffBuilder/SideBySideDiffBuilder.cs

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using DiffPlex.Chunkers;
45
using DiffPlex.DiffBuilder.Model;
56
using DiffPlex.Model;
@@ -12,8 +13,8 @@ public class SideBySideDiffBuilder : ISideBySideDiffBuilder
1213
private readonly IChunker lineChunker;
1314
private readonly IChunker wordChunker;
1415

15-
private delegate void PieceBuilder(string oldText, string newText, List<DiffPiece> oldPieces, List<DiffPiece> newPieces);
16-
16+
private delegate ChangeType PieceBuilder(string oldText, string newText, List<DiffPiece> oldPieces, List<DiffPiece> newPieces, bool ignoreWhitespace, bool ignoreCase);
17+
1718
/// <summary>
1819
/// Gets the default singleton instance.
1920
/// </summary>
@@ -26,25 +27,32 @@ public SideBySideDiffBuilder(IDiffer differ, IChunker lineChunker, IChunker word
2627
this.wordChunker = wordChunker ?? throw new ArgumentNullException(nameof(wordChunker));
2728
}
2829

29-
public SideBySideDiffBuilder(IDiffer differ = null) :
30+
public SideBySideDiffBuilder(IDiffer differ = null) :
3031
this(differ, new LineChunker(), new WordChunker())
3132
{
3233
}
3334

34-
public SideBySideDiffBuilder(IDiffer differ, char[] wordSeparators)
35+
public SideBySideDiffBuilder(IDiffer differ, char[] wordSeparators)
3536
: this(differ, new LineChunker(), new DelimiterChunker(wordSeparators))
3637
{
3738
}
3839

3940
public SideBySideDiffModel BuildDiffModel(string oldText, string newText)
4041
=> BuildDiffModel(oldText, newText, ignoreWhitespace: true);
4142

42-
public SideBySideDiffModel BuildDiffModel(string oldText, string newText, bool ignoreWhitespace)
43+
public SideBySideDiffModel BuildDiffModel(string oldText, string newText, bool ignoreWhitespace) => BuildDiffModel(
44+
oldText,
45+
newText,
46+
ignoreWhitespace,
47+
false);
48+
49+
public SideBySideDiffModel BuildDiffModel(string oldText, string newText, bool ignoreWhitespace, bool ignoreCase)
4350
{
4451
return BuildLineDiff(
4552
oldText ?? throw new ArgumentNullException(nameof(oldText)),
4653
newText ?? throw new ArgumentNullException(nameof(newText)),
47-
ignoreWhitespace);
54+
ignoreWhitespace,
55+
ignoreCase);
4856
}
4957

5058
/// <summary>
@@ -62,7 +70,7 @@ public static SideBySideDiffModel Diff(string oldText, string newText, bool igno
6270

6371
var model = new SideBySideDiffModel();
6472
var diffResult = Differ.Instance.CreateDiffs(oldText, newText, ignoreWhiteSpace, ignoreCase, LineChunker.Instance);
65-
BuildDiffPieces(diffResult, model.OldText.Lines, model.NewText.Lines, BuildWordDiffPiecesInternal);
73+
BuildDiffPieces(diffResult, model.OldText.Lines, model.NewText.Lines, BuildWordDiffPiecesInternal, ignoreWhiteSpace, ignoreCase);
6674

6775
return model;
6876
}
@@ -84,43 +92,46 @@ public static SideBySideDiffModel Diff(IDiffer differ, string oldText, string ne
8492
if (newText == null) throw new ArgumentNullException(nameof(newText));
8593

8694
if (differ == null) return Diff(oldText, newText, ignoreWhiteSpace, ignoreCase);
95+
8796
var model = new SideBySideDiffModel();
8897
var diffResult = differ.CreateDiffs(oldText, newText, ignoreWhiteSpace, ignoreCase, lineChunker ?? LineChunker.Instance);
89-
BuildDiffPieces(diffResult, model.OldText.Lines, model.NewText.Lines, (ot, nt, op, np) =>
98+
BuildDiffPieces(diffResult, model.OldText.Lines, model.NewText.Lines, (ot, nt, op, np, iw, ic) =>
9099
{
91-
var r = differ.CreateDiffs(oldText, newText, false, false, wordChunker ?? WordChunker.Instance);
92-
BuildDiffPieces(r, op, np, null);
93-
});
94-
100+
var r = differ.CreateDiffs(oldText, newText, iw, ic, wordChunker ?? WordChunker.Instance);
101+
return BuildDiffPieces(r, op, np, null, iw, ic);
102+
}, ignoreWhiteSpace, ignoreCase);
103+
95104
return model;
96105
}
97106

98-
private static void BuildWordDiffPiecesInternal(string oldText, string newText, List<DiffPiece> oldPieces, List<DiffPiece> newPieces)
107+
private static ChangeType BuildWordDiffPiecesInternal(string oldText, string newText, List<DiffPiece> oldPieces, List<DiffPiece> newPieces, bool ignoreWhiteSpace, bool ignoreCase)
99108
{
100-
var diffResult = Differ.Instance.CreateDiffs(oldText, newText, false, false, WordChunker.Instance);
101-
BuildDiffPieces(diffResult, oldPieces, newPieces, null);
109+
var diffResult = Differ.Instance.CreateDiffs(oldText, newText, ignoreWhiteSpace, ignoreCase, WordChunker.Instance);
110+
return BuildDiffPieces(diffResult, oldPieces, newPieces, null, ignoreWhiteSpace, ignoreCase);
102111
}
103112

104-
private SideBySideDiffModel BuildLineDiff(string oldText, string newText, bool ignoreWhitespace)
113+
private SideBySideDiffModel BuildLineDiff(string oldText, string newText, bool ignoreWhiteSpace, bool ignoreCase)
105114
{
106115
var model = new SideBySideDiffModel();
107-
var diffResult = differ.CreateDiffs(oldText, newText, ignoreWhitespace, false, lineChunker);
108-
BuildDiffPieces(diffResult, model.OldText.Lines, model.NewText.Lines, BuildWordDiffPieces);
109-
116+
var diffResult = differ.CreateDiffs(oldText, newText, ignoreWhiteSpace, ignoreCase, lineChunker);
117+
BuildDiffPieces(diffResult, model.OldText.Lines, model.NewText.Lines, BuildWordDiffPieces, ignoreWhiteSpace, ignoreCase);
118+
110119
return model;
111120
}
112121

113-
private void BuildWordDiffPieces(string oldText, string newText, List<DiffPiece> oldPieces, List<DiffPiece> newPieces)
122+
private ChangeType BuildWordDiffPieces(string oldText, string newText, List<DiffPiece> oldPieces, List<DiffPiece> newPieces, bool ignoreWhiteSpace, bool ignoreCase)
114123
{
115-
var diffResult = differ.CreateDiffs(oldText, newText, ignoreWhiteSpace: false, false, wordChunker);
116-
BuildDiffPieces(diffResult, oldPieces, newPieces, subPieceBuilder: null);
124+
var diffResult = differ.CreateDiffs(oldText, newText, ignoreWhiteSpace: ignoreWhiteSpace, ignoreCase, wordChunker);
125+
return BuildDiffPieces(diffResult, oldPieces, newPieces, subPieceBuilder: null, ignoreWhiteSpace, ignoreCase);
117126
}
118127

119-
private static void BuildDiffPieces(DiffResult diffResult, List<DiffPiece> oldPieces, List<DiffPiece> newPieces, PieceBuilder subPieceBuilder)
128+
private static ChangeType BuildDiffPieces(DiffResult diffResult, List<DiffPiece> oldPieces, List<DiffPiece> newPieces, PieceBuilder subPieceBuilder, bool ignoreWhiteSpace, bool ignoreCase)
120129
{
121130
int aPos = 0;
122131
int bPos = 0;
123132

133+
ChangeType changeSummary = ChangeType.Unchanged;
134+
124135
foreach (var diffBlock in diffResult.DiffBlocks)
125136
{
126137
while (bPos < diffBlock.InsertStartB && aPos < diffBlock.DeleteStartA)
@@ -139,8 +150,8 @@ private static void BuildDiffPieces(DiffResult diffResult, List<DiffPiece> oldPi
139150

140151
if (subPieceBuilder != null)
141152
{
142-
subPieceBuilder(diffResult.PiecesOld[aPos], diffResult.PiecesNew[bPos], oldPiece.SubPieces, newPiece.SubPieces);
143-
newPiece.Type = oldPiece.Type = ChangeType.Modified;
153+
var subChangeSummary = subPieceBuilder(diffResult.PiecesOld[aPos], diffResult.PiecesNew[bPos], oldPiece.SubPieces, newPiece.SubPieces, ignoreWhiteSpace, ignoreCase);
154+
newPiece.Type = oldPiece.Type = subChangeSummary;
144155
}
145156

146157
oldPieces.Add(oldPiece);
@@ -176,6 +187,18 @@ private static void BuildDiffPieces(DiffResult diffResult, List<DiffPiece> oldPi
176187
aPos++;
177188
bPos++;
178189
}
190+
191+
// Consider the whole diff as "modified" if we found any change, otherwise we consider it unchanged
192+
if(oldPieces.Any(x=> x.Type == ChangeType.Modified || x.Type == ChangeType.Inserted || x.Type == ChangeType.Deleted))
193+
{
194+
changeSummary = ChangeType.Modified;
195+
}
196+
else if (newPieces.Any(x => x.Type == ChangeType.Modified || x.Type == ChangeType.Inserted || x.Type == ChangeType.Deleted))
197+
{
198+
changeSummary = ChangeType.Modified;
199+
}
200+
201+
return changeSummary;
179202
}
180203
}
181204
}

DiffPlex/DiffPlex.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Import Project="..\NuGet.props" />
33
<PropertyGroup>
44
<TargetFrameworks>net35;net40;netstandard1.0;netstandard2.0</TargetFrameworks>
5-
<Version>1.6.3</Version>
5+
<Version>1.7.0</Version>
66
<PackageTags>diff</PackageTags>
77
<Description>DiffPlex is a diffing library that allows you to programatically create text diffs. DiffPlex is a fast and tested library.</Description>
88
<PackageReleaseNotes>* Add HasDifferences property.</PackageReleaseNotes>

0 commit comments

Comments
 (0)