lighthouse 13.5.0-dev.20261006 → 13.5.0-dev.20261007
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/core/lib/legacy-javascript/legacy-javascript.d.ts +1 -0
- package/core/lib/legacy-javascript/legacy-javascript.js +234 -110
- package/core/lib/legacy-javascript/polyfill-graph-data.json +94 -89
- package/core/lib/legacy-javascript/polyfill-module-data.json +48 -7
- package/core/lib/minification-estimator.js +10 -10
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* ./core/scripts/legacy-javascript - verification tool.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
/** @typedef {{name: string, expression: string, estimateBytes?: (content: string) => number}} Pattern */
|
|
14
|
+
/** @typedef {{name: string, expression: string, estimateBytes?: (content: string) => number, resolveName?: (match: string) => string}} Pattern */
|
|
15
15
|
/** @typedef {{name: string, line: number, column: number}} PatternMatchResult */
|
|
16
16
|
/** @typedef {{matches: PatternMatchResult[], estimatedByteSavings: number}} Result */
|
|
17
17
|
|
|
@@ -27,7 +27,7 @@ const graph = graph_;
|
|
|
27
27
|
/**
|
|
28
28
|
* Takes a list of patterns (consisting of a name identifier and a RegExp expression string)
|
|
29
29
|
* and via `match` returns match results with line / column information for a given code input.
|
|
30
|
-
* Only returns the first match per pattern
|
|
30
|
+
* Only returns the first match per pattern name.
|
|
31
31
|
*/
|
|
32
32
|
class CodePatternMatcher {
|
|
33
33
|
/**
|
|
@@ -45,12 +45,13 @@ class CodePatternMatcher {
|
|
|
45
45
|
if (!this.re) {
|
|
46
46
|
const patternsExpression =
|
|
47
47
|
this.patterns.map(pattern => `(${pattern.expression})`).join('|');
|
|
48
|
-
this.re = new RegExp(
|
|
48
|
+
this.re = new RegExp(patternsExpression, 'g');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// Reset RegExp state.
|
|
52
52
|
this.re.lastIndex = 0;
|
|
53
53
|
|
|
54
|
+
/** @type {Set<string>} */
|
|
54
55
|
const seen = new Set();
|
|
55
56
|
/** @type {PatternMatchResult[]} */
|
|
56
57
|
const matches = [];
|
|
@@ -58,29 +59,41 @@ class CodePatternMatcher {
|
|
|
58
59
|
let result;
|
|
59
60
|
let line = 0;
|
|
60
61
|
let lineBeginsAtIndex = 0;
|
|
62
|
+
let scannedToIndex = 0;
|
|
61
63
|
// Each pattern maps to one subgroup in the generated regex. For each iteration of RegExp.exec,
|
|
62
64
|
// only one subgroup will be defined. Exec until no more matches.
|
|
63
65
|
while ((result = this.re.exec(code)) !== null) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (isNewline) {
|
|
71
|
-
line++;
|
|
72
|
-
lineBeginsAtIndex = result.index + 1;
|
|
73
|
-
continue;
|
|
66
|
+
let patternIndex = -1;
|
|
67
|
+
for (let i = 1; i < result.length; i++) {
|
|
68
|
+
if (result[i] !== undefined) {
|
|
69
|
+
patternIndex = i - 1;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
74
72
|
}
|
|
75
|
-
|
|
73
|
+
if (patternIndex === -1) continue;
|
|
76
74
|
|
|
77
|
-
|
|
75
|
+
const pattern = this.patterns[patternIndex];
|
|
76
|
+
const name = pattern.resolveName ? pattern.resolveName(result[0]) : pattern.name;
|
|
77
|
+
if (seen.has(name)) {
|
|
78
78
|
continue;
|
|
79
79
|
}
|
|
80
|
-
seen.add(
|
|
80
|
+
seen.add(name);
|
|
81
|
+
|
|
82
|
+
// Lazily advance line and column tracking up to `result.index`.
|
|
83
|
+
// Because `[scannedToIndex, result.index)` includes the text of any previous matches,
|
|
84
|
+
// this also accounts for newlines inside multi-line matches.
|
|
85
|
+
// Scanning for `\n` handles both LF (`\n`) and CRLF (`\r\n`) line endings since
|
|
86
|
+
// the next line always begins at `nlIdx + 1`.
|
|
87
|
+
let nlIdx = code.indexOf('\n', scannedToIndex);
|
|
88
|
+
while (nlIdx !== -1 && nlIdx < result.index) {
|
|
89
|
+
line++;
|
|
90
|
+
lineBeginsAtIndex = nlIdx + 1;
|
|
91
|
+
nlIdx = code.indexOf('\n', lineBeginsAtIndex);
|
|
92
|
+
}
|
|
93
|
+
scannedToIndex = result.index;
|
|
81
94
|
|
|
82
95
|
matches.push({
|
|
83
|
-
name
|
|
96
|
+
name,
|
|
84
97
|
line,
|
|
85
98
|
column: result.index - lineBeginsAtIndex,
|
|
86
99
|
});
|
|
@@ -90,70 +103,6 @@ class CodePatternMatcher {
|
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
105
|
|
|
93
|
-
/**
|
|
94
|
-
* @param {string?} object
|
|
95
|
-
* @param {string} property
|
|
96
|
-
* @param {string} coreJs3Module
|
|
97
|
-
*/
|
|
98
|
-
function buildPolyfillExpression(object, property, coreJs3Module) {
|
|
99
|
-
const qt = (/** @type {string} */ token) =>
|
|
100
|
-
`['"]${token}['"]`; // don't worry about matching string delims
|
|
101
|
-
|
|
102
|
-
let expression = '';
|
|
103
|
-
|
|
104
|
-
if (object) {
|
|
105
|
-
// String.prototype.startsWith =
|
|
106
|
-
expression += `${object}\\.${property}\\s?=[^=]`;
|
|
107
|
-
} else {
|
|
108
|
-
// Promise =
|
|
109
|
-
// window.Promise =// Promise =Z
|
|
110
|
-
// but not: SomePromise =
|
|
111
|
-
expression += `(?:window\\.|[\\s;]+)${property}\\s?=[^=]`;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// String.prototype['startsWith'] =
|
|
115
|
-
if (object) {
|
|
116
|
-
expression += `|${object}\\[${qt(property)}\\]\\s?=[^=]`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Object.defineProperty(String.prototype, 'startsWith'
|
|
120
|
-
expression += `|defineProperty\\(${object || 'window'},\\s?${qt(property)}`;
|
|
121
|
-
|
|
122
|
-
// es-shims
|
|
123
|
-
// no(Object,{entries:r},{entries:function
|
|
124
|
-
if (object) {
|
|
125
|
-
expression += `|\\(${object},\\s*{${property}:.*},\\s*{${property}`;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// core-js
|
|
129
|
-
if (object) {
|
|
130
|
-
const objectWithoutPrototype = object.replace('.prototype', '');
|
|
131
|
-
// e(e.S,"Object",{values
|
|
132
|
-
// Minified + mangled pattern found in CDN babel-polyfill.
|
|
133
|
-
// see https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.min.js
|
|
134
|
-
// TODO: perhaps this is the wrong place to check for a CDN polyfill. Remove?
|
|
135
|
-
// expression += `|;e\\([^,]+,${qt(objectWithoutPrototype)},{${property}:`;
|
|
136
|
-
|
|
137
|
-
// core-js@3 minified pattern.
|
|
138
|
-
// {target:"Array",proto:true},{fill:fill
|
|
139
|
-
// {target:"Array",proto:true,forced:!HAS_SPECIES_SUPPORT||!USES_TO_LENGTH},{filter:
|
|
140
|
-
expression += `|{target:${qt(objectWithoutPrototype)}[^;]*},{${property}:`;
|
|
141
|
-
} else {
|
|
142
|
-
// Detect polyfills for new classes: Map, Set, WeakSet, etc.
|
|
143
|
-
// TODO: so far, no class polyfills are enabled for detection.
|
|
144
|
-
// See `modulesToSkip` in create-polyfill-module-data.js
|
|
145
|
-
|
|
146
|
-
// collection("Map",
|
|
147
|
-
// expression += `|collection\\(${qt(property)},`;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Un-minified code may have module names.
|
|
151
|
-
// core-js/modules/es.object.is-frozen
|
|
152
|
-
expression += `|${coreJs3Module.replaceAll('.', '\\.')}(?:\\.js)?"`;
|
|
153
|
-
|
|
154
|
-
return expression;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
106
|
function getCoreJsPolyfillData() {
|
|
158
107
|
return polyfillModuleData.filter(d => d.corejs).map(d => {
|
|
159
108
|
return {
|
|
@@ -164,34 +113,171 @@ function getCoreJsPolyfillData() {
|
|
|
164
113
|
}
|
|
165
114
|
|
|
166
115
|
/**
|
|
116
|
+
* Builds factored polyfill patterns grouped by receiver object, core-js target, and
|
|
117
|
+
* core-js module prefix so the regex engine evaluates a few shared branches instead
|
|
118
|
+
* of repeating common prefixes (like `defineProperty(`, `{target:`, `Array.prototype.`)
|
|
119
|
+
* once per polyfill.
|
|
120
|
+
*
|
|
167
121
|
* @return {Pattern[]}
|
|
168
122
|
*/
|
|
169
123
|
function getPolyfillPatterns() {
|
|
170
|
-
/** @
|
|
171
|
-
const
|
|
124
|
+
/** @param {string} str */
|
|
125
|
+
const escapeRegExp = str => str.replaceAll('.', '\\.');
|
|
126
|
+
|
|
127
|
+
/** @type {Map<string, string[]>} */
|
|
128
|
+
const byObject = new Map();
|
|
129
|
+
/** @type {Map<string, string[]>} */
|
|
130
|
+
const byTarget = new Map();
|
|
131
|
+
/** @type {Map<string, string>} */
|
|
132
|
+
const targetPropToName = new Map();
|
|
133
|
+
/** @type {Map<string, string>} */
|
|
134
|
+
const coreJsModuleToName = new Map();
|
|
135
|
+
/** @type {Map<string, string[]>} */
|
|
136
|
+
const byModulePrefix = new Map();
|
|
172
137
|
|
|
173
138
|
for (const {name, coreJs3Module} of getCoreJsPolyfillData()) {
|
|
174
139
|
const parts = name.split('.');
|
|
175
|
-
const object = parts.
|
|
140
|
+
const object = parts.slice(0, parts.length - 1).join('.');
|
|
176
141
|
const property = parts[parts.length - 1];
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
142
|
+
|
|
143
|
+
let objProps = byObject.get(object);
|
|
144
|
+
if (!objProps) {
|
|
145
|
+
objProps = [];
|
|
146
|
+
byObject.set(object, objProps);
|
|
147
|
+
}
|
|
148
|
+
objProps.push(property);
|
|
149
|
+
|
|
150
|
+
const target = object.replace('.prototype', '');
|
|
151
|
+
let targetProps = byTarget.get(target);
|
|
152
|
+
if (!targetProps) {
|
|
153
|
+
targetProps = [];
|
|
154
|
+
byTarget.set(target, targetProps);
|
|
155
|
+
}
|
|
156
|
+
targetProps.push(property);
|
|
157
|
+
targetPropToName.set(`${target}.${property}`, name);
|
|
158
|
+
|
|
159
|
+
coreJsModuleToName.set(coreJs3Module, name);
|
|
160
|
+
const modParts = coreJs3Module.split('.');
|
|
161
|
+
const modPrefix = modParts.slice(0, 2).join('.');
|
|
162
|
+
const modRest = modParts.slice(2).join('.');
|
|
163
|
+
let modRests = byModulePrefix.get(modPrefix);
|
|
164
|
+
if (!modRests) {
|
|
165
|
+
modRests = [];
|
|
166
|
+
byModulePrefix.set(modPrefix, modRests);
|
|
167
|
+
}
|
|
168
|
+
modRests.push(modRest);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 1. Direct property assignment: `String.prototype.startsWith =`
|
|
172
|
+
const directBranches = [];
|
|
173
|
+
for (const [object, props] of byObject) {
|
|
174
|
+
directBranches.push(`${escapeRegExp(object)}\\.(?:${props.join('|')})\\s?=[^=]`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 2. Bracket property assignment: `String.prototype['startsWith'] =`
|
|
178
|
+
const bracketBranches = [];
|
|
179
|
+
for (const [object, props] of byObject) {
|
|
180
|
+
bracketBranches.push(`${escapeRegExp(object)}\\[['"](?:${props.join('|')})['"]\\]\\s?=[^=]`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// 3. Object.defineProperty: `Object.defineProperty(String.prototype, 'startsWith'`
|
|
184
|
+
const definePropBranches = [];
|
|
185
|
+
for (const [object, props] of byObject) {
|
|
186
|
+
definePropBranches.push(`${escapeRegExp(object)},\\s?['"](?:${props.join('|')})['"]`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 4. es-shims: `no(Object,{entries:r},{entries:function`
|
|
190
|
+
const esShimsBranches = [];
|
|
191
|
+
for (const [object, props] of byObject) {
|
|
192
|
+
const propAlt = `(?:${props.join('|')})`;
|
|
193
|
+
esShimsBranches.push(`${escapeRegExp(object)},\\s*{${propAlt}:.*},\\s*{${propAlt}`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 5. core-js@3 minified pattern:
|
|
197
|
+
// `{target:"Array",proto:true},{fill:fill`
|
|
198
|
+
// `{target:"Array",proto:true,forced:!HAS_SPECIES_SUPPORT||!USES_TO_LENGTH},{filter:`
|
|
199
|
+
const targetBranches = [];
|
|
200
|
+
for (const [target, props] of byTarget) {
|
|
201
|
+
targetBranches.push(`['"]${escapeRegExp(target)}['"][^;]*?},{(?:${props.join('|')}):`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// 6. Un-minified core-js module names: `core-js/modules/es.object.is-frozen`
|
|
205
|
+
const moduleBranches = [];
|
|
206
|
+
for (const [prefix, rests] of byModulePrefix) {
|
|
207
|
+
moduleBranches.push(
|
|
208
|
+
`${escapeRegExp(prefix)}\\.(?:${rests.map(escapeRegExp).join('|')})`
|
|
209
|
+
);
|
|
181
210
|
}
|
|
182
211
|
|
|
183
|
-
return
|
|
212
|
+
return [
|
|
213
|
+
{
|
|
214
|
+
name: 'direct-assignment',
|
|
215
|
+
expression: directBranches.join('|'),
|
|
216
|
+
resolveName: match => match.slice(0, match.indexOf('=')).trimEnd(),
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'bracket-assignment',
|
|
220
|
+
expression: bracketBranches.join('|'),
|
|
221
|
+
resolveName: match => {
|
|
222
|
+
const bracketIdx = match.indexOf('[');
|
|
223
|
+
const closeIdx = match.indexOf(']', bracketIdx);
|
|
224
|
+
return `${match.slice(0, bracketIdx)}.${match.slice(bracketIdx + 2, closeIdx - 1)}`;
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
name: 'defineProperty',
|
|
229
|
+
expression: `defineProperty\\((?:${definePropBranches.join('|')})`,
|
|
230
|
+
resolveName: match => {
|
|
231
|
+
const openIdx = match.indexOf('(');
|
|
232
|
+
const commaIdx = match.indexOf(',', openIdx);
|
|
233
|
+
const obj = match.slice(openIdx + 1, commaIdx);
|
|
234
|
+
const prop = match.slice(commaIdx + 1).trimStart().slice(1, -1);
|
|
235
|
+
return `${obj}.${prop}`;
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: 'es-shims',
|
|
240
|
+
expression: `\\((?:${esShimsBranches.join('|')})`,
|
|
241
|
+
resolveName: match => {
|
|
242
|
+
const commaIdx = match.indexOf(',');
|
|
243
|
+
const obj = match.slice(1, commaIdx);
|
|
244
|
+
const braceIdx = match.indexOf('{', commaIdx);
|
|
245
|
+
const colonIdx = match.indexOf(':', braceIdx);
|
|
246
|
+
const prop = match.slice(braceIdx + 1, colonIdx);
|
|
247
|
+
return `${obj}.${prop}`;
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'core-js-target',
|
|
252
|
+
expression: `{target:(?:${targetBranches.join('|')})`,
|
|
253
|
+
resolveName: match => {
|
|
254
|
+
const targetEnd = match.indexOf(match[8], 9);
|
|
255
|
+
const target = match.slice(9, targetEnd);
|
|
256
|
+
const lastBrace = match.lastIndexOf('{');
|
|
257
|
+
const prop = match.slice(lastBrace + 1, -1);
|
|
258
|
+
return /** @type {string} */ (targetPropToName.get(`${target}.${prop}`));
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'core-js-module',
|
|
263
|
+
expression: `(?:${moduleBranches.join('|')})(?:\\.js)?"`,
|
|
264
|
+
resolveName: match => {
|
|
265
|
+
const mod = match.endsWith('.js"') ? match.slice(0, -4) : match.slice(0, -1);
|
|
266
|
+
return /** @type {string} */ (coreJsModuleToName.get(mod));
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
];
|
|
184
270
|
}
|
|
185
271
|
|
|
186
272
|
/**
|
|
187
273
|
* @return {Pattern[]}
|
|
188
274
|
*/
|
|
189
275
|
function getTransformPatterns() {
|
|
190
|
-
/**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
276
|
+
/**
|
|
277
|
+
* @param {string} content
|
|
278
|
+
* @param {RegExp|string} pattern
|
|
279
|
+
* @return {number}
|
|
280
|
+
*/
|
|
195
281
|
const count = (content, pattern) => {
|
|
196
282
|
// Split is slightly faster than match.
|
|
197
283
|
if (typeof pattern === 'string') {
|
|
@@ -259,6 +345,17 @@ function getTransformPatterns() {
|
|
|
259
345
|
];
|
|
260
346
|
}
|
|
261
347
|
|
|
348
|
+
const transformPatterns = getTransformPatterns();
|
|
349
|
+
const transformPatternsByName = new Map(transformPatterns.map(p => [p.name, p]));
|
|
350
|
+
|
|
351
|
+
/** @type {Map<string, string>} */
|
|
352
|
+
const moduleToPolyfillName = new Map();
|
|
353
|
+
for (const {name, modules} of polyfillModuleData) {
|
|
354
|
+
for (const mod of modules) {
|
|
355
|
+
moduleToPolyfillName.set(mod, name);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
262
359
|
/**
|
|
263
360
|
* @param {string} content
|
|
264
361
|
* @param {PatternMatchResult[]} matches
|
|
@@ -287,7 +384,7 @@ function estimateWastedBytes(content, matches) {
|
|
|
287
384
|
let estimatedWastedBytesFromTransforms = 0;
|
|
288
385
|
|
|
289
386
|
for (const result of transformResults) {
|
|
290
|
-
const pattern =
|
|
387
|
+
const pattern = transformPatternsByName.get(result.name);
|
|
291
388
|
if (!pattern || !pattern.estimateBytes || !content) continue;
|
|
292
389
|
estimatedWastedBytesFromTransforms += pattern.estimateBytes(content);
|
|
293
390
|
}
|
|
@@ -299,7 +396,7 @@ function estimateWastedBytes(content, matches) {
|
|
|
299
396
|
|
|
300
397
|
const matcher = new CodePatternMatcher([
|
|
301
398
|
...getPolyfillPatterns(),
|
|
302
|
-
...
|
|
399
|
+
...transformPatterns,
|
|
303
400
|
]);
|
|
304
401
|
|
|
305
402
|
/**
|
|
@@ -315,20 +412,47 @@ function detectLegacyJavaScript(content, map) {
|
|
|
315
412
|
|
|
316
413
|
// If it's a bundle with source maps, add in the polyfill modules by name too.
|
|
317
414
|
if (map) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
415
|
+
const matchedNames = new Set(matches.map(m => m.name));
|
|
416
|
+
/** @type {Array<{name: string, source: string}>} */
|
|
417
|
+
const foundInMap = [];
|
|
418
|
+
|
|
419
|
+
for (const source of map.sourceURLs()) {
|
|
420
|
+
if (source.endsWith('.js')) {
|
|
421
|
+
const slashIdx = source.lastIndexOf('/');
|
|
422
|
+
if (slashIdx !== -1) {
|
|
423
|
+
const polyfillName = moduleToPolyfillName.get(source.slice(slashIdx + 1, -3));
|
|
424
|
+
if (polyfillName && !matchedNames.has(polyfillName)) {
|
|
425
|
+
matchedNames.add(polyfillName);
|
|
426
|
+
foundInMap.push({name: polyfillName, source});
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (source.includes('node_modules/')) {
|
|
431
|
+
let nmIdx = source.indexOf('node_modules/');
|
|
432
|
+
while (nmIdx !== -1) {
|
|
433
|
+
const modStart = nmIdx + 13; // 'node_modules/'.length
|
|
434
|
+
const nextSlash = source.indexOf('/', modStart);
|
|
435
|
+
if (nextSlash !== -1) {
|
|
436
|
+
const polyfillName = moduleToPolyfillName.get(source.slice(modStart, nextSlash));
|
|
437
|
+
if (polyfillName && !matchedNames.has(polyfillName)) {
|
|
438
|
+
matchedNames.add(polyfillName);
|
|
439
|
+
foundInMap.push({name: polyfillName, source});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
nmIdx = source.indexOf('node_modules/', modStart);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (foundInMap.length > 0) {
|
|
448
|
+
const mappings = map.mappings();
|
|
449
|
+
for (const {name, source} of foundInMap) {
|
|
450
|
+
const mapping = mappings.find(m => m.sourceURL === source);
|
|
451
|
+
if (mapping) {
|
|
452
|
+
matches.push({name, line: mapping.lineNumber, column: mapping.columnNumber});
|
|
453
|
+
} else {
|
|
454
|
+
matches.push({name, line: 0, column: 0});
|
|
455
|
+
}
|
|
332
456
|
}
|
|
333
457
|
}
|
|
334
458
|
}
|
|
@@ -1,93 +1,98 @@
|
|
|
1
1
|
{
|
|
2
|
-
"moduleSizes": [
|
|
2
|
+
"moduleSizes": [26175, 498, 282, 294, 281, 467, 164, 236, 229, 765, 555, 339, 300, 1977, 723, 729, 1547, 438, 214, 657, 111, 759, 537, 209, 281, 685, 217, 757, 631, 293, 182, 475, 79, 407, 140, 366, 792, 269, 222, 158, 280, 192, 137, 158, 105, 189, 543, 160, 742, 1436, 88, 978, 146, 314, 375, 183, 1083, 195, 503, 269, 208, 334, 233, 350, 580, 491, 229, 1155, 334, 266, 30, 120, 309, 370, 358, 1952, 1638, 304, 153, 274, 1288, 192, 543, 74, 144, 137, 33, 336, 457, 2219, 535, 711, 1323, 64, 117, 1961, 244, 557, 318, 119, 173, 108, 144, 96, 133, 441, 210, 1627, 1956, 693, 1426, 863, 637, 301, 51, 708, 583, 119, 600, 221, 370, 728, 1085, 552, 629, 125, 1746, 97, 441, 543, 2931, 767, 371, 588, 548, 243, 266, 217, 99, 440, 183, 607, 180, 464, 207, 983, 530, 237, 382, 249, 675, 402, 254, 223, 164, 214, 191, 831, 218, 202, 232, 124, 250, 160, 251, 217, 717, 78, 561, 1696, 256, 386, 225, 432, 499, 394, 364, 445, 625, 680, 177, 346, 663, 142, 588, 414, 686, 1628, 380, 2580, 558, 783, 1410, 1040, 417, 433, 266, 263, 214, 303, 163, 141, 510, 397, 137, 137, 133, 133, 390, 266, 137, 183, 215, 191, 485, 328, 575, 799, 533, 148, 215, 589, 589, 130, 362, 562, 471, 179, 186, 1266, 1456, 366, 521, 1536, 511, 444, 406, 1053, 150, 283, 144, 485, 470, 205, 1268, 796, 658, 595, 306, 3750, 814, 146, 2298, 1226, 881, 1144, 237, 206, 198, 250, 283, 60, 3000],
|
|
3
3
|
"dependencies": {
|
|
4
|
-
"Array.prototype.at": [0, 5,
|
|
5
|
-
"Array.prototype.concat": [0,
|
|
6
|
-
"Array.prototype.copyWithin": [0, 5, 9,
|
|
7
|
-
"Array.prototype.every": [0,
|
|
8
|
-
"Array.prototype.fill": [0, 5, 10,
|
|
9
|
-
"Array.prototype.filter": [0,
|
|
10
|
-
"Array.prototype.find": [0, 5,
|
|
11
|
-
"Array.prototype.findIndex": [0, 5,
|
|
12
|
-
"Array.prototype.findLast": [0, 5,
|
|
13
|
-
"Array.prototype.findLastIndex": [0, 5,
|
|
14
|
-
"Array.prototype.flat": [0,
|
|
15
|
-
"Array.prototype.flatMap": [0,
|
|
16
|
-
"Array.prototype.forEach": [0, 11,
|
|
17
|
-
"Array.from": [0,
|
|
18
|
-
"Array.prototype.
|
|
19
|
-
"Array.
|
|
20
|
-
"Array.
|
|
21
|
-
"Array.prototype.
|
|
22
|
-
"Array.
|
|
23
|
-
"Array.
|
|
24
|
-
"Array.prototype.
|
|
25
|
-
"Array.prototype.
|
|
26
|
-
"Array.prototype.
|
|
27
|
-
"Array.prototype.
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"Math.
|
|
31
|
-
"Math.
|
|
32
|
-
"Math.
|
|
33
|
-
"Math.
|
|
34
|
-
"Math.
|
|
35
|
-
"Math.
|
|
36
|
-
"Math.
|
|
37
|
-
"Math.
|
|
38
|
-
"Math.
|
|
39
|
-
"Math.
|
|
40
|
-
"Math.
|
|
41
|
-
"Math.
|
|
42
|
-
"Math.
|
|
43
|
-
"Math.
|
|
44
|
-
"Math.
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"Object.
|
|
48
|
-
"Object.
|
|
49
|
-
"Object.
|
|
50
|
-
"Object.
|
|
51
|
-
"Object.
|
|
52
|
-
"Object.
|
|
53
|
-
"Object.
|
|
54
|
-
"Object.
|
|
55
|
-
"Object.
|
|
56
|
-
"Object.
|
|
57
|
-
"Object.
|
|
58
|
-
"Object.
|
|
59
|
-
"Object.
|
|
60
|
-
"Object.
|
|
61
|
-
"Object.
|
|
62
|
-
"Object.
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"Reflect.
|
|
68
|
-
"Reflect.
|
|
69
|
-
"Reflect.
|
|
70
|
-
"Reflect.
|
|
71
|
-
"Reflect.
|
|
72
|
-
"Reflect.
|
|
73
|
-
"Reflect.
|
|
74
|
-
"Reflect.
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"String.prototype.
|
|
79
|
-
"String.prototype.
|
|
80
|
-
"String.
|
|
81
|
-
"String.prototype.
|
|
82
|
-
"String.prototype.
|
|
83
|
-
"String.prototype.
|
|
84
|
-
"String.
|
|
85
|
-
"String.prototype.
|
|
86
|
-
"String.prototype.
|
|
87
|
-
"String.prototype.
|
|
88
|
-
"String.prototype.
|
|
89
|
-
"
|
|
90
|
-
"
|
|
4
|
+
"Array.prototype.at": [0, 5, 71, 108, 109, 119, 168],
|
|
5
|
+
"Array.prototype.concat": [0, 17, 19, 22, 23, 27, 35, 41, 78, 80, 159, 169],
|
|
6
|
+
"Array.prototype.copyWithin": [0, 5, 9, 38, 71, 108, 109, 119, 170],
|
|
7
|
+
"Array.prototype.every": [0, 16, 18, 22, 23, 27, 35, 54, 60, 78, 80, 159, 171],
|
|
8
|
+
"Array.prototype.fill": [0, 5, 10, 71, 108, 109, 119, 172],
|
|
9
|
+
"Array.prototype.filter": [0, 16, 17, 22, 23, 27, 35, 54, 60, 78, 80, 159, 173],
|
|
10
|
+
"Array.prototype.find": [0, 5, 16, 22, 23, 27, 35, 54, 60, 71, 78, 80, 108, 109, 119, 159, 177],
|
|
11
|
+
"Array.prototype.findIndex": [0, 5, 16, 22, 23, 27, 35, 54, 60, 71, 78, 80, 108, 109, 119, 159, 174],
|
|
12
|
+
"Array.prototype.findLast": [0, 5, 15, 54, 60, 71, 108, 109, 119, 176],
|
|
13
|
+
"Array.prototype.findLastIndex": [0, 5, 15, 54, 60, 71, 108, 109, 119, 175],
|
|
14
|
+
"Array.prototype.flat": [0, 22, 23, 27, 35, 41, 51, 54, 60, 78, 80, 159, 179],
|
|
15
|
+
"Array.prototype.flatMap": [0, 22, 23, 27, 35, 41, 51, 54, 60, 78, 80, 159, 178],
|
|
16
|
+
"Array.prototype.forEach": [0, 11, 16, 18, 22, 23, 27, 35, 54, 60, 78, 80, 159, 180],
|
|
17
|
+
"Array.from": [0, 13, 19, 24, 25, 27, 35, 41, 54, 60, 64, 65, 77, 78, 80, 90, 93, 159, 181],
|
|
18
|
+
"Array.prototype.indexOf": [0, 18, 60, 182],
|
|
19
|
+
"Array.isArray": [0, 78, 183],
|
|
20
|
+
"Array.prototype.join": [0, 18, 184],
|
|
21
|
+
"Array.prototype.map": [0, 16, 17, 22, 23, 27, 35, 54, 60, 78, 80, 159, 185],
|
|
22
|
+
"Array.of": [0, 19, 27, 35, 78, 80, 159, 186],
|
|
23
|
+
"Array.prototype.slice": [0, 17, 19, 20, 27, 35, 78, 80, 159, 187],
|
|
24
|
+
"Array.prototype.some": [0, 16, 18, 22, 23, 27, 35, 54, 60, 78, 80, 159, 188],
|
|
25
|
+
"Array.prototype.sort": [0, 18, 20, 21, 27, 38, 43, 44, 47, 159, 160, 189],
|
|
26
|
+
"Array.prototype.toReversed": [0, 5, 35, 71, 108, 109, 119, 190],
|
|
27
|
+
"Array.prototype.toSorted": [0, 5, 12, 62, 71, 108, 109, 119, 191],
|
|
28
|
+
"Array.prototype.toSpliced": [0, 5, 35, 41, 71, 108, 109, 119, 192],
|
|
29
|
+
"Array.prototype.unshift": [0, 19, 38, 41, 78, 193],
|
|
30
|
+
"Math.acosh": [0, 100, 194],
|
|
31
|
+
"Math.asinh": [0, 100, 195],
|
|
32
|
+
"Math.atanh": [0, 100, 196],
|
|
33
|
+
"Math.cbrt": [0, 103, 197],
|
|
34
|
+
"Math.clz32": [0, 198],
|
|
35
|
+
"Math.cosh": [0, 96, 199],
|
|
36
|
+
"Math.expm1": [0, 96, 200],
|
|
37
|
+
"Math.fround": [0, 97, 98, 102, 103, 201],
|
|
38
|
+
"Math.hypot": [0, 202],
|
|
39
|
+
"Math.imul": [0, 203],
|
|
40
|
+
"Math.log10": [0, 99, 204],
|
|
41
|
+
"Math.log1p": [0, 100, 205],
|
|
42
|
+
"Math.log2": [0, 101, 206],
|
|
43
|
+
"Math.sign": [0, 103, 207],
|
|
44
|
+
"Math.sinh": [0, 96, 208],
|
|
45
|
+
"Math.tanh": [0, 96, 209],
|
|
46
|
+
"Math.trunc": [0, 210],
|
|
47
|
+
"Object.assign": [0, 107, 119, 211],
|
|
48
|
+
"Object.create": [0, 71, 108, 109, 119, 212],
|
|
49
|
+
"Object.entries": [0, 30, 115, 119, 122, 213],
|
|
50
|
+
"Object.freeze": [0, 8, 20, 52, 75, 112, 116, 214],
|
|
51
|
+
"Object.fromEntries": [0, 35, 54, 60, 64, 65, 77, 89, 90, 93, 215],
|
|
52
|
+
"Object.getOwnPropertyDescriptor": [0, 216],
|
|
53
|
+
"Object.getOwnPropertyDescriptors": [0, 35, 217],
|
|
54
|
+
"Object.getPrototypeOf": [0, 30, 115, 218],
|
|
55
|
+
"Object.hasOwn": [0, 219],
|
|
56
|
+
"Object.is": [0, 138, 223],
|
|
57
|
+
"Object.isExtensible": [0, 8, 116, 220],
|
|
58
|
+
"Object.isFrozen": [0, 8, 221],
|
|
59
|
+
"Object.isSealed": [0, 8, 222],
|
|
60
|
+
"Object.keys": [0, 119, 224],
|
|
61
|
+
"Object.preventExtensions": [0, 8, 20, 52, 75, 112, 116, 225],
|
|
62
|
+
"Object.seal": [0, 8, 20, 52, 75, 112, 116, 226],
|
|
63
|
+
"Object.setPrototypeOf": [0, 4, 59, 85, 121, 227],
|
|
64
|
+
"Object.values": [0, 30, 115, 119, 122, 228],
|
|
65
|
+
"Promise.any": [0, 25, 48, 54, 60, 64, 65, 77, 89, 90, 93, 105, 125, 126, 127, 128, 230],
|
|
66
|
+
"Promise.withResolvers": [0, 105, 231],
|
|
67
|
+
"Reflect.apply": [0, 53, 232],
|
|
68
|
+
"Reflect.construct": [0, 3, 20, 27, 53, 56, 71, 80, 108, 109, 119, 159, 233],
|
|
69
|
+
"Reflect.deleteProperty": [0, 234],
|
|
70
|
+
"Reflect.get": [0, 30, 81, 115, 237],
|
|
71
|
+
"Reflect.getOwnPropertyDescriptor": [0, 235],
|
|
72
|
+
"Reflect.getPrototypeOf": [0, 30, 115, 236],
|
|
73
|
+
"Reflect.has": [0, 238],
|
|
74
|
+
"Reflect.isExtensible": [0, 8, 116, 239],
|
|
75
|
+
"Reflect.ownKeys": [0, 240],
|
|
76
|
+
"Reflect.preventExtensions": [0, 52, 241],
|
|
77
|
+
"Reflect.setPrototypeOf": [0, 4, 59, 85, 121, 242],
|
|
78
|
+
"String.prototype.codePointAt": [0, 27, 145, 159, 160, 243],
|
|
79
|
+
"String.prototype.endsWith": [0, 27, 29, 60, 87, 106, 159, 160, 244],
|
|
80
|
+
"String.fromCodePoint": [0, 245],
|
|
81
|
+
"String.prototype.includes": [0, 27, 29, 87, 106, 159, 160, 246],
|
|
82
|
+
"String.prototype.isWellFormed": [0, 27, 159, 160, 247],
|
|
83
|
+
"String.prototype.matchAll": [0, 3, 6, 27, 30, 32, 60, 71, 80, 87, 91, 92, 93, 108, 109, 115, 119, 129, 130, 131, 132, 133, 134, 135, 136, 139, 143, 145, 159, 160, 249],
|
|
84
|
+
"String.raw": [0, 27, 159, 160, 250],
|
|
85
|
+
"String.prototype.repeat": [0, 27, 146, 159, 160, 251],
|
|
86
|
+
"String.prototype.replaceAll": [0, 27, 67, 87, 131, 132, 133, 159, 160, 252],
|
|
87
|
+
"String.prototype.startsWith": [0, 27, 29, 60, 87, 106, 159, 160, 253],
|
|
88
|
+
"String.prototype.substr": [0, 27, 159, 160, 254],
|
|
89
|
+
"String.prototype.toWellFormed": [0, 27, 159, 160, 255],
|
|
90
|
+
"String.prototype.trim": [0, 27, 148, 150, 159, 160, 167, 260],
|
|
91
|
+
"String.prototype.trimEnd": [0, 27, 147, 148, 150, 159, 160, 167, 256, 258],
|
|
92
|
+
"String.prototype.trimStart": [0, 27, 148, 149, 150, 159, 160, 167, 257, 259],
|
|
93
|
+
"String.prototype.link": [0, 27, 31, 144, 159, 160, 248],
|
|
94
|
+
"Promise.allSettled": [0, 25, 48, 54, 60, 64, 65, 77, 89, 90, 93, 105, 125, 126, 127, 128, 229, 261],
|
|
95
|
+
"focus-visible": [262]
|
|
91
96
|
},
|
|
92
|
-
"maxSize":
|
|
97
|
+
"maxSize": 163427
|
|
93
98
|
}
|
|
@@ -112,13 +112,6 @@
|
|
|
112
112
|
],
|
|
113
113
|
"corejs": true
|
|
114
114
|
},
|
|
115
|
-
{
|
|
116
|
-
"name": "Array.prototype.includes",
|
|
117
|
-
"modules": [
|
|
118
|
-
"es.array.includes"
|
|
119
|
-
],
|
|
120
|
-
"corejs": true
|
|
121
|
-
},
|
|
122
115
|
{
|
|
123
116
|
"name": "Array.prototype.indexOf",
|
|
124
117
|
"modules": [
|
|
@@ -175,6 +168,30 @@
|
|
|
175
168
|
],
|
|
176
169
|
"corejs": true
|
|
177
170
|
},
|
|
171
|
+
{
|
|
172
|
+
"name": "Array.prototype.toReversed",
|
|
173
|
+
"modules": [
|
|
174
|
+
"es.array.to-reversed",
|
|
175
|
+
"esnext.array.to-reversed"
|
|
176
|
+
],
|
|
177
|
+
"corejs": true
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "Array.prototype.toSorted",
|
|
181
|
+
"modules": [
|
|
182
|
+
"es.array.to-sorted",
|
|
183
|
+
"esnext.array.to-sorted"
|
|
184
|
+
],
|
|
185
|
+
"corejs": true
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"name": "Array.prototype.toSpliced",
|
|
189
|
+
"modules": [
|
|
190
|
+
"es.array.to-spliced",
|
|
191
|
+
"esnext.array.to-spliced"
|
|
192
|
+
],
|
|
193
|
+
"corejs": true
|
|
194
|
+
},
|
|
178
195
|
{
|
|
179
196
|
"name": "Array.prototype.unshift",
|
|
180
197
|
"modules": [
|
|
@@ -436,6 +453,14 @@
|
|
|
436
453
|
],
|
|
437
454
|
"corejs": true
|
|
438
455
|
},
|
|
456
|
+
{
|
|
457
|
+
"name": "Promise.withResolvers",
|
|
458
|
+
"modules": [
|
|
459
|
+
"es.promise.with-resolvers",
|
|
460
|
+
"esnext.promise.with-resolvers"
|
|
461
|
+
],
|
|
462
|
+
"corejs": true
|
|
463
|
+
},
|
|
439
464
|
{
|
|
440
465
|
"name": "Reflect.apply",
|
|
441
466
|
"modules": [
|
|
@@ -541,6 +566,14 @@
|
|
|
541
566
|
],
|
|
542
567
|
"corejs": true
|
|
543
568
|
},
|
|
569
|
+
{
|
|
570
|
+
"name": "String.prototype.isWellFormed",
|
|
571
|
+
"modules": [
|
|
572
|
+
"es.string.is-well-formed",
|
|
573
|
+
"esnext.string.is-well-formed"
|
|
574
|
+
],
|
|
575
|
+
"corejs": true
|
|
576
|
+
},
|
|
544
577
|
{
|
|
545
578
|
"name": "String.prototype.matchAll",
|
|
546
579
|
"modules": [
|
|
@@ -585,6 +618,14 @@
|
|
|
585
618
|
],
|
|
586
619
|
"corejs": true
|
|
587
620
|
},
|
|
621
|
+
{
|
|
622
|
+
"name": "String.prototype.toWellFormed",
|
|
623
|
+
"modules": [
|
|
624
|
+
"es.string.to-well-formed",
|
|
625
|
+
"esnext.string.to-well-formed"
|
|
626
|
+
],
|
|
627
|
+
"corejs": true
|
|
628
|
+
},
|
|
588
629
|
{
|
|
589
630
|
"name": "String.prototype.trim",
|
|
590
631
|
"modules": [
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-punctuators
|
|
8
8
|
// eslint-disable-next-line max-len
|
|
9
9
|
const PUNCTUATOR_REGEX = /(return|case|else|{|\(|\[|\.\.\.|;|,|<|>|<=|>=|==|!=|===|!==|\+|-|\*|%|\*\*|\+\+|--|<<|>>|>>>|&|\||\^|!|~|&&|\|\||\?|:|=|\+=|-=|\*=|%=|\*\*=|<<=|>>=|>>>=|&=|\|=|\^=|=>|\/|\/=|\})$/;
|
|
10
|
-
const WHITESPACE_REGEX = /( |\n|\t)+$/;
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Look backwards from `startPosition` in `content` for an ECMAScript punctuator.
|
|
@@ -19,11 +18,13 @@ const WHITESPACE_REGEX = /( |\n|\t)+$/;
|
|
|
19
18
|
*/
|
|
20
19
|
function hasPunctuatorBefore(content, startPosition) {
|
|
21
20
|
for (let i = startPosition; i > 0; i--) {
|
|
21
|
+
const char = content[i - 1];
|
|
22
|
+
// Skip over any ending whitespace
|
|
23
|
+
if (char === ' ' || char === '\n' || char === '\t') continue;
|
|
24
|
+
|
|
22
25
|
// Try to grab at least 6 characters so we can check for `return`
|
|
23
26
|
const sliceStart = Math.max(0, i - 6);
|
|
24
27
|
const precedingCharacters = content.slice(sliceStart, i);
|
|
25
|
-
// Skip over any ending whitespace
|
|
26
|
-
if (WHITESPACE_REGEX.test(precedingCharacters)) continue;
|
|
27
28
|
// Check if it's a punctuator
|
|
28
29
|
return PUNCTUATOR_REGEX.test(precedingCharacters);
|
|
29
30
|
}
|
|
@@ -56,8 +57,7 @@ function computeTokenLength(content, features) {
|
|
|
56
57
|
const templateLiteralDepth = [];
|
|
57
58
|
|
|
58
59
|
for (let i = 0; i < content.length; i++) {
|
|
59
|
-
const
|
|
60
|
-
const char = twoChars.charAt(0);
|
|
60
|
+
const char = content[i];
|
|
61
61
|
|
|
62
62
|
const isWhitespace = char === ' ' || char === '\n' || char === '\t';
|
|
63
63
|
const isAStringOpenChar = char === `'` || char === '"' || char === '`';
|
|
@@ -71,7 +71,7 @@ function computeTokenLength(content, features) {
|
|
|
71
71
|
// License comments count
|
|
72
72
|
if (isInLicenseComment) totalTokenLength++;
|
|
73
73
|
|
|
74
|
-
if (
|
|
74
|
+
if (char === '*' && content[i + 1] === '/') {
|
|
75
75
|
// License comments count, account for the '/' character we're skipping over
|
|
76
76
|
if (isInLicenseComment) totalTokenLength++;
|
|
77
77
|
// End the comment when we hit the closing sequence
|
|
@@ -83,7 +83,7 @@ function computeTokenLength(content, features) {
|
|
|
83
83
|
// String characters count
|
|
84
84
|
totalTokenLength++;
|
|
85
85
|
|
|
86
|
-
if (stringOpenChar === '`' &&
|
|
86
|
+
if (stringOpenChar === '`' && char === '$' && content[i + 1] === '{') {
|
|
87
87
|
// Start new template literal
|
|
88
88
|
templateLiteralDepth.push('templateBrace');
|
|
89
89
|
isInString = false;
|
|
@@ -119,16 +119,16 @@ function computeTokenLength(content, features) {
|
|
|
119
119
|
}
|
|
120
120
|
} else {
|
|
121
121
|
// We're not in any particular token mode, look for the start of different
|
|
122
|
-
if (
|
|
122
|
+
if (char === '/' && content[i + 1] === '*') {
|
|
123
123
|
// Start the multi-line comment
|
|
124
124
|
isInMultilineComment = true;
|
|
125
125
|
// Check if it's a license comment so we know whether to count it
|
|
126
|
-
isInLicenseComment = content
|
|
126
|
+
isInLicenseComment = content[i + 2] === '!';
|
|
127
127
|
// += 2 because we are processing 2 characters, not just 1
|
|
128
128
|
if (isInLicenseComment) totalTokenLength += 2;
|
|
129
129
|
// Skip over the '*' character since we've already processed it
|
|
130
130
|
i++;
|
|
131
|
-
} else if (
|
|
131
|
+
} else if (char === '/' && content[i + 1] === '/' && features.singlelineComments) {
|
|
132
132
|
// Start the single-line comment
|
|
133
133
|
isInSinglelineComment = true;
|
|
134
134
|
isInMultilineComment = false;
|
package/package.json
CHANGED