webpack 5.81.0 → 5.82.0

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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (40) hide show
  1. package/bin/webpack.js +13 -2
  2. package/lib/Compilation.js +2 -0
  3. package/lib/CssModule.js +39 -7
  4. package/lib/WebpackOptionsApply.js +33 -40
  5. package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
  6. package/lib/config/defaults.js +1 -0
  7. package/lib/css/CssGenerator.js +4 -0
  8. package/lib/css/CssLoadingRuntimeModule.js +9 -2
  9. package/lib/css/CssModulesPlugin.js +136 -33
  10. package/lib/css/CssParser.js +144 -80
  11. package/lib/css/walkCssTokens.js +96 -20
  12. package/lib/debug/ProfilingPlugin.js +2 -0
  13. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +1 -0
  14. package/lib/javascript/BasicEvaluatedExpression.js +108 -1
  15. package/lib/javascript/JavascriptParser.js +132 -11
  16. package/lib/json/JsonData.js +25 -0
  17. package/lib/json/JsonGenerator.js +15 -3
  18. package/lib/json/JsonModulesPlugin.js +1 -0
  19. package/lib/json/JsonParser.js +2 -1
  20. package/lib/library/ModuleLibraryPlugin.js +2 -1
  21. package/lib/runtime/GetChunkFilenameRuntimeModule.js +4 -0
  22. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +22 -3
  23. package/lib/schemes/DataUriPlugin.js +4 -0
  24. package/lib/schemes/HttpUriPlugin.js +38 -0
  25. package/lib/sharing/utils.js +293 -7
  26. package/lib/stats/DefaultStatsPrinterPlugin.js +25 -0
  27. package/lib/util/StackedCacheMap.js +6 -0
  28. package/lib/util/StringXor.js +51 -0
  29. package/lib/util/compileBooleanMatcher.js +31 -0
  30. package/lib/util/deprecation.js +8 -0
  31. package/lib/util/identifier.js +4 -0
  32. package/lib/util/numberHash.js +75 -21
  33. package/lib/util/propertyAccess.js +5 -0
  34. package/lib/wasm/EnableWasmLoadingPlugin.js +4 -0
  35. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -0
  36. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  37. package/package.json +1 -1
  38. package/schemas/WebpackOptions.check.js +1 -1
  39. package/schemas/WebpackOptions.json +25 -0
  40. package/types.d.ts +121 -26
@@ -5,7 +5,9 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const ModuleDependencyWarning = require("../ModuleDependencyWarning");
8
9
  const Parser = require("../Parser");
10
+ const WebpackError = require("../WebpackError");
9
11
  const ConstDependency = require("../dependencies/ConstDependency");
10
12
  const CssExportDependency = require("../dependencies/CssExportDependency");
11
13
  const CssImportDependency = require("../dependencies/CssImportDependency");
@@ -34,6 +36,11 @@ const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/;
34
36
  const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY =
35
37
  /^(-\w+-)?animation(-name)?$/i;
36
38
 
39
+ /**
40
+ * @param {string} str url string
41
+ * @param {boolean} isString is url wrapped in quotes
42
+ * @returns {string} normalized url
43
+ */
37
44
  const normalizeUrl = (str, isString) => {
38
45
  // Remove extra spaces and newlines:
39
46
  // `url("im\
@@ -71,6 +78,9 @@ const normalizeUrl = (str, isString) => {
71
78
  };
72
79
 
73
80
  class LocConverter {
81
+ /**
82
+ * @param {string} input input
83
+ */
74
84
  constructor(input) {
75
85
  this._input = input;
76
86
  this.line = 1;
@@ -78,6 +88,10 @@ class LocConverter {
78
88
  this.pos = 0;
79
89
  }
80
90
 
91
+ /**
92
+ * @param {number} pos position
93
+ * @returns {LocConverter} location converter
94
+ */
81
95
  get(pos) {
82
96
  if (this.pos !== pos) {
83
97
  if (this.pos < pos) {
@@ -110,26 +124,8 @@ const CSS_MODE_IN_RULE = 1;
110
124
  const CSS_MODE_IN_LOCAL_RULE = 2;
111
125
  const CSS_MODE_AT_IMPORT_EXPECT_URL = 3;
112
126
  const CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA = 4;
113
- const CSS_MODE_AT_OTHER = 5;
114
-
115
- const explainMode = mode => {
116
- switch (mode) {
117
- case CSS_MODE_TOP_LEVEL:
118
- return "parsing top level css";
119
- case CSS_MODE_IN_RULE:
120
- return "parsing css rule content (global)";
121
- case CSS_MODE_IN_LOCAL_RULE:
122
- return "parsing css rule content (local)";
123
- case CSS_MODE_AT_IMPORT_EXPECT_URL:
124
- return "parsing @import (expecting url)";
125
- case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA:
126
- return "parsing @import (expecting optionally layer, supports or media query)";
127
- case CSS_MODE_AT_OTHER:
128
- return "parsing at-rule";
129
- default:
130
- return mode;
131
- }
132
- };
127
+ const CSS_MODE_AT_IMPORT_INVALID = 5;
128
+ const CSS_MODE_AT_NAMESPACE_INVALID = 6;
133
129
 
134
130
  class CssParser extends Parser {
135
131
  constructor({
@@ -143,6 +139,25 @@ class CssParser extends Parser {
143
139
  this.defaultMode = defaultMode;
144
140
  }
145
141
 
142
+ /**
143
+ * @param {ParserState} state parser state
144
+ * @param {string} message warning message
145
+ * @param {LocConverter} locConverter location converter
146
+ * @param {number} start start offset
147
+ * @param {number} end end offset
148
+ */
149
+ _emitWarning(state, message, locConverter, start, end) {
150
+ const { line: sl, column: sc } = locConverter.get(start);
151
+ const { line: el, column: ec } = locConverter.get(end);
152
+
153
+ state.current.addWarning(
154
+ new ModuleDependencyWarning(state.module, new WebpackError(message), {
155
+ start: { line: sl, column: sc },
156
+ end: { line: el, column: ec }
157
+ })
158
+ );
159
+ }
160
+
146
161
  /**
147
162
  * @param {string | Buffer | PreparsedAst} source the source to parse
148
163
  * @param {ParserState} state the parser state
@@ -163,11 +178,18 @@ class CssParser extends Parser {
163
178
  const declaredCssVariables = new Set();
164
179
 
165
180
  const locConverter = new LocConverter(source);
181
+ /** @type {number} */
166
182
  let mode = CSS_MODE_TOP_LEVEL;
183
+ /** @type {number} */
167
184
  let modeNestingLevel = 0;
185
+ /** @type {boolean} */
186
+ let allowImportAtRule = true;
168
187
  let modeData = undefined;
188
+ /** @type {string | boolean | undefined} */
169
189
  let singleClassSelector = undefined;
190
+ /** @type {[number, number] | undefined} */
170
191
  let lastIdentifier = undefined;
192
+ /** @type {boolean} */
171
193
  let awaitRightParenthesis = false;
172
194
  /** @type [string, number, number][] */
173
195
  let balanced = [];
@@ -176,18 +198,6 @@ class CssParser extends Parser {
176
198
  const isTopLevelLocal = () =>
177
199
  modeData === "local" ||
178
200
  (this.defaultMode === "local" && modeData === undefined);
179
- const eatWhiteLine = (input, pos) => {
180
- for (;;) {
181
- const cc = input.charCodeAt(pos);
182
- if (cc === 32 || cc === 9) {
183
- pos++;
184
- continue;
185
- }
186
- if (cc === 10) pos++;
187
- break;
188
- }
189
- return pos;
190
- };
191
201
  const eatUntil = chars => {
192
202
  const charCodes = Array.from({ length: chars.length }, (_, i) =>
193
203
  chars.charCodeAt(i)
@@ -238,10 +248,16 @@ class CssParser extends Parser {
238
248
  const parseExports = (input, pos) => {
239
249
  pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
240
250
  const cc = input.charCodeAt(pos);
241
- if (cc !== CC_LEFT_CURLY)
242
- throw new Error(
243
- `Unexpected ${input[pos]} at ${pos} during parsing of ':export' (expected '{')`
251
+ if (cc !== CC_LEFT_CURLY) {
252
+ this._emitWarning(
253
+ state,
254
+ `Unexpected '${input[pos]}' at ${pos} during parsing of ':export' (expected '{')`,
255
+ locConverter,
256
+ pos,
257
+ pos
244
258
  );
259
+ return pos;
260
+ }
245
261
  pos++;
246
262
  pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
247
263
  for (;;) {
@@ -253,9 +269,14 @@ class CssParser extends Parser {
253
269
  [pos, name] = eatText(input, pos, eatExportName);
254
270
  if (pos === input.length) return pos;
255
271
  if (input.charCodeAt(pos) !== CC_COLON) {
256
- throw new Error(
257
- `Unexpected ${input[pos]} at ${pos} during parsing of export name in ':export' (expected ':')`
272
+ this._emitWarning(
273
+ state,
274
+ `Unexpected '${input[pos]}' at ${pos} during parsing of export name in ':export' (expected ':')`,
275
+ locConverter,
276
+ start,
277
+ pos
258
278
  );
279
+ return pos;
259
280
  }
260
281
  pos++;
261
282
  if (pos === input.length) return pos;
@@ -271,9 +292,14 @@ class CssParser extends Parser {
271
292
  pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
272
293
  if (pos === input.length) return pos;
273
294
  } else if (cc !== CC_RIGHT_CURLY) {
274
- throw new Error(
275
- `Unexpected ${input[pos]} at ${pos} during parsing of export value in ':export' (expected ';' or '}')`
295
+ this._emitWarning(
296
+ state,
297
+ `Unexpected '${input[pos]}' at ${pos} during parsing of export value in ':export' (expected ';' or '}')`,
298
+ locConverter,
299
+ start,
300
+ pos
276
301
  );
302
+ return pos;
277
303
  }
278
304
  const dep = new CssExportDependency(name, value);
279
305
  const { line: sl, column: sc } = locConverter.get(start);
@@ -283,7 +309,7 @@ class CssParser extends Parser {
283
309
  }
284
310
  pos++;
285
311
  if (pos === input.length) return pos;
286
- pos = eatWhiteLine(input, pos);
312
+ pos = walkCssTokens.eatWhiteLine(input, pos);
287
313
  return pos;
288
314
  };
289
315
  const eatPropertyName = eatUntil(":{};");
@@ -339,14 +365,13 @@ class CssParser extends Parser {
339
365
  mode !== CSS_MODE_IN_RULE &&
340
366
  mode !== CSS_MODE_IN_LOCAL_RULE &&
341
367
  mode !== CSS_MODE_AT_IMPORT_EXPECT_URL &&
342
- mode !== CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA
368
+ mode !== CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA &&
369
+ mode !== CSS_MODE_AT_IMPORT_INVALID &&
370
+ mode !== CSS_MODE_AT_NAMESPACE_INVALID
343
371
  );
344
372
  },
345
- url: (input, start, end, contentStart, contentEnd, isString) => {
346
- let value = normalizeUrl(
347
- input.slice(contentStart, contentEnd),
348
- isString
349
- );
373
+ url: (input, start, end, contentStart, contentEnd) => {
374
+ let value = normalizeUrl(input.slice(contentStart, contentEnd), false);
350
375
  switch (mode) {
351
376
  case CSS_MODE_AT_IMPORT_EXPECT_URL: {
352
377
  modeData.url = value;
@@ -358,13 +383,14 @@ class CssParser extends Parser {
358
383
  case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
359
384
  break;
360
385
  }
386
+ // Do not parse URLs in import between rules
387
+ case CSS_MODE_AT_NAMESPACE_INVALID:
388
+ case CSS_MODE_AT_IMPORT_INVALID: {
389
+ break;
390
+ }
361
391
  default: {
362
- if (
363
- // Ignore `url(#highlight)` URLs
364
- /^#/.test(value) ||
365
- // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
366
- value.length === 0
367
- ) {
392
+ // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
393
+ if (value.length === 0) {
368
394
  break;
369
395
  }
370
396
 
@@ -408,12 +434,8 @@ class CssParser extends Parser {
408
434
  ) {
409
435
  let value = normalizeUrl(input.slice(start + 1, end - 1), true);
410
436
 
411
- if (
412
- // Ignore `url(#highlight)` URLs
413
- /^#/.test(value) ||
414
- // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
415
- value.length === 0
416
- ) {
437
+ // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
438
+ if (value.length === 0) {
417
439
  break;
418
440
  }
419
441
 
@@ -436,14 +458,28 @@ class CssParser extends Parser {
436
458
  atKeyword: (input, start, end) => {
437
459
  const name = input.slice(start, end).toLowerCase();
438
460
  if (name === "@namespace") {
439
- throw new Error("@namespace is not supported in bundled CSS");
440
- }
441
- if (name === "@import") {
442
- if (mode !== CSS_MODE_TOP_LEVEL) {
443
- throw new Error(
444
- `Unexpected @import at ${start} during ${explainMode(mode)}`
461
+ mode = CSS_MODE_AT_NAMESPACE_INVALID;
462
+ this._emitWarning(
463
+ state,
464
+ "@namespace is not supported in bundled CSS",
465
+ locConverter,
466
+ start,
467
+ end
468
+ );
469
+ return end;
470
+ } else if (name === "@import") {
471
+ if (!allowImportAtRule) {
472
+ mode = CSS_MODE_AT_IMPORT_INVALID;
473
+ this._emitWarning(
474
+ state,
475
+ "Any @import rules must precede all other rules",
476
+ locConverter,
477
+ start,
478
+ end
445
479
  );
480
+ return end;
446
481
  }
482
+
447
483
  mode = CSS_MODE_AT_IMPORT_EXPECT_URL;
448
484
  modeData = {
449
485
  atRuleStart: start,
@@ -453,37 +489,50 @@ class CssParser extends Parser {
453
489
  supports: undefined,
454
490
  media: undefined
455
491
  };
456
- }
457
- if (OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name)) {
492
+ } else if (
493
+ isTopLevelLocal() &&
494
+ OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name)
495
+ ) {
458
496
  let pos = end;
459
497
  pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
460
498
  if (pos === input.length) return pos;
461
499
  const [newPos, name] = eatText(input, pos, eatKeyframes);
500
+ if (newPos === input.length) return newPos;
501
+ if (input.charCodeAt(newPos) !== CC_LEFT_CURLY) {
502
+ this._emitWarning(
503
+ state,
504
+ `Unexpected '${input[newPos]}' at ${newPos} during parsing of @keyframes (expected '{')`,
505
+ locConverter,
506
+ start,
507
+ end
508
+ );
509
+
510
+ return newPos;
511
+ }
462
512
  const { line: sl, column: sc } = locConverter.get(pos);
463
513
  const { line: el, column: ec } = locConverter.get(newPos);
464
514
  const dep = new CssLocalIdentifierDependency(name, [pos, newPos]);
465
515
  dep.setLoc(sl, sc, el, ec);
466
516
  module.addDependency(dep);
467
517
  pos = newPos;
468
- if (pos === input.length) return pos;
469
- if (input.charCodeAt(pos) !== CC_LEFT_CURLY) {
470
- throw new Error(
471
- `Unexpected ${input[pos]} at ${pos} during parsing of @keyframes (expected '{')`
472
- );
473
- }
474
518
  mode = CSS_MODE_IN_LOCAL_RULE;
475
519
  modeNestingLevel = 1;
476
520
  return pos + 1;
477
- }
478
- if (name === "@media" || name === "@supports") {
521
+ } else if (name === "@media" || name === "@supports") {
522
+ // TODO handle nested CSS syntax
479
523
  let pos = end;
480
524
  const [newPos] = eatText(input, pos, eatAtRuleNested);
481
525
  pos = newPos;
482
526
  if (pos === input.length) return pos;
483
527
  if (input.charCodeAt(pos) !== CC_LEFT_CURLY) {
484
- throw new Error(
485
- `Unexpected ${input[pos]} at ${pos} during parsing of @media or @supports (expected '{')`
528
+ this._emitWarning(
529
+ state,
530
+ `Unexpected ${input[pos]} at ${pos} during parsing of @media or @supports (expected '{')`,
531
+ locConverter,
532
+ start,
533
+ pos
486
534
  );
535
+ return pos;
487
536
  }
488
537
  return pos + 1;
489
538
  }
@@ -491,15 +540,29 @@ class CssParser extends Parser {
491
540
  },
492
541
  semicolon: (input, start, end) => {
493
542
  switch (mode) {
494
- case CSS_MODE_AT_IMPORT_EXPECT_URL:
495
- throw new Error(`Expected URL for @import at ${start}`);
543
+ case CSS_MODE_AT_IMPORT_EXPECT_URL: {
544
+ this._emitWarning(
545
+ state,
546
+ `Expected URL for @import at ${start}`,
547
+ locConverter,
548
+ start,
549
+ end
550
+ );
551
+ return end;
552
+ }
496
553
  case CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA: {
497
554
  if (modeData.url === undefined) {
498
- throw new Error(
499
- `Expected URL for @import at ${modeData.atRuleStart}`
555
+ this._emitWarning(
556
+ state,
557
+ `Expected URL for @import at ${modeData.atRuleStart}`,
558
+ locConverter,
559
+ modeData.atRuleStart,
560
+ modeData.lastPos
500
561
  );
562
+ return end;
501
563
  }
502
564
  const semicolonPos = end;
565
+ end = walkCssTokens.eatWhiteLine(input, end + 1);
503
566
  const { line: sl, column: sc } = locConverter.get(
504
567
  modeData.atRuleStart
505
568
  );
@@ -545,6 +608,7 @@ class CssParser extends Parser {
545
608
  leftCurlyBracket: (input, start, end) => {
546
609
  switch (mode) {
547
610
  case CSS_MODE_TOP_LEVEL:
611
+ allowImportAtRule = false;
548
612
  mode = isTopLevelLocal()
549
613
  ? CSS_MODE_IN_LOCAL_RULE
550
614
  : CSS_MODE_IN_RULE;
@@ -76,6 +76,10 @@ const CC_HYPHEN_MINUS = "-".charCodeAt(0);
76
76
  const CC_LESS_THAN_SIGN = "<".charCodeAt(0);
77
77
  const CC_GREATER_THAN_SIGN = ">".charCodeAt(0);
78
78
 
79
+ /**
80
+ * @param {number} cc char code
81
+ * @returns {boolean} true, if cc is a newline
82
+ */
79
83
  const _isNewLine = cc => {
80
84
  return (
81
85
  cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED
@@ -84,6 +88,7 @@ const _isNewLine = cc => {
84
88
 
85
89
  /** @type {CharHandler} */
86
90
  const consumeSpace = (input, pos, callbacks) => {
91
+ /** @type {number} */
87
92
  let cc;
88
93
  do {
89
94
  pos++;
@@ -92,16 +97,36 @@ const consumeSpace = (input, pos, callbacks) => {
92
97
  return pos;
93
98
  };
94
99
 
95
- const _isWhiteSpace = cc => {
100
+ /**
101
+ * @param {number} cc char code
102
+ * @returns {boolean} true, if cc is a newline
103
+ */
104
+ const _isNewline = cc => {
96
105
  return (
97
- cc === CC_LINE_FEED ||
98
- cc === CC_CARRIAGE_RETURN ||
99
- cc === CC_FORM_FEED ||
100
- cc === CC_TAB ||
101
- cc === CC_SPACE
106
+ cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED
102
107
  );
103
108
  };
104
109
 
110
+ /**
111
+ * @param {number} cc char code
112
+ * @returns {boolean} true, if cc is a space (U+0009 CHARACTER TABULATION or U+0020 SPACE)
113
+ */
114
+ const _isSpace = cc => {
115
+ return cc === CC_TAB || cc === CC_SPACE;
116
+ };
117
+
118
+ /**
119
+ * @param {number} cc char code
120
+ * @returns {boolean} true, if cc is a whitespace
121
+ */
122
+ const _isWhiteSpace = cc => {
123
+ return _isNewline(cc) || _isSpace(cc);
124
+ };
125
+
126
+ /**
127
+ * @param {number} cc char code
128
+ * @returns {boolean} true, if cc is a start code point of an identifier
129
+ */
105
130
  const _isIdentStartCodePoint = cc => {
106
131
  return (
107
132
  (cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
@@ -145,21 +170,27 @@ const consumeComments = (input, pos, callbacks) => {
145
170
  };
146
171
 
147
172
  /** @type {function(number): CharHandler} */
148
- const consumeString = end => (input, pos, callbacks) => {
173
+ const consumeString = quote_cc => (input, pos, callbacks) => {
149
174
  const start = pos;
150
- pos = _consumeString(input, pos, end);
175
+ pos = _consumeString(input, pos, quote_cc);
151
176
  if (callbacks.string !== undefined) {
152
177
  pos = callbacks.string(input, start, pos);
153
178
  }
154
179
  return pos;
155
180
  };
156
181
 
157
- const _consumeString = (input, pos, end) => {
182
+ /**
183
+ * @param {string} input input
184
+ * @param {number} pos position
185
+ * @param {number} quote_cc quote char code
186
+ * @returns {number} new position
187
+ */
188
+ const _consumeString = (input, pos, quote_cc) => {
158
189
  pos++;
159
190
  for (;;) {
160
191
  if (pos === input.length) return pos;
161
192
  const cc = input.charCodeAt(pos);
162
- if (cc === end) return pos + 1;
193
+ if (cc === quote_cc) return pos + 1;
163
194
  if (_isNewLine(cc)) {
164
195
  // bad string
165
196
  return pos;
@@ -176,6 +207,10 @@ const _consumeString = (input, pos, end) => {
176
207
  }
177
208
  };
178
209
 
210
+ /**
211
+ * @param {number} cc char code
212
+ * @returns {boolean} is identifier start code
213
+ */
179
214
  const _isIdentifierStartCode = cc => {
180
215
  return (
181
216
  cc === CC_LOW_LINE ||
@@ -185,16 +220,30 @@ const _isIdentifierStartCode = cc => {
185
220
  );
186
221
  };
187
222
 
223
+ /**
224
+ * @param {number} first first code point
225
+ * @param {number} second second code point
226
+ * @returns {boolean} true if two code points are a valid escape
227
+ */
188
228
  const _isTwoCodePointsAreValidEscape = (first, second) => {
189
229
  if (first !== CC_REVERSE_SOLIDUS) return false;
190
230
  if (_isNewLine(second)) return false;
191
231
  return true;
192
232
  };
193
233
 
234
+ /**
235
+ * @param {number} cc char code
236
+ * @returns {boolean} is digit
237
+ */
194
238
  const _isDigit = cc => {
195
239
  return cc >= CC_0 && cc <= CC_9;
196
240
  };
197
241
 
242
+ /**
243
+ * @param {string} input input
244
+ * @param {number} pos position
245
+ * @returns {boolean} true, if input at pos starts an identifier
246
+ */
198
247
  const _startsIdentifier = (input, pos) => {
199
248
  const cc = input.charCodeAt(pos);
200
249
  if (cc === CC_HYPHEN_MINUS) {
@@ -220,7 +269,7 @@ const consumeNumberSign = (input, pos, callbacks) => {
220
269
  pos++;
221
270
  if (pos === input.length) return pos;
222
271
  if (callbacks.isSelector(input, pos) && _startsIdentifier(input, pos)) {
223
- pos = _consumeIdentifier(input, pos);
272
+ pos = _consumeIdentifier(input, pos, callbacks);
224
273
  if (callbacks.id !== undefined) {
225
274
  return callbacks.id(input, start, pos);
226
275
  }
@@ -244,7 +293,7 @@ const consumeMinus = (input, pos, callbacks) => {
244
293
  if (cc === CC_GREATER_THAN_SIGN) {
245
294
  return pos + 1;
246
295
  } else {
247
- pos = _consumeIdentifier(input, pos);
296
+ pos = _consumeIdentifier(input, pos, callbacks);
248
297
  if (callbacks.identifier !== undefined) {
249
298
  return callbacks.identifier(input, start, pos);
250
299
  }
@@ -253,7 +302,7 @@ const consumeMinus = (input, pos, callbacks) => {
253
302
  if (pos + 1 === input.length) return pos;
254
303
  const cc = input.charCodeAt(pos + 1);
255
304
  if (_isNewLine(cc)) return pos;
256
- pos = _consumeIdentifier(input, pos);
305
+ pos = _consumeIdentifier(input, pos, callbacks);
257
306
  if (callbacks.identifier !== undefined) {
258
307
  return callbacks.identifier(input, start, pos);
259
308
  }
@@ -272,16 +321,17 @@ const consumeDot = (input, pos, callbacks) => {
272
321
  if (_isDigit(cc)) return consumeNumericToken(input, pos - 2, callbacks);
273
322
  if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
274
323
  return pos;
275
- pos = _consumeIdentifier(input, pos);
324
+ pos = _consumeIdentifier(input, pos, callbacks);
276
325
  if (callbacks.class !== undefined) return callbacks.class(input, start, pos);
277
326
  return pos;
278
327
  };
279
328
 
280
329
  /** @type {CharHandler} */
281
330
  const consumeNumericToken = (input, pos, callbacks) => {
282
- pos = _consumeNumber(input, pos);
331
+ pos = _consumeNumber(input, pos, callbacks);
283
332
  if (pos === input.length) return pos;
284
- if (_startsIdentifier(input, pos)) return _consumeIdentifier(input, pos);
333
+ if (_startsIdentifier(input, pos))
334
+ return _consumeIdentifier(input, pos, callbacks);
285
335
  const cc = input.charCodeAt(pos);
286
336
  if (cc === CC_PERCENTAGE) return pos + 1;
287
337
  return pos;
@@ -290,7 +340,7 @@ const consumeNumericToken = (input, pos, callbacks) => {
290
340
  /** @type {CharHandler} */
291
341
  const consumeOtherIdentifier = (input, pos, callbacks) => {
292
342
  const start = pos;
293
- pos = _consumeIdentifier(input, pos);
343
+ pos = _consumeIdentifier(input, pos, callbacks);
294
344
  if (
295
345
  pos !== input.length &&
296
346
  !callbacks.isSelector(input, pos) &&
@@ -311,7 +361,7 @@ const consumeOtherIdentifier = (input, pos, callbacks) => {
311
361
  /** @type {CharHandler} */
312
362
  const consumePotentialUrl = (input, pos, callbacks) => {
313
363
  const start = pos;
314
- pos = _consumeIdentifier(input, pos);
364
+ pos = _consumeIdentifier(input, pos, callbacks);
315
365
  const nextPos = pos + 1;
316
366
  if (
317
367
  pos === start + 3 &&
@@ -331,6 +381,7 @@ const consumePotentialUrl = (input, pos, callbacks) => {
331
381
  return nextPos;
332
382
  } else {
333
383
  const contentStart = pos;
384
+ /** @type {number} */
334
385
  let contentEnd;
335
386
  for (;;) {
336
387
  if (cc === CC_REVERSE_SOLIDUS) {
@@ -380,7 +431,7 @@ const consumePotentialPseudo = (input, pos, callbacks) => {
380
431
  pos++;
381
432
  if (!callbacks.isSelector(input, pos) || !_startsIdentifier(input, pos))
382
433
  return pos;
383
- pos = _consumeIdentifier(input, pos);
434
+ pos = _consumeIdentifier(input, pos, callbacks);
384
435
  let cc = input.charCodeAt(pos);
385
436
  if (cc === CC_LEFT_PARENTHESIS) {
386
437
  pos++;
@@ -449,6 +500,7 @@ const consumeComma = (input, pos, callbacks) => {
449
500
  return pos;
450
501
  };
451
502
 
503
+ /** @type {CharHandler} */
452
504
  const _consumeIdentifier = (input, pos) => {
453
505
  for (;;) {
454
506
  const cc = input.charCodeAt(pos);
@@ -468,6 +520,7 @@ const _consumeIdentifier = (input, pos) => {
468
520
  }
469
521
  };
470
522
 
523
+ /** @type {CharHandler} */
471
524
  const _consumeNumber = (input, pos) => {
472
525
  pos++;
473
526
  if (pos === input.length) return pos;
@@ -526,12 +579,13 @@ const consumeLessThan = (input, pos, callbacks) => {
526
579
  return pos + 1;
527
580
  };
528
581
 
582
+ /** @type {CharHandler} */
529
583
  const consumeAt = (input, pos, callbacks) => {
530
584
  const start = pos;
531
585
  pos++;
532
586
  if (pos === input.length) return pos;
533
587
  if (_startsIdentifier(input, pos)) {
534
- pos = _consumeIdentifier(input, pos);
588
+ pos = _consumeIdentifier(input, pos, callbacks);
535
589
  if (callbacks.atKeyword !== undefined) {
536
590
  pos = callbacks.atKeyword(input, start, pos);
537
591
  }
@@ -697,3 +751,25 @@ module.exports.eatWhitespaceAndComments = (input, pos) => {
697
751
 
698
752
  return pos;
699
753
  };
754
+
755
+ /**
756
+ * @param {string} input input
757
+ * @param {number} pos position
758
+ * @returns {number} position after whitespace
759
+ */
760
+ module.exports.eatWhiteLine = (input, pos) => {
761
+ for (;;) {
762
+ const cc = input.charCodeAt(pos);
763
+ if (_isSpace(cc)) {
764
+ pos++;
765
+ continue;
766
+ }
767
+ if (_isNewLine(cc)) pos++;
768
+ // For `\r\n`
769
+ if (cc === CC_CARRIAGE_RETURN && input.charCodeAt(pos + 1) === CC_LINE_FEED)
770
+ pos++;
771
+ break;
772
+ }
773
+
774
+ return pos;
775
+ };
@@ -100,6 +100,8 @@ class Profiler {
100
100
  return this.sendCommand("Profiler.stop").then(({ profile }) => {
101
101
  const hrtime = process.hrtime();
102
102
  const endTime = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000);
103
+ // Avoid coverage problems due indirect changes
104
+ /* istanbul ignore next */
103
105
  if (profile.startTime < this._startTime || profile.endTime > endTime) {
104
106
  // In some cases timestamps mismatch and we need to adjust them
105
107
  // Both process.hrtime and the inspector timestamps claim to be relative
@@ -159,6 +159,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
159
159
 
160
160
  const rootInfo = rightPart.rootInfo;
161
161
  if (
162
+ typeof rootInfo === "string" ||
162
163
  !rootInfo ||
163
164
  !rootInfo.tagInfo ||
164
165
  rootInfo.tagInfo.tag !== harmonySpecifierTag