monocart-coverage-reports 2.9.3 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/README.zh-Hans.md +4 -1
- package/lib/assets.js +98 -0
- package/lib/converter/converter.js +36 -12
- package/lib/converter/find-original-range.js +29 -13
- package/lib/converter/flatten-source-maps.js +186 -166
- package/lib/converter/ignore.js +86 -24
- package/lib/converter/info-function.js +7 -4
- package/lib/generate.js +91 -476
- package/lib/index.d.ts +22 -1
- package/lib/istanbul/istanbul.js +11 -8
- package/lib/packages/monocart-coverage-assets.js +4 -0
- package/lib/packages/monocart-coverage-vendor.js +16 -16
- package/lib/platform/share.js +22 -0
- package/lib/reports/codacy.js +43 -0
- package/lib/reports/codecov.js +28 -0
- package/lib/reports/console-details.js +174 -0
- package/lib/reports/console-summary.js +83 -0
- package/lib/reports/custom.js +34 -0
- package/lib/reports/markdown-details.js +120 -0
- package/lib/reports/markdown-summary.js +44 -0
- package/lib/reports/raw.js +33 -0
- package/lib/reports/v8-json.js +22 -0
- package/lib/reports/v8.js +51 -0
- package/lib/utils/markdown.js +132 -132
- package/lib/utils/util.js +95 -155
- package/lib/v8/v8.js +16 -74
- package/package.json +116 -112
- package/lib/packages/monocart-coverage-app.js +0 -1
package/lib/utils/markdown.js
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
const os = require('os');
|
|
2
|
-
|
|
3
|
-
const renderLine = (ls, padding) => {
|
|
4
|
-
const spacing = ''.padEnd(padding, ' ');
|
|
5
|
-
const line = ls.join(`${spacing}|${spacing}`);
|
|
6
|
-
return `|${spacing}${line}${spacing}|`;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const renderCell = (cellValue, column) => {
|
|
10
|
-
|
|
11
|
-
// To include a pipe | as content within your cell, use a \ before the pipe:
|
|
12
|
-
cellValue = cellValue.split(/\\?\|/g).join('\\|');
|
|
13
|
-
const valueWidth = cellValue.length;
|
|
14
|
-
const width = column.width;
|
|
15
|
-
|
|
16
|
-
if (width <= valueWidth) {
|
|
17
|
-
return cellValue;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const spacingWidth = width - valueWidth;
|
|
21
|
-
const spacing = ''.padEnd(spacingWidth, ' ');
|
|
22
|
-
|
|
23
|
-
const align = column.align;
|
|
24
|
-
|
|
25
|
-
if (align === 'right') {
|
|
26
|
-
return spacing + cellValue;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (align === 'center') {
|
|
30
|
-
const l = Math.round(spacingWidth * 0.5);
|
|
31
|
-
const r = spacingWidth - l;
|
|
32
|
-
const spacingL = ''.padEnd(l, ' ');
|
|
33
|
-
const spacingR = ''.padEnd(r, ' ');
|
|
34
|
-
return spacingL + cellValue + spacingR;
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return cellValue + spacing;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const renderHyphen = (column) => {
|
|
42
|
-
const width = column.width;
|
|
43
|
-
const align = column.align;
|
|
44
|
-
if (align === 'right') {
|
|
45
|
-
return ':'.padStart(width, '-');
|
|
46
|
-
}
|
|
47
|
-
if (align === 'center') {
|
|
48
|
-
const hyphen = ''.padEnd(width - 2, '-');
|
|
49
|
-
return `:${hyphen}:`;
|
|
50
|
-
}
|
|
51
|
-
// default to left
|
|
52
|
-
return ':'.padEnd(width, '-');
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const options = {
|
|
58
|
-
name: '',
|
|
59
|
-
padding: 1,
|
|
60
|
-
nullPlaceholder: '',
|
|
61
|
-
... data.options
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const padding = options.padding;
|
|
65
|
-
|
|
66
|
-
// console.log(data, options);
|
|
67
|
-
|
|
68
|
-
const lines = [];
|
|
69
|
-
|
|
70
|
-
if (options.name) {
|
|
71
|
-
lines.push(`## ${options.name}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// init columns
|
|
75
|
-
const columns = data.columns.map((item) => {
|
|
76
|
-
if (typeof item === 'string') {
|
|
77
|
-
item = {
|
|
78
|
-
name: item
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
const column = {
|
|
82
|
-
... item
|
|
83
|
-
};
|
|
84
|
-
column.name = `${column.name}`;
|
|
85
|
-
if (typeof column.width !== 'number') {
|
|
86
|
-
column.width = column.name.length;
|
|
87
|
-
}
|
|
88
|
-
column.width = Math.max(column.width, 3);
|
|
89
|
-
return column;
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// header
|
|
93
|
-
const headers = [];
|
|
94
|
-
columns.forEach((column) => {
|
|
95
|
-
headers.push(renderCell(column.name, column));
|
|
96
|
-
});
|
|
97
|
-
lines.push(renderLine(headers, padding));
|
|
98
|
-
|
|
99
|
-
const hyphens = [];
|
|
100
|
-
columns.forEach((column) => {
|
|
101
|
-
hyphens.push(renderHyphen(column));
|
|
102
|
-
});
|
|
103
|
-
lines.push(renderLine(hyphens, padding));
|
|
104
|
-
|
|
105
|
-
// rows
|
|
106
|
-
data.rows.forEach((row) => {
|
|
107
|
-
const cells = [];
|
|
108
|
-
columns.forEach((column, i) => {
|
|
109
|
-
let cellValue = '';
|
|
110
|
-
if (Array.isArray(row)) {
|
|
111
|
-
cellValue += row[i];
|
|
112
|
-
} else {
|
|
113
|
-
let v = row[column.id];
|
|
114
|
-
if (typeof v === 'undefined' || v === null) {
|
|
115
|
-
v = options.nullPlaceholder;
|
|
116
|
-
}
|
|
117
|
-
if (column.formatter) {
|
|
118
|
-
v = column.formatter(v, row, column);
|
|
119
|
-
}
|
|
120
|
-
cellValue += v;
|
|
121
|
-
}
|
|
122
|
-
cells.push(renderCell(cellValue, column));
|
|
123
|
-
});
|
|
124
|
-
lines.push(renderLine(cells, padding));
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
return lines.join(os.EOL) + os.EOL;
|
|
128
|
-
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
module.exports =
|
|
1
|
+
const os = require('os');
|
|
2
|
+
|
|
3
|
+
const renderLine = (ls, padding) => {
|
|
4
|
+
const spacing = ''.padEnd(padding, ' ');
|
|
5
|
+
const line = ls.join(`${spacing}|${spacing}`);
|
|
6
|
+
return `|${spacing}${line}${spacing}|`;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const renderCell = (cellValue, column) => {
|
|
10
|
+
|
|
11
|
+
// To include a pipe | as content within your cell, use a \ before the pipe:
|
|
12
|
+
cellValue = cellValue.split(/\\?\|/g).join('\\|');
|
|
13
|
+
const valueWidth = cellValue.length;
|
|
14
|
+
const width = column.width;
|
|
15
|
+
|
|
16
|
+
if (width <= valueWidth) {
|
|
17
|
+
return cellValue;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const spacingWidth = width - valueWidth;
|
|
21
|
+
const spacing = ''.padEnd(spacingWidth, ' ');
|
|
22
|
+
|
|
23
|
+
const align = column.align;
|
|
24
|
+
|
|
25
|
+
if (align === 'right') {
|
|
26
|
+
return spacing + cellValue;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (align === 'center') {
|
|
30
|
+
const l = Math.round(spacingWidth * 0.5);
|
|
31
|
+
const r = spacingWidth - l;
|
|
32
|
+
const spacingL = ''.padEnd(l, ' ');
|
|
33
|
+
const spacingR = ''.padEnd(r, ' ');
|
|
34
|
+
return spacingL + cellValue + spacingR;
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return cellValue + spacing;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const renderHyphen = (column) => {
|
|
42
|
+
const width = column.width;
|
|
43
|
+
const align = column.align;
|
|
44
|
+
if (align === 'right') {
|
|
45
|
+
return ':'.padStart(width, '-');
|
|
46
|
+
}
|
|
47
|
+
if (align === 'center') {
|
|
48
|
+
const hyphen = ''.padEnd(width - 2, '-');
|
|
49
|
+
return `:${hyphen}:`;
|
|
50
|
+
}
|
|
51
|
+
// default to left
|
|
52
|
+
return ':'.padEnd(width, '-');
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const markdownGrid = (data) => {
|
|
56
|
+
|
|
57
|
+
const options = {
|
|
58
|
+
name: '',
|
|
59
|
+
padding: 1,
|
|
60
|
+
nullPlaceholder: '',
|
|
61
|
+
... data.options
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const padding = options.padding;
|
|
65
|
+
|
|
66
|
+
// console.log(data, options);
|
|
67
|
+
|
|
68
|
+
const lines = [];
|
|
69
|
+
|
|
70
|
+
if (options.name) {
|
|
71
|
+
lines.push(`## ${options.name}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// init columns
|
|
75
|
+
const columns = data.columns.map((item) => {
|
|
76
|
+
if (typeof item === 'string') {
|
|
77
|
+
item = {
|
|
78
|
+
name: item
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const column = {
|
|
82
|
+
... item
|
|
83
|
+
};
|
|
84
|
+
column.name = `${column.name}`;
|
|
85
|
+
if (typeof column.width !== 'number') {
|
|
86
|
+
column.width = column.name.length;
|
|
87
|
+
}
|
|
88
|
+
column.width = Math.max(column.width, 3);
|
|
89
|
+
return column;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// header
|
|
93
|
+
const headers = [];
|
|
94
|
+
columns.forEach((column) => {
|
|
95
|
+
headers.push(renderCell(column.name, column));
|
|
96
|
+
});
|
|
97
|
+
lines.push(renderLine(headers, padding));
|
|
98
|
+
|
|
99
|
+
const hyphens = [];
|
|
100
|
+
columns.forEach((column) => {
|
|
101
|
+
hyphens.push(renderHyphen(column));
|
|
102
|
+
});
|
|
103
|
+
lines.push(renderLine(hyphens, padding));
|
|
104
|
+
|
|
105
|
+
// rows
|
|
106
|
+
data.rows.forEach((row) => {
|
|
107
|
+
const cells = [];
|
|
108
|
+
columns.forEach((column, i) => {
|
|
109
|
+
let cellValue = '';
|
|
110
|
+
if (Array.isArray(row)) {
|
|
111
|
+
cellValue += row[i];
|
|
112
|
+
} else {
|
|
113
|
+
let v = row[column.id];
|
|
114
|
+
if (typeof v === 'undefined' || v === null) {
|
|
115
|
+
v = options.nullPlaceholder;
|
|
116
|
+
}
|
|
117
|
+
if (column.formatter) {
|
|
118
|
+
v = column.formatter(v, row, column);
|
|
119
|
+
}
|
|
120
|
+
cellValue += v;
|
|
121
|
+
}
|
|
122
|
+
cells.push(renderCell(cellValue, column));
|
|
123
|
+
});
|
|
124
|
+
lines.push(renderLine(cells, padding));
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return lines.join(os.EOL) + os.EOL;
|
|
128
|
+
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
module.exports = markdownGrid;
|
package/lib/utils/util.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const { writeFile, readFile } = require('fs/promises');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const { pathToFileURL } = require('url');
|
|
5
4
|
const os = require('os');
|
|
6
5
|
const crypto = require('crypto');
|
|
7
6
|
const EC = require('eight-colors');
|
|
8
7
|
const CG = require('console-grid');
|
|
8
|
+
const acornWalk = require('acorn-walk');
|
|
9
|
+
|
|
9
10
|
const Share = require('../platform/share.js');
|
|
10
11
|
const request = require('./request.js');
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const acornWalk = require('acorn-walk');
|
|
12
|
+
const version = require('../../package.json').version;
|
|
13
|
+
const markdownGrid = require('./markdown.js');
|
|
14
14
|
|
|
15
15
|
const { findUpSync, supportsColor } = require('../packages/monocart-coverage-vendor.js');
|
|
16
16
|
|
|
@@ -21,6 +21,8 @@ if (!supportsColor.stdout) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const Util = {
|
|
24
|
+
version,
|
|
25
|
+
|
|
24
26
|
... Share,
|
|
25
27
|
|
|
26
28
|
EC,
|
|
@@ -29,6 +31,7 @@ const Util = {
|
|
|
29
31
|
root: process.cwd(),
|
|
30
32
|
|
|
31
33
|
request,
|
|
34
|
+
markdownGrid,
|
|
32
35
|
|
|
33
36
|
relativePath: function(p, root) {
|
|
34
37
|
p = `${p}`;
|
|
@@ -149,42 +152,6 @@ const Util = {
|
|
|
149
152
|
return htmlPathHandler();
|
|
150
153
|
},
|
|
151
154
|
|
|
152
|
-
resolveNodeModule: (id) => {
|
|
153
|
-
|
|
154
|
-
// for deno npm module
|
|
155
|
-
const mp = require.resolve(id);
|
|
156
|
-
if (fs.existsSync(mp)) {
|
|
157
|
-
return mp;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const p = `${it}/dist/${it}.js`;
|
|
161
|
-
// root
|
|
162
|
-
const cwd = path.resolve('node_modules', p);
|
|
163
|
-
if (fs.existsSync(cwd)) {
|
|
164
|
-
return cwd;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// sub node modules
|
|
168
|
-
const sub = path.resolve(__dirname, '../../node_modules', p);
|
|
169
|
-
if (fs.existsSync(sub)) {
|
|
170
|
-
return sub;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// same level dep
|
|
174
|
-
const dep = path.resolve(__dirname, '../../../', p);
|
|
175
|
-
if (fs.existsSync(dep)) {
|
|
176
|
-
return dep;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
Util.logError(`Not found module: ${p}`);
|
|
180
|
-
|
|
181
|
-
return cwd;
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
resolvePackage: (p) => {
|
|
185
|
-
return path.resolve(__dirname, '../packages', p);
|
|
186
|
-
},
|
|
187
|
-
|
|
188
155
|
getCacheFileInfo: (type, id, cacheDir) => {
|
|
189
156
|
const cacheName = `${type}-${id}.json`;
|
|
190
157
|
const cachePath = path.resolve(cacheDir, cacheName);
|
|
@@ -219,104 +186,6 @@ const Util = {
|
|
|
219
186
|
// default config not found
|
|
220
187
|
},
|
|
221
188
|
|
|
222
|
-
saveHtmlReport: async (options) => {
|
|
223
|
-
|
|
224
|
-
const {
|
|
225
|
-
inline,
|
|
226
|
-
reportData,
|
|
227
|
-
jsFiles,
|
|
228
|
-
assetsPath,
|
|
229
|
-
outputDir,
|
|
230
|
-
htmlFile,
|
|
231
|
-
|
|
232
|
-
reportDataFile
|
|
233
|
-
} = options;
|
|
234
|
-
|
|
235
|
-
// report data
|
|
236
|
-
const reportDataCompressed = deflateSync(JSON.stringify(reportData));
|
|
237
|
-
const reportDataStr = `window.reportData = '${reportDataCompressed}';`;
|
|
238
|
-
|
|
239
|
-
// js libs
|
|
240
|
-
const jsList = [];
|
|
241
|
-
for (const jsFile of jsFiles) {
|
|
242
|
-
const jsStr = await Util.readFile(jsFile);
|
|
243
|
-
jsList.push({
|
|
244
|
-
filename: path.basename(jsFile),
|
|
245
|
-
str: jsStr
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// html content
|
|
250
|
-
let htmlStr = '';
|
|
251
|
-
const EOL = Util.getEOL();
|
|
252
|
-
if (inline) {
|
|
253
|
-
htmlStr = [
|
|
254
|
-
'<script>',
|
|
255
|
-
reportDataStr,
|
|
256
|
-
... jsList.map((it) => it.str),
|
|
257
|
-
'</script>'
|
|
258
|
-
].join(EOL);
|
|
259
|
-
} else {
|
|
260
|
-
|
|
261
|
-
await Util.writeFile(path.resolve(outputDir, reportDataFile), reportDataStr);
|
|
262
|
-
|
|
263
|
-
const assetsDir = path.resolve(outputDir, assetsPath);
|
|
264
|
-
const relAssetsDir = Util.relativePath(assetsDir, outputDir);
|
|
265
|
-
|
|
266
|
-
for (const item of jsList) {
|
|
267
|
-
const filePath = path.resolve(assetsDir, item.filename);
|
|
268
|
-
if (!fs.existsSync(filePath)) {
|
|
269
|
-
await Util.writeFile(filePath, item.str);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
htmlStr = [
|
|
274
|
-
`<script src="${reportDataFile}"></script>`,
|
|
275
|
-
... jsList.map((it) => `<script src="${relAssetsDir}/${it.filename}"></script>`)
|
|
276
|
-
].join(EOL);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// html
|
|
280
|
-
const htmlPath = path.resolve(outputDir, htmlFile);
|
|
281
|
-
const template = Util.getTemplate(path.resolve(__dirname, '../default/template.html'));
|
|
282
|
-
const html = Util.replace(template, {
|
|
283
|
-
title: reportData.title,
|
|
284
|
-
content: htmlStr
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
await Util.writeFile(htmlPath, html);
|
|
288
|
-
|
|
289
|
-
return Util.relativePath(htmlPath);
|
|
290
|
-
},
|
|
291
|
-
|
|
292
|
-
runCustomReporter: async (reportName, reportData, reportOptions, globalOptions) => {
|
|
293
|
-
let CustomReporter;
|
|
294
|
-
let err;
|
|
295
|
-
try {
|
|
296
|
-
CustomReporter = await import(reportName);
|
|
297
|
-
} catch (e) {
|
|
298
|
-
err = e;
|
|
299
|
-
try {
|
|
300
|
-
CustomReporter = await import(pathToFileURL(reportName));
|
|
301
|
-
} catch (ee) {
|
|
302
|
-
err = ee;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (!CustomReporter) {
|
|
307
|
-
Util.logError(err.message);
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
CustomReporter = CustomReporter.default || CustomReporter;
|
|
312
|
-
|
|
313
|
-
const reporter = new CustomReporter(reportOptions, globalOptions);
|
|
314
|
-
|
|
315
|
-
const results = await reporter.generate(reportData);
|
|
316
|
-
|
|
317
|
-
return results;
|
|
318
|
-
},
|
|
319
|
-
|
|
320
189
|
getEOL: function(content) {
|
|
321
190
|
if (!content) {
|
|
322
191
|
return os.EOL;
|
|
@@ -485,26 +354,16 @@ const Util = {
|
|
|
485
354
|
}
|
|
486
355
|
},
|
|
487
356
|
|
|
488
|
-
getTemplate: function(templatePath) {
|
|
489
|
-
if (!Util.templateCache) {
|
|
490
|
-
Util.templateCache = {};
|
|
491
|
-
}
|
|
492
|
-
let template = Util.templateCache[templatePath];
|
|
493
|
-
if (!template) {
|
|
494
|
-
template = Util.readFileSync(templatePath);
|
|
495
|
-
if (template) {
|
|
496
|
-
Util.templateCache[templatePath] = template;
|
|
497
|
-
} else {
|
|
498
|
-
Util.logError(`not found template: ${templatePath}`);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
return template;
|
|
502
|
-
},
|
|
503
|
-
|
|
504
357
|
normalizeColorType: (color) => {
|
|
505
358
|
return `${color}`.trim().toLowerCase();
|
|
506
359
|
},
|
|
507
360
|
|
|
361
|
+
normalizeMaxCols: (maxCols, min = 1) => {
|
|
362
|
+
if (Util.isNum(maxCols)) {
|
|
363
|
+
return Math.max(maxCols, min);
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
|
|
508
367
|
getColorStrByStatus: (str, status, color = '') => {
|
|
509
368
|
|
|
510
369
|
const colorHandlers = {
|
|
@@ -545,7 +404,7 @@ const Util = {
|
|
|
545
404
|
return str;
|
|
546
405
|
},
|
|
547
406
|
'tex': () => {
|
|
548
|
-
const texStr = str.replace(
|
|
407
|
+
const texStr = str.replace(/%/g, '\\\\%');
|
|
549
408
|
if (status === 'low') {
|
|
550
409
|
return `$\\color{red}{\\textsf{${texStr}}}$`;
|
|
551
410
|
}
|
|
@@ -673,6 +532,87 @@ const Util = {
|
|
|
673
532
|
return lines.join(',');
|
|
674
533
|
},
|
|
675
534
|
|
|
535
|
+
// skip \s and comments
|
|
536
|
+
fixSourceRange: (locator, start, end) => {
|
|
537
|
+
|
|
538
|
+
let fixedStart = start;
|
|
539
|
+
let fixedEnd = end;
|
|
540
|
+
|
|
541
|
+
const rangeText = locator.getSlice(start, end);
|
|
542
|
+
|
|
543
|
+
let text = rangeText;
|
|
544
|
+
|
|
545
|
+
// =======================================
|
|
546
|
+
// handle end first
|
|
547
|
+
const oldLen = text.length;
|
|
548
|
+
text = text.trimEnd();
|
|
549
|
+
const newLen = text.length;
|
|
550
|
+
if (newLen < oldLen) {
|
|
551
|
+
fixedEnd -= oldLen - newLen;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// =======================================
|
|
555
|
+
// handle start
|
|
556
|
+
|
|
557
|
+
const comments = locator.lineParser.commentParser.comments;
|
|
558
|
+
|
|
559
|
+
let startOffset = 0;
|
|
560
|
+
|
|
561
|
+
// never start in a comment, skip to comment end
|
|
562
|
+
const inComment = comments.find((it) => start > it.start && start < it.end);
|
|
563
|
+
if (inComment) {
|
|
564
|
+
startOffset = inComment.end - start;
|
|
565
|
+
// next text
|
|
566
|
+
text = text.slice(startOffset);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
while (startOffset < newLen) {
|
|
570
|
+
|
|
571
|
+
const beforeLen = text.length;
|
|
572
|
+
text = text.trimStart();
|
|
573
|
+
const afterLen = text.length;
|
|
574
|
+
if (afterLen === beforeLen) {
|
|
575
|
+
// no indent
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
const indentLen = beforeLen - afterLen;
|
|
580
|
+
|
|
581
|
+
startOffset += indentLen;
|
|
582
|
+
|
|
583
|
+
// no comments
|
|
584
|
+
if (!comments.length) {
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const nextPos = start + startOffset;
|
|
589
|
+
const comment = comments.find((it) => it.start === nextPos);
|
|
590
|
+
if (!comment) {
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
const commentLen = comment.end - comment.start;
|
|
595
|
+
|
|
596
|
+
startOffset += commentLen;
|
|
597
|
+
|
|
598
|
+
// next text
|
|
599
|
+
text = text.slice(commentLen);
|
|
600
|
+
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// It should never be possible to start with }
|
|
604
|
+
if (rangeText[startOffset] === '}') {
|
|
605
|
+
startOffset += 1;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
fixedStart = start + startOffset;
|
|
609
|
+
|
|
610
|
+
return {
|
|
611
|
+
fixedStart,
|
|
612
|
+
fixedEnd
|
|
613
|
+
};
|
|
614
|
+
},
|
|
615
|
+
|
|
676
616
|
cmpVersion: (v1, v2) => {
|
|
677
617
|
const [strMajor1, strMinor1, strPatch1] = `${v1}`.split('.');
|
|
678
618
|
const [strMajor2, strMinor2, strPatch2] = `${v2}`.split('.');
|