monocart-reporter 1.7.1 → 1.7.2
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 +7 -5
- package/lib/cli.js +1 -1
- package/lib/common.js +2 -3
- package/lib/default/options.js +4 -1
- package/lib/generate-data.js +2 -7
- package/lib/generate-report.js +10 -11
- package/lib/index.d.ts +2 -4
- package/lib/index.js +6 -0
- package/lib/merge-data.js +7 -6
- package/lib/plugins/audit/audit.js +4 -2
- package/lib/plugins/comments.js +2 -3
- package/lib/plugins/coverage/converter/collect-source-maps.js +194 -0
- package/lib/plugins/coverage/converter/converter.js +547 -0
- package/lib/plugins/coverage/converter/decode-mappings.js +49 -0
- package/lib/plugins/coverage/{v8 → converter}/dedupe.js +8 -1
- package/lib/plugins/coverage/converter/find-original-range.js +576 -0
- package/lib/plugins/coverage/converter/info-branch.js +30 -0
- package/lib/plugins/coverage/converter/info-function.js +29 -0
- package/lib/plugins/coverage/converter/info-line.js +20 -0
- package/lib/plugins/coverage/converter/position-mapping.js +183 -0
- package/lib/plugins/coverage/{coverage-utils.js → converter/source-path.js} +26 -42
- package/lib/plugins/coverage/coverage.js +51 -67
- package/lib/plugins/coverage/istanbul/istanbul.js +15 -174
- package/lib/plugins/coverage/v8/v8.js +22 -13
- package/lib/plugins/network/network.js +4 -13
- package/lib/plugins/state/client.js +3 -4
- package/lib/plugins/state/state.js +6 -3
- package/lib/runtime/monocart-code-viewer.js +1 -1
- package/lib/runtime/monocart-coverage.js +13 -14
- package/lib/runtime/monocart-formatter.js +1 -1
- package/lib/runtime/monocart-network.js +1 -1
- package/lib/runtime/monocart-reporter.js +1 -1
- package/lib/runtime/monocart-v8.js +1 -1
- package/lib/runtime/monocart-vendor.js +13 -13
- package/lib/utils/util.js +97 -3
- package/package.json +4 -5
- package/lib/plugins/coverage/v8/position-mapping.js +0 -92
- package/lib/plugins/coverage/v8/source-map.js +0 -451
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
|
|
2
|
+
const findMapping = (list, offset) => {
|
|
3
|
+
let start = 0;
|
|
4
|
+
let end = list.length - 1;
|
|
5
|
+
while (end - start > 1) {
|
|
6
|
+
const i = Math.floor((start + end) * 0.5);
|
|
7
|
+
const item = list[i];
|
|
8
|
+
if (offset < item.generatedOffset) {
|
|
9
|
+
end = i;
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
if (offset > item.generatedOffset) {
|
|
13
|
+
start = i;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
return list[i];
|
|
17
|
+
}
|
|
18
|
+
// last two items, less is start
|
|
19
|
+
const endItem = list[end];
|
|
20
|
+
if (offset < endItem.generatedOffset) {
|
|
21
|
+
return list[start];
|
|
22
|
+
}
|
|
23
|
+
return list[end];
|
|
24
|
+
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const findOffsetMapping = (generatedState, offset) => {
|
|
28
|
+
|
|
29
|
+
const decodedMappings = generatedState.decodedMappings;
|
|
30
|
+
|
|
31
|
+
const mapping = findMapping(decodedMappings, offset);
|
|
32
|
+
|
|
33
|
+
const generatedOffset = mapping.generatedOffset;
|
|
34
|
+
|
|
35
|
+
// not found, allow > last, not allow < first
|
|
36
|
+
if (offset < generatedOffset) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// exact matched no need fix
|
|
41
|
+
const exact = generatedOffset === offset;
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
... mapping,
|
|
45
|
+
// could be fixed if not exact matched
|
|
46
|
+
column: mapping.originalColumn,
|
|
47
|
+
exact
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const findNextOriginalDiffMapping = (originalState, mapping) => {
|
|
52
|
+
const decodedMappings = originalState.decodedMappings;
|
|
53
|
+
const { originalIndex, originalOffset } = mapping;
|
|
54
|
+
|
|
55
|
+
let i = originalIndex + 1;
|
|
56
|
+
const l = decodedMappings.length;
|
|
57
|
+
while (i < l) {
|
|
58
|
+
const item = decodedMappings[i];
|
|
59
|
+
// sometimes next is same line/column
|
|
60
|
+
if (item.originalOffset > originalOffset) {
|
|
61
|
+
return item;
|
|
62
|
+
}
|
|
63
|
+
i += 1;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const findNextGeneratedDiffMapping = (generatedState, mapping) => {
|
|
68
|
+
const decodedMappings = generatedState.decodedMappings;
|
|
69
|
+
const i = mapping.generatedIndex + 1;
|
|
70
|
+
const l = decodedMappings.length;
|
|
71
|
+
if (i < l) {
|
|
72
|
+
return decodedMappings[i];
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const getGeneratedText = (mapping, generatedState) => {
|
|
77
|
+
|
|
78
|
+
const generatedText = mapping.generatedText;
|
|
79
|
+
if (typeof generatedText === 'string') {
|
|
80
|
+
return generatedText;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let text = '';
|
|
84
|
+
|
|
85
|
+
const { positionMapping } = generatedState;
|
|
86
|
+
const nextMapping = findNextGeneratedDiffMapping(generatedState, mapping);
|
|
87
|
+
if (nextMapping) {
|
|
88
|
+
text = positionMapping.getSlice(mapping.generatedOffset, nextMapping.generatedOffset);
|
|
89
|
+
} else {
|
|
90
|
+
// to the end
|
|
91
|
+
text = positionMapping.getSlice(mapping.generatedOffset);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// never cross line
|
|
95
|
+
if (mapping.generatedEndOffset) {
|
|
96
|
+
const len = mapping.generatedEndOffset - mapping.generatedOffset;
|
|
97
|
+
text = text.slice(0, len);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// keep cache
|
|
101
|
+
mapping.generatedText = text;
|
|
102
|
+
|
|
103
|
+
return text;
|
|
104
|
+
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const getOriginalText = (mapping, originalState) => {
|
|
108
|
+
|
|
109
|
+
const originalText = mapping.originalText;
|
|
110
|
+
if (typeof originalText === 'string') {
|
|
111
|
+
return originalText;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let text = '';
|
|
115
|
+
|
|
116
|
+
const { positionMapping } = originalState;
|
|
117
|
+
const nextMapping = findNextOriginalDiffMapping(originalState, mapping);
|
|
118
|
+
if (nextMapping) {
|
|
119
|
+
text = positionMapping.getSlice(mapping.originalOffset, nextMapping.originalOffset);
|
|
120
|
+
} else {
|
|
121
|
+
// to the end
|
|
122
|
+
text = positionMapping.getSlice(mapping.originalOffset);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// the last two items could have same line and column
|
|
126
|
+
// so can NOT pre-calculate original end offset, just search new line with regex
|
|
127
|
+
|
|
128
|
+
// never cross line
|
|
129
|
+
const newLineIndex = text.search(/\r?\n/);
|
|
130
|
+
if (newLineIndex !== -1) {
|
|
131
|
+
text = text.slice(0, newLineIndex);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// keep cache
|
|
135
|
+
mapping.originalText = text;
|
|
136
|
+
|
|
137
|
+
return text;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// ========================================================================================================
|
|
141
|
+
|
|
142
|
+
const getBlockStartPosition = (originalText) => {
|
|
143
|
+
// start block characters
|
|
144
|
+
|
|
145
|
+
// originalText: 'argument) {',
|
|
146
|
+
// generatedLeft: 'o',
|
|
147
|
+
// generatedRight: '&&'
|
|
148
|
+
|
|
149
|
+
// function/block could be started with {(
|
|
150
|
+
const startBlockIndex = originalText.search(/[<{(]/);
|
|
151
|
+
if (startBlockIndex !== -1) {
|
|
152
|
+
return startBlockIndex;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// end a block
|
|
156
|
+
const list = ['>', '}', ')'];
|
|
157
|
+
for (const s of list) {
|
|
158
|
+
const endBlockIndex = originalText.lastIndexOf(s);
|
|
159
|
+
if (endBlockIndex !== -1) {
|
|
160
|
+
return endBlockIndex + 1;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return -1;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const getBlockEndPosition = (originalText) => {
|
|
168
|
+
// generatedText: 'e),',
|
|
169
|
+
// generatedPos: 2,
|
|
170
|
+
// originalText: 'prop))'
|
|
171
|
+
|
|
172
|
+
// generatedText: ' = false)',
|
|
173
|
+
// generatedPos: 8,
|
|
174
|
+
// originalText: '=false"'
|
|
175
|
+
|
|
176
|
+
// generatedText: '), 1 /* TEXT */)])])) : (0,vue__...)("v-if", true)], 6 /* CLASS, STYLE */);',
|
|
177
|
+
// generatedPos: 17,
|
|
178
|
+
// originalText: ' }}</slot>'
|
|
179
|
+
|
|
180
|
+
const list = ['>', '}', ')'];
|
|
181
|
+
for (const s of list) {
|
|
182
|
+
const endBlockIndex = originalText.lastIndexOf(s);
|
|
183
|
+
if (endBlockIndex !== -1) {
|
|
184
|
+
return endBlockIndex + 1;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const startBlockIndex = originalText.search(/[<{(]/);
|
|
189
|
+
if (startBlockIndex !== -1) {
|
|
190
|
+
return startBlockIndex;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return -1;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const getOriginalStartPosition = (originalText, generatedText, generatedPos) => {
|
|
197
|
+
|
|
198
|
+
if (!originalText.length) {
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (originalText === generatedText) {
|
|
203
|
+
return generatedPos;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ============================
|
|
207
|
+
// left matched
|
|
208
|
+
|
|
209
|
+
// originalText: '1;',
|
|
210
|
+
// generatedText: '1;else',
|
|
211
|
+
// generatedLeft: '1;'
|
|
212
|
+
|
|
213
|
+
const generatedLeft = generatedText.slice(0, generatedPos);
|
|
214
|
+
if (originalText.startsWith(generatedLeft)) {
|
|
215
|
+
return generatedLeft.length;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ============================
|
|
219
|
+
// no case for right
|
|
220
|
+
// const generatedRight = generatedText.slice(generatedPos);
|
|
221
|
+
// if (originalText.endsWith(generatedRight)) {
|
|
222
|
+
// return originalText.length - generatedRight.length;
|
|
223
|
+
// }
|
|
224
|
+
|
|
225
|
+
// ============================
|
|
226
|
+
// starts with original text (few case possible useless)
|
|
227
|
+
|
|
228
|
+
// generatedText "(void 0, void 0, void 0, function* () {"
|
|
229
|
+
// originalText " {"
|
|
230
|
+
|
|
231
|
+
// generatedLen: 1629,
|
|
232
|
+
// generatedText: '__exports__);\r\n\r\n/***/ }),\r\n\r\n/***/ "./packages/v8',
|
|
233
|
+
// generatedPos: 489,
|
|
234
|
+
// originalText: '__exports__',
|
|
235
|
+
|
|
236
|
+
// original less, generated more
|
|
237
|
+
// const includeIndex = generatedText.indexOf(originalText);
|
|
238
|
+
// if (includeIndex !== -1) {
|
|
239
|
+
|
|
240
|
+
// console.log('=================== includeIndex', includeIndex, generatedPos);
|
|
241
|
+
// console.log(JSON.stringify(generatedText.slice(0, originalText.length + includeIndex + 10)));
|
|
242
|
+
// console.log(JSON.stringify(originalText));
|
|
243
|
+
|
|
244
|
+
// if (includeIndex >= generatedPos) {
|
|
245
|
+
// return 0;
|
|
246
|
+
// }
|
|
247
|
+
|
|
248
|
+
// return originalText.length;
|
|
249
|
+
// }
|
|
250
|
+
|
|
251
|
+
// ============================
|
|
252
|
+
// {} () <>
|
|
253
|
+
const blockIndex = getBlockStartPosition(originalText);
|
|
254
|
+
if (blockIndex !== -1) {
|
|
255
|
+
return blockIndex;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ============================
|
|
259
|
+
// end characters
|
|
260
|
+
|
|
261
|
+
// ends with ">" in vue
|
|
262
|
+
// <span v-if="data.distFile">
|
|
263
|
+
|
|
264
|
+
// originalText: '">',
|
|
265
|
+
// generatedText: ' ? ((0,vue__.openBlock)(), '
|
|
266
|
+
|
|
267
|
+
// originalMethod?.apply
|
|
268
|
+
// originalText: '?.' no ?
|
|
269
|
+
|
|
270
|
+
const indexEndBlock = originalText.search(/(?<=[;,:"'\s])/);
|
|
271
|
+
if (indexEndBlock !== -1) {
|
|
272
|
+
return indexEndBlock;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// console.log('====================================================================');
|
|
276
|
+
// console.log('start position can NOT be fixed');
|
|
277
|
+
// console.log({
|
|
278
|
+
// generatedText,
|
|
279
|
+
// generatedPos,
|
|
280
|
+
// originalText
|
|
281
|
+
// // originalPos
|
|
282
|
+
// });
|
|
283
|
+
|
|
284
|
+
// ============================
|
|
285
|
+
// can NOT be fixed
|
|
286
|
+
// using original column
|
|
287
|
+
return 0;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const getOriginalEndPosition = (originalText, generatedText, generatedPos) => {
|
|
291
|
+
|
|
292
|
+
if (!originalText.length) {
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (originalText === generatedText) {
|
|
297
|
+
return generatedPos;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ============================
|
|
301
|
+
// {} () <>
|
|
302
|
+
const blockIndex = getBlockEndPosition(originalText);
|
|
303
|
+
if (blockIndex !== -1) {
|
|
304
|
+
return blockIndex;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// console.log('====================================================================');
|
|
308
|
+
// console.log('end position can NOT be fixed');
|
|
309
|
+
// console.log({
|
|
310
|
+
// generatedText,
|
|
311
|
+
// generatedPos,
|
|
312
|
+
// originalText
|
|
313
|
+
// // originalPos
|
|
314
|
+
// });
|
|
315
|
+
|
|
316
|
+
// ============================
|
|
317
|
+
// can NOT be fixed
|
|
318
|
+
// to the line end
|
|
319
|
+
return originalText.length;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// ========================================================================================================
|
|
323
|
+
|
|
324
|
+
const fixStartColumn = (startMapping, range, generatedState, originalState) => {
|
|
325
|
+
// exact matched no need fix
|
|
326
|
+
if (startMapping.exact) {
|
|
327
|
+
// originalColumn is the column
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// fix column
|
|
332
|
+
const originalColumn = startMapping.originalColumn;
|
|
333
|
+
|
|
334
|
+
const originalText = getOriginalText(startMapping, originalState);
|
|
335
|
+
const generatedText = getGeneratedText(startMapping, generatedState);
|
|
336
|
+
|
|
337
|
+
// actual generatedOffset < range startOffset
|
|
338
|
+
const generatedPos = range.startOffset - startMapping.generatedOffset;
|
|
339
|
+
|
|
340
|
+
const originalPos = getOriginalStartPosition(originalText, generatedText, generatedPos);
|
|
341
|
+
|
|
342
|
+
// if (originalState.sourcePath.endsWith('src/components/report.vue') && range.count === 0) {
|
|
343
|
+
// console.log('====================================================================');
|
|
344
|
+
// console.log('fix startMapping', originalState.sourcePath);
|
|
345
|
+
// console.log(startMapping);
|
|
346
|
+
// console.log({
|
|
347
|
+
// generatedPos,
|
|
348
|
+
// originalPos
|
|
349
|
+
// });
|
|
350
|
+
// }
|
|
351
|
+
|
|
352
|
+
// failed if originalPos = 0
|
|
353
|
+
startMapping.column = originalColumn + originalPos;
|
|
354
|
+
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
// ========================================================================================================
|
|
358
|
+
|
|
359
|
+
const fixEndColumn = (endMapping, range, startMapping, generatedState, originalState) => {
|
|
360
|
+
|
|
361
|
+
const originalColumn = endMapping.originalColumn;
|
|
362
|
+
|
|
363
|
+
// exact matched, but already -1 so need +1
|
|
364
|
+
if (endMapping.exact) {
|
|
365
|
+
endMapping.column = originalColumn + 1;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// ================================
|
|
370
|
+
// diff line, to the line end
|
|
371
|
+
if (endMapping.originalLine !== startMapping.originalLine) {
|
|
372
|
+
endMapping.column = Infinity;
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// ================================
|
|
377
|
+
// in the same line
|
|
378
|
+
|
|
379
|
+
const originalText = getOriginalText(endMapping, originalState);
|
|
380
|
+
|
|
381
|
+
// exclusive, need exclude some end strings
|
|
382
|
+
if (!endMapping.exclusive) {
|
|
383
|
+
endMapping.column = originalColumn + originalText.length;
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
const generatedText = getGeneratedText(endMapping, generatedState);
|
|
389
|
+
|
|
390
|
+
// actual generatedOffset < range endOffset
|
|
391
|
+
const generatedPos = range.endOffset - endMapping.generatedOffset;
|
|
392
|
+
|
|
393
|
+
const originalPos = getOriginalEndPosition(originalText, generatedText, generatedPos);
|
|
394
|
+
|
|
395
|
+
// if (originalState.sourcePath.endsWith('v8/src/app.vue') && range.count === 0) {
|
|
396
|
+
// console.log('====================================================================');
|
|
397
|
+
// console.log('fix endMapping', originalState.sourcePath);
|
|
398
|
+
// console.log(startMapping, endMapping);
|
|
399
|
+
// const generatedLen = generatedText.length;
|
|
400
|
+
// const gt = generatedLen > 50 ? generatedText.slice(0, 50) : generatedText;
|
|
401
|
+
// console.log({
|
|
402
|
+
// generatedLen,
|
|
403
|
+
// generatedText: gt,
|
|
404
|
+
// generatedPos,
|
|
405
|
+
// originalText,
|
|
406
|
+
// originalPos
|
|
407
|
+
// });
|
|
408
|
+
// }
|
|
409
|
+
|
|
410
|
+
// failed if originalPos = 0
|
|
411
|
+
endMapping.column = originalColumn + originalPos;
|
|
412
|
+
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
// ========================================================================================================
|
|
416
|
+
|
|
417
|
+
const isOffsetCrossLine = (startMapping, offset) => {
|
|
418
|
+
const { exact, generatedEndOffset } = startMapping;
|
|
419
|
+
if (!exact && generatedEndOffset) {
|
|
420
|
+
if (offset >= generatedEndOffset) {
|
|
421
|
+
return true;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return false;
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
const findStartMapping = (range, generatedState, originalMap) => {
|
|
428
|
+
|
|
429
|
+
// startOffset: inclusive
|
|
430
|
+
const startOffset = range.startOffset;
|
|
431
|
+
|
|
432
|
+
const startMapping = findOffsetMapping(generatedState, startOffset);
|
|
433
|
+
if (!startMapping) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// check end offset for start mapping only
|
|
438
|
+
// start mapping is inclusive, do not allow cross line
|
|
439
|
+
// but end mapping is exclusive and offset do -1, possible no mapping found, do not check it
|
|
440
|
+
if (isOffsetCrossLine(startMapping, startOffset)) {
|
|
441
|
+
// try next mapping if its offset in the range
|
|
442
|
+
const nextMapping = findNextGeneratedDiffMapping(generatedState, startMapping);
|
|
443
|
+
if (!nextMapping) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// ignore out of range
|
|
448
|
+
if (nextMapping.generatedOffset >= range.endOffset) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// if (startMapping.sourceIndex === 1 && range.count === 0) {
|
|
453
|
+
// console.log('=========================================================');
|
|
454
|
+
// console.log('find next start');
|
|
455
|
+
// console.log(startMapping, nextMapping, range);
|
|
456
|
+
// }
|
|
457
|
+
|
|
458
|
+
// exact and column
|
|
459
|
+
Object.assign(startMapping, nextMapping, {
|
|
460
|
+
exact: true,
|
|
461
|
+
column: nextMapping.originalColumn
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
// check source first, sourceIndex could be undefined
|
|
468
|
+
const sourceIndex = startMapping.sourceIndex;
|
|
469
|
+
|
|
470
|
+
const originalState = originalMap.get(sourceIndex);
|
|
471
|
+
if (!originalState) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return {
|
|
476
|
+
startMapping,
|
|
477
|
+
originalState
|
|
478
|
+
};
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
const findEndMapping = (range, generatedState, startMapping) => {
|
|
483
|
+
|
|
484
|
+
// endOffset: exclusive
|
|
485
|
+
const endOffset = range.endOffset;
|
|
486
|
+
|
|
487
|
+
// there could be some comments before end mapping even exact matched
|
|
488
|
+
const endMapping = findOffsetMapping(generatedState, endOffset - 1);
|
|
489
|
+
if (!endMapping) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// cross file ignore
|
|
494
|
+
if (endMapping.sourceIndex !== startMapping.sourceIndex) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// still exclusive
|
|
499
|
+
const exclusiveMapping = findOffsetMapping(generatedState, endOffset);
|
|
500
|
+
if (exclusiveMapping && exclusiveMapping.originalOffset === endMapping.originalOffset) {
|
|
501
|
+
endMapping.exclusive = true;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return endMapping;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const findOriginalRange = (range, generatedState, originalMap) => {
|
|
508
|
+
|
|
509
|
+
// startOffset: inclusive
|
|
510
|
+
// endOffset: exclusive
|
|
511
|
+
|
|
512
|
+
const startResult = findStartMapping(range, generatedState, originalMap);
|
|
513
|
+
if (!startResult) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const { startMapping, originalState } = startResult;
|
|
517
|
+
|
|
518
|
+
// ==================================================================================
|
|
519
|
+
// if (originalState.sourcePath.endsWith('app/app.module.ts')) {
|
|
520
|
+
// originalState.showLog = true;
|
|
521
|
+
// console.log('============================================================');
|
|
522
|
+
// console.log(originalState.sourcePath);
|
|
523
|
+
// console.log(range);
|
|
524
|
+
// } else {
|
|
525
|
+
// originalState.showLog = false;
|
|
526
|
+
// }
|
|
527
|
+
// ==================================================================================
|
|
528
|
+
|
|
529
|
+
const endMapping = findEndMapping(range, generatedState, startMapping);
|
|
530
|
+
if (!endMapping) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// fix start
|
|
535
|
+
fixStartColumn(startMapping, range, generatedState, originalState);
|
|
536
|
+
|
|
537
|
+
// fix end
|
|
538
|
+
fixEndColumn(endMapping, range, startMapping, generatedState, originalState);
|
|
539
|
+
|
|
540
|
+
const positionMapping = originalState.positionMapping;
|
|
541
|
+
const originalStart = positionMapping.locationToOffset({
|
|
542
|
+
line: startMapping.originalLine + 1,
|
|
543
|
+
column: startMapping.column
|
|
544
|
+
});
|
|
545
|
+
const originalEnd = positionMapping.locationToOffset({
|
|
546
|
+
line: endMapping.originalLine + 1,
|
|
547
|
+
column: endMapping.column
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// range start greater than end
|
|
551
|
+
if (originalStart >= originalEnd) {
|
|
552
|
+
// console.log(`start >= end: ${originalState.sourcePath}`);
|
|
553
|
+
// console.log(range, originalRange);
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
const originalRange = {
|
|
558
|
+
startOffset: originalStart,
|
|
559
|
+
endOffset: originalEnd,
|
|
560
|
+
count: range.count
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
// if (originalState.showLog) {
|
|
564
|
+
// console.log('startMapping and endMapping:');
|
|
565
|
+
// console.log(startMapping, endMapping);
|
|
566
|
+
// console.log(originalStart, originalEnd);
|
|
567
|
+
// }
|
|
568
|
+
|
|
569
|
+
return {
|
|
570
|
+
originalRange,
|
|
571
|
+
originalState
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
module.exports = findOriginalRange;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module.exports = class InfoBranch {
|
|
2
|
+
constructor(sLoc, eLoc, count) {
|
|
3
|
+
this.startLine = sLoc.line;
|
|
4
|
+
this.startColumn = sLoc.column;
|
|
5
|
+
this.endLine = eLoc.line;
|
|
6
|
+
this.endColumn = eLoc.column;
|
|
7
|
+
this.count = count;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
generate() {
|
|
11
|
+
const location = {
|
|
12
|
+
start: {
|
|
13
|
+
line: this.startLine,
|
|
14
|
+
column: this.startColumn
|
|
15
|
+
},
|
|
16
|
+
end: {
|
|
17
|
+
line: this.endLine,
|
|
18
|
+
column: this.endColumn
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
type: 'branch',
|
|
23
|
+
line: this.startLine,
|
|
24
|
+
loc: location,
|
|
25
|
+
locations: [{
|
|
26
|
+
... location
|
|
27
|
+
}]
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module.exports = class InfoFunction {
|
|
2
|
+
constructor(sLoc, eLoc, count, name) {
|
|
3
|
+
this.startLine = sLoc.line;
|
|
4
|
+
this.startColumn = sLoc.column;
|
|
5
|
+
this.endLine = eLoc.line;
|
|
6
|
+
this.endColumn = eLoc.column;
|
|
7
|
+
this.count = count;
|
|
8
|
+
this.name = name || '(anonymous)';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
generate() {
|
|
12
|
+
const loc = {
|
|
13
|
+
start: {
|
|
14
|
+
line: this.startLine,
|
|
15
|
+
column: this.startColumn
|
|
16
|
+
},
|
|
17
|
+
end: {
|
|
18
|
+
line: this.endLine,
|
|
19
|
+
column: this.endColumn
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
name: this.name,
|
|
24
|
+
decl: loc,
|
|
25
|
+
loc: loc,
|
|
26
|
+
line: this.startLine
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module.exports = class InfoLine {
|
|
2
|
+
constructor(line, column) {
|
|
3
|
+
this.line = line;
|
|
4
|
+
this.column = column;
|
|
5
|
+
this.count = 1;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
generate() {
|
|
9
|
+
return {
|
|
10
|
+
start: {
|
|
11
|
+
line: this.line,
|
|
12
|
+
column: 0
|
|
13
|
+
},
|
|
14
|
+
end: {
|
|
15
|
+
line: this.line,
|
|
16
|
+
column: this.column
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
};
|