-
Notifications
You must be signed in to change notification settings - Fork 9
/
DiffStringOptimizeStrategy.ts
105 lines (95 loc) · 2.94 KB
/
DiffStringOptimizeStrategy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import {Reporter, ReportLevel} from "../../reporter/Reporter";
import {Range} from "../Range";
import * as StringWhitespaceUtils from "./StringWhitespaceUtils";
const diff = require("diff");
export class DiffStringOptimizeStrategy implements StringOptimizeStrategy {
private reporter: Reporter;
constructor(reporter?: Reporter) {
this.reporter = reporter;
}
getChangedRanges(original: string, modified: string): Range[] {
const aResult: Range[] = [];
let iCount = 0;
// const aDiffWords = diff.diffWordsWithSpace(original, modified);
const aDiffWords = diff.diffLines(original, modified, {
ignoreWhitespace: true,
});
for (let i = 0; i < aDiffWords.length; i++) {
const oResultElement = aDiffWords[i];
const sLength = oResultElement.value.length;
// ignore removed elements
if (oResultElement.added) {
aResult.push(Range.from(iCount, iCount + sLength));
}
if (!oResultElement.removed) {
iCount += sLength;
}
}
return aResult;
}
async optimizeString(original: string, modified: string): Promise<string> {
let sIgnoreWhitespaceChanges = "";
if (this.reporter) {
this.reporter.report(
ReportLevel.TRACE,
`Performing DiffStringOptimizeStrategy ${original.length} and ${modified.length}`
);
}
// use diff with words to minimize false positives
// diffs two blocks of text, comparing word by word, treating whitespace
// as significant.
const aResult = diff.diffWordsWithSpace(original, modified);
if (this.reporter) {
this.reporter.report(
ReportLevel.TRACE,
`DIFF: Found ${aResult.length} diffs`
);
}
let iIndex = 0;
aResult.forEach(oChange => {
iIndex = sIgnoreWhitespaceChanges.length;
if (oChange.removed === undefined && oChange.added === undefined) {
// neither added nor removed
// safely apply the changes
sIgnoreWhitespaceChanges += oChange.value;
} else if (oChange.added && oChange.removed === undefined) {
// skip whitespaces
if (StringWhitespaceUtils.isWhitespace(oChange.value)) {
if (this.reporter) {
this.reporter.collect(
"DiffStringOptimizeStrategy.skipped",
1
);
this.reporter.report(
ReportLevel.TRACE,
`DIFF Skipped ${iIndex}: ${StringWhitespaceUtils.formatWhitespaceChars(
oChange.value
)}`
);
}
} else {
// add non-whitespace changes
sIgnoreWhitespaceChanges += oChange.value;
}
} else if (oChange.removed && oChange.added === undefined) {
// add whitespace change if it was removed
if (StringWhitespaceUtils.isWhitespace(oChange.value)) {
sIgnoreWhitespaceChanges += oChange.value;
if (this.reporter) {
this.reporter.collect(
"DiffStringOptimizeStrategy.added",
1
);
this.reporter.report(
ReportLevel.TRACE,
`DIFF Added ${iIndex}: ${StringWhitespaceUtils.formatWhitespaceChars(
oChange.value
)}`
);
}
}
}
});
return sIgnoreWhitespaceChanges;
}
}