1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.applyFixes = void 0;
|
4 | const stableSort = require("stable");
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | function applyFixes(source, fixes) {
|
13 | let fixed = fixes.length;
|
14 | const replacements = [];
|
15 | for (const fix of fixes) {
|
16 | const state = { replacements: combineReplacements(fix.replacements), skip: false, state: undefined };
|
17 | for (const replacement of state.replacements)
|
18 | replacements.push({ fix: state, ...replacement });
|
19 | }
|
20 | const range = {
|
21 | span: {
|
22 | start: 0,
|
23 | length: 0,
|
24 | },
|
25 | newLength: 0,
|
26 | };
|
27 | let output = '';
|
28 | let position = -1;
|
29 | replacements.sort(compareReplacements);
|
30 | for (let i = 0; i < replacements.length; ++i) {
|
31 | const replacement = replacements[i];
|
32 | const { fix } = replacement;
|
33 | if (fix.skip)
|
34 | continue;
|
35 | if (replacement.start <= position) {
|
36 |
|
37 | if (fix.state !== undefined) {
|
38 |
|
39 | const rollbackToIndex = fix.state.index;
|
40 | for (--i; i !== rollbackToIndex; --i) {
|
41 | const f = replacements[i].fix;
|
42 |
|
43 |
|
44 | if (f.state !== undefined && f.state.index === i)
|
45 | f.state = undefined;
|
46 |
|
47 |
|
48 | if (f.state === undefined && f.skip) {
|
49 | ++fixed;
|
50 | f.skip = false;
|
51 | }
|
52 | }
|
53 | output = output.substring(0, fix.state.length);
|
54 | position = fix.state.position;
|
55 | }
|
56 | fix.skip = true;
|
57 | --fixed;
|
58 | continue;
|
59 | }
|
60 |
|
61 | if (fix.state === undefined && fix.replacements.length !== 1)
|
62 | fix.state = { position, index: i, length: output.length };
|
63 | if (position === -1) {
|
64 |
|
65 | range.span.start = replacement.start;
|
66 | output = source.substring(0, replacement.start);
|
67 | }
|
68 | else {
|
69 | output += source.substring(position, replacement.start);
|
70 | }
|
71 | output += replacement.text;
|
72 | position = replacement.end;
|
73 | }
|
74 | output += source.substring(position);
|
75 | range.span.length = position - range.span.start;
|
76 | range.newLength = range.span.length + output.length - source.length;
|
77 | return {
|
78 | fixed,
|
79 | range,
|
80 | result: output,
|
81 | };
|
82 | }
|
83 | exports.applyFixes = applyFixes;
|
84 | function compareReplacements(a, b) {
|
85 | return a.start - b.start || a.end - b.end;
|
86 | }
|
87 |
|
88 | function combineReplacements(replacements) {
|
89 | if (replacements.length === 1)
|
90 | return replacements;
|
91 |
|
92 | replacements = stableSort.inplace(replacements.slice(), compareReplacements);
|
93 | const result = [];
|
94 | let current = replacements[0];
|
95 | for (let i = 1; i < replacements.length; ++i) {
|
96 | const replacement = replacements[i];
|
97 | if (current.end > replacement.start)
|
98 | throw new Error('Replacements of fix overlap.');
|
99 | if (current.end === replacement.start) {
|
100 | current = {
|
101 | start: current.start,
|
102 | end: replacement.end,
|
103 | text: current.text + replacement.text,
|
104 | };
|
105 | }
|
106 | else {
|
107 | result.push(current);
|
108 | current = replacement;
|
109 | }
|
110 | }
|
111 | result.push(current);
|
112 | return result;
|
113 | }
|
114 |
|
\ | No newline at end of file |