monocart-coverage-reports 2.4.2 → 2.4.4
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 +52 -12
- package/lib/converter/ast-visitor.js +40 -20
- package/lib/converter/ast.js +1 -1
- package/lib/converter/converter.js +3 -3
- package/lib/converter/find-original-range.js +113 -65
- package/lib/generate.js +1 -1
- package/lib/packages/monocart-coverage-v8.js +1 -1
- package/lib/packages/monocart-coverage-vendor.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
* [Node.js V8 Coverage Report for Server Side](#nodejs-v8-coverage-report-for-server-side)
|
|
25
25
|
* [Multiprocessing Support](#multiprocessing-support)
|
|
26
26
|
* [Merge Coverage Reports](#merge-coverage-reports)
|
|
27
|
+
* [Resolve `sourcePath` for the Source Files](#resolve-sourcepath-for-the-source-files)
|
|
28
|
+
* [Adding Empty Coverage for Untested Files](#adding-empty-coverage-for-untested-files)
|
|
27
29
|
* [Ignoring Uncovered Codes](#ignoring-uncovered-codes)
|
|
28
30
|
* [Chromium Coverage API](#chromium-coverage-api)
|
|
29
31
|
* [V8 Coverage Data Format](#v8-coverage-data-format)
|
|
@@ -70,8 +72,6 @@ console.log(coverageResults.summary);
|
|
|
70
72
|
- [V8 coverage-report.json](https://cenfun.github.io/monocart-coverage-reports/v8-and-istanbul/coverage-report.json)
|
|
71
73
|
- `codecov` (V8 data only)
|
|
72
74
|
- coverage data for [Codecov](https://docs.codecov.com/docs/codecov-custom-coverage-format), see [example](https://app.codecov.io/github/cenfun/monocart-coverage-reports)
|
|
73
|
-
|
|
74
|
-

|
|
75
75
|
|
|
76
76
|
> Istanbul [build-in reports](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib)
|
|
77
77
|
- `clover`
|
|
@@ -95,6 +95,7 @@ console.log(coverageResults.summary);
|
|
|
95
95
|
|
|
96
96
|
> Other reports
|
|
97
97
|
- `console-summary` shows coverage summary in console
|
|
98
|
+

|
|
98
99
|
- `raw` only keep all original data, which can be used for other reports input with `inputDir`
|
|
99
100
|
- see [Merge Coverage Reports](#merge-coverage-reports)
|
|
100
101
|
|
|
@@ -258,16 +259,14 @@ mcr "node ./test/test-node-env.js" -c test/cli-options.js
|
|
|
258
259
|
| Coverage data | [Istanbul](https://github.com/gotwarlost/istanbul/blob/master/coverage.json.md) (Object) | [V8](#v8-coverage-data-format) (Array) | [V8](#v8-coverage-data-format) (Array) |
|
|
259
260
|
| Output | [Istanbul reports](#available-reports) | [V8 reports](#available-reports) | [Istanbul reports](#available-reports) |
|
|
260
261
|
| - Bytes | ❌ | ✅ | ❌ |
|
|
261
|
-
| - Statements | ✅ |
|
|
262
|
-
| - Branches | ✅ |
|
|
262
|
+
| - Statements | ✅ | ✅ | ✅ |
|
|
263
|
+
| - Branches | ✅ | ✅ | ✅ |
|
|
263
264
|
| - Functions | ✅ | ✅ | ✅ |
|
|
264
265
|
| - Lines | ✅ | ✅ | ✅ |
|
|
265
266
|
| - Execution counts | ✅ | ✅ | ✅ |
|
|
266
267
|
| CSS coverage | ❌ | ✅ | ✅ |
|
|
267
268
|
| Minified code | ❌ | ✅ | ❌ |
|
|
268
269
|
|
|
269
|
-
❔ - Partial or conditional support
|
|
270
|
-
|
|
271
270
|
## Compare Workflows
|
|
272
271
|
- Istanbul Workflows
|
|
273
272
|
- 1, [Collecting Istanbul coverage data](#collecting-istanbul-coverage-data)
|
|
@@ -451,7 +450,10 @@ const coverageOptions = {
|
|
|
451
450
|
};
|
|
452
451
|
await new CoverageReport(coverageOptions).generate();
|
|
453
452
|
```
|
|
454
|
-
|
|
453
|
+
|
|
454
|
+
## Resolve `sourcePath` for the Source Files
|
|
455
|
+
If the source file comes from the sourcemap, then its path is a virtual path. Using the `sourcePath` option to resolve a custom path.
|
|
456
|
+
For example, we have tested multiple dist files, which contain some common files. We hope to merge the coverage of the same files, so we need to unify the `sourcePath` in order to be able to merge the coverage data.
|
|
455
457
|
```js
|
|
456
458
|
const coverageOptions = {
|
|
457
459
|
sourcePath: (filePath) => {
|
|
@@ -468,6 +470,44 @@ const coverageOptions = {
|
|
|
468
470
|
```
|
|
469
471
|
see example: [./test/test-merge.js](./test/test-merge.js)
|
|
470
472
|
|
|
473
|
+
## Adding Empty Coverage for Untested Files
|
|
474
|
+
By default the untested files will not be included in the coverage report, we can first add empty coverage data for all files, so the files with coverage data will be merged, and untested files will retain 0% coverage.
|
|
475
|
+
```js
|
|
476
|
+
const fs = require('fs');
|
|
477
|
+
const path = require('path');
|
|
478
|
+
const { pathToFileURL } = require('url');
|
|
479
|
+
const MCR = require('monocart-coverage-reports');
|
|
480
|
+
|
|
481
|
+
const dir = "./src";
|
|
482
|
+
const coverageData = [];
|
|
483
|
+
const fileList = fs.readdirSync(dir);
|
|
484
|
+
for (const filename of fileList) {
|
|
485
|
+
const filePath = path.resolve(dir, filename);
|
|
486
|
+
const source = fs.readFileSync(filePath).toString('utf-8');
|
|
487
|
+
const sourcePath = path.relative(process.cwd(), filePath);
|
|
488
|
+
const url = pathToFileURL(sourcePath).toString();
|
|
489
|
+
const extname = path.extname(filename);
|
|
490
|
+
if (['.css'].includes(extname)) {
|
|
491
|
+
coverageData.push({
|
|
492
|
+
empty: true,
|
|
493
|
+
type: 'css',
|
|
494
|
+
url,
|
|
495
|
+
text: source
|
|
496
|
+
});
|
|
497
|
+
} else {
|
|
498
|
+
coverageData.push({
|
|
499
|
+
empty: true,
|
|
500
|
+
type: 'js',
|
|
501
|
+
url,
|
|
502
|
+
source
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
const options = require('path-to/same-options.js');
|
|
507
|
+
await MCR(options).add(coverageData);
|
|
508
|
+
```
|
|
509
|
+
see example: [./test/cli-options.js](./test/cli-options.js)
|
|
510
|
+
|
|
471
511
|
## Ignoring Uncovered Codes
|
|
472
512
|
To ignore codes, use the special comment which starts with `v8 ignore `:
|
|
473
513
|
- Ignoring all until stop
|
|
@@ -575,15 +615,15 @@ see source code [v8-to-istanbul.js](https://github.com/istanbuljs/v8-to-istanbul
|
|
|
575
615
|
### How Monocart Works
|
|
576
616
|
We implemented new converter instead of v8-to-istanbul:
|
|
577
617
|
- 1, Trying to fix the middle position if not found the exact mapping for the position.
|
|
578
|
-
- 2, Finding all functions and branches by parsing the source code [AST](https://github.com/acornjs/acorn), however the V8 cannot provide effective branch coverage information
|
|
618
|
+
- 2, Finding all functions, statements and branches by parsing the source code [AST](https://github.com/acornjs/acorn), however the V8 cannot provide effective branch coverage information for `AssignmentPattern`.
|
|
579
619
|
|
|
580
620
|
| AST | V8 |
|
|
581
621
|
| :---------------------| :------------- |
|
|
582
622
|
| AssignmentPattern | 🛇 Not Support |
|
|
583
|
-
| ConditionalExpression | ✔
|
|
584
|
-
| IfStatement | ✔
|
|
585
|
-
| LogicalExpression | ✔
|
|
586
|
-
| SwitchStatement | ✔
|
|
623
|
+
| ConditionalExpression | ✔ |
|
|
624
|
+
| IfStatement | ✔ |
|
|
625
|
+
| LogicalExpression | ✔ |
|
|
626
|
+
| SwitchStatement | ✔ |
|
|
587
627
|
|
|
588
628
|
## Debug for Coverage and Sourcemap
|
|
589
629
|
> Sometimes, the coverage is not what we expect. The next step is to figure out why, and we can easily find out the answer step by step through debugging.
|
|
@@ -117,18 +117,21 @@ const createBranchGroup = (type, node, parents, branchMap) => {
|
|
|
117
117
|
group.operator = node.operator;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
// could be same start
|
|
121
|
+
const branchKey = `${start}_${end}`;
|
|
122
|
+
|
|
123
|
+
branchMap.set(branchKey, group);
|
|
121
124
|
return group;
|
|
122
125
|
};
|
|
123
126
|
|
|
124
127
|
const addBranch = (group, node, locationMap) => {
|
|
125
128
|
const { start, end } = node;
|
|
126
129
|
|
|
127
|
-
const
|
|
130
|
+
const branchKey = `${group.start}_${group.end}`;
|
|
128
131
|
|
|
129
132
|
const branchInfo = {
|
|
130
133
|
// for get previous group for LogicalExpression
|
|
131
|
-
|
|
134
|
+
branchKey,
|
|
132
135
|
start,
|
|
133
136
|
end,
|
|
134
137
|
// branch count default to 0
|
|
@@ -203,23 +206,16 @@ const IfStatement = (group, parentCount) => {
|
|
|
203
206
|
|
|
204
207
|
// const b = tf2 || tf1 || a;
|
|
205
208
|
const LogicalExpression = (group, parentCount) => {
|
|
206
|
-
const { noBlockList, blockCount } = updateBlockLocations(group.locations);
|
|
207
|
-
if (!noBlockList.length) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
209
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
// from left to right
|
|
211
|
+
group.locations.forEach((item, i) => {
|
|
212
|
+
if (item.block) {
|
|
213
|
+
item.count = item.block.count;
|
|
214
|
+
} else {
|
|
214
215
|
item.count = parentCount;
|
|
215
|
-
}
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const count = parentCount - blockCount;
|
|
220
|
-
noBlockList.forEach((item) => {
|
|
221
|
-
item.count = count;
|
|
216
|
+
}
|
|
222
217
|
});
|
|
218
|
+
|
|
223
219
|
};
|
|
224
220
|
|
|
225
221
|
const SwitchStatement = (group, parentCount) => {
|
|
@@ -408,7 +404,7 @@ const collectNodes = (ast) => {
|
|
|
408
404
|
// =============================================================
|
|
409
405
|
// id: { type: 'Identifier', name: '__webpack_modules__' },
|
|
410
406
|
const name = node.id && node.id.name;
|
|
411
|
-
if (name === '__webpack_modules__' && node.init) {
|
|
407
|
+
if (name === '__webpack_modules__' && node.init && node.init.properties) {
|
|
412
408
|
// mark all as wrap function
|
|
413
409
|
node.init.properties.forEach((it) => {
|
|
414
410
|
it.value._wrapKey = it.key && it.key.value;
|
|
@@ -501,12 +497,15 @@ const collectNodes = (ast) => {
|
|
|
501
497
|
const { left, right } = node;
|
|
502
498
|
// console.log(left.start, right.start);
|
|
503
499
|
|
|
500
|
+
// could be same branch start
|
|
501
|
+
// const da = arguments.length > 1 && typeof arguments[1] !== 'undefined' ? arguments[1] : true;
|
|
502
|
+
|
|
504
503
|
let group;
|
|
505
504
|
// link to same branch start if LogicalExpression
|
|
506
505
|
const prevLocation = locationMap.get(node.start);
|
|
507
506
|
if (prevLocation) {
|
|
508
507
|
// console.log('link branch ==================', type);
|
|
509
|
-
group = branchMap.get(prevLocation.
|
|
508
|
+
group = branchMap.get(prevLocation.branchKey);
|
|
510
509
|
} else {
|
|
511
510
|
group = createBranchGroup('LogicalExpression', node, parents, branchMap);
|
|
512
511
|
addBranch(group, left, locationMap);
|
|
@@ -574,6 +573,26 @@ const getRootFunctionState = (ast, coverageInfo) => {
|
|
|
574
573
|
return rootState;
|
|
575
574
|
};
|
|
576
575
|
|
|
576
|
+
const findFunctionRange = (item, coverageInfo) => {
|
|
577
|
+
|
|
578
|
+
const { node, reverseParents } = item;
|
|
579
|
+
const { start, end } = node;
|
|
580
|
+
|
|
581
|
+
// try function start/end
|
|
582
|
+
const functionRange = getFunctionRange(start, end, coverageInfo);
|
|
583
|
+
if (functionRange) {
|
|
584
|
+
return functionRange;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// try if class MethodDefinition
|
|
588
|
+
// 0 is function self
|
|
589
|
+
const parent = reverseParents[1];
|
|
590
|
+
if (parent && parent.type === 'MethodDefinition') {
|
|
591
|
+
return getFunctionRange(parent.start, parent.end, coverageInfo);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
};
|
|
595
|
+
|
|
577
596
|
const collectAstInfo = (ast, coverageInfo) => {
|
|
578
597
|
|
|
579
598
|
const {
|
|
@@ -611,7 +630,8 @@ const collectAstInfo = (ast, coverageInfo) => {
|
|
|
611
630
|
isFunction: true,
|
|
612
631
|
count: functionItem.count
|
|
613
632
|
};
|
|
614
|
-
|
|
633
|
+
|
|
634
|
+
const functionRange = findFunctionRange(item, coverageInfo);
|
|
615
635
|
if (functionRange) {
|
|
616
636
|
if (isWrap) {
|
|
617
637
|
functionRange.wrap = true;
|
package/lib/converter/ast.js
CHANGED
|
@@ -159,8 +159,8 @@ const getJsAstInfo = (item, coverageList) => {
|
|
|
159
159
|
// most time for node.js file
|
|
160
160
|
allowReturnOutsideFunction: true,
|
|
161
161
|
allowImportExportEverywhere: true,
|
|
162
|
-
allowSuperOutsideMethod: true,
|
|
163
162
|
allowAwaitOutsideFunction: true,
|
|
163
|
+
allowSuperOutsideMethod: true,
|
|
164
164
|
// first line: #!/usr/bin/env node
|
|
165
165
|
allowHashBang: true
|
|
166
166
|
};
|
|
@@ -579,11 +579,12 @@ const handleOriginalBranchesCoverage = (state, originalStateMap) => {
|
|
|
579
579
|
return newLoc;
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
+
// before new range
|
|
583
|
+
newLoc.generatedStart = newLoc.start;
|
|
584
|
+
newLoc.generatedEnd = newLoc.end;
|
|
582
585
|
// mapping to new range
|
|
583
586
|
newLoc.start = locResult.start;
|
|
584
587
|
newLoc.end = locResult.end;
|
|
585
|
-
newLoc.generatedStart = newLoc.start;
|
|
586
|
-
newLoc.generatedEnd = newLoc.end;
|
|
587
588
|
|
|
588
589
|
return newLoc;
|
|
589
590
|
});
|
|
@@ -826,7 +827,6 @@ const getOriginalDecodedMappings = (originalDecodedMap, sourceIndex, locator) =>
|
|
|
826
827
|
|
|
827
828
|
// add offset and index
|
|
828
829
|
decodedMappings.forEach((item, i) => {
|
|
829
|
-
item.originalIndex = i;
|
|
830
830
|
item.originalOffset = locator.locationToOffset({
|
|
831
831
|
line: item.originalLine + 1,
|
|
832
832
|
column: item.originalColumn
|
|
@@ -266,13 +266,13 @@ const getOriginalEndOffset = (m, rangeInfo) => {
|
|
|
266
266
|
return m.originalEndOffset;
|
|
267
267
|
};
|
|
268
268
|
|
|
269
|
-
const getOriginalText = (m1, m2, rangeInfo) => {
|
|
269
|
+
const getOriginalText = (m1, m2, rangeInfo, direction) => {
|
|
270
270
|
const originalLocator = rangeInfo.originalState.locator;
|
|
271
271
|
|
|
272
272
|
const o1 = m1.originalOffset;
|
|
273
273
|
const o2 = m2.originalOffset;
|
|
274
274
|
|
|
275
|
-
// most of time
|
|
275
|
+
// o1 < o2: most of time
|
|
276
276
|
if (o1 < o2) {
|
|
277
277
|
// could be multiple lines for original text
|
|
278
278
|
return {
|
|
@@ -291,10 +291,28 @@ const getOriginalText = (m1, m2, rangeInfo) => {
|
|
|
291
291
|
};
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
// o1 > o2
|
|
294
|
+
// o1 > o2: should be wrong sourcemap
|
|
295
|
+
|
|
296
|
+
// just reverse offsets if few cross lines
|
|
297
|
+
const crossLines = m1.originalLine - m2.originalLine;
|
|
298
|
+
if (crossLines < 2) {
|
|
299
|
+
return {
|
|
300
|
+
originalOffset: o2,
|
|
301
|
+
originalText: originalLocator.getSlice(o2, o1)
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// if (direction === 'start') {
|
|
306
|
+
// should be m2 ?
|
|
307
|
+
// console.log(direction, rangeInfo.originalState.sourcePath);
|
|
308
|
+
// console.log(m1, m2);
|
|
309
|
+
// }
|
|
310
|
+
|
|
311
|
+
// should be wrong, ignore m2
|
|
312
|
+
const originalEndOffset = getOriginalEndOffset(m1, rangeInfo);
|
|
295
313
|
return {
|
|
296
|
-
originalOffset:
|
|
297
|
-
originalText: originalLocator.getSlice(
|
|
314
|
+
originalOffset: o1,
|
|
315
|
+
originalText: originalLocator.getSlice(o1, originalEndOffset)
|
|
298
316
|
};
|
|
299
317
|
|
|
300
318
|
};
|
|
@@ -350,34 +368,12 @@ const getGeneratedText = (m1, m2, state, offset) => {
|
|
|
350
368
|
|
|
351
369
|
};
|
|
352
370
|
|
|
353
|
-
const checkOriginalMappings = (m1, m2, direction) => {
|
|
354
|
-
// check original offset order
|
|
355
|
-
if (m1.originalOffset <= m2.originalOffset) {
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// just reverse offsets if few cross lines
|
|
360
|
-
const crossLines = m1.originalLine - m2.originalLine;
|
|
361
|
-
if (crossLines < 2) {
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// console.log('================================================');
|
|
366
|
-
// console.log(crossLines);
|
|
367
|
-
// console.log(m1, m2);
|
|
368
|
-
|
|
369
|
-
// should be mistake
|
|
370
|
-
return {
|
|
371
|
-
error: true,
|
|
372
|
-
errors: [`invalid original ${direction}: ${EC.yellow(m1.originalOffset)} > ${EC.yellow(m2.originalOffset)}`]
|
|
373
|
-
};
|
|
374
|
-
};
|
|
375
|
-
|
|
376
371
|
// ========================================================================================================
|
|
377
372
|
|
|
378
373
|
const getFixedOriginalStart = (start, mappings, state, rangeInfo) => {
|
|
379
|
-
|
|
374
|
+
|
|
380
375
|
const [m1, m2] = mappings;
|
|
376
|
+
const { originalState, crossStart } = rangeInfo;
|
|
381
377
|
|
|
382
378
|
// cross file from start of line
|
|
383
379
|
if (crossStart) {
|
|
@@ -387,12 +383,7 @@ const getFixedOriginalStart = (start, mappings, state, rangeInfo) => {
|
|
|
387
383
|
}
|
|
388
384
|
|
|
389
385
|
const direction = 'start';
|
|
390
|
-
const
|
|
391
|
-
if (errorInfo) {
|
|
392
|
-
return errorInfo;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
const { originalText, originalOffset } = getOriginalText(m1, m2, rangeInfo);
|
|
386
|
+
const { originalText, originalOffset } = getOriginalText(m1, m2, rangeInfo, direction);
|
|
396
387
|
const { generatedText, generatedPos } = getGeneratedText(m1, m2, state, start);
|
|
397
388
|
|
|
398
389
|
const originalPos = getFixedPosition({
|
|
@@ -402,6 +393,17 @@ const getFixedOriginalStart = (start, mappings, state, rangeInfo) => {
|
|
|
402
393
|
originalState
|
|
403
394
|
}, direction);
|
|
404
395
|
|
|
396
|
+
// if (start === 2660) {
|
|
397
|
+
// console.log('=====================================================');
|
|
398
|
+
// console.log('fixed start', originalState.sourcePath);
|
|
399
|
+
// console.log({
|
|
400
|
+
// generatedText,
|
|
401
|
+
// generatedPos,
|
|
402
|
+
// originalText,
|
|
403
|
+
// originalPos
|
|
404
|
+
// });
|
|
405
|
+
// }
|
|
406
|
+
|
|
405
407
|
return {
|
|
406
408
|
originalStart: originalOffset + originalPos
|
|
407
409
|
};
|
|
@@ -409,18 +411,8 @@ const getFixedOriginalStart = (start, mappings, state, rangeInfo) => {
|
|
|
409
411
|
|
|
410
412
|
const getFixedOriginalEnd = (end, mappings, state, rangeInfo) => {
|
|
411
413
|
|
|
412
|
-
const { decodedMappings } = state;
|
|
413
|
-
|
|
414
|
-
// end is exclusive, try previous one if exact match
|
|
415
|
-
const prevMapping = findMapping(decodedMappings, end - 1);
|
|
416
|
-
if (prevMapping && !Array.isArray(prevMapping)) {
|
|
417
|
-
return {
|
|
418
|
-
originalEnd: prevMapping.originalOffset + 1
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const { originalState, crossEnd } = rangeInfo;
|
|
423
414
|
const [m1, m2] = mappings;
|
|
415
|
+
const { originalState, crossEnd } = rangeInfo;
|
|
424
416
|
|
|
425
417
|
// cross file until e1 line end (not file end)
|
|
426
418
|
if (crossEnd) {
|
|
@@ -430,13 +422,41 @@ const getFixedOriginalEnd = (end, mappings, state, rangeInfo) => {
|
|
|
430
422
|
};
|
|
431
423
|
}
|
|
432
424
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
425
|
+
// end is exclusive
|
|
426
|
+
// quick check previous one if exact match
|
|
427
|
+
// most of case is matching "}"
|
|
428
|
+
if (m1.generatedOffset === end - 1) {
|
|
429
|
+
return {
|
|
430
|
+
originalEnd: m1.originalOffset + 1
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// quick check next one if exact match
|
|
435
|
+
// most of case is same string
|
|
436
|
+
if (m2.generatedOffset === end + 1) {
|
|
437
|
+
const gt = state.locator.source[end];
|
|
438
|
+
const oi = m2.originalOffset - 1;
|
|
439
|
+
const ot = originalState.locator.source[oi];
|
|
440
|
+
if (gt === ot) {
|
|
441
|
+
return {
|
|
442
|
+
originalEnd: oi
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Not applicable
|
|
447
|
+
// console.log('==================================');
|
|
448
|
+
// console.log({
|
|
449
|
+
// gp: state.sourcePath,
|
|
450
|
+
// g: end,
|
|
451
|
+
// gt,
|
|
452
|
+
// op: originalState.sourcePath,
|
|
453
|
+
// o: oi,
|
|
454
|
+
// ot
|
|
455
|
+
// });
|
|
437
456
|
}
|
|
438
457
|
|
|
439
|
-
const
|
|
458
|
+
const direction = 'end';
|
|
459
|
+
const { originalText, originalOffset } = getOriginalText(m1, m2, rangeInfo, direction);
|
|
440
460
|
const { generatedText, generatedPos } = getGeneratedText(m1, m2, state, end);
|
|
441
461
|
|
|
442
462
|
const originalPos = getFixedPosition({
|
|
@@ -446,6 +466,17 @@ const getFixedOriginalEnd = (end, mappings, state, rangeInfo) => {
|
|
|
446
466
|
originalState
|
|
447
467
|
}, direction);
|
|
448
468
|
|
|
469
|
+
// if (end === 2858) {
|
|
470
|
+
// console.log('=====================================================');
|
|
471
|
+
// console.log('fixed end', originalState.sourcePath);
|
|
472
|
+
// console.log({
|
|
473
|
+
// generatedText,
|
|
474
|
+
// generatedPos,
|
|
475
|
+
// originalText,
|
|
476
|
+
// originalPos
|
|
477
|
+
// });
|
|
478
|
+
// }
|
|
479
|
+
|
|
449
480
|
return {
|
|
450
481
|
originalEnd: originalOffset + originalPos
|
|
451
482
|
};
|
|
@@ -614,23 +645,13 @@ const getOriginalState = (startMappings, endMappings, originalMap) => {
|
|
|
614
645
|
};
|
|
615
646
|
};
|
|
616
647
|
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
const createMappingError = (errors) => {
|
|
648
|
+
const getMappingInfo = (decodedMappings, start, end) => {
|
|
649
|
+
// possible no length
|
|
650
|
+
if (decodedMappings.length < 2) {
|
|
622
651
|
return {
|
|
623
652
|
error: true,
|
|
624
|
-
|
|
625
|
-
end,
|
|
626
|
-
sourcePath,
|
|
627
|
-
errors
|
|
653
|
+
errors: ['invalid decoded mappings (length < 2)']
|
|
628
654
|
};
|
|
629
|
-
};
|
|
630
|
-
|
|
631
|
-
// possible no length
|
|
632
|
-
if (decodedMappings.length < 2) {
|
|
633
|
-
return createMappingError(['not found decoded mappings']);
|
|
634
655
|
}
|
|
635
656
|
|
|
636
657
|
// start: inclusive
|
|
@@ -653,6 +674,33 @@ const findOriginalRange = (start, end, state, originalMap) => {
|
|
|
653
674
|
};
|
|
654
675
|
}
|
|
655
676
|
|
|
677
|
+
return {
|
|
678
|
+
startMappings,
|
|
679
|
+
endMappings
|
|
680
|
+
};
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
const findOriginalRange = (start, end, state, originalMap) => {
|
|
684
|
+
|
|
685
|
+
const { sourcePath, decodedMappings } = state;
|
|
686
|
+
|
|
687
|
+
const createMappingError = (errors) => {
|
|
688
|
+
return {
|
|
689
|
+
error: true,
|
|
690
|
+
start,
|
|
691
|
+
end,
|
|
692
|
+
sourcePath,
|
|
693
|
+
errors
|
|
694
|
+
};
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
const mappingInfo = getMappingInfo(decodedMappings, start, end);
|
|
698
|
+
if (mappingInfo.error) {
|
|
699
|
+
return createMappingError(mappingInfo.errors);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
const { startMappings, endMappings } = mappingInfo;
|
|
703
|
+
|
|
656
704
|
const rangeInfo = getOriginalState(startMappings, endMappings, originalMap);
|
|
657
705
|
if (rangeInfo.error) {
|
|
658
706
|
return createMappingError(rangeInfo.errors);
|