@vitest/coverage-v8 3.2.3 → 4.0.0-beta.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/dist/provider.d.ts +2 -4
- package/dist/provider.js +75 -2537
- package/package.json +6 -9
package/dist/provider.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import { promises } from 'node:fs';
|
2
2
|
import { pathToFileURL, fileURLToPath } from 'node:url';
|
3
|
-
import remapping from '@ampproject/remapping';
|
4
3
|
import { mergeProcessCovs } from '@bcoe/v8-coverage';
|
5
4
|
import astV8ToIstanbul from 'ast-v8-to-istanbul';
|
6
5
|
import createDebug from 'debug';
|
@@ -8,17 +7,9 @@ import libCoverage from 'istanbul-lib-coverage';
|
|
8
7
|
import libReport from 'istanbul-lib-report';
|
9
8
|
import libSourceMaps from 'istanbul-lib-source-maps';
|
10
9
|
import reports from 'istanbul-reports';
|
11
|
-
import MagicString from 'magic-string';
|
12
10
|
import { parseModule } from 'magicast';
|
13
11
|
import { provider } from 'std-env';
|
14
|
-
import TestExclude from 'test-exclude';
|
15
12
|
import c from 'tinyrainbow';
|
16
|
-
import require$$0 from 'assert';
|
17
|
-
import require$$2 from 'util';
|
18
|
-
import require$$3 from 'path';
|
19
|
-
import require$$4 from 'url';
|
20
|
-
import require$$9 from 'fs';
|
21
|
-
import require$$11 from 'module';
|
22
13
|
import { builtinModules } from 'node:module';
|
23
14
|
import { BaseCoverageProvider } from 'vitest/coverage';
|
24
15
|
import { parseAstAsync } from 'vitest/node';
|
@@ -63,30 +54,6 @@ const normalize = function(path) {
|
|
63
54
|
}
|
64
55
|
return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
|
65
56
|
};
|
66
|
-
function cwd() {
|
67
|
-
if (typeof process !== "undefined" && typeof process.cwd === "function") {
|
68
|
-
return process.cwd().replace(/\\/g, "/");
|
69
|
-
}
|
70
|
-
return "/";
|
71
|
-
}
|
72
|
-
const resolve = function(...arguments_) {
|
73
|
-
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
74
|
-
let resolvedPath = "";
|
75
|
-
let resolvedAbsolute = false;
|
76
|
-
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
77
|
-
const path = index >= 0 ? arguments_[index] : cwd();
|
78
|
-
if (!path || path.length === 0) {
|
79
|
-
continue;
|
80
|
-
}
|
81
|
-
resolvedPath = `${path}/${resolvedPath}`;
|
82
|
-
resolvedAbsolute = isAbsolute(path);
|
83
|
-
}
|
84
|
-
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
85
|
-
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
|
86
|
-
return `/${resolvedPath}`;
|
87
|
-
}
|
88
|
-
return resolvedPath.length > 0 ? resolvedPath : ".";
|
89
|
-
};
|
90
57
|
function normalizeString(path, allowAboveRoot) {
|
91
58
|
let res = "";
|
92
59
|
let lastSegmentLength = 0;
|
@@ -150,2373 +117,6 @@ const isAbsolute = function(p) {
|
|
150
117
|
return _IS_ABSOLUTE_RE.test(p);
|
151
118
|
};
|
152
119
|
|
153
|
-
function getDefaultExportFromCjs (x) {
|
154
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
155
|
-
}
|
156
|
-
|
157
|
-
var convertSourceMap = {};
|
158
|
-
|
159
|
-
var hasRequiredConvertSourceMap;
|
160
|
-
|
161
|
-
function requireConvertSourceMap () {
|
162
|
-
if (hasRequiredConvertSourceMap) return convertSourceMap;
|
163
|
-
hasRequiredConvertSourceMap = 1;
|
164
|
-
(function (exports) {
|
165
|
-
|
166
|
-
Object.defineProperty(exports, 'commentRegex', {
|
167
|
-
get: function getCommentRegex () {
|
168
|
-
// Groups: 1: media type, 2: MIME type, 3: charset, 4: encoding, 5: data.
|
169
|
-
return /^\s*?\/[\/\*][@#]\s+?sourceMappingURL=data:(((?:application|text)\/json)(?:;charset=([^;,]+?)?)?)?(?:;(base64))?,(.*?)$/mg;
|
170
|
-
}
|
171
|
-
});
|
172
|
-
|
173
|
-
|
174
|
-
Object.defineProperty(exports, 'mapFileCommentRegex', {
|
175
|
-
get: function getMapFileCommentRegex () {
|
176
|
-
// Matches sourceMappingURL in either // or /* comment styles.
|
177
|
-
return /(?:\/\/[@#][ \t]+?sourceMappingURL=([^\s'"`]+?)[ \t]*?$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^*]+?)[ \t]*?(?:\*\/){1}[ \t]*?$)/mg;
|
178
|
-
}
|
179
|
-
});
|
180
|
-
|
181
|
-
var decodeBase64;
|
182
|
-
if (typeof Buffer !== 'undefined') {
|
183
|
-
if (typeof Buffer.from === 'function') {
|
184
|
-
decodeBase64 = decodeBase64WithBufferFrom;
|
185
|
-
} else {
|
186
|
-
decodeBase64 = decodeBase64WithNewBuffer;
|
187
|
-
}
|
188
|
-
} else {
|
189
|
-
decodeBase64 = decodeBase64WithAtob;
|
190
|
-
}
|
191
|
-
|
192
|
-
function decodeBase64WithBufferFrom(base64) {
|
193
|
-
return Buffer.from(base64, 'base64').toString();
|
194
|
-
}
|
195
|
-
|
196
|
-
function decodeBase64WithNewBuffer(base64) {
|
197
|
-
if (typeof value === 'number') {
|
198
|
-
throw new TypeError('The value to decode must not be of type number.');
|
199
|
-
}
|
200
|
-
return new Buffer(base64, 'base64').toString();
|
201
|
-
}
|
202
|
-
|
203
|
-
function decodeBase64WithAtob(base64) {
|
204
|
-
return decodeURIComponent(escape(atob(base64)));
|
205
|
-
}
|
206
|
-
|
207
|
-
function stripComment(sm) {
|
208
|
-
return sm.split(',').pop();
|
209
|
-
}
|
210
|
-
|
211
|
-
function readFromFileMap(sm, read) {
|
212
|
-
var r = exports.mapFileCommentRegex.exec(sm);
|
213
|
-
// for some odd reason //# .. captures in 1 and /* .. */ in 2
|
214
|
-
var filename = r[1] || r[2];
|
215
|
-
|
216
|
-
try {
|
217
|
-
var sm = read(filename);
|
218
|
-
if (sm != null && typeof sm.catch === 'function') {
|
219
|
-
return sm.catch(throwError);
|
220
|
-
} else {
|
221
|
-
return sm;
|
222
|
-
}
|
223
|
-
} catch (e) {
|
224
|
-
throwError(e);
|
225
|
-
}
|
226
|
-
|
227
|
-
function throwError(e) {
|
228
|
-
throw new Error('An error occurred while trying to read the map file at ' + filename + '\n' + e.stack);
|
229
|
-
}
|
230
|
-
}
|
231
|
-
|
232
|
-
function Converter (sm, opts) {
|
233
|
-
opts = opts || {};
|
234
|
-
|
235
|
-
if (opts.hasComment) {
|
236
|
-
sm = stripComment(sm);
|
237
|
-
}
|
238
|
-
|
239
|
-
if (opts.encoding === 'base64') {
|
240
|
-
sm = decodeBase64(sm);
|
241
|
-
} else if (opts.encoding === 'uri') {
|
242
|
-
sm = decodeURIComponent(sm);
|
243
|
-
}
|
244
|
-
|
245
|
-
if (opts.isJSON || opts.encoding) {
|
246
|
-
sm = JSON.parse(sm);
|
247
|
-
}
|
248
|
-
|
249
|
-
this.sourcemap = sm;
|
250
|
-
}
|
251
|
-
|
252
|
-
Converter.prototype.toJSON = function (space) {
|
253
|
-
return JSON.stringify(this.sourcemap, null, space);
|
254
|
-
};
|
255
|
-
|
256
|
-
if (typeof Buffer !== 'undefined') {
|
257
|
-
if (typeof Buffer.from === 'function') {
|
258
|
-
Converter.prototype.toBase64 = encodeBase64WithBufferFrom;
|
259
|
-
} else {
|
260
|
-
Converter.prototype.toBase64 = encodeBase64WithNewBuffer;
|
261
|
-
}
|
262
|
-
} else {
|
263
|
-
Converter.prototype.toBase64 = encodeBase64WithBtoa;
|
264
|
-
}
|
265
|
-
|
266
|
-
function encodeBase64WithBufferFrom() {
|
267
|
-
var json = this.toJSON();
|
268
|
-
return Buffer.from(json, 'utf8').toString('base64');
|
269
|
-
}
|
270
|
-
|
271
|
-
function encodeBase64WithNewBuffer() {
|
272
|
-
var json = this.toJSON();
|
273
|
-
if (typeof json === 'number') {
|
274
|
-
throw new TypeError('The json to encode must not be of type number.');
|
275
|
-
}
|
276
|
-
return new Buffer(json, 'utf8').toString('base64');
|
277
|
-
}
|
278
|
-
|
279
|
-
function encodeBase64WithBtoa() {
|
280
|
-
var json = this.toJSON();
|
281
|
-
return btoa(unescape(encodeURIComponent(json)));
|
282
|
-
}
|
283
|
-
|
284
|
-
Converter.prototype.toURI = function () {
|
285
|
-
var json = this.toJSON();
|
286
|
-
return encodeURIComponent(json);
|
287
|
-
};
|
288
|
-
|
289
|
-
Converter.prototype.toComment = function (options) {
|
290
|
-
var encoding, content, data;
|
291
|
-
if (options != null && options.encoding === 'uri') {
|
292
|
-
encoding = '';
|
293
|
-
content = this.toURI();
|
294
|
-
} else {
|
295
|
-
encoding = ';base64';
|
296
|
-
content = this.toBase64();
|
297
|
-
}
|
298
|
-
data = 'sourceMappingURL=data:application/json;charset=utf-8' + encoding + ',' + content;
|
299
|
-
return options != null && options.multiline ? '/*# ' + data + ' */' : '//# ' + data;
|
300
|
-
};
|
301
|
-
|
302
|
-
// returns copy instead of original
|
303
|
-
Converter.prototype.toObject = function () {
|
304
|
-
return JSON.parse(this.toJSON());
|
305
|
-
};
|
306
|
-
|
307
|
-
Converter.prototype.addProperty = function (key, value) {
|
308
|
-
if (this.sourcemap.hasOwnProperty(key)) throw new Error('property "' + key + '" already exists on the sourcemap, use set property instead');
|
309
|
-
return this.setProperty(key, value);
|
310
|
-
};
|
311
|
-
|
312
|
-
Converter.prototype.setProperty = function (key, value) {
|
313
|
-
this.sourcemap[key] = value;
|
314
|
-
return this;
|
315
|
-
};
|
316
|
-
|
317
|
-
Converter.prototype.getProperty = function (key) {
|
318
|
-
return this.sourcemap[key];
|
319
|
-
};
|
320
|
-
|
321
|
-
exports.fromObject = function (obj) {
|
322
|
-
return new Converter(obj);
|
323
|
-
};
|
324
|
-
|
325
|
-
exports.fromJSON = function (json) {
|
326
|
-
return new Converter(json, { isJSON: true });
|
327
|
-
};
|
328
|
-
|
329
|
-
exports.fromURI = function (uri) {
|
330
|
-
return new Converter(uri, { encoding: 'uri' });
|
331
|
-
};
|
332
|
-
|
333
|
-
exports.fromBase64 = function (base64) {
|
334
|
-
return new Converter(base64, { encoding: 'base64' });
|
335
|
-
};
|
336
|
-
|
337
|
-
exports.fromComment = function (comment) {
|
338
|
-
var m, encoding;
|
339
|
-
comment = comment
|
340
|
-
.replace(/^\/\*/g, '//')
|
341
|
-
.replace(/\*\/$/g, '');
|
342
|
-
m = exports.commentRegex.exec(comment);
|
343
|
-
encoding = m && m[4] || 'uri';
|
344
|
-
return new Converter(comment, { encoding: encoding, hasComment: true });
|
345
|
-
};
|
346
|
-
|
347
|
-
function makeConverter(sm) {
|
348
|
-
return new Converter(sm, { isJSON: true });
|
349
|
-
}
|
350
|
-
|
351
|
-
exports.fromMapFileComment = function (comment, read) {
|
352
|
-
if (typeof read === 'string') {
|
353
|
-
throw new Error(
|
354
|
-
'String directory paths are no longer supported with `fromMapFileComment`\n' +
|
355
|
-
'Please review the Upgrading documentation at https://github.com/thlorenz/convert-source-map#upgrading'
|
356
|
-
)
|
357
|
-
}
|
358
|
-
|
359
|
-
var sm = readFromFileMap(comment, read);
|
360
|
-
if (sm != null && typeof sm.then === 'function') {
|
361
|
-
return sm.then(makeConverter);
|
362
|
-
} else {
|
363
|
-
return makeConverter(sm);
|
364
|
-
}
|
365
|
-
};
|
366
|
-
|
367
|
-
// Finds last sourcemap comment in file or returns null if none was found
|
368
|
-
exports.fromSource = function (content) {
|
369
|
-
var m = content.match(exports.commentRegex);
|
370
|
-
return m ? exports.fromComment(m.pop()) : null;
|
371
|
-
};
|
372
|
-
|
373
|
-
// Finds last sourcemap comment in file or returns null if none was found
|
374
|
-
exports.fromMapFileSource = function (content, read) {
|
375
|
-
if (typeof read === 'string') {
|
376
|
-
throw new Error(
|
377
|
-
'String directory paths are no longer supported with `fromMapFileSource`\n' +
|
378
|
-
'Please review the Upgrading documentation at https://github.com/thlorenz/convert-source-map#upgrading'
|
379
|
-
)
|
380
|
-
}
|
381
|
-
var m = content.match(exports.mapFileCommentRegex);
|
382
|
-
return m ? exports.fromMapFileComment(m.pop(), read) : null;
|
383
|
-
};
|
384
|
-
|
385
|
-
exports.removeComments = function (src) {
|
386
|
-
return src.replace(exports.commentRegex, '');
|
387
|
-
};
|
388
|
-
|
389
|
-
exports.removeMapFileComments = function (src) {
|
390
|
-
return src.replace(exports.mapFileCommentRegex, '');
|
391
|
-
};
|
392
|
-
|
393
|
-
exports.generateMapFileComment = function (file, options) {
|
394
|
-
var data = 'sourceMappingURL=' + file;
|
395
|
-
return options && options.multiline ? '/*# ' + data + ' */' : '//# ' + data;
|
396
|
-
};
|
397
|
-
} (convertSourceMap));
|
398
|
-
return convertSourceMap;
|
399
|
-
}
|
400
|
-
|
401
|
-
var branch;
|
402
|
-
var hasRequiredBranch;
|
403
|
-
|
404
|
-
function requireBranch () {
|
405
|
-
if (hasRequiredBranch) return branch;
|
406
|
-
hasRequiredBranch = 1;
|
407
|
-
branch = class CovBranch {
|
408
|
-
constructor (startLine, startCol, endLine, endCol, count) {
|
409
|
-
this.startLine = startLine;
|
410
|
-
this.startCol = startCol;
|
411
|
-
this.endLine = endLine;
|
412
|
-
this.endCol = endCol;
|
413
|
-
this.count = count;
|
414
|
-
}
|
415
|
-
|
416
|
-
toIstanbul () {
|
417
|
-
const location = {
|
418
|
-
start: {
|
419
|
-
line: this.startLine,
|
420
|
-
column: this.startCol
|
421
|
-
},
|
422
|
-
end: {
|
423
|
-
line: this.endLine,
|
424
|
-
column: this.endCol
|
425
|
-
}
|
426
|
-
};
|
427
|
-
return {
|
428
|
-
type: 'branch',
|
429
|
-
line: this.startLine,
|
430
|
-
loc: location,
|
431
|
-
locations: [Object.assign({}, location)]
|
432
|
-
}
|
433
|
-
}
|
434
|
-
};
|
435
|
-
return branch;
|
436
|
-
}
|
437
|
-
|
438
|
-
var _function;
|
439
|
-
var hasRequired_function;
|
440
|
-
|
441
|
-
function require_function () {
|
442
|
-
if (hasRequired_function) return _function;
|
443
|
-
hasRequired_function = 1;
|
444
|
-
_function = class CovFunction {
|
445
|
-
constructor (name, startLine, startCol, endLine, endCol, count) {
|
446
|
-
this.name = name;
|
447
|
-
this.startLine = startLine;
|
448
|
-
this.startCol = startCol;
|
449
|
-
this.endLine = endLine;
|
450
|
-
this.endCol = endCol;
|
451
|
-
this.count = count;
|
452
|
-
}
|
453
|
-
|
454
|
-
toIstanbul () {
|
455
|
-
const loc = {
|
456
|
-
start: {
|
457
|
-
line: this.startLine,
|
458
|
-
column: this.startCol
|
459
|
-
},
|
460
|
-
end: {
|
461
|
-
line: this.endLine,
|
462
|
-
column: this.endCol
|
463
|
-
}
|
464
|
-
};
|
465
|
-
return {
|
466
|
-
name: this.name,
|
467
|
-
decl: loc,
|
468
|
-
loc,
|
469
|
-
line: this.startLine
|
470
|
-
}
|
471
|
-
}
|
472
|
-
};
|
473
|
-
return _function;
|
474
|
-
}
|
475
|
-
|
476
|
-
var line;
|
477
|
-
var hasRequiredLine;
|
478
|
-
|
479
|
-
function requireLine () {
|
480
|
-
if (hasRequiredLine) return line;
|
481
|
-
hasRequiredLine = 1;
|
482
|
-
line = class CovLine {
|
483
|
-
constructor (line, startCol, lineStr) {
|
484
|
-
this.line = line;
|
485
|
-
// note that startCol and endCol are absolute positions
|
486
|
-
// within a file, not relative to the line.
|
487
|
-
this.startCol = startCol;
|
488
|
-
|
489
|
-
// the line length itself does not include the newline characters,
|
490
|
-
// these are however taken into account when enumerating absolute offset.
|
491
|
-
const matchedNewLineChar = lineStr.match(/\r?\n$/u);
|
492
|
-
const newLineLength = matchedNewLineChar ? matchedNewLineChar[0].length : 0;
|
493
|
-
this.endCol = startCol + lineStr.length - newLineLength;
|
494
|
-
|
495
|
-
// we start with all lines having been executed, and work
|
496
|
-
// backwards zeroing out lines based on V8 output.
|
497
|
-
this.count = 1;
|
498
|
-
|
499
|
-
// set by source.js during parsing, if /* c8 ignore next */ is found.
|
500
|
-
this.ignore = false;
|
501
|
-
}
|
502
|
-
|
503
|
-
toIstanbul () {
|
504
|
-
return {
|
505
|
-
start: {
|
506
|
-
line: this.line,
|
507
|
-
column: 0
|
508
|
-
},
|
509
|
-
end: {
|
510
|
-
line: this.line,
|
511
|
-
column: this.endCol - this.startCol
|
512
|
-
}
|
513
|
-
}
|
514
|
-
}
|
515
|
-
};
|
516
|
-
return line;
|
517
|
-
}
|
518
|
-
|
519
|
-
var range = {};
|
520
|
-
|
521
|
-
/**
|
522
|
-
* ...something resembling a binary search, to find the lowest line within the range.
|
523
|
-
* And then you could break as soon as the line is longer than the range...
|
524
|
-
*/
|
525
|
-
|
526
|
-
var hasRequiredRange;
|
527
|
-
|
528
|
-
function requireRange () {
|
529
|
-
if (hasRequiredRange) return range;
|
530
|
-
hasRequiredRange = 1;
|
531
|
-
range.sliceRange = (lines, startCol, endCol, inclusive = false) => {
|
532
|
-
let start = 0;
|
533
|
-
let end = lines.length;
|
534
|
-
|
535
|
-
if (inclusive) {
|
536
|
-
// I consider this a temporary solution until I find an alternaive way to fix the "off by one issue"
|
537
|
-
--startCol;
|
538
|
-
}
|
539
|
-
|
540
|
-
while (start < end) {
|
541
|
-
let mid = (start + end) >> 1;
|
542
|
-
if (startCol >= lines[mid].endCol) {
|
543
|
-
start = mid + 1;
|
544
|
-
} else if (endCol < lines[mid].startCol) {
|
545
|
-
end = mid - 1;
|
546
|
-
} else {
|
547
|
-
end = mid;
|
548
|
-
while (mid >= 0 && startCol < lines[mid].endCol && endCol >= lines[mid].startCol) {
|
549
|
-
--mid;
|
550
|
-
}
|
551
|
-
start = mid + 1;
|
552
|
-
break
|
553
|
-
}
|
554
|
-
}
|
555
|
-
|
556
|
-
while (end < lines.length && startCol < lines[end].endCol && endCol >= lines[end].startCol) {
|
557
|
-
++end;
|
558
|
-
}
|
559
|
-
|
560
|
-
return lines.slice(start, end)
|
561
|
-
};
|
562
|
-
return range;
|
563
|
-
}
|
564
|
-
|
565
|
-
var traceMapping_umd$1 = {exports: {}};
|
566
|
-
|
567
|
-
var sourcemapCodec_umd$1 = {exports: {}};
|
568
|
-
|
569
|
-
var sourcemapCodec_umd = sourcemapCodec_umd$1.exports;
|
570
|
-
|
571
|
-
var hasRequiredSourcemapCodec_umd;
|
572
|
-
|
573
|
-
function requireSourcemapCodec_umd () {
|
574
|
-
if (hasRequiredSourcemapCodec_umd) return sourcemapCodec_umd$1.exports;
|
575
|
-
hasRequiredSourcemapCodec_umd = 1;
|
576
|
-
(function (module, exports) {
|
577
|
-
(function (global, factory) {
|
578
|
-
factory(exports) ;
|
579
|
-
})(sourcemapCodec_umd, (function (exports) {
|
580
|
-
const comma = ','.charCodeAt(0);
|
581
|
-
const semicolon = ';'.charCodeAt(0);
|
582
|
-
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
583
|
-
const intToChar = new Uint8Array(64); // 64 possible chars.
|
584
|
-
const charToInt = new Uint8Array(128); // z is 122 in ASCII
|
585
|
-
for (let i = 0; i < chars.length; i++) {
|
586
|
-
const c = chars.charCodeAt(i);
|
587
|
-
intToChar[i] = c;
|
588
|
-
charToInt[c] = i;
|
589
|
-
}
|
590
|
-
function decodeInteger(reader, relative) {
|
591
|
-
let value = 0;
|
592
|
-
let shift = 0;
|
593
|
-
let integer = 0;
|
594
|
-
do {
|
595
|
-
const c = reader.next();
|
596
|
-
integer = charToInt[c];
|
597
|
-
value |= (integer & 31) << shift;
|
598
|
-
shift += 5;
|
599
|
-
} while (integer & 32);
|
600
|
-
const shouldNegate = value & 1;
|
601
|
-
value >>>= 1;
|
602
|
-
if (shouldNegate) {
|
603
|
-
value = -2147483648 | -value;
|
604
|
-
}
|
605
|
-
return relative + value;
|
606
|
-
}
|
607
|
-
function encodeInteger(builder, num, relative) {
|
608
|
-
let delta = num - relative;
|
609
|
-
delta = delta < 0 ? (-delta << 1) | 1 : delta << 1;
|
610
|
-
do {
|
611
|
-
let clamped = delta & 0b011111;
|
612
|
-
delta >>>= 5;
|
613
|
-
if (delta > 0)
|
614
|
-
clamped |= 0b100000;
|
615
|
-
builder.write(intToChar[clamped]);
|
616
|
-
} while (delta > 0);
|
617
|
-
return num;
|
618
|
-
}
|
619
|
-
function hasMoreVlq(reader, max) {
|
620
|
-
if (reader.pos >= max)
|
621
|
-
return false;
|
622
|
-
return reader.peek() !== comma;
|
623
|
-
}
|
624
|
-
|
625
|
-
const bufLength = 1024 * 16;
|
626
|
-
// Provide a fallback for older environments.
|
627
|
-
const td = typeof TextDecoder !== 'undefined'
|
628
|
-
? /* #__PURE__ */ new TextDecoder()
|
629
|
-
: typeof Buffer !== 'undefined'
|
630
|
-
? {
|
631
|
-
decode(buf) {
|
632
|
-
const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
|
633
|
-
return out.toString();
|
634
|
-
},
|
635
|
-
}
|
636
|
-
: {
|
637
|
-
decode(buf) {
|
638
|
-
let out = '';
|
639
|
-
for (let i = 0; i < buf.length; i++) {
|
640
|
-
out += String.fromCharCode(buf[i]);
|
641
|
-
}
|
642
|
-
return out;
|
643
|
-
},
|
644
|
-
};
|
645
|
-
class StringWriter {
|
646
|
-
constructor() {
|
647
|
-
this.pos = 0;
|
648
|
-
this.out = '';
|
649
|
-
this.buffer = new Uint8Array(bufLength);
|
650
|
-
}
|
651
|
-
write(v) {
|
652
|
-
const { buffer } = this;
|
653
|
-
buffer[this.pos++] = v;
|
654
|
-
if (this.pos === bufLength) {
|
655
|
-
this.out += td.decode(buffer);
|
656
|
-
this.pos = 0;
|
657
|
-
}
|
658
|
-
}
|
659
|
-
flush() {
|
660
|
-
const { buffer, out, pos } = this;
|
661
|
-
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
|
662
|
-
}
|
663
|
-
}
|
664
|
-
class StringReader {
|
665
|
-
constructor(buffer) {
|
666
|
-
this.pos = 0;
|
667
|
-
this.buffer = buffer;
|
668
|
-
}
|
669
|
-
next() {
|
670
|
-
return this.buffer.charCodeAt(this.pos++);
|
671
|
-
}
|
672
|
-
peek() {
|
673
|
-
return this.buffer.charCodeAt(this.pos);
|
674
|
-
}
|
675
|
-
indexOf(char) {
|
676
|
-
const { buffer, pos } = this;
|
677
|
-
const idx = buffer.indexOf(char, pos);
|
678
|
-
return idx === -1 ? buffer.length : idx;
|
679
|
-
}
|
680
|
-
}
|
681
|
-
|
682
|
-
const EMPTY = [];
|
683
|
-
function decodeOriginalScopes(input) {
|
684
|
-
const { length } = input;
|
685
|
-
const reader = new StringReader(input);
|
686
|
-
const scopes = [];
|
687
|
-
const stack = [];
|
688
|
-
let line = 0;
|
689
|
-
for (; reader.pos < length; reader.pos++) {
|
690
|
-
line = decodeInteger(reader, line);
|
691
|
-
const column = decodeInteger(reader, 0);
|
692
|
-
if (!hasMoreVlq(reader, length)) {
|
693
|
-
const last = stack.pop();
|
694
|
-
last[2] = line;
|
695
|
-
last[3] = column;
|
696
|
-
continue;
|
697
|
-
}
|
698
|
-
const kind = decodeInteger(reader, 0);
|
699
|
-
const fields = decodeInteger(reader, 0);
|
700
|
-
const hasName = fields & 0b0001;
|
701
|
-
const scope = (hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]);
|
702
|
-
let vars = EMPTY;
|
703
|
-
if (hasMoreVlq(reader, length)) {
|
704
|
-
vars = [];
|
705
|
-
do {
|
706
|
-
const varsIndex = decodeInteger(reader, 0);
|
707
|
-
vars.push(varsIndex);
|
708
|
-
} while (hasMoreVlq(reader, length));
|
709
|
-
}
|
710
|
-
scope.vars = vars;
|
711
|
-
scopes.push(scope);
|
712
|
-
stack.push(scope);
|
713
|
-
}
|
714
|
-
return scopes;
|
715
|
-
}
|
716
|
-
function encodeOriginalScopes(scopes) {
|
717
|
-
const writer = new StringWriter();
|
718
|
-
for (let i = 0; i < scopes.length;) {
|
719
|
-
i = _encodeOriginalScopes(scopes, i, writer, [0]);
|
720
|
-
}
|
721
|
-
return writer.flush();
|
722
|
-
}
|
723
|
-
function _encodeOriginalScopes(scopes, index, writer, state) {
|
724
|
-
const scope = scopes[index];
|
725
|
-
const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;
|
726
|
-
if (index > 0)
|
727
|
-
writer.write(comma);
|
728
|
-
state[0] = encodeInteger(writer, startLine, state[0]);
|
729
|
-
encodeInteger(writer, startColumn, 0);
|
730
|
-
encodeInteger(writer, kind, 0);
|
731
|
-
const fields = scope.length === 6 ? 0b0001 : 0;
|
732
|
-
encodeInteger(writer, fields, 0);
|
733
|
-
if (scope.length === 6)
|
734
|
-
encodeInteger(writer, scope[5], 0);
|
735
|
-
for (const v of vars) {
|
736
|
-
encodeInteger(writer, v, 0);
|
737
|
-
}
|
738
|
-
for (index++; index < scopes.length;) {
|
739
|
-
const next = scopes[index];
|
740
|
-
const { 0: l, 1: c } = next;
|
741
|
-
if (l > endLine || (l === endLine && c >= endColumn)) {
|
742
|
-
break;
|
743
|
-
}
|
744
|
-
index = _encodeOriginalScopes(scopes, index, writer, state);
|
745
|
-
}
|
746
|
-
writer.write(comma);
|
747
|
-
state[0] = encodeInteger(writer, endLine, state[0]);
|
748
|
-
encodeInteger(writer, endColumn, 0);
|
749
|
-
return index;
|
750
|
-
}
|
751
|
-
function decodeGeneratedRanges(input) {
|
752
|
-
const { length } = input;
|
753
|
-
const reader = new StringReader(input);
|
754
|
-
const ranges = [];
|
755
|
-
const stack = [];
|
756
|
-
let genLine = 0;
|
757
|
-
let definitionSourcesIndex = 0;
|
758
|
-
let definitionScopeIndex = 0;
|
759
|
-
let callsiteSourcesIndex = 0;
|
760
|
-
let callsiteLine = 0;
|
761
|
-
let callsiteColumn = 0;
|
762
|
-
let bindingLine = 0;
|
763
|
-
let bindingColumn = 0;
|
764
|
-
do {
|
765
|
-
const semi = reader.indexOf(';');
|
766
|
-
let genColumn = 0;
|
767
|
-
for (; reader.pos < semi; reader.pos++) {
|
768
|
-
genColumn = decodeInteger(reader, genColumn);
|
769
|
-
if (!hasMoreVlq(reader, semi)) {
|
770
|
-
const last = stack.pop();
|
771
|
-
last[2] = genLine;
|
772
|
-
last[3] = genColumn;
|
773
|
-
continue;
|
774
|
-
}
|
775
|
-
const fields = decodeInteger(reader, 0);
|
776
|
-
const hasDefinition = fields & 0b0001;
|
777
|
-
const hasCallsite = fields & 0b0010;
|
778
|
-
const hasScope = fields & 0b0100;
|
779
|
-
let callsite = null;
|
780
|
-
let bindings = EMPTY;
|
781
|
-
let range;
|
782
|
-
if (hasDefinition) {
|
783
|
-
const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);
|
784
|
-
definitionScopeIndex = decodeInteger(reader, definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0);
|
785
|
-
definitionSourcesIndex = defSourcesIndex;
|
786
|
-
range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex];
|
787
|
-
}
|
788
|
-
else {
|
789
|
-
range = [genLine, genColumn, 0, 0];
|
790
|
-
}
|
791
|
-
range.isScope = !!hasScope;
|
792
|
-
if (hasCallsite) {
|
793
|
-
const prevCsi = callsiteSourcesIndex;
|
794
|
-
const prevLine = callsiteLine;
|
795
|
-
callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);
|
796
|
-
const sameSource = prevCsi === callsiteSourcesIndex;
|
797
|
-
callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);
|
798
|
-
callsiteColumn = decodeInteger(reader, sameSource && prevLine === callsiteLine ? callsiteColumn : 0);
|
799
|
-
callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];
|
800
|
-
}
|
801
|
-
range.callsite = callsite;
|
802
|
-
if (hasMoreVlq(reader, semi)) {
|
803
|
-
bindings = [];
|
804
|
-
do {
|
805
|
-
bindingLine = genLine;
|
806
|
-
bindingColumn = genColumn;
|
807
|
-
const expressionsCount = decodeInteger(reader, 0);
|
808
|
-
let expressionRanges;
|
809
|
-
if (expressionsCount < -1) {
|
810
|
-
expressionRanges = [[decodeInteger(reader, 0)]];
|
811
|
-
for (let i = -1; i > expressionsCount; i--) {
|
812
|
-
const prevBl = bindingLine;
|
813
|
-
bindingLine = decodeInteger(reader, bindingLine);
|
814
|
-
bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);
|
815
|
-
const expression = decodeInteger(reader, 0);
|
816
|
-
expressionRanges.push([expression, bindingLine, bindingColumn]);
|
817
|
-
}
|
818
|
-
}
|
819
|
-
else {
|
820
|
-
expressionRanges = [[expressionsCount]];
|
821
|
-
}
|
822
|
-
bindings.push(expressionRanges);
|
823
|
-
} while (hasMoreVlq(reader, semi));
|
824
|
-
}
|
825
|
-
range.bindings = bindings;
|
826
|
-
ranges.push(range);
|
827
|
-
stack.push(range);
|
828
|
-
}
|
829
|
-
genLine++;
|
830
|
-
reader.pos = semi + 1;
|
831
|
-
} while (reader.pos < length);
|
832
|
-
return ranges;
|
833
|
-
}
|
834
|
-
function encodeGeneratedRanges(ranges) {
|
835
|
-
if (ranges.length === 0)
|
836
|
-
return '';
|
837
|
-
const writer = new StringWriter();
|
838
|
-
for (let i = 0; i < ranges.length;) {
|
839
|
-
i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);
|
840
|
-
}
|
841
|
-
return writer.flush();
|
842
|
-
}
|
843
|
-
function _encodeGeneratedRanges(ranges, index, writer, state) {
|
844
|
-
const range = ranges[index];
|
845
|
-
const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, isScope, callsite, bindings, } = range;
|
846
|
-
if (state[0] < startLine) {
|
847
|
-
catchupLine(writer, state[0], startLine);
|
848
|
-
state[0] = startLine;
|
849
|
-
state[1] = 0;
|
850
|
-
}
|
851
|
-
else if (index > 0) {
|
852
|
-
writer.write(comma);
|
853
|
-
}
|
854
|
-
state[1] = encodeInteger(writer, range[1], state[1]);
|
855
|
-
const fields = (range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0);
|
856
|
-
encodeInteger(writer, fields, 0);
|
857
|
-
if (range.length === 6) {
|
858
|
-
const { 4: sourcesIndex, 5: scopesIndex } = range;
|
859
|
-
if (sourcesIndex !== state[2]) {
|
860
|
-
state[3] = 0;
|
861
|
-
}
|
862
|
-
state[2] = encodeInteger(writer, sourcesIndex, state[2]);
|
863
|
-
state[3] = encodeInteger(writer, scopesIndex, state[3]);
|
864
|
-
}
|
865
|
-
if (callsite) {
|
866
|
-
const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite;
|
867
|
-
if (sourcesIndex !== state[4]) {
|
868
|
-
state[5] = 0;
|
869
|
-
state[6] = 0;
|
870
|
-
}
|
871
|
-
else if (callLine !== state[5]) {
|
872
|
-
state[6] = 0;
|
873
|
-
}
|
874
|
-
state[4] = encodeInteger(writer, sourcesIndex, state[4]);
|
875
|
-
state[5] = encodeInteger(writer, callLine, state[5]);
|
876
|
-
state[6] = encodeInteger(writer, callColumn, state[6]);
|
877
|
-
}
|
878
|
-
if (bindings) {
|
879
|
-
for (const binding of bindings) {
|
880
|
-
if (binding.length > 1)
|
881
|
-
encodeInteger(writer, -binding.length, 0);
|
882
|
-
const expression = binding[0][0];
|
883
|
-
encodeInteger(writer, expression, 0);
|
884
|
-
let bindingStartLine = startLine;
|
885
|
-
let bindingStartColumn = startColumn;
|
886
|
-
for (let i = 1; i < binding.length; i++) {
|
887
|
-
const expRange = binding[i];
|
888
|
-
bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine);
|
889
|
-
bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn);
|
890
|
-
encodeInteger(writer, expRange[0], 0);
|
891
|
-
}
|
892
|
-
}
|
893
|
-
}
|
894
|
-
for (index++; index < ranges.length;) {
|
895
|
-
const next = ranges[index];
|
896
|
-
const { 0: l, 1: c } = next;
|
897
|
-
if (l > endLine || (l === endLine && c >= endColumn)) {
|
898
|
-
break;
|
899
|
-
}
|
900
|
-
index = _encodeGeneratedRanges(ranges, index, writer, state);
|
901
|
-
}
|
902
|
-
if (state[0] < endLine) {
|
903
|
-
catchupLine(writer, state[0], endLine);
|
904
|
-
state[0] = endLine;
|
905
|
-
state[1] = 0;
|
906
|
-
}
|
907
|
-
else {
|
908
|
-
writer.write(comma);
|
909
|
-
}
|
910
|
-
state[1] = encodeInteger(writer, endColumn, state[1]);
|
911
|
-
return index;
|
912
|
-
}
|
913
|
-
function catchupLine(writer, lastLine, line) {
|
914
|
-
do {
|
915
|
-
writer.write(semicolon);
|
916
|
-
} while (++lastLine < line);
|
917
|
-
}
|
918
|
-
|
919
|
-
function decode(mappings) {
|
920
|
-
const { length } = mappings;
|
921
|
-
const reader = new StringReader(mappings);
|
922
|
-
const decoded = [];
|
923
|
-
let genColumn = 0;
|
924
|
-
let sourcesIndex = 0;
|
925
|
-
let sourceLine = 0;
|
926
|
-
let sourceColumn = 0;
|
927
|
-
let namesIndex = 0;
|
928
|
-
do {
|
929
|
-
const semi = reader.indexOf(';');
|
930
|
-
const line = [];
|
931
|
-
let sorted = true;
|
932
|
-
let lastCol = 0;
|
933
|
-
genColumn = 0;
|
934
|
-
while (reader.pos < semi) {
|
935
|
-
let seg;
|
936
|
-
genColumn = decodeInteger(reader, genColumn);
|
937
|
-
if (genColumn < lastCol)
|
938
|
-
sorted = false;
|
939
|
-
lastCol = genColumn;
|
940
|
-
if (hasMoreVlq(reader, semi)) {
|
941
|
-
sourcesIndex = decodeInteger(reader, sourcesIndex);
|
942
|
-
sourceLine = decodeInteger(reader, sourceLine);
|
943
|
-
sourceColumn = decodeInteger(reader, sourceColumn);
|
944
|
-
if (hasMoreVlq(reader, semi)) {
|
945
|
-
namesIndex = decodeInteger(reader, namesIndex);
|
946
|
-
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];
|
947
|
-
}
|
948
|
-
else {
|
949
|
-
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];
|
950
|
-
}
|
951
|
-
}
|
952
|
-
else {
|
953
|
-
seg = [genColumn];
|
954
|
-
}
|
955
|
-
line.push(seg);
|
956
|
-
reader.pos++;
|
957
|
-
}
|
958
|
-
if (!sorted)
|
959
|
-
sort(line);
|
960
|
-
decoded.push(line);
|
961
|
-
reader.pos = semi + 1;
|
962
|
-
} while (reader.pos <= length);
|
963
|
-
return decoded;
|
964
|
-
}
|
965
|
-
function sort(line) {
|
966
|
-
line.sort(sortComparator);
|
967
|
-
}
|
968
|
-
function sortComparator(a, b) {
|
969
|
-
return a[0] - b[0];
|
970
|
-
}
|
971
|
-
function encode(decoded) {
|
972
|
-
const writer = new StringWriter();
|
973
|
-
let sourcesIndex = 0;
|
974
|
-
let sourceLine = 0;
|
975
|
-
let sourceColumn = 0;
|
976
|
-
let namesIndex = 0;
|
977
|
-
for (let i = 0; i < decoded.length; i++) {
|
978
|
-
const line = decoded[i];
|
979
|
-
if (i > 0)
|
980
|
-
writer.write(semicolon);
|
981
|
-
if (line.length === 0)
|
982
|
-
continue;
|
983
|
-
let genColumn = 0;
|
984
|
-
for (let j = 0; j < line.length; j++) {
|
985
|
-
const segment = line[j];
|
986
|
-
if (j > 0)
|
987
|
-
writer.write(comma);
|
988
|
-
genColumn = encodeInteger(writer, segment[0], genColumn);
|
989
|
-
if (segment.length === 1)
|
990
|
-
continue;
|
991
|
-
sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
|
992
|
-
sourceLine = encodeInteger(writer, segment[2], sourceLine);
|
993
|
-
sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
|
994
|
-
if (segment.length === 4)
|
995
|
-
continue;
|
996
|
-
namesIndex = encodeInteger(writer, segment[4], namesIndex);
|
997
|
-
}
|
998
|
-
}
|
999
|
-
return writer.flush();
|
1000
|
-
}
|
1001
|
-
|
1002
|
-
exports.decode = decode;
|
1003
|
-
exports.decodeGeneratedRanges = decodeGeneratedRanges;
|
1004
|
-
exports.decodeOriginalScopes = decodeOriginalScopes;
|
1005
|
-
exports.encode = encode;
|
1006
|
-
exports.encodeGeneratedRanges = encodeGeneratedRanges;
|
1007
|
-
exports.encodeOriginalScopes = encodeOriginalScopes;
|
1008
|
-
|
1009
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
1010
|
-
|
1011
|
-
}));
|
1012
|
-
|
1013
|
-
} (sourcemapCodec_umd$1, sourcemapCodec_umd$1.exports));
|
1014
|
-
return sourcemapCodec_umd$1.exports;
|
1015
|
-
}
|
1016
|
-
|
1017
|
-
var resolveUri_umd$1 = {exports: {}};
|
1018
|
-
|
1019
|
-
var resolveUri_umd = resolveUri_umd$1.exports;
|
1020
|
-
|
1021
|
-
var hasRequiredResolveUri_umd;
|
1022
|
-
|
1023
|
-
function requireResolveUri_umd () {
|
1024
|
-
if (hasRequiredResolveUri_umd) return resolveUri_umd$1.exports;
|
1025
|
-
hasRequiredResolveUri_umd = 1;
|
1026
|
-
(function (module, exports) {
|
1027
|
-
(function (global, factory) {
|
1028
|
-
module.exports = factory() ;
|
1029
|
-
})(resolveUri_umd, (function () {
|
1030
|
-
// Matches the scheme of a URL, eg "http://"
|
1031
|
-
const schemeRegex = /^[\w+.-]+:\/\//;
|
1032
|
-
/**
|
1033
|
-
* Matches the parts of a URL:
|
1034
|
-
* 1. Scheme, including ":", guaranteed.
|
1035
|
-
* 2. User/password, including "@", optional.
|
1036
|
-
* 3. Host, guaranteed.
|
1037
|
-
* 4. Port, including ":", optional.
|
1038
|
-
* 5. Path, including "/", optional.
|
1039
|
-
* 6. Query, including "?", optional.
|
1040
|
-
* 7. Hash, including "#", optional.
|
1041
|
-
*/
|
1042
|
-
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
|
1043
|
-
/**
|
1044
|
-
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
|
1045
|
-
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
|
1046
|
-
*
|
1047
|
-
* 1. Host, optional.
|
1048
|
-
* 2. Path, which may include "/", guaranteed.
|
1049
|
-
* 3. Query, including "?", optional.
|
1050
|
-
* 4. Hash, including "#", optional.
|
1051
|
-
*/
|
1052
|
-
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
|
1053
|
-
var UrlType;
|
1054
|
-
(function (UrlType) {
|
1055
|
-
UrlType[UrlType["Empty"] = 1] = "Empty";
|
1056
|
-
UrlType[UrlType["Hash"] = 2] = "Hash";
|
1057
|
-
UrlType[UrlType["Query"] = 3] = "Query";
|
1058
|
-
UrlType[UrlType["RelativePath"] = 4] = "RelativePath";
|
1059
|
-
UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath";
|
1060
|
-
UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative";
|
1061
|
-
UrlType[UrlType["Absolute"] = 7] = "Absolute";
|
1062
|
-
})(UrlType || (UrlType = {}));
|
1063
|
-
function isAbsoluteUrl(input) {
|
1064
|
-
return schemeRegex.test(input);
|
1065
|
-
}
|
1066
|
-
function isSchemeRelativeUrl(input) {
|
1067
|
-
return input.startsWith('//');
|
1068
|
-
}
|
1069
|
-
function isAbsolutePath(input) {
|
1070
|
-
return input.startsWith('/');
|
1071
|
-
}
|
1072
|
-
function isFileUrl(input) {
|
1073
|
-
return input.startsWith('file:');
|
1074
|
-
}
|
1075
|
-
function isRelative(input) {
|
1076
|
-
return /^[.?#]/.test(input);
|
1077
|
-
}
|
1078
|
-
function parseAbsoluteUrl(input) {
|
1079
|
-
const match = urlRegex.exec(input);
|
1080
|
-
return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
|
1081
|
-
}
|
1082
|
-
function parseFileUrl(input) {
|
1083
|
-
const match = fileRegex.exec(input);
|
1084
|
-
const path = match[2];
|
1085
|
-
return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
|
1086
|
-
}
|
1087
|
-
function makeUrl(scheme, user, host, port, path, query, hash) {
|
1088
|
-
return {
|
1089
|
-
scheme,
|
1090
|
-
user,
|
1091
|
-
host,
|
1092
|
-
port,
|
1093
|
-
path,
|
1094
|
-
query,
|
1095
|
-
hash,
|
1096
|
-
type: UrlType.Absolute,
|
1097
|
-
};
|
1098
|
-
}
|
1099
|
-
function parseUrl(input) {
|
1100
|
-
if (isSchemeRelativeUrl(input)) {
|
1101
|
-
const url = parseAbsoluteUrl('http:' + input);
|
1102
|
-
url.scheme = '';
|
1103
|
-
url.type = UrlType.SchemeRelative;
|
1104
|
-
return url;
|
1105
|
-
}
|
1106
|
-
if (isAbsolutePath(input)) {
|
1107
|
-
const url = parseAbsoluteUrl('http://foo.com' + input);
|
1108
|
-
url.scheme = '';
|
1109
|
-
url.host = '';
|
1110
|
-
url.type = UrlType.AbsolutePath;
|
1111
|
-
return url;
|
1112
|
-
}
|
1113
|
-
if (isFileUrl(input))
|
1114
|
-
return parseFileUrl(input);
|
1115
|
-
if (isAbsoluteUrl(input))
|
1116
|
-
return parseAbsoluteUrl(input);
|
1117
|
-
const url = parseAbsoluteUrl('http://foo.com/' + input);
|
1118
|
-
url.scheme = '';
|
1119
|
-
url.host = '';
|
1120
|
-
url.type = input
|
1121
|
-
? input.startsWith('?')
|
1122
|
-
? UrlType.Query
|
1123
|
-
: input.startsWith('#')
|
1124
|
-
? UrlType.Hash
|
1125
|
-
: UrlType.RelativePath
|
1126
|
-
: UrlType.Empty;
|
1127
|
-
return url;
|
1128
|
-
}
|
1129
|
-
function stripPathFilename(path) {
|
1130
|
-
// If a path ends with a parent directory "..", then it's a relative path with excess parent
|
1131
|
-
// paths. It's not a file, so we can't strip it.
|
1132
|
-
if (path.endsWith('/..'))
|
1133
|
-
return path;
|
1134
|
-
const index = path.lastIndexOf('/');
|
1135
|
-
return path.slice(0, index + 1);
|
1136
|
-
}
|
1137
|
-
function mergePaths(url, base) {
|
1138
|
-
normalizePath(base, base.type);
|
1139
|
-
// If the path is just a "/", then it was an empty path to begin with (remember, we're a relative
|
1140
|
-
// path).
|
1141
|
-
if (url.path === '/') {
|
1142
|
-
url.path = base.path;
|
1143
|
-
}
|
1144
|
-
else {
|
1145
|
-
// Resolution happens relative to the base path's directory, not the file.
|
1146
|
-
url.path = stripPathFilename(base.path) + url.path;
|
1147
|
-
}
|
1148
|
-
}
|
1149
|
-
/**
|
1150
|
-
* The path can have empty directories "//", unneeded parents "foo/..", or current directory
|
1151
|
-
* "foo/.". We need to normalize to a standard representation.
|
1152
|
-
*/
|
1153
|
-
function normalizePath(url, type) {
|
1154
|
-
const rel = type <= UrlType.RelativePath;
|
1155
|
-
const pieces = url.path.split('/');
|
1156
|
-
// We need to preserve the first piece always, so that we output a leading slash. The item at
|
1157
|
-
// pieces[0] is an empty string.
|
1158
|
-
let pointer = 1;
|
1159
|
-
// Positive is the number of real directories we've output, used for popping a parent directory.
|
1160
|
-
// Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
|
1161
|
-
let positive = 0;
|
1162
|
-
// We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
|
1163
|
-
// generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
|
1164
|
-
// real directory, we won't need to append, unless the other conditions happen again.
|
1165
|
-
let addTrailingSlash = false;
|
1166
|
-
for (let i = 1; i < pieces.length; i++) {
|
1167
|
-
const piece = pieces[i];
|
1168
|
-
// An empty directory, could be a trailing slash, or just a double "//" in the path.
|
1169
|
-
if (!piece) {
|
1170
|
-
addTrailingSlash = true;
|
1171
|
-
continue;
|
1172
|
-
}
|
1173
|
-
// If we encounter a real directory, then we don't need to append anymore.
|
1174
|
-
addTrailingSlash = false;
|
1175
|
-
// A current directory, which we can always drop.
|
1176
|
-
if (piece === '.')
|
1177
|
-
continue;
|
1178
|
-
// A parent directory, we need to see if there are any real directories we can pop. Else, we
|
1179
|
-
// have an excess of parents, and we'll need to keep the "..".
|
1180
|
-
if (piece === '..') {
|
1181
|
-
if (positive) {
|
1182
|
-
addTrailingSlash = true;
|
1183
|
-
positive--;
|
1184
|
-
pointer--;
|
1185
|
-
}
|
1186
|
-
else if (rel) {
|
1187
|
-
// If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
|
1188
|
-
// URL, protocol relative URL, or an absolute path, we don't need to keep excess.
|
1189
|
-
pieces[pointer++] = piece;
|
1190
|
-
}
|
1191
|
-
continue;
|
1192
|
-
}
|
1193
|
-
// We've encountered a real directory. Move it to the next insertion pointer, which accounts for
|
1194
|
-
// any popped or dropped directories.
|
1195
|
-
pieces[pointer++] = piece;
|
1196
|
-
positive++;
|
1197
|
-
}
|
1198
|
-
let path = '';
|
1199
|
-
for (let i = 1; i < pointer; i++) {
|
1200
|
-
path += '/' + pieces[i];
|
1201
|
-
}
|
1202
|
-
if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
|
1203
|
-
path += '/';
|
1204
|
-
}
|
1205
|
-
url.path = path;
|
1206
|
-
}
|
1207
|
-
/**
|
1208
|
-
* Attempts to resolve `input` URL/path relative to `base`.
|
1209
|
-
*/
|
1210
|
-
function resolve(input, base) {
|
1211
|
-
if (!input && !base)
|
1212
|
-
return '';
|
1213
|
-
const url = parseUrl(input);
|
1214
|
-
let inputType = url.type;
|
1215
|
-
if (base && inputType !== UrlType.Absolute) {
|
1216
|
-
const baseUrl = parseUrl(base);
|
1217
|
-
const baseType = baseUrl.type;
|
1218
|
-
switch (inputType) {
|
1219
|
-
case UrlType.Empty:
|
1220
|
-
url.hash = baseUrl.hash;
|
1221
|
-
// fall through
|
1222
|
-
case UrlType.Hash:
|
1223
|
-
url.query = baseUrl.query;
|
1224
|
-
// fall through
|
1225
|
-
case UrlType.Query:
|
1226
|
-
case UrlType.RelativePath:
|
1227
|
-
mergePaths(url, baseUrl);
|
1228
|
-
// fall through
|
1229
|
-
case UrlType.AbsolutePath:
|
1230
|
-
// The host, user, and port are joined, you can't copy one without the others.
|
1231
|
-
url.user = baseUrl.user;
|
1232
|
-
url.host = baseUrl.host;
|
1233
|
-
url.port = baseUrl.port;
|
1234
|
-
// fall through
|
1235
|
-
case UrlType.SchemeRelative:
|
1236
|
-
// The input doesn't have a schema at least, so we need to copy at least that over.
|
1237
|
-
url.scheme = baseUrl.scheme;
|
1238
|
-
}
|
1239
|
-
if (baseType > inputType)
|
1240
|
-
inputType = baseType;
|
1241
|
-
}
|
1242
|
-
normalizePath(url, inputType);
|
1243
|
-
const queryHash = url.query + url.hash;
|
1244
|
-
switch (inputType) {
|
1245
|
-
// This is impossible, because of the empty checks at the start of the function.
|
1246
|
-
// case UrlType.Empty:
|
1247
|
-
case UrlType.Hash:
|
1248
|
-
case UrlType.Query:
|
1249
|
-
return queryHash;
|
1250
|
-
case UrlType.RelativePath: {
|
1251
|
-
// The first char is always a "/", and we need it to be relative.
|
1252
|
-
const path = url.path.slice(1);
|
1253
|
-
if (!path)
|
1254
|
-
return queryHash || '.';
|
1255
|
-
if (isRelative(base || input) && !isRelative(path)) {
|
1256
|
-
// If base started with a leading ".", or there is no base and input started with a ".",
|
1257
|
-
// then we need to ensure that the relative path starts with a ".". We don't know if
|
1258
|
-
// relative starts with a "..", though, so check before prepending.
|
1259
|
-
return './' + path + queryHash;
|
1260
|
-
}
|
1261
|
-
return path + queryHash;
|
1262
|
-
}
|
1263
|
-
case UrlType.AbsolutePath:
|
1264
|
-
return url.path + queryHash;
|
1265
|
-
default:
|
1266
|
-
return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
|
1267
|
-
}
|
1268
|
-
}
|
1269
|
-
|
1270
|
-
return resolve;
|
1271
|
-
|
1272
|
-
}));
|
1273
|
-
|
1274
|
-
} (resolveUri_umd$1));
|
1275
|
-
return resolveUri_umd$1.exports;
|
1276
|
-
}
|
1277
|
-
|
1278
|
-
var traceMapping_umd = traceMapping_umd$1.exports;
|
1279
|
-
|
1280
|
-
var hasRequiredTraceMapping_umd;
|
1281
|
-
|
1282
|
-
function requireTraceMapping_umd () {
|
1283
|
-
if (hasRequiredTraceMapping_umd) return traceMapping_umd$1.exports;
|
1284
|
-
hasRequiredTraceMapping_umd = 1;
|
1285
|
-
(function (module, exports) {
|
1286
|
-
(function (global, factory) {
|
1287
|
-
factory(exports, requireSourcemapCodec_umd(), requireResolveUri_umd()) ;
|
1288
|
-
})(traceMapping_umd, (function (exports, sourcemapCodec, resolveUri) {
|
1289
|
-
function resolve(input, base) {
|
1290
|
-
// The base is always treated as a directory, if it's not empty.
|
1291
|
-
// https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327
|
1292
|
-
// https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401
|
1293
|
-
if (base && !base.endsWith('/'))
|
1294
|
-
base += '/';
|
1295
|
-
return resolveUri(input, base);
|
1296
|
-
}
|
1297
|
-
|
1298
|
-
/**
|
1299
|
-
* Removes everything after the last "/", but leaves the slash.
|
1300
|
-
*/
|
1301
|
-
function stripFilename(path) {
|
1302
|
-
if (!path)
|
1303
|
-
return '';
|
1304
|
-
const index = path.lastIndexOf('/');
|
1305
|
-
return path.slice(0, index + 1);
|
1306
|
-
}
|
1307
|
-
|
1308
|
-
const COLUMN = 0;
|
1309
|
-
const SOURCES_INDEX = 1;
|
1310
|
-
const SOURCE_LINE = 2;
|
1311
|
-
const SOURCE_COLUMN = 3;
|
1312
|
-
const NAMES_INDEX = 4;
|
1313
|
-
const REV_GENERATED_LINE = 1;
|
1314
|
-
const REV_GENERATED_COLUMN = 2;
|
1315
|
-
|
1316
|
-
function maybeSort(mappings, owned) {
|
1317
|
-
const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
|
1318
|
-
if (unsortedIndex === mappings.length)
|
1319
|
-
return mappings;
|
1320
|
-
// If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If
|
1321
|
-
// not, we do not want to modify the consumer's input array.
|
1322
|
-
if (!owned)
|
1323
|
-
mappings = mappings.slice();
|
1324
|
-
for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) {
|
1325
|
-
mappings[i] = sortSegments(mappings[i], owned);
|
1326
|
-
}
|
1327
|
-
return mappings;
|
1328
|
-
}
|
1329
|
-
function nextUnsortedSegmentLine(mappings, start) {
|
1330
|
-
for (let i = start; i < mappings.length; i++) {
|
1331
|
-
if (!isSorted(mappings[i]))
|
1332
|
-
return i;
|
1333
|
-
}
|
1334
|
-
return mappings.length;
|
1335
|
-
}
|
1336
|
-
function isSorted(line) {
|
1337
|
-
for (let j = 1; j < line.length; j++) {
|
1338
|
-
if (line[j][COLUMN] < line[j - 1][COLUMN]) {
|
1339
|
-
return false;
|
1340
|
-
}
|
1341
|
-
}
|
1342
|
-
return true;
|
1343
|
-
}
|
1344
|
-
function sortSegments(line, owned) {
|
1345
|
-
if (!owned)
|
1346
|
-
line = line.slice();
|
1347
|
-
return line.sort(sortComparator);
|
1348
|
-
}
|
1349
|
-
function sortComparator(a, b) {
|
1350
|
-
return a[COLUMN] - b[COLUMN];
|
1351
|
-
}
|
1352
|
-
|
1353
|
-
let found = false;
|
1354
|
-
/**
|
1355
|
-
* A binary search implementation that returns the index if a match is found.
|
1356
|
-
* If no match is found, then the left-index (the index associated with the item that comes just
|
1357
|
-
* before the desired index) is returned. To maintain proper sort order, a splice would happen at
|
1358
|
-
* the next index:
|
1359
|
-
*
|
1360
|
-
* ```js
|
1361
|
-
* const array = [1, 3];
|
1362
|
-
* const needle = 2;
|
1363
|
-
* const index = binarySearch(array, needle, (item, needle) => item - needle);
|
1364
|
-
*
|
1365
|
-
* assert.equal(index, 0);
|
1366
|
-
* array.splice(index + 1, 0, needle);
|
1367
|
-
* assert.deepEqual(array, [1, 2, 3]);
|
1368
|
-
* ```
|
1369
|
-
*/
|
1370
|
-
function binarySearch(haystack, needle, low, high) {
|
1371
|
-
while (low <= high) {
|
1372
|
-
const mid = low + ((high - low) >> 1);
|
1373
|
-
const cmp = haystack[mid][COLUMN] - needle;
|
1374
|
-
if (cmp === 0) {
|
1375
|
-
found = true;
|
1376
|
-
return mid;
|
1377
|
-
}
|
1378
|
-
if (cmp < 0) {
|
1379
|
-
low = mid + 1;
|
1380
|
-
}
|
1381
|
-
else {
|
1382
|
-
high = mid - 1;
|
1383
|
-
}
|
1384
|
-
}
|
1385
|
-
found = false;
|
1386
|
-
return low - 1;
|
1387
|
-
}
|
1388
|
-
function upperBound(haystack, needle, index) {
|
1389
|
-
for (let i = index + 1; i < haystack.length; index = i++) {
|
1390
|
-
if (haystack[i][COLUMN] !== needle)
|
1391
|
-
break;
|
1392
|
-
}
|
1393
|
-
return index;
|
1394
|
-
}
|
1395
|
-
function lowerBound(haystack, needle, index) {
|
1396
|
-
for (let i = index - 1; i >= 0; index = i--) {
|
1397
|
-
if (haystack[i][COLUMN] !== needle)
|
1398
|
-
break;
|
1399
|
-
}
|
1400
|
-
return index;
|
1401
|
-
}
|
1402
|
-
function memoizedState() {
|
1403
|
-
return {
|
1404
|
-
lastKey: -1,
|
1405
|
-
lastNeedle: -1,
|
1406
|
-
lastIndex: -1,
|
1407
|
-
};
|
1408
|
-
}
|
1409
|
-
/**
|
1410
|
-
* This overly complicated beast is just to record the last tested line/column and the resulting
|
1411
|
-
* index, allowing us to skip a few tests if mappings are monotonically increasing.
|
1412
|
-
*/
|
1413
|
-
function memoizedBinarySearch(haystack, needle, state, key) {
|
1414
|
-
const { lastKey, lastNeedle, lastIndex } = state;
|
1415
|
-
let low = 0;
|
1416
|
-
let high = haystack.length - 1;
|
1417
|
-
if (key === lastKey) {
|
1418
|
-
if (needle === lastNeedle) {
|
1419
|
-
found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
|
1420
|
-
return lastIndex;
|
1421
|
-
}
|
1422
|
-
if (needle >= lastNeedle) {
|
1423
|
-
// lastIndex may be -1 if the previous needle was not found.
|
1424
|
-
low = lastIndex === -1 ? 0 : lastIndex;
|
1425
|
-
}
|
1426
|
-
else {
|
1427
|
-
high = lastIndex;
|
1428
|
-
}
|
1429
|
-
}
|
1430
|
-
state.lastKey = key;
|
1431
|
-
state.lastNeedle = needle;
|
1432
|
-
return (state.lastIndex = binarySearch(haystack, needle, low, high));
|
1433
|
-
}
|
1434
|
-
|
1435
|
-
// Rebuilds the original source files, with mappings that are ordered by source line/column instead
|
1436
|
-
// of generated line/column.
|
1437
|
-
function buildBySources(decoded, memos) {
|
1438
|
-
const sources = memos.map(buildNullArray);
|
1439
|
-
for (let i = 0; i < decoded.length; i++) {
|
1440
|
-
const line = decoded[i];
|
1441
|
-
for (let j = 0; j < line.length; j++) {
|
1442
|
-
const seg = line[j];
|
1443
|
-
if (seg.length === 1)
|
1444
|
-
continue;
|
1445
|
-
const sourceIndex = seg[SOURCES_INDEX];
|
1446
|
-
const sourceLine = seg[SOURCE_LINE];
|
1447
|
-
const sourceColumn = seg[SOURCE_COLUMN];
|
1448
|
-
const originalSource = sources[sourceIndex];
|
1449
|
-
const originalLine = (originalSource[sourceLine] || (originalSource[sourceLine] = []));
|
1450
|
-
const memo = memos[sourceIndex];
|
1451
|
-
// The binary search either found a match, or it found the left-index just before where the
|
1452
|
-
// segment should go. Either way, we want to insert after that. And there may be multiple
|
1453
|
-
// generated segments associated with an original location, so there may need to move several
|
1454
|
-
// indexes before we find where we need to insert.
|
1455
|
-
let index = upperBound(originalLine, sourceColumn, memoizedBinarySearch(originalLine, sourceColumn, memo, sourceLine));
|
1456
|
-
memo.lastIndex = ++index;
|
1457
|
-
insert(originalLine, index, [sourceColumn, i, seg[COLUMN]]);
|
1458
|
-
}
|
1459
|
-
}
|
1460
|
-
return sources;
|
1461
|
-
}
|
1462
|
-
function insert(array, index, value) {
|
1463
|
-
for (let i = array.length; i > index; i--) {
|
1464
|
-
array[i] = array[i - 1];
|
1465
|
-
}
|
1466
|
-
array[index] = value;
|
1467
|
-
}
|
1468
|
-
// Null arrays allow us to use ordered index keys without actually allocating contiguous memory like
|
1469
|
-
// a real array. We use a null-prototype object to avoid prototype pollution and deoptimizations.
|
1470
|
-
// Numeric properties on objects are magically sorted in ascending order by the engine regardless of
|
1471
|
-
// the insertion order. So, by setting any numeric keys, even out of order, we'll get ascending
|
1472
|
-
// order when iterating with for-in.
|
1473
|
-
function buildNullArray() {
|
1474
|
-
return { __proto__: null };
|
1475
|
-
}
|
1476
|
-
|
1477
|
-
const AnyMap = function (map, mapUrl) {
|
1478
|
-
const parsed = parse(map);
|
1479
|
-
if (!('sections' in parsed)) {
|
1480
|
-
return new TraceMap(parsed, mapUrl);
|
1481
|
-
}
|
1482
|
-
const mappings = [];
|
1483
|
-
const sources = [];
|
1484
|
-
const sourcesContent = [];
|
1485
|
-
const names = [];
|
1486
|
-
const ignoreList = [];
|
1487
|
-
recurse(parsed, mapUrl, mappings, sources, sourcesContent, names, ignoreList, 0, 0, Infinity, Infinity);
|
1488
|
-
const joined = {
|
1489
|
-
version: 3,
|
1490
|
-
file: parsed.file,
|
1491
|
-
names,
|
1492
|
-
sources,
|
1493
|
-
sourcesContent,
|
1494
|
-
mappings,
|
1495
|
-
ignoreList,
|
1496
|
-
};
|
1497
|
-
return presortedDecodedMap(joined);
|
1498
|
-
};
|
1499
|
-
function parse(map) {
|
1500
|
-
return typeof map === 'string' ? JSON.parse(map) : map;
|
1501
|
-
}
|
1502
|
-
function recurse(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) {
|
1503
|
-
const { sections } = input;
|
1504
|
-
for (let i = 0; i < sections.length; i++) {
|
1505
|
-
const { map, offset } = sections[i];
|
1506
|
-
let sl = stopLine;
|
1507
|
-
let sc = stopColumn;
|
1508
|
-
if (i + 1 < sections.length) {
|
1509
|
-
const nextOffset = sections[i + 1].offset;
|
1510
|
-
sl = Math.min(stopLine, lineOffset + nextOffset.line);
|
1511
|
-
if (sl === stopLine) {
|
1512
|
-
sc = Math.min(stopColumn, columnOffset + nextOffset.column);
|
1513
|
-
}
|
1514
|
-
else if (sl < stopLine) {
|
1515
|
-
sc = columnOffset + nextOffset.column;
|
1516
|
-
}
|
1517
|
-
}
|
1518
|
-
addSection(map, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset + offset.line, columnOffset + offset.column, sl, sc);
|
1519
|
-
}
|
1520
|
-
}
|
1521
|
-
function addSection(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) {
|
1522
|
-
const parsed = parse(input);
|
1523
|
-
if ('sections' in parsed)
|
1524
|
-
return recurse(...arguments);
|
1525
|
-
const map = new TraceMap(parsed, mapUrl);
|
1526
|
-
const sourcesOffset = sources.length;
|
1527
|
-
const namesOffset = names.length;
|
1528
|
-
const decoded = decodedMappings(map);
|
1529
|
-
const { resolvedSources, sourcesContent: contents, ignoreList: ignores } = map;
|
1530
|
-
append(sources, resolvedSources);
|
1531
|
-
append(names, map.names);
|
1532
|
-
if (contents)
|
1533
|
-
append(sourcesContent, contents);
|
1534
|
-
else
|
1535
|
-
for (let i = 0; i < resolvedSources.length; i++)
|
1536
|
-
sourcesContent.push(null);
|
1537
|
-
if (ignores)
|
1538
|
-
for (let i = 0; i < ignores.length; i++)
|
1539
|
-
ignoreList.push(ignores[i] + sourcesOffset);
|
1540
|
-
for (let i = 0; i < decoded.length; i++) {
|
1541
|
-
const lineI = lineOffset + i;
|
1542
|
-
// We can only add so many lines before we step into the range that the next section's map
|
1543
|
-
// controls. When we get to the last line, then we'll start checking the segments to see if
|
1544
|
-
// they've crossed into the column range. But it may not have any columns that overstep, so we
|
1545
|
-
// still need to check that we don't overstep lines, too.
|
1546
|
-
if (lineI > stopLine)
|
1547
|
-
return;
|
1548
|
-
// The out line may already exist in mappings (if we're continuing the line started by a
|
1549
|
-
// previous section). Or, we may have jumped ahead several lines to start this section.
|
1550
|
-
const out = getLine(mappings, lineI);
|
1551
|
-
// On the 0th loop, the section's column offset shifts us forward. On all other lines (since the
|
1552
|
-
// map can be multiple lines), it doesn't.
|
1553
|
-
const cOffset = i === 0 ? columnOffset : 0;
|
1554
|
-
const line = decoded[i];
|
1555
|
-
for (let j = 0; j < line.length; j++) {
|
1556
|
-
const seg = line[j];
|
1557
|
-
const column = cOffset + seg[COLUMN];
|
1558
|
-
// If this segment steps into the column range that the next section's map controls, we need
|
1559
|
-
// to stop early.
|
1560
|
-
if (lineI === stopLine && column >= stopColumn)
|
1561
|
-
return;
|
1562
|
-
if (seg.length === 1) {
|
1563
|
-
out.push([column]);
|
1564
|
-
continue;
|
1565
|
-
}
|
1566
|
-
const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX];
|
1567
|
-
const sourceLine = seg[SOURCE_LINE];
|
1568
|
-
const sourceColumn = seg[SOURCE_COLUMN];
|
1569
|
-
out.push(seg.length === 4
|
1570
|
-
? [column, sourcesIndex, sourceLine, sourceColumn]
|
1571
|
-
: [column, sourcesIndex, sourceLine, sourceColumn, namesOffset + seg[NAMES_INDEX]]);
|
1572
|
-
}
|
1573
|
-
}
|
1574
|
-
}
|
1575
|
-
function append(arr, other) {
|
1576
|
-
for (let i = 0; i < other.length; i++)
|
1577
|
-
arr.push(other[i]);
|
1578
|
-
}
|
1579
|
-
function getLine(arr, index) {
|
1580
|
-
for (let i = arr.length; i <= index; i++)
|
1581
|
-
arr[i] = [];
|
1582
|
-
return arr[index];
|
1583
|
-
}
|
1584
|
-
|
1585
|
-
const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)';
|
1586
|
-
const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)';
|
1587
|
-
const LEAST_UPPER_BOUND = -1;
|
1588
|
-
const GREATEST_LOWER_BOUND = 1;
|
1589
|
-
class TraceMap {
|
1590
|
-
constructor(map, mapUrl) {
|
1591
|
-
const isString = typeof map === 'string';
|
1592
|
-
if (!isString && map._decodedMemo)
|
1593
|
-
return map;
|
1594
|
-
const parsed = (isString ? JSON.parse(map) : map);
|
1595
|
-
const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
|
1596
|
-
this.version = version;
|
1597
|
-
this.file = file;
|
1598
|
-
this.names = names || [];
|
1599
|
-
this.sourceRoot = sourceRoot;
|
1600
|
-
this.sources = sources;
|
1601
|
-
this.sourcesContent = sourcesContent;
|
1602
|
-
this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || undefined;
|
1603
|
-
const from = resolve(sourceRoot || '', stripFilename(mapUrl));
|
1604
|
-
this.resolvedSources = sources.map((s) => resolve(s || '', from));
|
1605
|
-
const { mappings } = parsed;
|
1606
|
-
if (typeof mappings === 'string') {
|
1607
|
-
this._encoded = mappings;
|
1608
|
-
this._decoded = undefined;
|
1609
|
-
}
|
1610
|
-
else {
|
1611
|
-
this._encoded = undefined;
|
1612
|
-
this._decoded = maybeSort(mappings, isString);
|
1613
|
-
}
|
1614
|
-
this._decodedMemo = memoizedState();
|
1615
|
-
this._bySources = undefined;
|
1616
|
-
this._bySourceMemos = undefined;
|
1617
|
-
}
|
1618
|
-
}
|
1619
|
-
/**
|
1620
|
-
* Typescript doesn't allow friend access to private fields, so this just casts the map into a type
|
1621
|
-
* with public access modifiers.
|
1622
|
-
*/
|
1623
|
-
function cast(map) {
|
1624
|
-
return map;
|
1625
|
-
}
|
1626
|
-
/**
|
1627
|
-
* Returns the encoded (VLQ string) form of the SourceMap's mappings field.
|
1628
|
-
*/
|
1629
|
-
function encodedMappings(map) {
|
1630
|
-
var _a;
|
1631
|
-
var _b;
|
1632
|
-
return ((_a = (_b = cast(map))._encoded) !== null && _a !== void 0 ? _a : (_b._encoded = sourcemapCodec.encode(cast(map)._decoded)));
|
1633
|
-
}
|
1634
|
-
/**
|
1635
|
-
* Returns the decoded (array of lines of segments) form of the SourceMap's mappings field.
|
1636
|
-
*/
|
1637
|
-
function decodedMappings(map) {
|
1638
|
-
var _a;
|
1639
|
-
return ((_a = cast(map))._decoded || (_a._decoded = sourcemapCodec.decode(cast(map)._encoded)));
|
1640
|
-
}
|
1641
|
-
/**
|
1642
|
-
* A low-level API to find the segment associated with a generated line/column (think, from a
|
1643
|
-
* stack trace). Line and column here are 0-based, unlike `originalPositionFor`.
|
1644
|
-
*/
|
1645
|
-
function traceSegment(map, line, column) {
|
1646
|
-
const decoded = decodedMappings(map);
|
1647
|
-
// It's common for parent source maps to have pointers to lines that have no
|
1648
|
-
// mapping (like a "//# sourceMappingURL=") at the end of the child file.
|
1649
|
-
if (line >= decoded.length)
|
1650
|
-
return null;
|
1651
|
-
const segments = decoded[line];
|
1652
|
-
const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, GREATEST_LOWER_BOUND);
|
1653
|
-
return index === -1 ? null : segments[index];
|
1654
|
-
}
|
1655
|
-
/**
|
1656
|
-
* A higher-level API to find the source/line/column associated with a generated line/column
|
1657
|
-
* (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in
|
1658
|
-
* `source-map` library.
|
1659
|
-
*/
|
1660
|
-
function originalPositionFor(map, needle) {
|
1661
|
-
let { line, column, bias } = needle;
|
1662
|
-
line--;
|
1663
|
-
if (line < 0)
|
1664
|
-
throw new Error(LINE_GTR_ZERO);
|
1665
|
-
if (column < 0)
|
1666
|
-
throw new Error(COL_GTR_EQ_ZERO);
|
1667
|
-
const decoded = decodedMappings(map);
|
1668
|
-
// It's common for parent source maps to have pointers to lines that have no
|
1669
|
-
// mapping (like a "//# sourceMappingURL=") at the end of the child file.
|
1670
|
-
if (line >= decoded.length)
|
1671
|
-
return OMapping(null, null, null, null);
|
1672
|
-
const segments = decoded[line];
|
1673
|
-
const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND);
|
1674
|
-
if (index === -1)
|
1675
|
-
return OMapping(null, null, null, null);
|
1676
|
-
const segment = segments[index];
|
1677
|
-
if (segment.length === 1)
|
1678
|
-
return OMapping(null, null, null, null);
|
1679
|
-
const { names, resolvedSources } = map;
|
1680
|
-
return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
|
1681
|
-
}
|
1682
|
-
/**
|
1683
|
-
* Finds the generated line/column position of the provided source/line/column source position.
|
1684
|
-
*/
|
1685
|
-
function generatedPositionFor(map, needle) {
|
1686
|
-
const { source, line, column, bias } = needle;
|
1687
|
-
return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false);
|
1688
|
-
}
|
1689
|
-
/**
|
1690
|
-
* Finds all generated line/column positions of the provided source/line/column source position.
|
1691
|
-
*/
|
1692
|
-
function allGeneratedPositionsFor(map, needle) {
|
1693
|
-
const { source, line, column, bias } = needle;
|
1694
|
-
// SourceMapConsumer uses LEAST_UPPER_BOUND for some reason, so we follow suit.
|
1695
|
-
return generatedPosition(map, source, line, column, bias || LEAST_UPPER_BOUND, true);
|
1696
|
-
}
|
1697
|
-
/**
|
1698
|
-
* Iterates each mapping in generated position order.
|
1699
|
-
*/
|
1700
|
-
function eachMapping(map, cb) {
|
1701
|
-
const decoded = decodedMappings(map);
|
1702
|
-
const { names, resolvedSources } = map;
|
1703
|
-
for (let i = 0; i < decoded.length; i++) {
|
1704
|
-
const line = decoded[i];
|
1705
|
-
for (let j = 0; j < line.length; j++) {
|
1706
|
-
const seg = line[j];
|
1707
|
-
const generatedLine = i + 1;
|
1708
|
-
const generatedColumn = seg[0];
|
1709
|
-
let source = null;
|
1710
|
-
let originalLine = null;
|
1711
|
-
let originalColumn = null;
|
1712
|
-
let name = null;
|
1713
|
-
if (seg.length !== 1) {
|
1714
|
-
source = resolvedSources[seg[1]];
|
1715
|
-
originalLine = seg[2] + 1;
|
1716
|
-
originalColumn = seg[3];
|
1717
|
-
}
|
1718
|
-
if (seg.length === 5)
|
1719
|
-
name = names[seg[4]];
|
1720
|
-
cb({
|
1721
|
-
generatedLine,
|
1722
|
-
generatedColumn,
|
1723
|
-
source,
|
1724
|
-
originalLine,
|
1725
|
-
originalColumn,
|
1726
|
-
name,
|
1727
|
-
});
|
1728
|
-
}
|
1729
|
-
}
|
1730
|
-
}
|
1731
|
-
function sourceIndex(map, source) {
|
1732
|
-
const { sources, resolvedSources } = map;
|
1733
|
-
let index = sources.indexOf(source);
|
1734
|
-
if (index === -1)
|
1735
|
-
index = resolvedSources.indexOf(source);
|
1736
|
-
return index;
|
1737
|
-
}
|
1738
|
-
/**
|
1739
|
-
* Retrieves the source content for a particular source, if its found. Returns null if not.
|
1740
|
-
*/
|
1741
|
-
function sourceContentFor(map, source) {
|
1742
|
-
const { sourcesContent } = map;
|
1743
|
-
if (sourcesContent == null)
|
1744
|
-
return null;
|
1745
|
-
const index = sourceIndex(map, source);
|
1746
|
-
return index === -1 ? null : sourcesContent[index];
|
1747
|
-
}
|
1748
|
-
/**
|
1749
|
-
* Determines if the source is marked to ignore by the source map.
|
1750
|
-
*/
|
1751
|
-
function isIgnored(map, source) {
|
1752
|
-
const { ignoreList } = map;
|
1753
|
-
if (ignoreList == null)
|
1754
|
-
return false;
|
1755
|
-
const index = sourceIndex(map, source);
|
1756
|
-
return index === -1 ? false : ignoreList.includes(index);
|
1757
|
-
}
|
1758
|
-
/**
|
1759
|
-
* A helper that skips sorting of the input map's mappings array, which can be expensive for larger
|
1760
|
-
* maps.
|
1761
|
-
*/
|
1762
|
-
function presortedDecodedMap(map, mapUrl) {
|
1763
|
-
const tracer = new TraceMap(clone(map, []), mapUrl);
|
1764
|
-
cast(tracer)._decoded = map.mappings;
|
1765
|
-
return tracer;
|
1766
|
-
}
|
1767
|
-
/**
|
1768
|
-
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
|
1769
|
-
* a sourcemap, or to JSON.stringify.
|
1770
|
-
*/
|
1771
|
-
function decodedMap(map) {
|
1772
|
-
return clone(map, decodedMappings(map));
|
1773
|
-
}
|
1774
|
-
/**
|
1775
|
-
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
|
1776
|
-
* a sourcemap, or to JSON.stringify.
|
1777
|
-
*/
|
1778
|
-
function encodedMap(map) {
|
1779
|
-
return clone(map, encodedMappings(map));
|
1780
|
-
}
|
1781
|
-
function clone(map, mappings) {
|
1782
|
-
return {
|
1783
|
-
version: map.version,
|
1784
|
-
file: map.file,
|
1785
|
-
names: map.names,
|
1786
|
-
sourceRoot: map.sourceRoot,
|
1787
|
-
sources: map.sources,
|
1788
|
-
sourcesContent: map.sourcesContent,
|
1789
|
-
mappings,
|
1790
|
-
ignoreList: map.ignoreList || map.x_google_ignoreList,
|
1791
|
-
};
|
1792
|
-
}
|
1793
|
-
function OMapping(source, line, column, name) {
|
1794
|
-
return { source, line, column, name };
|
1795
|
-
}
|
1796
|
-
function GMapping(line, column) {
|
1797
|
-
return { line, column };
|
1798
|
-
}
|
1799
|
-
function traceSegmentInternal(segments, memo, line, column, bias) {
|
1800
|
-
let index = memoizedBinarySearch(segments, column, memo, line);
|
1801
|
-
if (found) {
|
1802
|
-
index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index);
|
1803
|
-
}
|
1804
|
-
else if (bias === LEAST_UPPER_BOUND)
|
1805
|
-
index++;
|
1806
|
-
if (index === -1 || index === segments.length)
|
1807
|
-
return -1;
|
1808
|
-
return index;
|
1809
|
-
}
|
1810
|
-
function sliceGeneratedPositions(segments, memo, line, column, bias) {
|
1811
|
-
let min = traceSegmentInternal(segments, memo, line, column, GREATEST_LOWER_BOUND);
|
1812
|
-
// We ignored the bias when tracing the segment so that we're guarnateed to find the first (in
|
1813
|
-
// insertion order) segment that matched. Even if we did respect the bias when tracing, we would
|
1814
|
-
// still need to call `lowerBound()` to find the first segment, which is slower than just looking
|
1815
|
-
// for the GREATEST_LOWER_BOUND to begin with. The only difference that matters for us is when the
|
1816
|
-
// binary search didn't match, in which case GREATEST_LOWER_BOUND just needs to increment to
|
1817
|
-
// match LEAST_UPPER_BOUND.
|
1818
|
-
if (!found && bias === LEAST_UPPER_BOUND)
|
1819
|
-
min++;
|
1820
|
-
if (min === -1 || min === segments.length)
|
1821
|
-
return [];
|
1822
|
-
// We may have found the segment that started at an earlier column. If this is the case, then we
|
1823
|
-
// need to slice all generated segments that match _that_ column, because all such segments span
|
1824
|
-
// to our desired column.
|
1825
|
-
const matchedColumn = found ? column : segments[min][COLUMN];
|
1826
|
-
// The binary search is not guaranteed to find the lower bound when a match wasn't found.
|
1827
|
-
if (!found)
|
1828
|
-
min = lowerBound(segments, matchedColumn, min);
|
1829
|
-
const max = upperBound(segments, matchedColumn, min);
|
1830
|
-
const result = [];
|
1831
|
-
for (; min <= max; min++) {
|
1832
|
-
const segment = segments[min];
|
1833
|
-
result.push(GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]));
|
1834
|
-
}
|
1835
|
-
return result;
|
1836
|
-
}
|
1837
|
-
function generatedPosition(map, source, line, column, bias, all) {
|
1838
|
-
var _a;
|
1839
|
-
line--;
|
1840
|
-
if (line < 0)
|
1841
|
-
throw new Error(LINE_GTR_ZERO);
|
1842
|
-
if (column < 0)
|
1843
|
-
throw new Error(COL_GTR_EQ_ZERO);
|
1844
|
-
const { sources, resolvedSources } = map;
|
1845
|
-
let sourceIndex = sources.indexOf(source);
|
1846
|
-
if (sourceIndex === -1)
|
1847
|
-
sourceIndex = resolvedSources.indexOf(source);
|
1848
|
-
if (sourceIndex === -1)
|
1849
|
-
return all ? [] : GMapping(null, null);
|
1850
|
-
const generated = ((_a = cast(map))._bySources || (_a._bySources = buildBySources(decodedMappings(map), (cast(map)._bySourceMemos = sources.map(memoizedState)))));
|
1851
|
-
const segments = generated[sourceIndex][line];
|
1852
|
-
if (segments == null)
|
1853
|
-
return all ? [] : GMapping(null, null);
|
1854
|
-
const memo = cast(map)._bySourceMemos[sourceIndex];
|
1855
|
-
if (all)
|
1856
|
-
return sliceGeneratedPositions(segments, memo, line, column, bias);
|
1857
|
-
const index = traceSegmentInternal(segments, memo, line, column, bias);
|
1858
|
-
if (index === -1)
|
1859
|
-
return GMapping(null, null);
|
1860
|
-
const segment = segments[index];
|
1861
|
-
return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]);
|
1862
|
-
}
|
1863
|
-
|
1864
|
-
exports.AnyMap = AnyMap;
|
1865
|
-
exports.GREATEST_LOWER_BOUND = GREATEST_LOWER_BOUND;
|
1866
|
-
exports.LEAST_UPPER_BOUND = LEAST_UPPER_BOUND;
|
1867
|
-
exports.TraceMap = TraceMap;
|
1868
|
-
exports.allGeneratedPositionsFor = allGeneratedPositionsFor;
|
1869
|
-
exports.decodedMap = decodedMap;
|
1870
|
-
exports.decodedMappings = decodedMappings;
|
1871
|
-
exports.eachMapping = eachMapping;
|
1872
|
-
exports.encodedMap = encodedMap;
|
1873
|
-
exports.encodedMappings = encodedMappings;
|
1874
|
-
exports.generatedPositionFor = generatedPositionFor;
|
1875
|
-
exports.isIgnored = isIgnored;
|
1876
|
-
exports.originalPositionFor = originalPositionFor;
|
1877
|
-
exports.presortedDecodedMap = presortedDecodedMap;
|
1878
|
-
exports.sourceContentFor = sourceContentFor;
|
1879
|
-
exports.traceSegment = traceSegment;
|
1880
|
-
|
1881
|
-
}));
|
1882
|
-
|
1883
|
-
} (traceMapping_umd$1, traceMapping_umd$1.exports));
|
1884
|
-
return traceMapping_umd$1.exports;
|
1885
|
-
}
|
1886
|
-
|
1887
|
-
var source;
|
1888
|
-
var hasRequiredSource;
|
1889
|
-
|
1890
|
-
function requireSource () {
|
1891
|
-
if (hasRequiredSource) return source;
|
1892
|
-
hasRequiredSource = 1;
|
1893
|
-
// Patch applied: https://github.com/istanbuljs/v8-to-istanbul/pull/244
|
1894
|
-
const CovLine = requireLine();
|
1895
|
-
const { sliceRange } = requireRange();
|
1896
|
-
const { originalPositionFor, generatedPositionFor, eachMapping, GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND } = requireTraceMapping_umd();
|
1897
|
-
|
1898
|
-
source = class CovSource {
|
1899
|
-
constructor (sourceRaw, wrapperLength, traceMap) {
|
1900
|
-
sourceRaw = sourceRaw ? sourceRaw.trimEnd() : '';
|
1901
|
-
this.lines = [];
|
1902
|
-
this.eof = sourceRaw.length;
|
1903
|
-
this.shebangLength = getShebangLength(sourceRaw);
|
1904
|
-
this.wrapperLength = wrapperLength - this.shebangLength;
|
1905
|
-
this._buildLines(sourceRaw, traceMap);
|
1906
|
-
}
|
1907
|
-
|
1908
|
-
_buildLines (source, traceMap) {
|
1909
|
-
let position = 0;
|
1910
|
-
let ignoreCount = 0;
|
1911
|
-
let ignoreAll = false;
|
1912
|
-
const linesToCover = traceMap && this._parseLinesToCover(traceMap);
|
1913
|
-
|
1914
|
-
for (const [i, lineStr] of source.split(/(?<=\r?\n)/u).entries()) {
|
1915
|
-
const lineNumber = i + 1;
|
1916
|
-
const line = new CovLine(lineNumber, position, lineStr);
|
1917
|
-
|
1918
|
-
if (linesToCover && !linesToCover.has(lineNumber)) {
|
1919
|
-
line.ignore = true;
|
1920
|
-
}
|
1921
|
-
|
1922
|
-
if (ignoreCount > 0) {
|
1923
|
-
line.ignore = true;
|
1924
|
-
ignoreCount--;
|
1925
|
-
} else if (ignoreAll) {
|
1926
|
-
line.ignore = true;
|
1927
|
-
}
|
1928
|
-
this.lines.push(line);
|
1929
|
-
position += lineStr.length;
|
1930
|
-
|
1931
|
-
const ignoreToken = this._parseIgnore(lineStr);
|
1932
|
-
if (!ignoreToken) continue
|
1933
|
-
|
1934
|
-
line.ignore = true;
|
1935
|
-
if (ignoreToken.count !== undefined) {
|
1936
|
-
ignoreCount = ignoreToken.count;
|
1937
|
-
}
|
1938
|
-
if (ignoreToken.start || ignoreToken.stop) {
|
1939
|
-
ignoreAll = ignoreToken.start;
|
1940
|
-
ignoreCount = 0;
|
1941
|
-
}
|
1942
|
-
}
|
1943
|
-
}
|
1944
|
-
|
1945
|
-
/**
|
1946
|
-
* Parses for comments:
|
1947
|
-
* c8 ignore next
|
1948
|
-
* c8 ignore next 3
|
1949
|
-
* c8 ignore start
|
1950
|
-
* c8 ignore stop
|
1951
|
-
* And equivalent ones for v8, e.g. v8 ignore next.
|
1952
|
-
* @param {string} lineStr
|
1953
|
-
* @return {{count?: number, start?: boolean, stop?: boolean}|undefined}
|
1954
|
-
*/
|
1955
|
-
_parseIgnore (lineStr) {
|
1956
|
-
const testIgnoreNextLines = lineStr.match(/^\W*\/\* (?:[cv]8|node:coverage) ignore next (?<count>[0-9]+)/);
|
1957
|
-
if (testIgnoreNextLines) {
|
1958
|
-
return { count: Number(testIgnoreNextLines.groups.count) }
|
1959
|
-
}
|
1960
|
-
|
1961
|
-
// Check if comment is on its own line.
|
1962
|
-
if (lineStr.match(/^\W*\/\* (?:[cv]8|node:coverage) ignore next/)) {
|
1963
|
-
return { count: 1 }
|
1964
|
-
}
|
1965
|
-
|
1966
|
-
if (lineStr.match(/\/\* ([cv]8|node:coverage) ignore next/)) {
|
1967
|
-
// Won't ignore successive lines, but the current line will be ignored.
|
1968
|
-
return { count: 0 }
|
1969
|
-
}
|
1970
|
-
|
1971
|
-
const testIgnoreStartStop = lineStr.match(/\/\* [c|v]8 ignore (?<mode>start|stop)/);
|
1972
|
-
if (testIgnoreStartStop) {
|
1973
|
-
if (testIgnoreStartStop.groups.mode === 'start') return { start: true }
|
1974
|
-
if (testIgnoreStartStop.groups.mode === 'stop') return { stop: true }
|
1975
|
-
}
|
1976
|
-
|
1977
|
-
const testNodeIgnoreStartStop = lineStr.match(/\/\* node:coverage (?<mode>enable|disable)/);
|
1978
|
-
if (testNodeIgnoreStartStop) {
|
1979
|
-
if (testNodeIgnoreStartStop.groups.mode === 'disable') return { start: true }
|
1980
|
-
if (testNodeIgnoreStartStop.groups.mode === 'enable') return { stop: true }
|
1981
|
-
}
|
1982
|
-
}
|
1983
|
-
|
1984
|
-
// given a start column and end column in absolute offsets within
|
1985
|
-
// a source file (0 - EOF), returns the relative line column positions.
|
1986
|
-
offsetToOriginalRelative (sourceMap, startCol, endCol) {
|
1987
|
-
const lines = sliceRange(this.lines, startCol, endCol, true);
|
1988
|
-
if (!lines.length) return {}
|
1989
|
-
|
1990
|
-
const start = originalPositionTryBoth(
|
1991
|
-
sourceMap,
|
1992
|
-
lines[0].line,
|
1993
|
-
Math.max(0, startCol - lines[0].startCol)
|
1994
|
-
);
|
1995
|
-
if (!(start && start.source)) {
|
1996
|
-
return {}
|
1997
|
-
}
|
1998
|
-
|
1999
|
-
let end = originalEndPositionFor(
|
2000
|
-
sourceMap,
|
2001
|
-
lines[lines.length - 1].line,
|
2002
|
-
endCol - lines[lines.length - 1].startCol
|
2003
|
-
);
|
2004
|
-
if (!(end && end.source)) {
|
2005
|
-
return {}
|
2006
|
-
}
|
2007
|
-
|
2008
|
-
if (start.source !== end.source) {
|
2009
|
-
return {}
|
2010
|
-
}
|
2011
|
-
|
2012
|
-
if (start.line === end.line && start.column === end.column) {
|
2013
|
-
end = originalPositionFor(sourceMap, {
|
2014
|
-
line: lines[lines.length - 1].line,
|
2015
|
-
column: endCol - lines[lines.length - 1].startCol,
|
2016
|
-
bias: LEAST_UPPER_BOUND
|
2017
|
-
});
|
2018
|
-
end.column -= 1;
|
2019
|
-
}
|
2020
|
-
|
2021
|
-
return {
|
2022
|
-
source: start.source,
|
2023
|
-
startLine: start.line,
|
2024
|
-
relStartCol: start.column,
|
2025
|
-
endLine: end.line,
|
2026
|
-
relEndCol: end.column
|
2027
|
-
}
|
2028
|
-
}
|
2029
|
-
|
2030
|
-
relativeToOffset (line, relCol) {
|
2031
|
-
line = Math.max(line, 1);
|
2032
|
-
if (this.lines[line - 1] === undefined) return this.eof
|
2033
|
-
return Math.min(this.lines[line - 1].startCol + relCol, this.lines[line - 1].endCol)
|
2034
|
-
}
|
2035
|
-
|
2036
|
-
_parseLinesToCover (traceMap) {
|
2037
|
-
const linesToCover = new Set();
|
2038
|
-
|
2039
|
-
eachMapping(traceMap, (mapping) => {
|
2040
|
-
if (mapping.originalLine !== null) {
|
2041
|
-
linesToCover.add(mapping.originalLine);
|
2042
|
-
}
|
2043
|
-
});
|
2044
|
-
|
2045
|
-
return linesToCover
|
2046
|
-
}
|
2047
|
-
};
|
2048
|
-
|
2049
|
-
// this implementation is pulled over from istanbul-lib-sourcemap:
|
2050
|
-
// https://github.com/istanbuljs/istanbuljs/blob/master/packages/istanbul-lib-source-maps/lib/get-mapping.js
|
2051
|
-
//
|
2052
|
-
/**
|
2053
|
-
* AST ranges are inclusive for start positions and exclusive for end positions.
|
2054
|
-
* Source maps are also logically ranges over text, though interacting with
|
2055
|
-
* them is generally achieved by working with explicit positions.
|
2056
|
-
*
|
2057
|
-
* When finding the _end_ location of an AST item, the range behavior is
|
2058
|
-
* important because what we're asking for is the _end_ of whatever range
|
2059
|
-
* corresponds to the end location we seek.
|
2060
|
-
*
|
2061
|
-
* This boils down to the following steps, conceptually, though the source-map
|
2062
|
-
* library doesn't expose primitives to do this nicely:
|
2063
|
-
*
|
2064
|
-
* 1. Find the range on the generated file that ends at, or exclusively
|
2065
|
-
* contains the end position of the AST node.
|
2066
|
-
* 2. Find the range on the original file that corresponds to
|
2067
|
-
* that generated range.
|
2068
|
-
* 3. Find the _end_ location of that original range.
|
2069
|
-
*/
|
2070
|
-
function originalEndPositionFor (sourceMap, line, column) {
|
2071
|
-
// Given the generated location, find the original location of the mapping
|
2072
|
-
// that corresponds to a range on the generated file that overlaps the
|
2073
|
-
// generated file end location. Note however that this position on its
|
2074
|
-
// own is not useful because it is the position of the _start_ of the range
|
2075
|
-
// on the original file, and we want the _end_ of the range.
|
2076
|
-
const beforeEndMapping = originalPositionTryBoth(
|
2077
|
-
sourceMap,
|
2078
|
-
line,
|
2079
|
-
Math.max(column - 1, 1)
|
2080
|
-
);
|
2081
|
-
|
2082
|
-
if (beforeEndMapping.source === null) {
|
2083
|
-
return null
|
2084
|
-
}
|
2085
|
-
|
2086
|
-
// Convert that original position back to a generated one, with a bump
|
2087
|
-
// to the right, and a rightward bias. Since 'generatedPositionFor' searches
|
2088
|
-
// for mappings in the original-order sorted list, this will find the
|
2089
|
-
// mapping that corresponds to the one immediately after the
|
2090
|
-
// beforeEndMapping mapping.
|
2091
|
-
const afterEndMapping = generatedPositionFor(sourceMap, {
|
2092
|
-
source: beforeEndMapping.source,
|
2093
|
-
line: beforeEndMapping.line,
|
2094
|
-
column: beforeEndMapping.column + 1,
|
2095
|
-
bias: LEAST_UPPER_BOUND
|
2096
|
-
});
|
2097
|
-
if (
|
2098
|
-
// If this is null, it means that we've hit the end of the file,
|
2099
|
-
// so we can use Infinity as the end column.
|
2100
|
-
afterEndMapping.line === null ||
|
2101
|
-
// If these don't match, it means that the call to
|
2102
|
-
// 'generatedPositionFor' didn't find any other original mappings on
|
2103
|
-
// the line we gave, so consider the binding to extend to infinity.
|
2104
|
-
originalPositionFor(sourceMap, afterEndMapping).line !==
|
2105
|
-
beforeEndMapping.line
|
2106
|
-
) {
|
2107
|
-
return {
|
2108
|
-
source: beforeEndMapping.source,
|
2109
|
-
line: beforeEndMapping.line,
|
2110
|
-
column: Infinity
|
2111
|
-
}
|
2112
|
-
}
|
2113
|
-
|
2114
|
-
// Convert the end mapping into the real original position.
|
2115
|
-
return originalPositionFor(sourceMap, afterEndMapping)
|
2116
|
-
}
|
2117
|
-
|
2118
|
-
function originalPositionTryBoth (sourceMap, line, column) {
|
2119
|
-
let original = originalPositionFor(sourceMap, {
|
2120
|
-
line,
|
2121
|
-
column,
|
2122
|
-
bias: GREATEST_LOWER_BOUND
|
2123
|
-
});
|
2124
|
-
if (original.line === null) {
|
2125
|
-
original = originalPositionFor(sourceMap, {
|
2126
|
-
line,
|
2127
|
-
column,
|
2128
|
-
bias: LEAST_UPPER_BOUND
|
2129
|
-
});
|
2130
|
-
}
|
2131
|
-
// The source maps generated by https://github.com/istanbuljs/istanbuljs
|
2132
|
-
// (using @babel/core 7.7.5) have behavior, such that a mapping
|
2133
|
-
// mid-way through a line maps to an earlier line than a mapping
|
2134
|
-
// at position 0. Using the line at positon 0 seems to provide better reports:
|
2135
|
-
//
|
2136
|
-
// if (true) {
|
2137
|
-
// cov_y5divc6zu().b[1][0]++;
|
2138
|
-
// cov_y5divc6zu().s[3]++;
|
2139
|
-
// console.info('reachable');
|
2140
|
-
// } else { ... }
|
2141
|
-
// ^ ^
|
2142
|
-
// l5 l3
|
2143
|
-
const min = originalPositionFor(sourceMap, {
|
2144
|
-
line,
|
2145
|
-
column: 0,
|
2146
|
-
bias: GREATEST_LOWER_BOUND
|
2147
|
-
});
|
2148
|
-
if (min.line > original.line) {
|
2149
|
-
original = min;
|
2150
|
-
}
|
2151
|
-
return original
|
2152
|
-
}
|
2153
|
-
|
2154
|
-
// Not required since Node 12, see: https://github.com/nodejs/node/pull/27375
|
2155
|
-
const isPreNode12 = /^v1[0-1]\./u.test(process.version);
|
2156
|
-
function getShebangLength (source) {
|
2157
|
-
/* c8 ignore start - platform-specific */
|
2158
|
-
if (isPreNode12 && source.indexOf('#!') === 0) {
|
2159
|
-
const match = source.match(/(?<shebang>#!.*)/);
|
2160
|
-
if (match) {
|
2161
|
-
return match.groups.shebang.length
|
2162
|
-
}
|
2163
|
-
} else {
|
2164
|
-
/* c8 ignore stop - platform-specific */
|
2165
|
-
return 0
|
2166
|
-
}
|
2167
|
-
}
|
2168
|
-
return source;
|
2169
|
-
}
|
2170
|
-
|
2171
|
-
var v8ToIstanbul$2;
|
2172
|
-
var hasRequiredV8ToIstanbul$1;
|
2173
|
-
|
2174
|
-
function requireV8ToIstanbul$1 () {
|
2175
|
-
if (hasRequiredV8ToIstanbul$1) return v8ToIstanbul$2;
|
2176
|
-
hasRequiredV8ToIstanbul$1 = 1;
|
2177
|
-
// Patch applied: https://github.com/istanbuljs/v8-to-istanbul/pull/244
|
2178
|
-
const assert = require$$0;
|
2179
|
-
const convertSourceMap = requireConvertSourceMap();
|
2180
|
-
const util = require$$2;
|
2181
|
-
const debuglog = util.debuglog('c8');
|
2182
|
-
const { dirname, isAbsolute, join, resolve } = require$$3;
|
2183
|
-
const { fileURLToPath } = require$$4;
|
2184
|
-
const CovBranch = requireBranch();
|
2185
|
-
const CovFunction = require_function();
|
2186
|
-
const CovSource = requireSource();
|
2187
|
-
const { sliceRange } = requireRange();
|
2188
|
-
const { readFileSync, promises } = require$$9;
|
2189
|
-
const readFile = promises.readFile;
|
2190
|
-
|
2191
|
-
const { TraceMap } = requireTraceMapping_umd();
|
2192
|
-
const isOlderNode10 = /^v10\.(([0-9]\.)|(1[0-5]\.))/u.test(process.version);
|
2193
|
-
const isNode8 = /^v8\./.test(process.version);
|
2194
|
-
|
2195
|
-
// Injected when Node.js is loading script into isolate pre Node 10.16.x.
|
2196
|
-
// see: https://github.com/nodejs/node/pull/21573.
|
2197
|
-
const cjsWrapperLength = isOlderNode10 ? require$$11.wrapper[0].length : 0;
|
2198
|
-
|
2199
|
-
v8ToIstanbul$2 = class V8ToIstanbul {
|
2200
|
-
constructor (scriptPath, wrapperLength, sources, excludePath, excludeEmptyLines) {
|
2201
|
-
assert(typeof scriptPath === 'string', 'scriptPath must be a string');
|
2202
|
-
assert(!isNode8, 'This module does not support node 8 or lower, please upgrade to node 10');
|
2203
|
-
this.path = parsePath(scriptPath);
|
2204
|
-
this.wrapperLength = wrapperLength === undefined ? cjsWrapperLength : wrapperLength;
|
2205
|
-
this.excludePath = excludePath || (() => false);
|
2206
|
-
this.excludeEmptyLines = excludeEmptyLines === true;
|
2207
|
-
this.sources = sources || {};
|
2208
|
-
this.generatedLines = [];
|
2209
|
-
this.branches = {};
|
2210
|
-
this.functions = {};
|
2211
|
-
this.covSources = [];
|
2212
|
-
this.rawSourceMap = undefined;
|
2213
|
-
this.sourceMap = undefined;
|
2214
|
-
this.sourceTranspiled = undefined;
|
2215
|
-
// Indicate that this report was generated with placeholder data from
|
2216
|
-
// running --all:
|
2217
|
-
this.all = false;
|
2218
|
-
}
|
2219
|
-
|
2220
|
-
async load () {
|
2221
|
-
const rawSource = this.sources.source || await readFile(this.path, 'utf8');
|
2222
|
-
this.rawSourceMap = this.sources.sourceMap ||
|
2223
|
-
// if we find a source-map (either inline, or a .map file) we load
|
2224
|
-
// both the transpiled and original source, both of which are used during
|
2225
|
-
// the backflips we perform to remap absolute to relative positions.
|
2226
|
-
convertSourceMap.fromSource(rawSource) || convertSourceMap.fromMapFileSource(rawSource, this._readFileFromDir.bind(this));
|
2227
|
-
|
2228
|
-
if (this.rawSourceMap) {
|
2229
|
-
if (this.rawSourceMap.sourcemap.sources.length > 1) {
|
2230
|
-
this.sourceMap = new TraceMap(this.rawSourceMap.sourcemap);
|
2231
|
-
if (!this.sourceMap.sourcesContent) {
|
2232
|
-
this.sourceMap.sourcesContent = await this.sourcesContentFromSources();
|
2233
|
-
}
|
2234
|
-
this.covSources = this.sourceMap.sourcesContent.map((rawSource, i) => ({ source: new CovSource(rawSource, this.wrapperLength, this.excludeEmptyLines ? this.sourceMap : null), path: this.sourceMap.sources[i] }));
|
2235
|
-
this.sourceTranspiled = new CovSource(rawSource, this.wrapperLength, this.excludeEmptyLines ? this.sourceMap : null);
|
2236
|
-
} else {
|
2237
|
-
const candidatePath = this.rawSourceMap.sourcemap.sources.length >= 1 ? this.rawSourceMap.sourcemap.sources[0] : this.rawSourceMap.sourcemap.file;
|
2238
|
-
this.path = this._resolveSource(this.rawSourceMap, candidatePath || this.path);
|
2239
|
-
this.sourceMap = new TraceMap(this.rawSourceMap.sourcemap);
|
2240
|
-
|
2241
|
-
let originalRawSource;
|
2242
|
-
if (this.sources.sourceMap && this.sources.sourceMap.sourcemap && this.sources.sourceMap.sourcemap.sourcesContent && this.sources.sourceMap.sourcemap.sourcesContent.length === 1) {
|
2243
|
-
// If the sourcesContent field has been provided, return it rather than attempting
|
2244
|
-
// to load the original source from disk.
|
2245
|
-
// TODO: investigate whether there's ever a case where we hit this logic with 1:many sources.
|
2246
|
-
originalRawSource = this.sources.sourceMap.sourcemap.sourcesContent[0];
|
2247
|
-
} else if (this.sources.originalSource) {
|
2248
|
-
// Original source may be populated on the sources object.
|
2249
|
-
originalRawSource = this.sources.originalSource;
|
2250
|
-
} else if (this.sourceMap.sourcesContent && this.sourceMap.sourcesContent[0]) {
|
2251
|
-
// perhaps we loaded sourcesContent was populated by an inline source map, or .map file?
|
2252
|
-
// TODO: investigate whether there's ever a case where we hit this logic with 1:many sources.
|
2253
|
-
originalRawSource = this.sourceMap.sourcesContent[0];
|
2254
|
-
} else {
|
2255
|
-
// We fallback to reading the original source from disk.
|
2256
|
-
originalRawSource = await readFile(this.path, 'utf8');
|
2257
|
-
}
|
2258
|
-
this.covSources = [{ source: new CovSource(originalRawSource, this.wrapperLength, this.excludeEmptyLines ? this.sourceMap : null), path: this.path }];
|
2259
|
-
this.sourceTranspiled = new CovSource(rawSource, this.wrapperLength, this.excludeEmptyLines ? this.sourceMap : null);
|
2260
|
-
}
|
2261
|
-
} else {
|
2262
|
-
this.covSources = [{ source: new CovSource(rawSource, this.wrapperLength), path: this.path }];
|
2263
|
-
}
|
2264
|
-
}
|
2265
|
-
|
2266
|
-
_readFileFromDir (filename) {
|
2267
|
-
return readFileSync(resolve(dirname(this.path), filename), 'utf-8')
|
2268
|
-
}
|
2269
|
-
|
2270
|
-
async sourcesContentFromSources () {
|
2271
|
-
const fileList = this.sourceMap.sources.map(relativePath => {
|
2272
|
-
const realPath = this._resolveSource(this.rawSourceMap, relativePath);
|
2273
|
-
return readFile(realPath, 'utf-8')
|
2274
|
-
.then(result => result)
|
2275
|
-
.catch(err => {
|
2276
|
-
debuglog(`failed to load ${realPath}: ${err.message}`);
|
2277
|
-
})
|
2278
|
-
});
|
2279
|
-
return await Promise.all(fileList)
|
2280
|
-
}
|
2281
|
-
|
2282
|
-
destroy () {
|
2283
|
-
// no longer necessary, but preserved for backwards compatibility.
|
2284
|
-
}
|
2285
|
-
|
2286
|
-
_resolveSource (rawSourceMap, sourcePath) {
|
2287
|
-
if (sourcePath.startsWith('file://')) {
|
2288
|
-
return fileURLToPath(sourcePath)
|
2289
|
-
}
|
2290
|
-
sourcePath = sourcePath.replace(/^webpack:\/\//, '');
|
2291
|
-
const sourceRoot = rawSourceMap.sourcemap.sourceRoot ? rawSourceMap.sourcemap.sourceRoot.replace('file://', '') : '';
|
2292
|
-
const candidatePath = join(sourceRoot, sourcePath);
|
2293
|
-
|
2294
|
-
if (isAbsolute(candidatePath)) {
|
2295
|
-
return candidatePath
|
2296
|
-
} else {
|
2297
|
-
return resolve(dirname(this.path), candidatePath)
|
2298
|
-
}
|
2299
|
-
}
|
2300
|
-
|
2301
|
-
applyCoverage (blocks) {
|
2302
|
-
blocks.forEach(block => {
|
2303
|
-
block.ranges.forEach((range, i) => {
|
2304
|
-
const isEmptyCoverage = block.functionName === '(empty-report)';
|
2305
|
-
const { startCol, endCol, path, covSource } = this._maybeRemapStartColEndCol(range, isEmptyCoverage);
|
2306
|
-
if (this.excludePath(path)) {
|
2307
|
-
return
|
2308
|
-
}
|
2309
|
-
let lines;
|
2310
|
-
if (isEmptyCoverage) {
|
2311
|
-
// (empty-report), this will result in a report that has all lines zeroed out.
|
2312
|
-
lines = covSource.lines.filter((line) => {
|
2313
|
-
line.count = 0;
|
2314
|
-
return true
|
2315
|
-
});
|
2316
|
-
this.all = lines.length > 0;
|
2317
|
-
} else {
|
2318
|
-
lines = sliceRange(covSource.lines, startCol, endCol);
|
2319
|
-
}
|
2320
|
-
if (!lines.length) {
|
2321
|
-
return
|
2322
|
-
}
|
2323
|
-
|
2324
|
-
const startLineInstance = lines[0];
|
2325
|
-
const endLineInstance = lines[lines.length - 1];
|
2326
|
-
|
2327
|
-
if (block.isBlockCoverage) {
|
2328
|
-
this.branches[path] = this.branches[path] || [];
|
2329
|
-
// record branches.
|
2330
|
-
this.branches[path].push(new CovBranch(
|
2331
|
-
startLineInstance.line,
|
2332
|
-
startCol - startLineInstance.startCol,
|
2333
|
-
endLineInstance.line,
|
2334
|
-
endCol - endLineInstance.startCol,
|
2335
|
-
range.count
|
2336
|
-
));
|
2337
|
-
|
2338
|
-
// if block-level granularity is enabled, we still create a single
|
2339
|
-
// CovFunction tracking object for each set of ranges.
|
2340
|
-
if (block.functionName && i === 0) {
|
2341
|
-
this.functions[path] = this.functions[path] || [];
|
2342
|
-
this.functions[path].push(new CovFunction(
|
2343
|
-
block.functionName,
|
2344
|
-
startLineInstance.line,
|
2345
|
-
startCol - startLineInstance.startCol,
|
2346
|
-
endLineInstance.line,
|
2347
|
-
endCol - endLineInstance.startCol,
|
2348
|
-
range.count
|
2349
|
-
));
|
2350
|
-
}
|
2351
|
-
} else if (block.functionName) {
|
2352
|
-
this.functions[path] = this.functions[path] || [];
|
2353
|
-
// record functions.
|
2354
|
-
this.functions[path].push(new CovFunction(
|
2355
|
-
block.functionName,
|
2356
|
-
startLineInstance.line,
|
2357
|
-
startCol - startLineInstance.startCol,
|
2358
|
-
endLineInstance.line,
|
2359
|
-
endCol - endLineInstance.startCol,
|
2360
|
-
range.count
|
2361
|
-
));
|
2362
|
-
}
|
2363
|
-
|
2364
|
-
// record the lines (we record these as statements, such that we're
|
2365
|
-
// compatible with Istanbul 2.0).
|
2366
|
-
lines.forEach(line => {
|
2367
|
-
// make sure branch spans entire line; don't record 'goodbye'
|
2368
|
-
// branch in `const foo = true ? 'hello' : 'goodbye'` as a
|
2369
|
-
// 0 for line coverage.
|
2370
|
-
//
|
2371
|
-
// All lines start out with coverage of 1, and are later set to 0
|
2372
|
-
// if they are not invoked; line.ignore prevents a line from being
|
2373
|
-
// set to 0, and is set if the special comment /* c8 ignore next */
|
2374
|
-
// is used.
|
2375
|
-
|
2376
|
-
if (startCol <= line.startCol && endCol >= line.endCol && !line.ignore) {
|
2377
|
-
line.count = range.count;
|
2378
|
-
}
|
2379
|
-
});
|
2380
|
-
});
|
2381
|
-
});
|
2382
|
-
}
|
2383
|
-
|
2384
|
-
_maybeRemapStartColEndCol (range, isEmptyCoverage) {
|
2385
|
-
let covSource = this.covSources[0].source;
|
2386
|
-
const covSourceWrapperLength = isEmptyCoverage ? 0 : covSource.wrapperLength;
|
2387
|
-
let startCol = Math.max(0, range.startOffset - covSourceWrapperLength);
|
2388
|
-
let endCol = Math.min(covSource.eof, range.endOffset - covSourceWrapperLength);
|
2389
|
-
let path = this.path;
|
2390
|
-
|
2391
|
-
if (this.sourceMap) {
|
2392
|
-
const sourceTranspiledWrapperLength = isEmptyCoverage ? 0 : this.sourceTranspiled.wrapperLength;
|
2393
|
-
startCol = Math.max(0, range.startOffset - sourceTranspiledWrapperLength);
|
2394
|
-
endCol = Math.min(this.sourceTranspiled.eof, range.endOffset - sourceTranspiledWrapperLength);
|
2395
|
-
|
2396
|
-
const { startLine, relStartCol, endLine, relEndCol, source } = this.sourceTranspiled.offsetToOriginalRelative(
|
2397
|
-
this.sourceMap,
|
2398
|
-
startCol,
|
2399
|
-
endCol
|
2400
|
-
);
|
2401
|
-
|
2402
|
-
const matchingSource = this.covSources.find(covSource => covSource.path === source);
|
2403
|
-
covSource = matchingSource ? matchingSource.source : this.covSources[0].source;
|
2404
|
-
path = matchingSource ? matchingSource.path : this.covSources[0].path;
|
2405
|
-
|
2406
|
-
// next we convert these relative positions back to absolute positions
|
2407
|
-
// in the original source (which is the format expected in the next step).
|
2408
|
-
startCol = covSource.relativeToOffset(startLine, relStartCol);
|
2409
|
-
endCol = covSource.relativeToOffset(endLine, relEndCol);
|
2410
|
-
}
|
2411
|
-
|
2412
|
-
return {
|
2413
|
-
path,
|
2414
|
-
covSource,
|
2415
|
-
startCol,
|
2416
|
-
endCol
|
2417
|
-
}
|
2418
|
-
}
|
2419
|
-
|
2420
|
-
getInnerIstanbul (source, path) {
|
2421
|
-
// We apply the "Resolving Sources" logic (as defined in
|
2422
|
-
// sourcemaps.info/spec.html) as a final step for 1:many source maps.
|
2423
|
-
// for 1:1 source maps, the resolve logic is applied while loading.
|
2424
|
-
//
|
2425
|
-
// TODO: could we move the resolving logic for 1:1 source maps to the final
|
2426
|
-
// step as well? currently this breaks some tests in c8.
|
2427
|
-
let resolvedPath = path;
|
2428
|
-
if (this.rawSourceMap && this.rawSourceMap.sourcemap.sources.length > 1) {
|
2429
|
-
resolvedPath = this._resolveSource(this.rawSourceMap, path);
|
2430
|
-
}
|
2431
|
-
|
2432
|
-
if (this.excludePath(resolvedPath)) {
|
2433
|
-
return
|
2434
|
-
}
|
2435
|
-
|
2436
|
-
return {
|
2437
|
-
[resolvedPath]: {
|
2438
|
-
path: resolvedPath,
|
2439
|
-
all: this.all,
|
2440
|
-
...this._statementsToIstanbul(source, path),
|
2441
|
-
...this._branchesToIstanbul(source, path),
|
2442
|
-
...this._functionsToIstanbul(source, path)
|
2443
|
-
}
|
2444
|
-
}
|
2445
|
-
}
|
2446
|
-
|
2447
|
-
toIstanbul () {
|
2448
|
-
return this.covSources.reduce((istanbulOuter, { source, path }) => Object.assign(istanbulOuter, this.getInnerIstanbul(source, path)), {})
|
2449
|
-
}
|
2450
|
-
|
2451
|
-
_statementsToIstanbul (source, path) {
|
2452
|
-
const statements = {
|
2453
|
-
statementMap: {},
|
2454
|
-
s: {}
|
2455
|
-
};
|
2456
|
-
source.lines.forEach((line, index) => {
|
2457
|
-
if (!line.ignore) {
|
2458
|
-
statements.statementMap[`${index}`] = line.toIstanbul();
|
2459
|
-
statements.s[`${index}`] = line.count;
|
2460
|
-
}
|
2461
|
-
});
|
2462
|
-
return statements
|
2463
|
-
}
|
2464
|
-
|
2465
|
-
_branchesToIstanbul (source, path) {
|
2466
|
-
const branches = {
|
2467
|
-
branchMap: {},
|
2468
|
-
b: {}
|
2469
|
-
};
|
2470
|
-
this.branches[path] = this.branches[path] || [];
|
2471
|
-
this.branches[path].forEach((branch, index) => {
|
2472
|
-
const srcLine = source.lines[branch.startLine - 1];
|
2473
|
-
const ignore = srcLine === undefined ? true : srcLine.ignore;
|
2474
|
-
branches.branchMap[`${index}`] = branch.toIstanbul();
|
2475
|
-
branches.b[`${index}`] = [ignore ? 1 : branch.count];
|
2476
|
-
});
|
2477
|
-
return branches
|
2478
|
-
}
|
2479
|
-
|
2480
|
-
_functionsToIstanbul (source, path) {
|
2481
|
-
const functions = {
|
2482
|
-
fnMap: {},
|
2483
|
-
f: {}
|
2484
|
-
};
|
2485
|
-
this.functions[path] = this.functions[path] || [];
|
2486
|
-
this.functions[path].forEach((fn, index) => {
|
2487
|
-
const srcLine = source.lines[fn.startLine - 1];
|
2488
|
-
const ignore = srcLine === undefined ? true : srcLine.ignore;
|
2489
|
-
functions.fnMap[`${index}`] = fn.toIstanbul();
|
2490
|
-
functions.f[`${index}`] = ignore ? 1 : fn.count;
|
2491
|
-
});
|
2492
|
-
return functions
|
2493
|
-
}
|
2494
|
-
};
|
2495
|
-
|
2496
|
-
function parsePath (scriptPath) {
|
2497
|
-
return scriptPath.startsWith('file://') ? fileURLToPath(scriptPath) : scriptPath
|
2498
|
-
}
|
2499
|
-
return v8ToIstanbul$2;
|
2500
|
-
}
|
2501
|
-
|
2502
|
-
var v8ToIstanbul$1;
|
2503
|
-
var hasRequiredV8ToIstanbul;
|
2504
|
-
|
2505
|
-
function requireV8ToIstanbul () {
|
2506
|
-
if (hasRequiredV8ToIstanbul) return v8ToIstanbul$1;
|
2507
|
-
hasRequiredV8ToIstanbul = 1;
|
2508
|
-
// Patch applied: https://github.com/istanbuljs/v8-to-istanbul/pull/244
|
2509
|
-
const V8ToIstanbul = requireV8ToIstanbul$1();
|
2510
|
-
|
2511
|
-
v8ToIstanbul$1 = function (path, wrapperLength, sources, excludePath, excludeEmptyLines) {
|
2512
|
-
return new V8ToIstanbul(path, wrapperLength, sources, excludePath, excludeEmptyLines)
|
2513
|
-
};
|
2514
|
-
return v8ToIstanbul$1;
|
2515
|
-
}
|
2516
|
-
|
2517
|
-
var v8ToIstanbulExports = requireV8ToIstanbul();
|
2518
|
-
var v8ToIstanbul = /*@__PURE__*/getDefaultExportFromCjs(v8ToIstanbulExports);
|
2519
|
-
|
2520
120
|
const isWindows = process.platform === "win32";
|
2521
121
|
const drive = isWindows ? process.cwd()[0] : null;
|
2522
122
|
drive ? drive === drive.toUpperCase() ? drive.toLowerCase() : drive.toUpperCase() : null;
|
@@ -2541,27 +141,15 @@ new Set([
|
|
2541
141
|
"wasi"
|
2542
142
|
]);
|
2543
143
|
|
2544
|
-
var version = "
|
144
|
+
var version = "4.0.0-beta.1";
|
2545
145
|
|
2546
|
-
// Note that this needs to match the line ending as well
|
2547
|
-
const VITE_EXPORTS_LINE_PATTERN = /Object\.defineProperty\(__vite_ssr_exports__.*\n/g;
|
2548
|
-
const DECORATOR_METADATA_PATTERN = /_ts_metadata\("design:paramtypes", \[[^\]]*\]\),*/g;
|
2549
146
|
const FILE_PROTOCOL = "file://";
|
2550
147
|
const debug = createDebug("vitest:coverage");
|
2551
148
|
class V8CoverageProvider extends BaseCoverageProvider {
|
2552
149
|
name = "v8";
|
2553
150
|
version = version;
|
2554
|
-
testExclude;
|
2555
151
|
initialize(ctx) {
|
2556
152
|
this._initialize(ctx);
|
2557
|
-
this.testExclude = new TestExclude({
|
2558
|
-
cwd: ctx.config.root,
|
2559
|
-
include: this.options.include,
|
2560
|
-
exclude: this.options.exclude,
|
2561
|
-
excludeNodeModules: true,
|
2562
|
-
extension: this.options.extension,
|
2563
|
-
relativePath: !this.options.allowExternal
|
2564
|
-
});
|
2565
153
|
}
|
2566
154
|
createCoverageMap() {
|
2567
155
|
return libCoverage.createCoverageMap({});
|
@@ -2593,13 +181,13 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2593
181
|
});
|
2594
182
|
// Include untested files when all tests were run (not a single file re-run)
|
2595
183
|
// or if previous results are preserved by "cleanOnRerun: false"
|
2596
|
-
if (this.options.
|
184
|
+
if (this.options.include != null && (allTestsRun || !this.options.cleanOnRerun)) {
|
2597
185
|
const coveredFiles = coverageMap.files();
|
2598
|
-
const untestedCoverage = await this.
|
186
|
+
const untestedCoverage = await this.getCoverageMapForUncoveredFiles(coveredFiles);
|
2599
187
|
coverageMap.merge(await transformCoverage(untestedCoverage));
|
2600
188
|
}
|
2601
189
|
if (this.options.excludeAfterRemap) {
|
2602
|
-
coverageMap.filter((filename) => this.
|
190
|
+
coverageMap.filter((filename) => this.isIncluded(filename));
|
2603
191
|
}
|
2604
192
|
if (debug.enabled) {
|
2605
193
|
debug(`Generate coverage total time ${(performance.now() - start).toFixed()} ms`);
|
@@ -2633,15 +221,10 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2633
221
|
async parseConfigModule(configFilePath) {
|
2634
222
|
return parseModule(await promises.readFile(configFilePath, "utf8"));
|
2635
223
|
}
|
2636
|
-
async
|
224
|
+
async getCoverageMapForUncoveredFiles(testedFiles) {
|
2637
225
|
const transformResults = normalizeTransformResults(this.ctx.vitenode.fetchCache);
|
2638
226
|
const transform = this.createUncoveredFileTransformer(this.ctx);
|
2639
|
-
const
|
2640
|
-
let includedFiles = allFiles.map((file) => resolve(this.ctx.config.root, file));
|
2641
|
-
if (this.ctx.config.changed) {
|
2642
|
-
includedFiles = (this.ctx.config.related || []).filter((file) => includedFiles.includes(file));
|
2643
|
-
}
|
2644
|
-
const uncoveredFiles = includedFiles.map((file) => pathToFileURL(file)).filter((file) => !testedFiles.includes(file.pathname));
|
227
|
+
const uncoveredFiles = await this.getUntestedFiles(testedFiles);
|
2645
228
|
let index = 0;
|
2646
229
|
const coverageMap = this.createCoverageMap();
|
2647
230
|
for (const chunk of this.toSlices(uncoveredFiles, this.options.processingConcurrency)) {
|
@@ -2654,86 +237,73 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2654
237
|
let start;
|
2655
238
|
if (debug.enabled) {
|
2656
239
|
start = performance.now();
|
2657
|
-
timeout = setTimeout(() => debug(c.bgRed(`File "${filename
|
240
|
+
timeout = setTimeout(() => debug(c.bgRed(`File "${filename}" is taking longer than 3s`)), 3e3);
|
2658
241
|
}
|
2659
|
-
const
|
2660
|
-
|
2661
|
-
|
2662
|
-
startOffset: 0,
|
2663
|
-
endOffset: sources.originalSource.length,
|
2664
|
-
count: 0
|
2665
|
-
}],
|
2666
|
-
isBlockCoverage: true,
|
2667
|
-
functionName: "(empty-report)"
|
2668
|
-
}]));
|
242
|
+
const url = pathToFileURL(filename);
|
243
|
+
const sources = await this.getSources(url.href, transformResults, transform);
|
244
|
+
coverageMap.merge(await this.remapCoverage(url.href, 0, sources, []));
|
2669
245
|
if (debug.enabled) {
|
2670
246
|
clearTimeout(timeout);
|
2671
247
|
const diff = performance.now() - start;
|
2672
248
|
const color = diff > 500 ? c.bgRed : c.bgGreen;
|
2673
|
-
debug(`${color(` ${diff.toFixed()} ms `)} ${filename
|
249
|
+
debug(`${color(` ${diff.toFixed()} ms `)} ${filename}`);
|
2674
250
|
}
|
2675
251
|
}));
|
2676
252
|
}
|
2677
253
|
return coverageMap;
|
2678
254
|
}
|
2679
|
-
async
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2683
|
-
|
2684
|
-
}
|
2685
|
-
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
return "ignore-this-and-nested-nodes";
|
2716
|
-
}
|
2717
|
-
// Web
|
2718
|
-
if (node.test.object.type === "MetaProperty" && node.test.object.meta.name === "import" && node.test.object.property.name === "meta") {
|
2719
|
-
return "ignore-this-and-nested-nodes";
|
2720
|
-
}
|
255
|
+
async remapCoverage(filename, wrapperLength, result, functions) {
|
256
|
+
let ast;
|
257
|
+
try {
|
258
|
+
ast = await parseAstAsync(result.code);
|
259
|
+
} catch (error) {
|
260
|
+
this.ctx.logger.error(`Failed to parse ${filename}. Excluding it from coverage.\n`, error);
|
261
|
+
return {};
|
262
|
+
}
|
263
|
+
return await astV8ToIstanbul({
|
264
|
+
code: result.code,
|
265
|
+
sourceMap: result.map,
|
266
|
+
ast,
|
267
|
+
coverage: {
|
268
|
+
functions,
|
269
|
+
url: filename
|
270
|
+
},
|
271
|
+
ignoreClassMethods: this.options.ignoreClassMethods,
|
272
|
+
wrapperLength,
|
273
|
+
ignoreNode: (node, type) => {
|
274
|
+
// SSR transformed imports
|
275
|
+
if (type === "statement" && node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.id.name.startsWith("__vite_ssr_import_")) {
|
276
|
+
return true;
|
277
|
+
}
|
278
|
+
// SSR transformed exports vite@>6.3.5
|
279
|
+
if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && node.expression.left.type === "MemberExpression" && node.expression.left.object.type === "Identifier" && node.expression.left.object.name === "__vite_ssr_exports__") {
|
280
|
+
return true;
|
281
|
+
}
|
282
|
+
// SSR transformed exports vite@^6.3.5
|
283
|
+
if (type === "statement" && node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.id.name === "__vite_ssr_export_default__") {
|
284
|
+
return true;
|
285
|
+
}
|
286
|
+
// in-source test with "if (import.meta.vitest)"
|
287
|
+
if ((type === "branch" || type === "statement") && node.type === "IfStatement" && node.test.type === "MemberExpression" && node.test.property.type === "Identifier" && node.test.property.name === "vitest") {
|
288
|
+
// SSR
|
289
|
+
if (node.test.object.type === "Identifier" && node.test.object.name === "__vite_ssr_import_meta__") {
|
290
|
+
return "ignore-this-and-nested-nodes";
|
2721
291
|
}
|
2722
|
-
//
|
2723
|
-
if (
|
2724
|
-
return
|
292
|
+
// Web
|
293
|
+
if (node.test.object.type === "MetaProperty" && node.test.object.meta.name === "import" && node.test.object.property.name === "meta") {
|
294
|
+
return "ignore-this-and-nested-nodes";
|
2725
295
|
}
|
2726
296
|
}
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
297
|
+
// Browser mode's "import.meta.env ="
|
298
|
+
if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && node.expression.left.type === "MemberExpression" && node.expression.left.object.type === "MetaProperty" && node.expression.left.object.meta.name === "import" && node.expression.left.object.property.name === "meta" && node.expression.left.property.type === "Identifier" && node.expression.left.property.name === "env") {
|
299
|
+
return true;
|
300
|
+
}
|
301
|
+
// SWC's decorators
|
302
|
+
if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" && node.expression.callee.name === "_ts_decorate") {
|
303
|
+
return "ignore-this-and-nested-nodes";
|
304
|
+
}
|
305
|
+
}
|
306
|
+
});
|
2737
307
|
}
|
2738
308
|
async getSources(url, transformResults, onTransform, functions = []) {
|
2739
309
|
const filePath = normalize(fileURLToPath(url));
|
@@ -2743,35 +313,26 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2743
313
|
}
|
2744
314
|
const map = transformResult?.map;
|
2745
315
|
const code = transformResult?.code;
|
2746
|
-
|
2747
|
-
|
2748
|
-
sourcesContent[0] = await promises.readFile(filePath, "utf-8").catch(() => {
|
316
|
+
if (!code) {
|
317
|
+
const original = await promises.readFile(filePath, "utf-8").catch(() => {
|
2749
318
|
// If file does not exist construct a dummy source for it.
|
2750
319
|
// These can be files that were generated dynamically during the test run and were removed after it.
|
2751
320
|
const length = findLongestFunctionLength(functions);
|
2752
321
|
return "/".repeat(length);
|
2753
322
|
});
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
if (sources.length === 0) {
|
2764
|
-
sources.push(url);
|
323
|
+
return { code: original };
|
324
|
+
}
|
325
|
+
// Vue needs special handling for "map.sources"
|
326
|
+
if (map) {
|
327
|
+
map.sources ||= [];
|
328
|
+
map.sources = map.sources.filter((source) => source != null).map((source) => new URL(source, url).href);
|
329
|
+
if (map.sources.length === 0) {
|
330
|
+
map.sources.push(url);
|
331
|
+
}
|
2765
332
|
}
|
2766
333
|
return {
|
2767
|
-
|
2768
|
-
|
2769
|
-
sourceMap: { sourcemap: excludeGeneratedCode(code, {
|
2770
|
-
...map,
|
2771
|
-
version: 3,
|
2772
|
-
sources,
|
2773
|
-
sourcesContent
|
2774
|
-
}) }
|
334
|
+
code,
|
335
|
+
map
|
2775
336
|
};
|
2776
337
|
}
|
2777
338
|
async convertCoverage(coverage, project = this.ctx.getRootProject(), transformMode) {
|
@@ -2803,7 +364,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2803
364
|
result.url = `${FILE_PROTOCOL}${project.config.root}${result.url}`;
|
2804
365
|
}
|
2805
366
|
}
|
2806
|
-
if (this.
|
367
|
+
if (this.isIncluded(fileURLToPath(result.url))) {
|
2807
368
|
scriptCoverages.push(result);
|
2808
369
|
}
|
2809
370
|
}
|
@@ -2822,7 +383,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2822
383
|
timeout = setTimeout(() => debug(c.bgRed(`File "${fileURLToPath(url)}" is taking longer than 3s`)), 3e3);
|
2823
384
|
}
|
2824
385
|
const sources = await this.getSources(url, transformResults, onTransform, functions);
|
2825
|
-
coverageMap.merge(await this.
|
386
|
+
coverageMap.merge(await this.remapCoverage(url, startOffset, sources, functions));
|
2826
387
|
if (debug.enabled) {
|
2827
388
|
clearTimeout(timeout);
|
2828
389
|
const diff = performance.now() - start;
|
@@ -2839,29 +400,6 @@ async function transformCoverage(coverageMap) {
|
|
2839
400
|
return await sourceMapStore.transformCoverage(coverageMap);
|
2840
401
|
}
|
2841
402
|
/**
|
2842
|
-
* Remove generated code from the source maps:
|
2843
|
-
* - Vite's export helpers: e.g. `Object.defineProperty(__vite_ssr_exports__, "sum", { enumerable: true, configurable: true, get(){ return sum }});`
|
2844
|
-
* - SWC's decorator metadata: e.g. `_ts_metadata("design:paramtypes", [\ntypeof Request === "undefined" ? Object : Request\n]),`
|
2845
|
-
*/
|
2846
|
-
function excludeGeneratedCode(source, map) {
|
2847
|
-
if (!source) {
|
2848
|
-
return map;
|
2849
|
-
}
|
2850
|
-
if (!source.match(VITE_EXPORTS_LINE_PATTERN) && !source.match(DECORATOR_METADATA_PATTERN)) {
|
2851
|
-
return map;
|
2852
|
-
}
|
2853
|
-
const trimmed = new MagicString(source);
|
2854
|
-
trimmed.replaceAll(VITE_EXPORTS_LINE_PATTERN, "\n");
|
2855
|
-
trimmed.replaceAll(DECORATOR_METADATA_PATTERN, (match) => "\n".repeat(match.split("\n").length - 1));
|
2856
|
-
const trimmedMap = trimmed.generateMap({ hires: "boundary" });
|
2857
|
-
// A merged source map where the first one excludes generated parts
|
2858
|
-
const combinedMap = remapping([{
|
2859
|
-
...trimmedMap,
|
2860
|
-
version: 3
|
2861
|
-
}, map], () => null);
|
2862
|
-
return combinedMap;
|
2863
|
-
}
|
2864
|
-
/**
|
2865
403
|
* Find the function with highest `endOffset` to determine the length of the file
|
2866
404
|
*/
|
2867
405
|
function findLongestFunctionLength(functions) {
|