sqlmath 2026.9.29 → 2026.10.30

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/jslint.mjs CHANGED
@@ -92,6 +92,7 @@
92
92
 
93
93
  /*jslint beta, node, trace*/
94
94
  /*property
95
+ AsyncLocalStorage,
95
96
  JSLINT_BETA,
96
97
  NODE_V8_COVERAGE,
97
98
  alive,
@@ -106,6 +107,7 @@
106
107
  assigned,
107
108
  assignment,
108
109
  async,
110
+ at,
109
111
  autofix,
110
112
  autofixed,
111
113
  beta,
@@ -115,13 +117,13 @@
115
117
  block_stack,
116
118
  browser,
117
119
  catch,
118
- causes,
119
120
  char,
120
121
  children,
121
122
  clear,
122
123
  closer,
123
124
  closure,
124
125
  code,
126
+ collected,
125
127
  column,
126
128
  concat,
127
129
  consoleError,
@@ -129,14 +131,18 @@
129
131
  console_log,
130
132
  constant,
131
133
  context,
134
+ context_report,
132
135
  convert,
133
136
  count,
137
+ countFailed,
134
138
  coverageDir,
135
139
  create,
136
140
  cwd,
137
141
  debugInline,
138
142
  default,
139
143
  delta,
144
+ describe,
145
+ description,
140
146
  devel,
141
147
  directive,
142
148
  directive_ignore_line,
@@ -155,6 +161,7 @@
155
161
  endsWith,
156
162
  entries,
157
163
  env,
164
+ err,
158
165
  error,
159
166
  eval,
160
167
  every,
@@ -193,6 +200,8 @@
193
200
  function_stack,
194
201
  functions,
195
202
  get,
203
+ getBuiltinModule,
204
+ getStore,
196
205
  getset,
197
206
  github_repo,
198
207
  globExclude,
@@ -218,11 +227,10 @@
218
227
  isNaN,
219
228
  is_equal,
220
229
  is_weird,
230
+ itList,
221
231
  join,
222
232
  jslint,
223
233
  jslint_apidoc,
224
- jslint_assert,
225
- jslint_autofix_warning_list,
226
234
  jslint_charset_ascii,
227
235
  jslint_cli,
228
236
  jslint_edition,
@@ -236,7 +244,8 @@
236
244
  json,
237
245
  jstestDescribe,
238
246
  jstestIt,
239
- jstestOnExit,
247
+ jstestOrderCheck,
248
+ jstestReport,
240
249
  keys,
241
250
  label_break,
242
251
  label_name,
@@ -280,10 +289,12 @@
280
289
  name,
281
290
  name_alias,
282
291
  name_list,
292
+ name_only,
283
293
  node,
284
294
  nomen,
285
295
  noop,
286
296
  now,
297
+ npm_config_mode_test_filter,
287
298
  nr,
288
299
  nud_prefix,
289
300
  objectDeepCopyWithKeysSorted,
@@ -300,13 +311,16 @@
300
311
  padEnd,
301
312
  padStart,
302
313
  parameter_count,
314
+ parameter_rest,
303
315
  parentIi,
304
316
  parse,
305
317
  parseInt,
318
+ pass,
306
319
  pathname,
307
320
  pathnameList,
308
321
  platform,
309
322
  pop,
323
+ printed,
310
324
  processArgv,
311
325
  process_argv,
312
326
  process_env,
@@ -320,6 +334,7 @@
320
334
  readFile,
321
335
  readdir,
322
336
  readonly,
337
+ record,
323
338
  recursive,
324
339
  reduce,
325
340
  repeat,
@@ -330,13 +345,16 @@
330
345
  rgx,
331
346
  role,
332
347
  round,
348
+ run,
333
349
  scope_block,
334
350
  scope_block_pop,
335
351
  scope_block_push,
336
352
  scope_declared,
353
+ scope_function,
337
354
  scope_function_pop,
338
355
  scope_function_push,
339
356
  scope_name,
357
+ scope_report_push,
340
358
  scriptId,
341
359
  search,
342
360
  set,
@@ -358,6 +376,7 @@
358
376
  startOffset,
359
377
  startsWith,
360
378
  statement,
379
+ status,
361
380
  stdio,
362
381
  stop,
363
382
  stop_at,
@@ -369,13 +388,15 @@
369
388
  syntax_dict,
370
389
  tenure,
371
390
  test,
372
- test_cause,
391
+ testFunction,
373
392
  test_internal_error,
374
393
  test_unknown_warning_code,
394
+ text,
375
395
  this,
376
396
  thru,
377
397
  toFixed,
378
398
  toLocaleString,
399
+ toLowerCase,
379
400
  toString,
380
401
  token,
381
402
  token_global,
@@ -453,7 +474,7 @@ const jslint_charset_ascii = (
453
474
  "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" +
454
475
  "`abcdefghijklmnopqrstuvwxyz{|}~\u007f"
455
476
  );
456
- const jslint_edition = "v2026.9.29";
477
+ const jslint_edition = "v2026.10.30";
457
478
  const jslint_fudge = 1; // Fudge starting line and starting
458
479
  // ... column to 1.
459
480
  const jslint_global_dict_all = {
@@ -778,12 +799,12 @@ const jslint_rgx_url_search_window_jslint = (
778
799
  const jslint_rgx_weird_property = (
779
800
  /^_|\$|Sync$|_$/m
780
801
  );
802
+ const jstestItRecordList = [];
781
803
  let jslint_export; // The jslint object to be exported.
782
804
  let jslint_import_meta_url = ""; // import.meta.url used by cli.
783
- let jstestCountFailed = 0;
784
- let jstestCountTotal = 0;
805
+ let jstestAls;
806
+ let jstestDescribePrv = "";
785
807
  let jstestItCount = 0;
786
- let jstestItList = [];
787
808
  let jstestTimeStart;
788
809
  let moduleChildProcess;
789
810
  let moduleFs;
@@ -1118,7 +1139,6 @@ function jslint(
1118
1139
 
1119
1140
  const block_list = []; // The array containing all lexical-blocks.
1120
1141
  const block_stack = []; // The stack of lexical-blocks.
1121
- const cause_dict = empty(); // The object of test-causes.
1122
1142
  const directive_list = []; // The directive comments.
1123
1143
  const export_dict = empty(); // The exported names and values.
1124
1144
  const function_list = []; // The array containing all functions.
@@ -1181,9 +1201,7 @@ function jslint(
1181
1201
  function is_equal(aa, bb) {
1182
1202
 
1183
1203
  // test_cause:
1184
- // ["0&&0", "is_equal", "", "", 0]
1185
-
1186
- test_cause("");
1204
+ // ["0&&0", "is_equal", "(live)", "", 0]
1187
1205
 
1188
1206
  // PR-510 - deadcode-confirmed - <aa> and <bb> are never the same object. Each
1189
1207
  // call below pairs a slot of <aa> with the same slot of <bb>, and the only
@@ -1207,10 +1225,9 @@ function jslint(
1207
1225
  aa.every(function (value, index) {
1208
1226
 
1209
1227
  // test_cause:
1210
- // ["`${0}`&&`${0}`", "is_equal", "recurse_isArray", "", 0]
1211
- // ["`${0}`&&`${1}`", "is_equal", "recurse_isArray", "", 0]
1228
+ // ["`${0}`&&`${0}`", "is_equal", "(live)", "", 0]
1229
+ // ["`${0}`&&`${1}`", "is_equal", "(live)", "", 0]
1212
1230
 
1213
- test_cause("recurse_isArray");
1214
1231
  return is_equal(value, bb[index]);
1215
1232
  })
1216
1233
  );
@@ -1236,9 +1253,8 @@ function jslint(
1236
1253
  case "`":
1237
1254
 
1238
1255
  // test_cause:
1239
- // ["aa=bb`${cc}${dd}`&&bb`${cc}${ee}`", "is_equal", "recurse_mega", "", 0]
1256
+ // ["aa=bb`${cc}${dd}`&&bb`${cc}${ee}`", "is_equal", "(live)", "", 0]
1240
1257
 
1241
- test_cause("recurse_mega");
1242
1258
  return (
1243
1259
 
1244
1260
  // PR-394 - Bugfix - Fix jslint treating megastrings bb`0` and bb`1` as equal.
@@ -1255,19 +1271,17 @@ function jslint(
1255
1271
  if (is_weird(aa) || is_weird(bb)) {
1256
1272
 
1257
1273
  // test_cause:
1258
- // ["aa(/./)||{}", "is_equal", "weird", "", 0]
1274
+ // ["aa(/./)||{}", "is_equal", "(live)", "", 0]
1259
1275
 
1260
- test_cause("weird");
1261
1276
  return false;
1262
1277
  }
1263
1278
  if (aa.arity === bb.arity && aa.id === bb.id) {
1264
1279
  if (aa.id === "." || aa.id === "?.") {
1265
1280
 
1266
1281
  // test_cause:
1267
- // ["aa.bb&&aa.bb", "is_equal", "recurse_arity_id", "", 0]
1268
- // ["aa?.bb&&aa?.bb", "is_equal", "recurse_arity_id", "", 0]
1282
+ // ["aa.bb&&aa.bb", "is_equal", "(live)", "", 0]
1283
+ // ["aa?.bb&&aa?.bb", "is_equal", "(live)", "", 0]
1269
1284
 
1270
- test_cause("recurse_arity_id");
1271
1285
  return (
1272
1286
  is_equal(aa.expression, bb.expression) &&
1273
1287
  is_equal(aa.name, bb.name)
@@ -1276,17 +1290,15 @@ function jslint(
1276
1290
  if (aa.arity === "unary") {
1277
1291
 
1278
1292
  // test_cause:
1279
- // ["+0&&+0", "is_equal", "recurse_unary", "", 0]
1293
+ // ["+0&&+0", "is_equal", "(live)", "", 0]
1280
1294
 
1281
- test_cause("recurse_unary");
1282
1295
  return is_equal(aa.expression, bb.expression);
1283
1296
  }
1284
1297
  if (aa.arity === "binary") {
1285
1298
 
1286
1299
  // test_cause:
1287
- // ["aa[0]&&aa[0]", "is_equal", "recurse_binary", "", 0]
1300
+ // ["aa[0]&&aa[0]", "is_equal", "(live)", "", 0]
1288
1301
 
1289
- test_cause("recurse_binary");
1290
1302
  return (
1291
1303
  aa.id !== "(" &&
1292
1304
  is_equal(aa.expression[0], bb.expression[0]) &&
@@ -1296,9 +1308,8 @@ function jslint(
1296
1308
  if (aa.arity === "ternary") {
1297
1309
 
1298
1310
  // test_cause:
1299
- // ["aa=(``?``:``)&&(``?``:``)", "is_equal", "recurse_ternary", "", 0]
1311
+ // ["aa=(``?``:``)&&(``?``:``)", "is_equal", "(live)", "", 0]
1300
1312
 
1301
- test_cause("recurse_ternary");
1302
1313
  return (
1303
1314
  is_equal(aa.expression[0], bb.expression[0]) &&
1304
1315
  is_equal(aa.expression[1], bb.expression[1]) &&
@@ -1325,16 +1336,14 @@ function jslint(
1325
1336
  );
1326
1337
 
1327
1338
  // test_cause:
1328
- // ["undefined&&undefined", "is_equal", "true", "", 0]
1339
+ // ["undefined&&undefined", "is_equal", "(live)", "", 0]
1329
1340
 
1330
- test_cause("true");
1331
1341
  return true;
1332
1342
  }
1333
1343
 
1334
1344
  // test_cause:
1335
- // ["null&&undefined", "is_equal", "false", "", 0]
1345
+ // ["null&&undefined", "is_equal", "(live)", "", 0]
1336
1346
 
1337
- test_cause("false");
1338
1347
  return false;
1339
1348
  }
1340
1349
 
@@ -1392,6 +1401,26 @@ function jslint(
1392
1401
  return value;
1393
1402
  }
1394
1403
 
1404
+ function scope_report_push(the_function, name) {
1405
+
1406
+ // PR-516 - Bugfix - This function will push <name> to what <jslint_report>
1407
+ // lists for <the_function>, which are the names it declares and the outer
1408
+ // names it uses. An own 'bb' and an outer 'bb' are two entries.
1409
+
1410
+ if (the_function.scope_name === name.scope_declared) {
1411
+
1412
+ // PR-516 - A function using its own name from <scope_name> lists it nowhere,
1413
+ // though a nested function using it lists it as outer.
1414
+
1415
+ // test_cause:
1416
+ // ["aa=function bb(){return bb;}", "scope_report_push", "(live)", "", 0]
1417
+
1418
+ return;
1419
+ }
1420
+ the_function.context_report ??= [];
1421
+ the_function.context_report.push(name);
1422
+ }
1423
+
1395
1424
  function stop(code, the_token, a, b, c, d) {
1396
1425
 
1397
1426
  // Similar to warn and stop_at. If the token already had a warning, that
@@ -1410,32 +1439,6 @@ function jslint(
1410
1439
  throw warn_at(code, line, column, a, b, c, d);
1411
1440
  }
1412
1441
 
1413
- function test_cause(code, aa, column) {
1414
-
1415
- // This function will instrument <cause> to <cause_dict> for test-purposes.
1416
-
1417
- if (option_dict.test_cause) {
1418
- cause_dict[
1419
- JSON.stringify([
1420
- String(new Error().stack)
1421
- .replace(
1422
- (/^ at (?:file|stop|stop_at|test_cause|warn|warn_at)\b.*?\n/gm),
1423
- ""
1424
- )
1425
- .match(/\n at ((?:Object\.\w+?_)?\w+?) /)[1]
1426
- .replace((/^Object\./), ""),
1427
- code,
1428
- String(
1429
- (aa === undefined || aa === token_global)
1430
- ? ""
1431
- : aa
1432
- ),
1433
- column || 0
1434
- ])
1435
- ] = true;
1436
- }
1437
- }
1438
-
1439
1442
  function warn(code, the_token, a, b, c, d) {
1440
1443
 
1441
1444
  // Same as warn_at, except the warning will be associated with a specific token.
@@ -1504,7 +1507,6 @@ function jslint(
1504
1507
  jslint_fudge +
1505
1508
  Math.max(0, Math.min(column, warning.line_source.length - 1))
1506
1509
  );
1507
- test_cause(code, b || a, warning.column);
1508
1510
  switch (code) {
1509
1511
 
1510
1512
  // The bundle contains the raw text messages that are generated by jslint. It
@@ -1834,9 +1836,8 @@ function jslint(
1834
1836
  if (warning.directive_ignore_line) {
1835
1837
 
1836
1838
  // test_cause:
1837
- // ["0 //jslint-ignore-line", "semicolon", "directive_ignore_line", "", 0]
1839
+ // ["0 //jslint-ignore-line", "warn_at", "(live)", "", 0]
1838
1840
 
1839
- test_cause("directive_ignore_line");
1840
1841
  return warning;
1841
1842
  }
1842
1843
  warning_list.push(warning);
@@ -1882,12 +1883,12 @@ function jslint(
1882
1883
  scope_block_push,
1883
1884
  scope_function_pop,
1884
1885
  scope_function_push,
1886
+ scope_report_push,
1885
1887
  source,
1886
1888
  stop,
1887
1889
  stop_at,
1888
1890
  syntax_dict,
1889
1891
  tenure,
1890
- test_cause,
1891
1892
  token_global,
1892
1893
  token_list,
1893
1894
  token_nxt: token_global,
@@ -2030,7 +2031,6 @@ function jslint(
2030
2031
  });
2031
2032
 
2032
2033
  return {
2033
- causes: cause_dict,
2034
2034
  directives: directive_list,
2035
2035
  edition: jslint_edition,
2036
2036
  exports: export_dict,
@@ -2891,7 +2891,6 @@ function jslint_phase2_lex(state) {
2891
2891
  stop,
2892
2892
  stop_at,
2893
2893
  tenure,
2894
- test_cause,
2895
2894
  token_global,
2896
2895
  token_list,
2897
2896
  warn,
@@ -2938,16 +2937,14 @@ function jslint_phase2_lex(state) {
2938
2937
  // matched an expected value.
2939
2938
 
2940
2939
  if (match !== undefined && char !== match) {
2940
+ return (
2941
+ char === ""
2941
2942
 
2942
2943
  // test_cause:
2943
2944
  // ["aa=/", "char_after", "expected_a_after_b", "/", 4]
2944
2945
  // ["aa=/(?-", "char_after", "expected_a_after_b", "-", 7]
2945
2946
  // ["aa=/[", "char_after", "expected_a_after_b", "[", 5]
2946
- // ["aa=/aa{/", "char_after", "expected_a_b", "/", 8]
2947
- // ["aa=/aa{/;", "char_after", "expected_a_b", "/", 8]
2948
2947
 
2949
- return (
2950
- char === ""
2951
2948
  ? stop_at(
2952
2949
  "expected_a_after_b",
2953
2950
  line,
@@ -2958,6 +2955,11 @@ function jslint_phase2_lex(state) {
2958
2955
 
2959
2956
  line_list[line].line_source.slice(-1)
2960
2957
  )
2958
+
2959
+ // test_cause:
2960
+ // ["aa=/aa{/", "char_after", "expected_a_b", "/", 8]
2961
+ // ["aa=/aa{/;", "char_after", "expected_a_b", "/", 8]
2962
+
2961
2963
  : stop_at("expected_a_b", line, column - 1, match, char)
2962
2964
  );
2963
2965
  }
@@ -2982,9 +2984,11 @@ function jslint_phase2_lex(state) {
2982
2984
  // A megastring's '\' at end of line continues the line.
2983
2985
 
2984
2986
  // test_cause:
2985
- // ["`\\\n`", "char_after_escape", "megastring_continue", "", 0]
2987
+ // ["
2988
+ // `\
2989
+ // `
2990
+ // ", "char_after_escape", "(live)", "", 0]
2986
2991
 
2987
- test_cause("megastring_continue");
2988
2992
  return;
2989
2993
  }
2990
2994
 
@@ -3009,10 +3013,9 @@ function jslint_phase2_lex(state) {
3009
3013
  case "t":
3010
3014
 
3011
3015
  // test_cause:
3012
- // ["\"\\/\\\\\\`\\b\\f\\n\\r\\t\"", "char_after_escape", "char_after", "", 0]
3013
- // ["`\\/\\\\\\`\\b\\f\\n\\r\\t`", "char_after_escape", "char_after", "", 0]
3016
+ // ["\"\\/\\\\\\`\\b\\f\\n\\r\\t\"", "char_after_escape", "(live)", "", 0]
3017
+ // ["`\\/\\\\\\`\\b\\f\\n\\r\\t`", "char_after_escape", "(live)", "", 0]
3014
3018
 
3015
- test_cause("char_after");
3016
3019
  return char_after();
3017
3020
  case "u":
3018
3021
  if (char_after("u") === "{") {
@@ -3401,15 +3404,44 @@ function jslint_phase2_lex(state) {
3401
3404
 
3402
3405
  check_numeric_separator(prefix, column - prefix.length);
3403
3406
  char_after();
3404
- switch (prefix === "0" && char) {
3407
+ switch (prefix === "0" && char.toLowerCase()) {
3405
3408
  case "b":
3406
3409
  case "o":
3407
3410
  case "x":
3408
- read_digits(char, mode_digits_numeric_separator);
3411
+
3412
+ // An uppercase radix prefix '0B', '0O' or '0X' is valid, so warn and read the
3413
+ // digits as for its lowercase form.
3414
+
3415
+ if (char !== char.toLowerCase()) {
3416
+
3417
+ // test_cause:
3418
+ // ["aa=0B1", "lex_number", "expected_a_b", "B", 5]
3419
+ // ["aa=0O7", "lex_number", "expected_a_b", "O", 5]
3420
+ // ["aa=0X1", "lex_number", "expected_a_b", "X", 5]
3421
+
3422
+ warn_at(
3423
+ "expected_a_b",
3424
+ line,
3425
+ column - 1,
3426
+ char.toLowerCase(),
3427
+ char
3428
+ );
3429
+ }
3430
+
3431
+ // test_cause:
3432
+ // ["aa=0b1", "lex_number", "(live)", "", 0]
3433
+ // ["aa=0o7", "lex_number", "(live)", "", 0]
3434
+ // ["aa=0x1", "lex_number", "(live)", "", 0]
3435
+
3436
+ read_digits(char.toLowerCase(), mode_digits_numeric_separator);
3409
3437
 
3410
3438
  // PR-351 - Ignore BigInt suffix 'n'.
3411
3439
 
3412
3440
  if (char === "n") {
3441
+
3442
+ // test_cause:
3443
+ // ["aa=0x1fn", "lex_number", "(live)", "", 0]
3444
+
3413
3445
  char_after("n");
3414
3446
  }
3415
3447
  break;
@@ -3418,8 +3450,17 @@ function jslint_phase2_lex(state) {
3418
3450
  read_digits("d", mode_digits_numeric_separator);
3419
3451
  }
3420
3452
  if (char === "E" || char === "e") {
3453
+
3454
+ // test_cause:
3455
+ // ["aa=1e+5", "lex_number", "(live)", "", 0]
3456
+ // ["aa=1e5", "lex_number", "(live)", "", 0]
3457
+
3421
3458
  char_after(char);
3422
3459
  if (char !== "+" && char !== "-") {
3460
+
3461
+ // test_cause:
3462
+ // ["aa=1e5", "lex_number", "(live)", "", 0]
3463
+
3423
3464
  char_before();
3424
3465
  }
3425
3466
  read_digits("d", mode_digits_numeric_separator);
@@ -3482,10 +3523,9 @@ function jslint_phase2_lex(state) {
3482
3523
  case "]":
3483
3524
 
3484
3525
  // test_cause:
3485
- // ["aa=/[", "lex_regexp_bracketed", "closer", "", 0]
3486
- // ["aa=/[]/", "lex_regexp_bracketed", "closer", "", 0]
3526
+ // ["aa=/[", "lex_regexp_bracketed", "(live)", "", 0]
3527
+ // ["aa=/[]/", "lex_regexp_bracketed", "(live)", "", 0]
3487
3528
 
3488
- test_cause("closer");
3489
3529
  if (mode_regexp_range) {
3490
3530
 
3491
3531
  // test_cause:
@@ -3560,17 +3600,23 @@ function jslint_phase2_lex(state) {
3560
3600
  let modifier_seen = "";
3561
3601
  switch (char) {
3562
3602
  case "":
3603
+
3604
+ // test_cause:
3605
+ // ["/ /", "lex_regexp_group", "expected_regexp_factor_a", "", 3]
3606
+
3563
3607
  warn_at("expected_regexp_factor_a", line, column - 0, char);
3564
3608
  break;
3565
3609
  case ")":
3610
+
3611
+ // test_cause:
3612
+ // ["aa=/)", "lex_regexp_group", "expected_regexp_factor_a", ")", 5]
3613
+ // ["aa=/);", "lex_regexp_group", "expected_regexp_factor_a", ")", 5]
3614
+
3566
3615
  warn_at("expected_regexp_factor_a", line, column - 1, char);
3567
3616
  break;
3568
3617
  case "]":
3569
3618
 
3570
3619
  // test_cause:
3571
- // ["/ /", "lex_regexp_group", "expected_regexp_factor_a", "", 3]
3572
- // ["aa=/)", "lex_regexp_group", "expected_regexp_factor_a", ")", 5]
3573
- // ["aa=/);", "lex_regexp_group", "expected_regexp_factor_a", ")", 5]
3574
3620
  // ["aa=/]", "lex_regexp_group", "expected_regexp_factor_a", "]", 5]
3575
3621
 
3576
3622
  warn_at("expected_regexp_factor_a", line, column - 1, char);
@@ -3612,7 +3658,6 @@ function jslint_phase2_lex(state) {
3612
3658
 
3613
3659
  // test_cause:
3614
3660
  // ["aa=/(:)/", "lex_regexp_group", "expected_a_before_b", ":", 6]
3615
- // ["aa=/?/", "lex_regexp_group", "expected_a_before_b", "?", 5]
3616
3661
 
3617
3662
  warn_at(
3618
3663
  "expected_a_before_b",
@@ -3661,12 +3706,12 @@ function jslint_phase2_lex(state) {
3661
3706
  case "i":
3662
3707
  case "m":
3663
3708
  case "s":
3709
+ if (modifier_seen.includes(char)) {
3664
3710
 
3665
3711
  // test_cause:
3666
3712
  // ["aa=/(?--:x)/", "lex_regexp_group", "unexpected_a_after_b", "(?-", 8]
3667
3713
  // ["aa=/(?ii:x)/", "lex_regexp_group", "unexpected_a_after_b", "(?i", 8]
3668
3714
 
3669
- if (modifier_seen.includes(char)) {
3670
3715
  warn_at(
3671
3716
  "unexpected_a_after_b",
3672
3717
  line,
@@ -3740,9 +3785,7 @@ function jslint_phase2_lex(state) {
3740
3785
  case "\\":
3741
3786
 
3742
3787
  // test_cause:
3743
- // ["aa=/\\/", "lex_regexp_group", "escape", "", 0]
3744
-
3745
- test_cause("escape");
3788
+ // ["aa=/\\/", "lex_regexp_group", "(live)", "", 0]
3746
3789
 
3747
3790
  // PR-437 - Add grammar for regexp-named-backreference.
3748
3791
 
@@ -3777,10 +3820,9 @@ function jslint_phase2_lex(state) {
3777
3820
  if (char_after(char) === "?") {
3778
3821
 
3779
3822
  // test_cause:
3780
- // ["aa=/.*?/", "lex_regexp_group", "?", "", 0]
3781
- // ["aa=/.+?/", "lex_regexp_group", "?", "", 0]
3823
+ // ["aa=/.*?/", "lex_regexp_group", "(live)", "", 0]
3824
+ // ["aa=/.+?/", "lex_regexp_group", "(live)", "", 0]
3782
3825
 
3783
- test_cause("?");
3784
3826
  char_after("?");
3785
3827
  }
3786
3828
  break;
@@ -3856,6 +3898,10 @@ function jslint_phase2_lex(state) {
3856
3898
  // PR-499 - Add ES2022-feature RegExp Match Indices.
3857
3899
 
3858
3900
  case "d":
3901
+
3902
+ // test_cause:
3903
+ // ["aa=/./d", "lex_regexp", "(live)", "", 0]
3904
+
3859
3905
  break;
3860
3906
  case "g":
3861
3907
  break;
@@ -3867,16 +3913,20 @@ function jslint_phase2_lex(state) {
3867
3913
  // PR-499 - Add ES2018-feature s (dotall) flag for regular expressions.
3868
3914
 
3869
3915
  case "s":
3916
+
3917
+ // test_cause:
3918
+ // ["aa=/./s", "lex_regexp", "(live)", "", 0]
3919
+
3870
3920
  break;
3871
3921
  case "u":
3922
+ if (
3923
+ flag.v //jslint-ignore-line
3924
+ ) {
3872
3925
 
3873
3926
  // test_cause:
3874
3927
  // ["aa=/./vu", "lex_regexp", "unexpected_a", "u", 8]
3875
3928
  // ["aa=/./vu;", "lex_regexp", "unexpected_a", "u", 8]
3876
3929
 
3877
- if (
3878
- flag.v //jslint-ignore-line
3879
- ) {
3880
3930
  warn_at("unexpected_a", line, column - 1, char);
3881
3931
  }
3882
3932
  break;
@@ -3887,21 +3937,21 @@ function jslint_phase2_lex(state) {
3887
3937
 
3888
3938
  // "u" and "v" select different grammars, so v8 rejects the pair.
3889
3939
 
3890
- // test_cause:
3891
- // ["aa=/./uv", "lex_regexp", "unexpected_a", "v", 8]
3892
-
3893
3940
  if (
3894
3941
  flag.u //jslint-ignore-line
3895
3942
  ) {
3943
+
3944
+ // test_cause:
3945
+ // ["aa=/./uv", "lex_regexp", "unexpected_a", "v", 8]
3946
+
3896
3947
  warn_at("unexpected_a", line, column - 1, char);
3897
3948
  }
3898
3949
  break;
3899
3950
  case "y":
3900
3951
 
3901
3952
  // test_cause:
3902
- // ["aa=/./gimuy", "lex_regexp", "flag", "", 0]
3953
+ // ["aa=/./gimuy", "lex_regexp", "(live)", "", 0]
3903
3954
 
3904
- test_cause("flag");
3905
3955
  break;
3906
3956
  default:
3907
3957
 
@@ -3978,6 +4028,10 @@ function jslint_phase2_lex(state) {
3978
4028
 
3979
4029
  return stop("unexpected_a", the_token);
3980
4030
  case "return":
4031
+
4032
+ // test_cause:
4033
+ // ["function aa(){return /./;}", "lex_slash_or_regexp", "(live)", "", 0]
4034
+
3981
4035
  return lex_regexp();
3982
4036
  }
3983
4037
  switch (!token_prv_expr.identifier && token_prv_expr.id.slice(-1)) {
@@ -4025,14 +4079,13 @@ function jslint_phase2_lex(state) {
4025
4079
  case "[":
4026
4080
 
4027
4081
  // test_cause:
4028
- // ["(/./", "lex_slash_or_regexp", "recurse", "", 0]
4029
- // [",/./", "lex_slash_or_regexp", "recurse", "", 0]
4030
- // [":/./", "lex_slash_or_regexp", "recurse", "", 0]
4031
- // ["=/./", "lex_slash_or_regexp", "recurse", "", 0]
4032
- // ["?/./", "lex_slash_or_regexp", "recurse", "", 0]
4033
- // ["aa[/./", "lex_slash_or_regexp", "recurse", "", 0]
4082
+ // ["(/./", "lex_slash_or_regexp", "(live)", "", 0]
4083
+ // [",/./", "lex_slash_or_regexp", "(live)", "", 0]
4084
+ // [":/./", "lex_slash_or_regexp", "(live)", "", 0]
4085
+ // ["=/./", "lex_slash_or_regexp", "(live)", "", 0]
4086
+ // ["?/./", "lex_slash_or_regexp", "(live)", "", 0]
4087
+ // ["aa[/./", "lex_slash_or_regexp", "(live)", "", 0]
4034
4088
 
4035
- test_cause("recurse");
4036
4089
  return lex_regexp();
4037
4090
  }
4038
4091
  if (line_source[0] === "=") {
@@ -4225,7 +4278,6 @@ function jslint_phase2_lex(state) {
4225
4278
  case "nomen": // Allow weird property name.
4226
4279
  case "single": // Allow single-quote strings.
4227
4280
  case "subscript": // Allow identifier in subscript-notation.
4228
- case "test_cause": // Test jslint's causes.
4229
4281
  case "test_internal_error": // Test jslint's internal-error
4230
4282
  // ... handling-ability.
4231
4283
  case "test_unknown_warning_code": // Test jslint's unknown-warning-code
@@ -4243,11 +4295,19 @@ function jslint_phase2_lex(state) {
4243
4295
  // PR-404 - Alias "evil" to sub-directive "eval" for backwards-compat.
4244
4296
 
4245
4297
  case "evil":
4298
+
4299
+ // test_cause:
4300
+ // ["/*jslint evil*/", "option_set_item", "(live)", "", 0]
4301
+
4246
4302
  return option_set_item("eval", value);
4247
4303
 
4248
4304
  // PR-404 - Alias "nomen" to sub-directive "name" for backwards-compat.
4249
4305
 
4250
4306
  case "name":
4307
+
4308
+ // test_cause:
4309
+ // ["/*jslint name*/", "option_set_item", "(live)", "", 0]
4310
+
4251
4311
  return option_set_item("nomen", value);
4252
4312
  default:
4253
4313
  return false;
@@ -4288,6 +4348,10 @@ function jslint_phase2_lex(state) {
4288
4348
  dict_name.startsWith("browser")
4289
4349
  ? "browser"
4290
4350
  : dict_name.startsWith("couch")
4351
+
4352
+ // test_cause:
4353
+ // ["/*jslint couch*/", "option_set_item", "(live)", "", 0]
4354
+
4291
4355
  ? "CouchDb"
4292
4356
  : dict_name.startsWith("devel")
4293
4357
  ? "development"
@@ -4308,8 +4372,16 @@ function jslint_phase2_lex(state) {
4308
4372
  function read_digits(base, mode) {
4309
4373
  let digits = line_source.match(
4310
4374
  base === "b"
4375
+
4376
+ // test_cause:
4377
+ // ["aa=0b1", "read_digits", "(live)", "", 0]
4378
+
4311
4379
  ? jslint_rgx_digits_bits
4312
4380
  : base === "o"
4381
+
4382
+ // test_cause:
4383
+ // ["aa=0o7", "read_digits", "(live)", "", 0]
4384
+
4313
4385
  ? jslint_rgx_digits_octals
4314
4386
  : base === "x"
4315
4387
  ? jslint_rgx_digits_hexs
@@ -4366,9 +4438,8 @@ function jslint_phase2_lex(state) {
4366
4438
  if (line_source[0] === ",") {
4367
4439
 
4368
4440
  // test_cause:
4369
- // ["aa=/.{,/", "read_digits", "comma", "", 0]
4441
+ // ["aa=/.{,/", "read_digits", "(live)", "", 0]
4370
4442
 
4371
- test_cause("comma");
4372
4443
  char_after();
4373
4444
 
4374
4445
  // Recurse read_digits.
@@ -4448,9 +4519,8 @@ function jslint_phase2_lex(state) {
4448
4519
  if (line_source === "/*jslint-disable*/") {
4449
4520
 
4450
4521
  // test_cause:
4451
- // ["/*jslint-disable*/", "read_line", "jslint_disable", "", 0]
4522
+ // ["/*jslint-disable*/", "read_line", "(live)", "", 0]
4452
4523
 
4453
- test_cause("jslint_disable");
4454
4524
  line_disable = line;
4455
4525
  } else if (line_source === "/*jslint-enable*/") {
4456
4526
  if (line_disable === undefined) {
@@ -4467,17 +4537,18 @@ function jslint_phase2_lex(state) {
4467
4537
  ) {
4468
4538
 
4469
4539
  // test_cause:
4470
- // ["0 //jslint-ignore-line", "read_line", "jslint_ignore_line", "", 0]
4540
+ // ["0 //jslint-ignore-line", "read_line", "(live)", "", 0]
4471
4541
 
4472
- test_cause("jslint_ignore_line");
4473
4542
  line_list[line].directive_ignore_line = true;
4474
4543
  }
4475
4544
  if (line_disable !== undefined) {
4476
4545
 
4477
4546
  // test_cause:
4478
- // ["/*jslint-disable*/\n0", "read_line", "line_disable", "", 0]
4547
+ // ["
4548
+ // /*jslint-disable*/
4549
+ // 0
4550
+ // ", "read_line", "(live)", "", 0]
4479
4551
 
4480
- test_cause("line_disable");
4481
4552
  line_source = "";
4482
4553
  }
4483
4554
  // jslint_rgx_tab
@@ -4682,6 +4753,10 @@ function jslint_phase2_lex(state) {
4682
4753
  // Scan first line for "#!" and ignore it.
4683
4754
 
4684
4755
  if (line_list[jslint_fudge].line_source.startsWith("#!")) {
4756
+
4757
+ // test_cause:
4758
+ // ["#!/usr/bin/env node", "jslint_phase2_lex", "(live)", "", 0]
4759
+
4685
4760
  line += 1;
4686
4761
  state.mode_shebang = true;
4687
4762
  }
@@ -4724,16 +4799,17 @@ function jslint_phase3_parse(state) {
4724
4799
  global_dict,
4725
4800
  import_list,
4726
4801
  is_equal,
4802
+ line_list,
4727
4803
  option_dict,
4728
4804
  property_dict,
4729
4805
  scope_block_pop,
4730
4806
  scope_block_push,
4731
4807
  scope_function_pop,
4732
4808
  scope_function_push,
4809
+ scope_report_push,
4733
4810
  stop,
4734
4811
  syntax_dict,
4735
4812
  tenure,
4736
- test_cause,
4737
4813
  token_global,
4738
4814
  token_list,
4739
4815
  warn,
@@ -4762,7 +4838,26 @@ function jslint_phase3_parse(state) {
4762
4838
  token_now.id !== "function" &&
4763
4839
  token_now.id !== "async"
4764
4840
  ) {
4765
- anon = token_now.id;
4841
+
4842
+ // PR-516 - Bugfix - A keyword such as 'return' names no function, so reset
4843
+ // <anon>, else it would keep an earlier identifier. Keep 'default', the name
4844
+ // the spec gives 'export default function () {}', and a property name such as
4845
+ // 'catch' in 'aa.catch' or '{catch: ...}', but not 'null' in 'aa ? null : ...'.
4846
+
4847
+ anon = (
4848
+ (
4849
+ syntax_dict[token_now.id] === undefined ||
4850
+ token_now.id === "default" ||
4851
+ token_prv.id === "." ||
4852
+ token_prv.id === "?." ||
4853
+ (
4854
+ token_nxt.id === ":" &&
4855
+ (token_prv.id === "{" || token_prv.id === ",")
4856
+ )
4857
+ )
4858
+ ? token_now.id
4859
+ : "anonymous"
4860
+ );
4766
4861
  } else if (
4767
4862
  token_now.id === "(string)" &&
4768
4863
  jslint_rgx_identifier.test(token_now.value)
@@ -4827,7 +4922,7 @@ function jslint_phase3_parse(state) {
4827
4922
  // other assignment operators can modify, but they cannot initialize.
4828
4923
 
4829
4924
  const the_symbol = symbol(id, 20);
4830
- the_symbol.led_infix = function (left) {
4925
+ the_symbol.led_infix = function parse_assignment_led(left) {
4831
4926
  const the_token = token_now;
4832
4927
  let right;
4833
4928
  the_token.arity = "assignment";
@@ -4851,6 +4946,10 @@ function jslint_phase3_parse(state) {
4851
4946
  right.arity === "preassign" ||
4852
4947
  right.arity === "postassign"
4853
4948
  ) {
4949
+
4950
+ // test_cause:
4951
+ // ["aa=aa++", "parse_assignment_led", "unexpected_a", "++", 6]
4952
+
4854
4953
  warn("unexpected_a", right);
4855
4954
  }
4856
4955
  check_mutation(left);
@@ -5141,9 +5240,8 @@ function jslint_phase3_parse(state) {
5141
5240
  case false:
5142
5241
 
5143
5242
  // test_cause:
5144
- // ["import \"aa\";let aa", "check", "import", "", 0]
5243
+ // ["import \"aa\";let aa", "check", "(live)", "", 0]
5145
5244
 
5146
- test_cause("import");
5147
5245
  break;
5148
5246
  default:
5149
5247
  if (
@@ -5187,11 +5285,10 @@ function jslint_phase3_parse(state) {
5187
5285
  let the_value;
5188
5286
 
5189
5287
  // test_cause:
5190
- // ["do{}while()", "condition", "", "", 0]
5191
- // ["if(){}", "condition", "", "", 0]
5192
- // ["while(){}", "condition", "", "", 0]
5288
+ // ["do{}while()", "condition", "(live)", "", 0]
5289
+ // ["if(){}", "condition", "(live)", "", 0]
5290
+ // ["while(){}", "condition", "(live)", "", 0]
5193
5291
 
5194
- test_cause("");
5195
5292
  advance("(");
5196
5293
  the_value = parse_expression(0);
5197
5294
  advance(")");
@@ -5207,68 +5304,113 @@ function jslint_phase3_parse(state) {
5207
5304
 
5208
5305
  switch (the_value.id) {
5209
5306
  case "%":
5307
+
5308
+ // test_cause:
5309
+ // ["if(0%0){}", "condition", "unexpected_a", "%", 5]
5310
+
5210
5311
  warn("unexpected_a", the_value);
5211
5312
  break;
5212
5313
  case "&":
5314
+
5315
+ // test_cause:
5316
+ // ["if(0&0){}", "condition", "unexpected_a", "&", 5]
5317
+
5213
5318
  warn("unexpected_a", the_value);
5214
5319
  break;
5215
5320
  case "(number)":
5321
+
5322
+ // test_cause:
5323
+ // ["if(0){}", "condition", "unexpected_a", "0", 4]
5324
+
5216
5325
  warn("unexpected_a", the_value);
5217
5326
  break;
5218
5327
  case "(string)":
5328
+
5329
+ // test_cause:
5330
+ // ["if(\"aa\"){}", "condition", "unexpected_a", "aa", 4]
5331
+
5219
5332
  warn("unexpected_a", the_value);
5220
5333
  break;
5221
5334
  case "*":
5335
+
5336
+ // test_cause:
5337
+ // ["if(0*0){}", "condition", "unexpected_a", "*", 5]
5338
+
5222
5339
  warn("unexpected_a", the_value);
5223
5340
  break;
5224
5341
  case "+":
5342
+
5343
+ // test_cause:
5344
+ // ["if(0+0){}", "condition", "unexpected_a", "+", 5]
5345
+
5225
5346
  warn("unexpected_a", the_value);
5226
5347
  break;
5227
5348
  case "-":
5349
+
5350
+ // test_cause:
5351
+ // ["if(0-0){}", "condition", "unexpected_a", "-", 5]
5352
+
5228
5353
  warn("unexpected_a", the_value);
5229
5354
  break;
5230
5355
  case "/":
5356
+
5357
+ // test_cause:
5358
+ // ["if(0/0){}", "condition", "unexpected_a", "/", 5]
5359
+
5231
5360
  warn("unexpected_a", the_value);
5232
5361
  break;
5233
5362
  case "<<":
5363
+
5364
+ // test_cause:
5365
+ // ["if(0<<0){}", "condition", "unexpected_a", "<<", 5]
5366
+
5234
5367
  warn("unexpected_a", the_value);
5235
5368
  break;
5236
5369
  case ">>":
5370
+
5371
+ // test_cause:
5372
+ // ["if(0>>0){}", "condition", "unexpected_a", ">>", 5]
5373
+
5237
5374
  warn("unexpected_a", the_value);
5238
5375
  break;
5239
5376
  case ">>>":
5377
+
5378
+ // test_cause:
5379
+ // ["if(0>>>0){}", "condition", "unexpected_a", ">>>", 5]
5380
+
5240
5381
  warn("unexpected_a", the_value);
5241
5382
  break;
5242
5383
  case "?":
5384
+
5385
+ // test_cause:
5386
+ // ["if(0?0:0){}", "condition", "unexpected_a", "?", 5]
5387
+
5243
5388
  warn("unexpected_a", the_value);
5244
5389
  break;
5245
5390
  case "^":
5391
+
5392
+ // test_cause:
5393
+ // ["if(0^0){}", "condition", "unexpected_a", "^", 5]
5394
+
5246
5395
  warn("unexpected_a", the_value);
5247
5396
  break;
5248
5397
  case "typeof":
5398
+
5399
+ // test_cause:
5400
+ // ["if(typeof 0){}", "condition", "unexpected_a", "typeof", 4]
5401
+
5249
5402
  warn("unexpected_a", the_value);
5250
5403
  break;
5251
5404
  case "|":
5405
+
5406
+ // test_cause:
5407
+ // ["if(0|0){}", "condition", "unexpected_a", "|", 5]
5408
+
5252
5409
  warn("unexpected_a", the_value);
5253
5410
  break;
5254
5411
  case "~":
5255
5412
 
5256
5413
  // test_cause:
5257
- // ["if(0%0){}", "condition", "unexpected_a", "%", 5]
5258
- // ["if(0&0){}", "condition", "unexpected_a", "&", 5]
5259
- // ["if(0){}", "condition", "unexpected_a", "0", 4]
5260
- // ["if(0*0){}", "condition", "unexpected_a", "*", 5]
5261
- // ["if(0+0){}", "condition", "unexpected_a", "+", 5]
5262
- // ["if(0-0){}", "condition", "unexpected_a", "-", 5]
5263
- // ["if(0/0){}", "condition", "unexpected_a", "/", 5]
5264
- // ["if(0<<0){}", "condition", "unexpected_a", "<<", 5]
5265
- // ["if(0>>0){}", "condition", "unexpected_a", ">>", 5]
5266
- // ["if(0>>>0){}", "condition", "unexpected_a", ">>>", 5]
5267
- // ["if(0?0:0){}", "condition", "unexpected_a", "?", 5]
5268
- // ["if(0^0){}", "condition", "unexpected_a", "^", 5]
5269
- // ["if(0|0){}", "condition", "unexpected_a", "|", 5]
5270
- // ["if(\"aa\"){}", "condition", "unexpected_a", "aa", 4]
5271
- // ["if(typeof 0){}", "condition", "unexpected_a", "typeof", 4]
5272
5414
  // ["if(~0){}", "condition", "unexpected_a", "~", 4]
5273
5415
 
5274
5416
  warn("unexpected_a", the_value);
@@ -5461,6 +5603,7 @@ function jslint_phase3_parse(state) {
5461
5603
  // ["\"aa\"?.0", "check_left", "unexpected_a", "?.", 5]
5462
5604
  // ["aa=[]?.aa", "check_left", "unexpected_a", "?.", 6]
5463
5605
  // ["new aa``.aa()", "check_left", "unexpected_a", ".", 9]
5606
+ // ["new aa``?.aa()", "check_left", "unexpected_a", "?.", 9]
5464
5607
 
5465
5608
  check_left(left, the_token);
5466
5609
  }
@@ -5473,10 +5616,8 @@ function jslint_phase3_parse(state) {
5473
5616
  ) {
5474
5617
 
5475
5618
  // test_cause:
5476
- // ["aa?.(bb)", "infix_dot", "dyn_prop_or_call", "", 0]
5477
- // ["aa?.[bb]", "infix_dot", "dyn_prop_or_call", "", 0]
5478
-
5479
- test_cause("dyn_prop_or_call");
5619
+ // ["aa?.(bb)", "infix_dot", "(live)", "", 0]
5620
+ // ["aa?.[bb]", "infix_dot", "(live)", "", 0]
5480
5621
 
5481
5622
  // PR-514 - Bugfix - The '?.' token leaves the tree here, so mark the '[' or '('
5482
5623
  // that follows it, for <optional_chain>.
@@ -5586,9 +5727,8 @@ function jslint_phase3_parse(state) {
5586
5727
  if (token_nxt.id === "...") {
5587
5728
 
5588
5729
  // test_cause:
5589
- // ["aa(...aa)", "infix_lparen", "aa(...aa)", "", 0]
5730
+ // ["aa(...aa)", "infix_lparen", "(live)", "", 0]
5590
5731
 
5591
- test_cause("aa(...aa)");
5592
5732
  the_argument = prefix_ellipsis();
5593
5733
  } else {
5594
5734
  the_argument = parse_expression(10);
@@ -5631,9 +5771,8 @@ function jslint_phase3_parse(state) {
5631
5771
  const the_token = token_now;
5632
5772
 
5633
5773
  // test_cause:
5634
- // ["0**0", "parse_infixr_led", "led_infix", "", 0]
5774
+ // ["0**0", "parse_infixr_led", "(live)", "", 0]
5635
5775
 
5636
- test_cause("led_infix");
5637
5776
  the_token.arity = "binary";
5638
5777
  the_token.expression = [left, parse_expression(bp - 1)];
5639
5778
  return the_token;
@@ -5770,14 +5909,11 @@ function jslint_phase3_parse(state) {
5770
5909
  if (earlier) {
5771
5910
 
5772
5911
  // test_cause:
5773
- // ["let aa;(function aa(){})", "name_declare", "scope_current", "aa", 0]
5774
- // ["let aa;function aa(){}", "name_declare", "scope_current", "aa", 0]
5912
+ // ["let aa;(function aa(){})", "name_declare", "redefinition_a_b", "1", 18]
5913
+ // ["let aa;function aa(){}", "name_declare", "redefinition_a_b", "1", 17]
5775
5914
  // ["let aa;let aa", "name_declare", "redefinition_a_b", "1", 12]
5776
- // ["let aa;let aa", "name_declare", "scope_current", "aa", 0]
5777
5915
  // ["var aa;if(0){var aa}", "name_declare", "redefinition_a_b", "1", 18]
5778
- // ["var aa;if(0){var aa}", "name_declare", "scope_current", "aa", 0]
5779
5916
 
5780
- test_cause("scope_current", id);
5781
5917
  warn("redefinition_a_b", name, id, earlier.line);
5782
5918
  return;
5783
5919
  }
@@ -5791,9 +5927,8 @@ function jslint_phase3_parse(state) {
5791
5927
  if (earlier.role !== "label") {
5792
5928
 
5793
5929
  // test_cause:
5794
- // ["let aa;aa:while(0){}", "name_declare", "label_vs_not_label", "aa", 0]
5930
+ // ["let aa;aa:while(0){}", "name_declare", "redefinition_a_b", "1", 8]
5795
5931
 
5796
- test_cause("label_vs_not_label", id);
5797
5932
  warn("redefinition_a_b", name, id, earlier.line);
5798
5933
  earlier = undefined;
5799
5934
  }
@@ -5804,9 +5939,8 @@ function jslint_phase3_parse(state) {
5804
5939
  if (earlier.role === "label") {
5805
5940
 
5806
5941
  // test_cause:
5807
- // ["aa:while(0){let aa}", "name_declare", "default_vs_label", "aa", 0]
5942
+ // ["aa:while(0){let aa}", "name_declare", "redefinition_a_b", "1", 17]
5808
5943
 
5809
- test_cause("default_vs_label", id);
5810
5944
  warn("redefinition_a_b", name, id, earlier.line);
5811
5945
  earlier = undefined;
5812
5946
  }
@@ -5819,15 +5953,26 @@ function jslint_phase3_parse(state) {
5819
5953
  scope_declared.context[id] = name;
5820
5954
  name.scope_declared = scope_declared;
5821
5955
 
5956
+ // PR-516 - Bugfix - Record the function that owns <name>, since a let/const
5957
+ // <scope_declared> may be a block inside it.
5958
+
5959
+ name.scope_function = scope_function;
5960
+ if (!scope_declared.name_only) {
5961
+
5962
+ // PR-516 - Omit a named function expression's name from its declaring
5963
+ // function. It sits in <scope_name>, a scope outside its own function.
5964
+
5965
+ scope_report_push(scope_function, name);
5966
+ }
5967
+
5822
5968
  // Warn about variable redefinition.
5823
5969
 
5824
5970
  if (earlier && id === "ignore") {
5825
5971
  if (earlier.role === "variable") {
5826
5972
 
5827
5973
  // test_cause:
5828
- // ["let ignore;(ignore)=>0", "name_declare", "ignore", "ignore", 0]
5974
+ // ["let ignore;(ignore)=>0", "name_declare", "redefinition_a_b", "1", 13]
5829
5975
 
5830
- test_cause("ignore", id);
5831
5976
  warn("redefinition_a_b", name, id, earlier.line);
5832
5977
  }
5833
5978
  return;
@@ -5839,20 +5984,21 @@ function jslint_phase3_parse(state) {
5839
5984
  ) {
5840
5985
 
5841
5986
  // test_cause:
5842
- // ["for(let aa;;)let aa", "name_declare", "scope_outer", "aa", 0]
5987
+ // ["for(let aa;;)let aa", "name_declare", "redefinition_a_b", "1", 18]
5843
5988
  // ["
5844
5989
  // function aa(){try{aa();}catch(aa){aa();}}
5845
- // ", "name_declare", "scope_outer", "aa", 0]
5846
- // ["function aa(){var aa}", "name_declare", "scope_outer", "aa", 0]
5847
- // ["let aa;do let aa;while(0)", "name_declare", "scope_outer", "aa", 0]
5848
- // ["let aa;do;while(0)let aa", "name_declare", "scope_outer", "aa", 0]
5849
- // ["let aa;for(let aa;;){}", "name_declare", "scope_outer", "aa", 0]
5850
- // ["let aa;if(0);else if(0)let aa", "name_declare", "scope_outer", "aa", 0]
5851
- // ["let aa;if(0);else let aa", "name_declare", "scope_outer", "aa", 0]
5852
- // ["let aa;if(0)let aa", "name_declare", "scope_outer", "aa", 0]
5853
- // ["let aa;while(0)let aa", "name_declare", "scope_outer", "aa", 0]
5854
-
5855
- test_cause("scope_outer", id);
5990
+ // ", "name_declare", "redefinition_a_b", "1", 31]
5991
+ // ["function aa(){var aa}", "name_declare", "redefinition_a_b", "1", 19]
5992
+ // ["let aa;do let aa;while(0)", "name_declare", "redefinition_a_b", "1", 15]
5993
+ // ["let aa;do;while(0)let aa", "name_declare", "redefinition_a_b", "1", 23]
5994
+ // ["let aa;for(let aa;;){}", "name_declare", "redefinition_a_b", "1", 16]
5995
+ // ["
5996
+ // let aa;if(0);else if(0)let aa
5997
+ // ", "name_declare", "redefinition_a_b", "1", 28]
5998
+ // ["let aa;if(0);else let aa", "name_declare", "redefinition_a_b", "1", 23]
5999
+ // ["let aa;if(0)let aa", "name_declare", "redefinition_a_b", "1", 17]
6000
+ // ["let aa;while(0)let aa", "name_declare", "redefinition_a_b", "1", 20]
6001
+
5856
6002
  warn("redefinition_a_b", name, id, earlier.line);
5857
6003
  return;
5858
6004
  }
@@ -5895,9 +6041,8 @@ function jslint_phase3_parse(state) {
5895
6041
  default:
5896
6042
 
5897
6043
  // test_cause:
5898
- // ["aa+aa=0", "optional_chain", "default", "", 0]
6044
+ // ["aa+aa=0", "optional_chain", "(live)", "", 0]
5899
6045
 
5900
- test_cause("default");
5901
6046
  return;
5902
6047
  }
5903
6048
  }
@@ -5984,16 +6129,14 @@ function jslint_phase3_parse(state) {
5984
6129
  if (the_symbol !== undefined && the_symbol.nud_prefix !== undefined) {
5985
6130
 
5986
6131
  // test_cause:
5987
- // ["0", "parse_expression", "symbol", "", 0]
6132
+ // ["0", "parse_expression", "(live)", "", 0]
5988
6133
 
5989
- test_cause("symbol");
5990
6134
  left = the_symbol.nud_prefix();
5991
6135
  } else if (token_now.identifier) {
5992
6136
 
5993
6137
  // test_cause:
5994
- // ["aa", "parse_expression", "identifier", "", 0]
6138
+ // ["aa", "parse_expression", "(live)", "", 0]
5995
6139
 
5996
- test_cause("identifier");
5997
6140
  left = token_now;
5998
6141
  left.arity = "variable";
5999
6142
  } else {
@@ -6028,9 +6171,11 @@ function jslint_phase3_parse(state) {
6028
6171
  ) {
6029
6172
 
6030
6173
  // test_cause:
6031
- // ["aa\n++aa", "parse_expression", "postfix_line_break", "", 0]
6174
+ // ["
6175
+ // aa
6176
+ // ++aa
6177
+ // ", "parse_expression", "(live)", "", 0]
6032
6178
 
6033
- test_cause("postfix_line_break");
6034
6179
  break;
6035
6180
  }
6036
6181
  advance();
@@ -6049,12 +6194,8 @@ function jslint_phase3_parse(state) {
6049
6194
  if (!jslint_rgx_json_number.test(token_nxt.value)) {
6050
6195
 
6051
6196
  // test_cause:
6052
- // ["[-.0]", "parse_json", "unexpected_a", ".", 3]
6053
6197
  // ["[-0x0]", "parse_json", "unexpected_a", "0x0", 3]
6054
- // ["[...]", "parse_json", "unexpected_a", "...", 2]
6055
- // ["[.0]", "parse_json", "unexpected_a", ".", 2]
6056
6198
  // ["[0x0]", "parse_json", "unexpected_a", "0x0", 2]
6057
- // ["{...}", "parse_json", "unexpected_a", "...", 2]
6058
6199
 
6059
6200
  warn("unexpected_a");
6060
6201
  }
@@ -6082,9 +6223,8 @@ function jslint_phase3_parse(state) {
6082
6223
  case "[":
6083
6224
 
6084
6225
  // test_cause:
6085
- // ["[]", "parse_json", "bracket", "", 0]
6226
+ // ["[]", "parse_json", "(live)", "", 0]
6086
6227
 
6087
- test_cause("bracket");
6088
6228
  container = token_nxt;
6089
6229
  container.expression = [];
6090
6230
  advance("[");
@@ -6107,19 +6247,17 @@ function jslint_phase3_parse(state) {
6107
6247
  case "true":
6108
6248
 
6109
6249
  // test_cause:
6110
- // ["[false]", "parse_json", "constant", "", 0]
6111
- // ["[null]", "parse_json", "constant", "", 0]
6112
- // ["[true]", "parse_json", "constant", "", 0]
6250
+ // ["[false]", "parse_json", "(live)", "", 0]
6251
+ // ["[null]", "parse_json", "(live)", "", 0]
6252
+ // ["[true]", "parse_json", "(live)", "", 0]
6113
6253
 
6114
- test_cause("constant");
6115
6254
  advance();
6116
6255
  return token_now;
6117
6256
  case "{":
6118
6257
 
6119
6258
  // test_cause:
6120
- // ["{}", "parse_json", "brace", "", 0]
6259
+ // ["{}", "parse_json", "(live)", "", 0]
6121
6260
 
6122
- test_cause("brace");
6123
6261
  container = token_nxt;
6124
6262
 
6125
6263
  // Explicit empty-object required to detect "__proto__".
@@ -6136,6 +6274,7 @@ function jslint_phase3_parse(state) {
6136
6274
  if (token_nxt.quote !== "\"") {
6137
6275
 
6138
6276
  // test_cause:
6277
+ // ["{...}", "parse_json", "unexpected_a", "...", 2]
6139
6278
  // ["{0:0}", "parse_json", "unexpected_a", "0", 2]
6140
6279
 
6141
6280
  warn(
@@ -6184,6 +6323,9 @@ function jslint_phase3_parse(state) {
6184
6323
  default:
6185
6324
 
6186
6325
  // test_cause:
6326
+ // ["[-.0]", "parse_json", "unexpected_a", ".", 3]
6327
+ // ["[...]", "parse_json", "unexpected_a", "...", 2]
6328
+ // ["[.0]", "parse_json", "unexpected_a", ".", 2]
6187
6329
  // ["[undefined]", "parse_json", "unexpected_a", "undefined", 2]
6188
6330
 
6189
6331
  return stop("unexpected_a");
@@ -6210,13 +6352,12 @@ function jslint_phase3_parse(state) {
6210
6352
  case "}":
6211
6353
 
6212
6354
  // test_cause:
6213
- // [";", "parse_statement_block", "closer", "", 0]
6214
- // ["case", "parse_statement_block", "closer", "", 0]
6215
- // ["default", "parse_statement_block", "closer", "", 0]
6216
- // ["else", "parse_statement_block", "closer", "", 0]
6217
- // ["}", "parse_statement_block", "closer", "", 0]
6355
+ // [";", "parse_statement_block", "(live)", "", 0]
6356
+ // ["case", "parse_statement_block", "(live)", "", 0]
6357
+ // ["default", "parse_statement_block", "(live)", "", 0]
6358
+ // ["else", "parse_statement_block", "(live)", "", 0]
6359
+ // ["}", "parse_statement_block", "(live)", "", 0]
6218
6360
 
6219
- test_cause("closer");
6220
6361
  return statement_list;
6221
6362
  }
6222
6363
  a_statement = parse_statement_single();
@@ -6357,14 +6498,16 @@ function jslint_phase3_parse(state) {
6357
6498
  advance("=>");
6358
6499
 
6359
6500
  // test_cause:
6360
- // ["async aa=>0", "prefix_async", "fart_unwrapped", "aa", 0]
6501
+ // ["async aa=>0", "prefix_async", "(live)", "", 0]
6361
6502
 
6362
- test_cause("fart_unwrapped", token_prv.id);
6363
6503
  prefix_function(the_function, true, true);
6364
6504
  } else if (token_nxt.fart) {
6365
6505
 
6366
6506
  // PR-414 - Parse async fart.
6367
6507
 
6508
+ // test_cause:
6509
+ // ["aa=async(bb)=>bb", "prefix_async", "(live)", "", 0]
6510
+
6368
6511
  advance("(");
6369
6512
  prefix_function(the_function, true, false);
6370
6513
  } else {
@@ -6425,23 +6568,11 @@ function jslint_phase3_parse(state) {
6425
6568
  const sub_list = [];
6426
6569
  const the_destructure = token_now;
6427
6570
  let optional;
6428
- function advance_and_signature_push(id) {
6429
- advance(id);
6430
- if (the_function?.signature) {
6431
- the_function.signature.push(id);
6432
- switch (id) {
6433
- case ",":
6434
- case ":":
6435
- the_function.signature.push(" ");
6436
- break;
6437
- }
6438
- }
6439
- }
6440
6571
  function name_parse() {
6441
6572
  let name = token_nxt;
6442
6573
  switch (name.id) {
6443
6574
  case "...":
6444
- advance_and_signature_push("...");
6575
+ advance("...");
6445
6576
  name = token_nxt;
6446
6577
  name.ellipsis = true;
6447
6578
  if (name.id === "...") {
@@ -6460,10 +6591,9 @@ function jslint_phase3_parse(state) {
6460
6591
  }
6461
6592
 
6462
6593
  // test_cause:
6463
- // ["let[...aa]=0", "name_parse", "recurse_ellipsis", "", 0]
6464
- // ["let{...aa}=0", "name_parse", "recurse_ellipsis", "", 0]
6594
+ // ["let[...aa]=0", "name_parse", "(live)", "", 0]
6595
+ // ["let{...aa}=0", "name_parse", "(live)", "", 0]
6465
6596
 
6466
- test_cause("recurse_ellipsis");
6467
6597
  name_parse();
6468
6598
  return true;
6469
6599
  case "[":
@@ -6486,11 +6616,10 @@ function jslint_phase3_parse(state) {
6486
6616
  }
6487
6617
 
6488
6618
  // test_cause:
6489
- // ["let[[aa]]=0", "name_parse", "recurse_element", "", 0]
6490
- // ["let[{aa}]=0", "name_parse", "recurse_element", "", 0]
6619
+ // ["let[[aa]]=0", "name_parse", "(live)", "", 0]
6620
+ // ["let[{aa}]=0", "name_parse", "(live)", "", 0]
6491
6621
 
6492
- test_cause("recurse_element");
6493
- advance_and_signature_push(token_nxt.id);
6622
+ advance(token_nxt.id);
6494
6623
  prefix_destructure(
6495
6624
  scope_declared, // scope_declared
6496
6625
  role, // role
@@ -6518,9 +6647,9 @@ function jslint_phase3_parse(state) {
6518
6647
  if (is_lbrace) {
6519
6648
  survey(name);
6520
6649
  }
6521
- advance_and_signature_push(token_nxt.id);
6650
+ advance(token_nxt.id);
6522
6651
  if (is_lbrace && token_nxt.id === ":") {
6523
- advance_and_signature_push(":");
6652
+ advance(":");
6524
6653
  if (!the_function_toplevel) {
6525
6654
  the_destructure.open = true;
6526
6655
  }
@@ -6534,10 +6663,9 @@ function jslint_phase3_parse(state) {
6534
6663
  if (!token_nxt.identifier) {
6535
6664
 
6536
6665
  // test_cause:
6537
- // ["let{aa:[aa]}=0", "name_parse", "recurse_property", "", 0]
6538
- // ["let{aa:{aa}}=0", "name_parse", "recurse_property", "", 0]
6666
+ // ["let{aa:[aa]}=0", "name_parse", "(live)", "", 0]
6667
+ // ["let{aa:{aa}}=0", "name_parse", "(live)", "", 0]
6539
6668
 
6540
- test_cause("recurse_property");
6541
6669
  name_parse();
6542
6670
  return;
6543
6671
  }
@@ -6555,7 +6683,7 @@ function jslint_phase3_parse(state) {
6555
6683
 
6556
6684
  true // assigned
6557
6685
  );
6558
- advance_and_signature_push(token_nxt.id);
6686
+ advance(token_nxt.id);
6559
6687
  return;
6560
6688
  }
6561
6689
  name_declare(
@@ -6572,7 +6700,7 @@ function jslint_phase3_parse(state) {
6572
6700
  );
6573
6701
  if (token_nxt.id === "=") {
6574
6702
  optional = the_function_toplevel && token_now;
6575
- advance_and_signature_push("=");
6703
+ advance("=");
6576
6704
  if (!the_function_toplevel) {
6577
6705
  the_destructure.open = true;
6578
6706
  }
@@ -6584,23 +6712,17 @@ function jslint_phase3_parse(state) {
6584
6712
  // so <prefix_lbracket> walks it and never looks it up as a target.
6585
6713
 
6586
6714
  // test_cause:
6587
- // [";[aa=0]=0", "name_parse", "default", "", 0]
6715
+ // [";[aa=0]=0", "name_parse", "(live)", "", 0]
6588
6716
 
6589
- test_cause("default");
6590
6717
  name_list.push([name.expression]);
6591
6718
  }
6592
6719
 
6593
6720
  // test_cause:
6594
- // ["function aa([aa=aa]){}", "name_lookup", "temporal_dead_zone_a", "aa", 17]
6595
- // ["function aa([aa=aa]){}", "name_parse", "optional", "aa", 0]
6596
- // ["function aa({aa=aa}){}", "name_lookup", "temporal_dead_zone_a", "aa", 17]
6597
- // ["function aa({aa=aa}){}", "name_parse", "optional", "aa", 0]
6598
- // ["let[aa=bb]=0;let bb", "name_lookup", "temporal_dead_zone_a", "bb", 8]
6599
- // ["let[aa=bb]=0;let bb", "name_parse", "optional", "aa", 0]
6600
- // ["let{aa=bb}=0;let bb", "name_lookup", "temporal_dead_zone_a", "bb", 8]
6601
- // ["let{aa=bb}=0;let bb", "name_parse", "optional", "aa", 0]
6721
+ // ["function aa([aa=aa]){}", "name_parse", "(live)", "", 0]
6722
+ // ["function aa({aa=aa}){}", "name_parse", "(live)", "", 0]
6723
+ // ["let[aa=bb]=0;let bb", "name_parse", "(live)", "", 0]
6724
+ // ["let{aa=bb}=0;let bb", "name_parse", "(live)", "", 0]
6602
6725
 
6603
- test_cause("optional", name.id);
6604
6726
  return;
6605
6727
  }
6606
6728
  if (optional) {
@@ -6615,27 +6737,32 @@ function jslint_phase3_parse(state) {
6615
6737
  if (!is_lbrace && !the_function_toplevel && token_nxt.id === ",") {
6616
6738
 
6617
6739
  // test_cause:
6618
- // ["(,aa)=>0", "name_parse", "expected_identifier_a", ",", 2]
6619
- // ["([,aa])=>0", "prefix_destructure", "ignore", "", 0]
6620
- // [";[,aa]=0", "prefix_destructure", "ignore", "", 0]
6621
- // ["let[,aa]=0", "prefix_destructure", "ignore", "", 0]
6740
+ // ["([,aa])=>0", "prefix_destructure", "(live)", "", 0]
6741
+ // [";[,aa]=0", "prefix_destructure", "(live)", "", 0]
6742
+ // ["let[,aa]=0", "prefix_destructure", "(live)", "", 0]
6622
6743
 
6623
- test_cause("ignore");
6624
- advance_and_signature_push(",");
6744
+ advance(",");
6625
6745
  }
6626
6746
  if (the_function_toplevel) {
6627
6747
  the_function.parameter_count += 1;
6628
6748
  }
6749
+
6750
+ // test_cause:
6751
+ // ["(,aa)=>0", "name_parse", "expected_identifier_a", ",", 2]
6752
+
6629
6753
  if (name_parse()) {
6630
6754
 
6631
6755
  // Break early from ellipsis.
6632
6756
 
6757
+ if (the_function_toplevel) {
6758
+ the_function.parameter_rest = true;
6759
+ }
6633
6760
  break;
6634
6761
  }
6635
6762
  if (token_nxt.id !== ",") {
6636
6763
  break;
6637
6764
  }
6638
- advance_and_signature_push(",");
6765
+ advance(",");
6639
6766
  }
6640
6767
  name_list.push(...sub_list);
6641
6768
  if (the_function_toplevel) {
@@ -6652,10 +6779,10 @@ function jslint_phase3_parse(state) {
6652
6779
  // PR-501 - Fix false-warning about ordering in nested-object-destructuring.
6653
6780
 
6654
6781
  check_ordered(role, sub_list);
6655
- advance_and_signature_push("}");
6782
+ advance("}");
6656
6783
  return the_destructure;
6657
6784
  }
6658
- advance_and_signature_push("]");
6785
+ advance("]");
6659
6786
  return the_destructure;
6660
6787
  }
6661
6788
 
@@ -6685,7 +6812,8 @@ function jslint_phase3_parse(state) {
6685
6812
  let scope_declared = scope_block;
6686
6813
  the_function = the_function || token_now;
6687
6814
  the_function.scope_name = {
6688
- context: empty()
6815
+ context: empty(),
6816
+ name_only: true
6689
6817
  };
6690
6818
  if (mode_fart) {
6691
6819
  the_function.arity = "binary";
@@ -6756,8 +6884,13 @@ function jslint_phase3_parse(state) {
6756
6884
  the_function.finally = 0;
6757
6885
  the_function.level = scope_function.level + 1;
6758
6886
  the_function.loop = 0;
6887
+
6888
+ // PR-516 - Bugfix - Keep the name <property_parse> gives a method or accessor,
6889
+ // 'aa' or 'get aa'. Else <anon> named it after the previous identifier.
6890
+
6759
6891
  the_function.name = (
6760
6892
  name ||
6893
+ the_function.name ||
6761
6894
  (
6762
6895
  mode_fart_unwrapped
6763
6896
  ? "anonymous"
@@ -6768,7 +6901,7 @@ function jslint_phase3_parse(state) {
6768
6901
  the_function.signature = (
6769
6902
  mode_fart_unwrapped
6770
6903
  ? token_prv.id
6771
- : ["("]
6904
+ : "("
6772
6905
  );
6773
6906
  the_function.switch = 0;
6774
6907
  the_function.try = 0;
@@ -6821,6 +6954,13 @@ function jslint_phase3_parse(state) {
6821
6954
  true // assigned
6822
6955
  );
6823
6956
  } else {
6957
+ const lparen = token_now;
6958
+ let default_depth;
6959
+ let default_from;
6960
+ let default_megastring = false;
6961
+ let depth = 0;
6962
+ let signature = "";
6963
+ let token_before;
6824
6964
  if (token_nxt.id !== ")" && token_nxt.id !== "(end)") {
6825
6965
 
6826
6966
  // PR-500 - Unify ES2015-destructure-logic. - function ([aa]) {...}
@@ -6838,7 +6978,78 @@ function jslint_phase3_parse(state) {
6838
6978
  );
6839
6979
  }
6840
6980
  advance(")");
6841
- the_function.signature = the_function.signature.join("") + ")";
6981
+
6982
+ // PR-516 - Bugfix - Copy <signature> from the source text of each token but
6983
+ // comments, so it keeps default values. A space joins tokens apart in the
6984
+ // source, except after an opener or before a comma or closer. A default value
6985
+ // over 40 characters shows as an ellipsis, and so does one holding a
6986
+ // megastring, whose tokens carry columns that do not match the source.
6987
+
6988
+ for (const token of token_list.slice(lparen.nr, token_now.nr + 1)) {
6989
+ if (token.id !== "(comment)") {
6990
+ const piece = (
6991
+ (
6992
+ token_before !== undefined &&
6993
+ (
6994
+ token_before.line !== token.line ||
6995
+ token_before.thru < token.from
6996
+ ) &&
6997
+ !["(", "[", "{"].includes(token_before.id) &&
6998
+ ![")", ",", "]", "}"].includes(token.id)
6999
+ )
7000
+ ? " "
7001
+ : ""
7002
+ ) + line_list[token.line].line_source.slice(
7003
+ token.from,
7004
+ token.thru
7005
+ );
7006
+ if ([")", "]", "}"].includes(token.id)) {
7007
+ depth -= 1;
7008
+ }
7009
+
7010
+ // A default value ends at a comma or a closer of its own depth.
7011
+
7012
+ if (
7013
+ default_from !== undefined &&
7014
+ (
7015
+ depth < default_depth ||
7016
+ (depth === default_depth && token.id === ",")
7017
+ )
7018
+ ) {
7019
+ if (
7020
+ default_megastring ||
7021
+ signature.slice(default_from).trim().length > 40
7022
+ ) {
7023
+
7024
+ // test_cause:
7025
+ // ["function aa(bb=`cc`){return bb;}", "prefix_function", "(live)", "", 0]
7026
+
7027
+ signature = (
7028
+ signature.slice(0, default_from) + " \u2026"
7029
+ );
7030
+ }
7031
+ default_from = undefined;
7032
+ default_megastring = false;
7033
+ }
7034
+ signature += piece;
7035
+ if (token.id === "=" && default_from === undefined) {
7036
+ default_depth = depth;
7037
+ default_from = signature.length;
7038
+ }
7039
+ if (token.id === "`" && default_from !== undefined) {
7040
+
7041
+ // test_cause:
7042
+ // ["function aa(bb=`cc`){return bb;}", "prefix_function", "(live)", "", 0]
7043
+
7044
+ default_megastring = true;
7045
+ }
7046
+ if (["${", "(", "[", "{"].includes(token.id)) {
7047
+ depth += 1;
7048
+ }
7049
+ token_before = token;
7050
+ }
7051
+ }
7052
+ the_function.signature = signature;
6842
7053
  }
6843
7054
  if (mode_fart && !mode_fart_unwrapped) {
6844
7055
  advance("=>");
@@ -6982,9 +7193,8 @@ function jslint_phase3_parse(state) {
6982
7193
  if (!name.identifier && token_nxt.id === "...") {
6983
7194
 
6984
7195
  // test_cause:
6985
- // ["aa={...aa}", "property_parse", "ellipsis", "", 0]
7196
+ // ["aa={...aa}", "property_parse", "(live)", "", 0]
6986
7197
 
6987
- test_cause("ellipsis");
6988
7198
  value = prefix_ellipsis();
6989
7199
  return value;
6990
7200
  }
@@ -7029,9 +7239,8 @@ function jslint_phase3_parse(state) {
7029
7239
  if (!name.identifier) {
7030
7240
 
7031
7241
  // test_cause:
7032
- // ["aa={\"aa\":0}", "property_parse", "colon", "", 0]
7242
+ // ["aa={\"aa\":0}", "property_parse", "(live)", "", 0]
7033
7243
 
7034
- test_cause("colon");
7035
7244
  advance(":");
7036
7245
  value = parse_expression(0);
7037
7246
  value.name_alias = name;
@@ -7041,19 +7250,19 @@ function jslint_phase3_parse(state) {
7041
7250
  if (typeof extra === "string") {
7042
7251
 
7043
7252
  // test_cause:
7044
- // ["aa={get aa}", "property_parse", "closer", "", 0]
7253
+ // ["aa={get aa}", "property_parse", "(live)", "", 0]
7045
7254
 
7046
- test_cause("closer");
7047
7255
  advance("(");
7048
7256
  }
7049
7257
  value = parse_expression(Infinity, true);
7050
7258
  } else if (token_nxt.id === "(") {
7051
7259
 
7052
7260
  // test_cause:
7053
- // ["aa={aa()}", "property_parse", "paren", "", 0]
7054
- // ["aa={get aa(){}}", "property_parse", "paren", "", 0]
7261
+ // ["aa={aa()}", "property_parse", "(live)", "", 0]
7262
+ // ["aa={get aa(){}}", "property_parse", "(live)", "", 0]
7263
+
7264
+ // PR-516 - Bugfix - Name an accessor 'get aa' in the report, not 'get'.
7055
7265
 
7056
- test_cause("paren");
7057
7266
  value = prefix_function(
7058
7267
  {
7059
7268
  arity: "unary",
@@ -7062,7 +7271,7 @@ function jslint_phase3_parse(state) {
7062
7271
  line: name.line,
7063
7272
  name: (
7064
7273
  typeof extra === "string"
7065
- ? extra
7274
+ ? full
7066
7275
  : id
7067
7276
  ),
7068
7277
  thru: name.from
@@ -7074,9 +7283,8 @@ function jslint_phase3_parse(state) {
7074
7283
  if (typeof extra === "string") {
7075
7284
 
7076
7285
  // test_cause:
7077
- // ["aa={get aa.aa}", "property_parse", "getset_no_paren", "", 0]
7286
+ // ["aa={get aa.aa}", "property_parse", "(live)", "", 0]
7078
7287
 
7079
- test_cause("getset_no_paren");
7080
7288
  advance("(");
7081
7289
  }
7082
7290
  the_colon = token_nxt;
@@ -7176,9 +7384,8 @@ function jslint_phase3_parse(state) {
7176
7384
  if (!state.mode_json && token_nxt.id === "...") {
7177
7385
 
7178
7386
  // test_cause:
7179
- // ["aa=[...aa]", "prefix_lbracket", "ellipsis", "...", 0]
7387
+ // ["aa=[...aa]", "prefix_lbracket", "(live)", "", 0]
7180
7388
 
7181
- test_cause("ellipsis", token_nxt.id);
7182
7389
  the_token.expression.push(prefix_ellipsis());
7183
7390
 
7184
7391
  // Issue #401 - Regression - Allow multiple-ellipsis in array-literal.
@@ -7215,9 +7422,8 @@ function jslint_phase3_parse(state) {
7215
7422
  }
7216
7423
 
7217
7424
  // test_cause:
7218
- // ["(0)", "prefix_lparen", "expr", "", 0]
7425
+ // ["(0)", "prefix_lparen", "(live)", "", 0]
7219
7426
 
7220
- test_cause("expr");
7221
7427
  the_value = parse_expression(0);
7222
7428
  if (the_value.wrapped === true) {
7223
7429
 
@@ -7256,7 +7462,6 @@ function jslint_phase3_parse(state) {
7256
7462
 
7257
7463
  // test_cause:
7258
7464
  // ["new aa?.aa()", "prefix_new", "unexpected_a", "?.", 7]
7259
- // ["new aa``?.aa()", "prefix_new", "unexpected_a", "?.", 9]
7260
7465
 
7261
7466
  warn("unexpected_a", optional_chain(right), "?.");
7262
7467
  }
@@ -7291,9 +7496,8 @@ function jslint_phase3_parse(state) {
7291
7496
  advance("${");
7292
7497
 
7293
7498
  // test_cause:
7294
- // ["let aa=`${}`", "prefix_tick", "${", "", 0]
7499
+ // ["let aa=`${}`", "prefix_tick", "(live)", "", 0]
7295
7500
 
7296
- test_cause("${");
7297
7501
  the_tick.expression.push(parse_expression(0));
7298
7502
  advance("}");
7299
7503
  }
@@ -7423,6 +7627,12 @@ function jslint_phase3_parse(state) {
7423
7627
  }
7424
7628
  check_not_top_level(the_continue);
7425
7629
  the_continue.disrupt = true;
7630
+
7631
+ // test_cause:
7632
+ // ["
7633
+ // function aa(){while(aa){continue;}}
7634
+ // ", "stmt_continue", "unexpected_a", "continue", 25]
7635
+
7426
7636
  warn("unexpected_a", the_continue);
7427
7637
  semicolon();
7428
7638
  return the_continue;
@@ -7489,8 +7699,8 @@ function jslint_phase3_parse(state) {
7489
7699
  if (the_do.block.disrupt === true) {
7490
7700
 
7491
7701
  // test_cause:
7492
- // [" do{break}while(0)", "stmt_do", "weird_loop", "do", 2]
7493
- // ["do{break}while(0)", "stmt_do", "weird_loop", "do", 1]
7702
+ // ["function aa(){ do{break}while(0)}", "stmt_do", "weird_loop", "do", 16]
7703
+ // ["function aa(){do{break}while(0)}", "stmt_do", "weird_loop", "do", 15]
7494
7704
 
7495
7705
  warn("weird_loop", the_do);
7496
7706
  }
@@ -7558,15 +7768,19 @@ function jslint_phase3_parse(state) {
7558
7768
  the_name = the_thing.name;
7559
7769
  the_id = the_name.id;
7560
7770
  the_name.used = true;
7561
- if (export_dict[the_id] !== undefined) {
7562
7771
 
7563
- // test_cause:
7564
- // ["
7565
- // let aa;export{aa};export function aa(){}
7566
- // ", "stmt_export", "duplicate_a", "aa", 35]
7772
+ // PR-xxx - deadcode-confirmed - This duplicate is never shown. An earlier
7773
+ // export of <the_id> needs it declared at top level, so declaring it again
7774
+ // above warns redefinition_a_b on the same token first, and <warn> drops a
7775
+ // second warning on one token.
7776
+ //
7777
+ // deadcode-revive - Check for the duplicate before <parse_statement_single>
7778
+ // declares the name, or let a token carry more than one warning.
7779
+ //
7780
+ // if (export_dict[the_id] !== undefined) {
7781
+ // warn("duplicate_a", the_name);
7782
+ // }
7567
7783
 
7568
- warn("duplicate_a", the_name);
7569
- }
7570
7784
  export_dict[the_id] = the_thing;
7571
7785
  the_export.expression.push(the_thing);
7572
7786
  the_thing.statement = false;
@@ -7587,9 +7801,8 @@ function jslint_phase3_parse(state) {
7587
7801
  } else if (token_nxt.id === "{") {
7588
7802
 
7589
7803
  // test_cause:
7590
- // ["export {}", "stmt_export", "advance{", "", 0]
7804
+ // ["export {}", "stmt_export", "(live)", "", 0]
7591
7805
 
7592
- test_cause("advance{");
7593
7806
  advance("{");
7594
7807
  while (true) {
7595
7808
  if (!token_nxt.identifier) {
@@ -7631,7 +7844,9 @@ function jslint_phase3_parse(state) {
7631
7844
  // PR-439 - Check exported properties are ordered.
7632
7845
 
7633
7846
  // test_cause:
7634
- // ["export {bb, aa}", "check_ordered", "expected_a_b_before_c_d", "aa", 13]
7847
+ // ["
7848
+ // let aa;let bb;export {bb, aa};
7849
+ // ", "check_ordered", "expected_a_b_before_c_d", "aa", 27]
7635
7850
 
7636
7851
  check_ordered("export", export_list);
7637
7852
  advance("}");
@@ -7667,7 +7882,9 @@ function jslint_phase3_parse(state) {
7667
7882
  if (the_for.for_semicolon) {
7668
7883
 
7669
7884
  // test_cause:
7670
- // ["for await(;;){}", "stmt_for", "expected_a", "for await...of", 1]
7885
+ // ["
7886
+ // function aa(){for await(;;){}}
7887
+ // ", "stmt_for", "expected_a", "for await...of", 15]
7671
7888
 
7672
7889
  warn("expected_a", the_for, "for await...of");
7673
7890
  }
@@ -7679,6 +7896,10 @@ function jslint_phase3_parse(state) {
7679
7896
  warn("unexpected_a", token_nxt);
7680
7897
  }
7681
7898
  if (scope_function.async === 1) {
7899
+
7900
+ // test_cause:
7901
+ // ["async function aa(bb){for await(aa of bb){}}", "stmt_for", "(live)", "", 0]
7902
+
7682
7903
  scope_function.async = 2;
7683
7904
  }
7684
7905
  advance("await");
@@ -7705,9 +7926,8 @@ function jslint_phase3_parse(state) {
7705
7926
  case "let":
7706
7927
 
7707
7928
  // test_cause:
7708
- // ["for(let aa;;){}", "stmt_for", "let", "let", 0]
7929
+ // ["for(let aa;;){}", "stmt_for", "(live)", "", 0]
7709
7930
 
7710
- test_cause("let", token_nxt.id);
7711
7931
  break;
7712
7932
  default:
7713
7933
 
@@ -7724,9 +7944,8 @@ function jslint_phase3_parse(state) {
7724
7944
  while (token_nxt.id === ",") {
7725
7945
 
7726
7946
  // test_cause:
7727
- // ["for(aa=0,bb=0;;){}", "stmt_for", "for_init_comma", "", 0]
7947
+ // ["for(aa=0,bb=0;;){}", "stmt_for", "(live)", "", 0]
7728
7948
 
7729
- test_cause("for_init_comma");
7730
7949
  advance(",");
7731
7950
  parse_expression(0);
7732
7951
  semicolon();
@@ -7758,12 +7977,11 @@ function jslint_phase3_parse(state) {
7758
7977
  case "let":
7759
7978
 
7760
7979
  // test_cause:
7761
- // ["for(const aa in aa){}", "stmt_for", "for_of_const", "const", 0]
7762
- // ["for(const aa of aa){}", "stmt_for", "for_of_const", "const", 0]
7763
- // ["for(let aa in aa){}", "stmt_for", "for_of_const", "let", 0]
7764
- // ["for(let aa of aa){}", "stmt_for", "for_of_const", "let", 0]
7980
+ // ["for(const aa in aa){}", "stmt_for", "(live)", "", 0]
7981
+ // ["for(const aa of aa){}", "stmt_for", "(live)", "", 0]
7982
+ // ["for(let aa in aa){}", "stmt_for", "(live)", "", 0]
7983
+ // ["for(let aa of aa){}", "stmt_for", "(live)", "", 0]
7765
7984
 
7766
- test_cause("for_of_const", token_nxt.id);
7767
7985
  break;
7768
7986
  case "var":
7769
7987
 
@@ -7802,6 +8020,7 @@ function jslint_phase3_parse(state) {
7802
8020
 
7803
8021
  // test_cause:
7804
8022
  // ["for(aa 0){}", "stmt_for", "expected_a_b", "0", 8]
8023
+ // ["for(aa=aa){}", "stmt_for", "expected_a_b", "=", 7]
7805
8024
 
7806
8025
  return stop(
7807
8026
  "expected_a_b",
@@ -7832,10 +8051,16 @@ function jslint_phase3_parse(state) {
7832
8051
  // iterable, so a bare 'for...of' would throw a TypeError.
7833
8052
 
7834
8053
  // test_cause:
7835
- // ["for(aa in aa){}", "stmt_for", "expected_a_b", "for in", 1]
7836
- // ["for(const aa in aa){}", "stmt_for", "expected_a_b", "for in", 1]
7837
- // ["for(let aa in aa){}", "stmt_for", "expected_a_b", "for in", 1]
7838
- // ["for(var aa in aa){}", "stmt_for", "expected_a_b", "for in", 1]
8054
+ // ["function aa(){for(aa in aa){}}", "stmt_for", "expected_a_b", "for in", 15]
8055
+ // ["
8056
+ // function aa(){for(const aa in aa){}}
8057
+ // ", "stmt_for", "expected_a_b", "for in", 15]
8058
+ // ["
8059
+ // function aa(){for(let aa in aa){}}
8060
+ // ", "stmt_for", "expected_a_b", "for in", 15]
8061
+ // ["
8062
+ // function aa(){for(var aa in aa){}}
8063
+ // ", "stmt_for", "expected_a_b", "for in", 15]
7839
8064
 
7840
8065
  warn("expected_a_b", the_for, "for...of Object.keys", "for in");
7841
8066
  break;
@@ -7845,19 +8070,17 @@ function jslint_phase3_parse(state) {
7845
8070
  case "of":
7846
8071
 
7847
8072
  // test_cause:
7848
- // ["for(aa of aa){}", "stmt_for", "of", "of", 0]
7849
- // ["for(aa of aa||aa){}", "stmt_for", "of", "of", 0]
7850
- // ["for(const aa of aa){}", "stmt_for", "of", "of", 0]
7851
- // ["for(let aa of aa){}", "stmt_for", "of", "of", 0]
7852
- // ["for(var aa of aa){}", "stmt_for", "of", "of", 0]
8073
+ // ["for(aa of aa){}", "stmt_for", "(live)", "", 0]
8074
+ // ["for(aa of aa||aa){}", "stmt_for", "(live)", "", 0]
8075
+ // ["for(const aa of aa){}", "stmt_for", "(live)", "", 0]
8076
+ // ["for(let aa of aa){}", "stmt_for", "(live)", "", 0]
8077
+ // ["for(var aa of aa){}", "stmt_for", "(live)", "", 0]
7853
8078
 
7854
- test_cause("of", the_operator.id);
7855
8079
  the_operator.for_init = true;
7856
8080
  break;
7857
8081
  default:
7858
8082
 
7859
8083
  // test_cause:
7860
- // ["for(aa=aa){}", "stmt_for", "expected_a_b", "=", 7]
7861
8084
  // ["for(const aa=aa){}", "stmt_for", "expected_a_b", "=", 13]
7862
8085
  // ["for(let aa=aa){}", "stmt_for", "expected_a_b", "=", 11]
7863
8086
  // ["for(var aa=aa){}", "stmt_for", "expected_a_b", "=", 11]
@@ -7902,17 +8125,15 @@ function jslint_phase3_parse(state) {
7902
8125
  );
7903
8126
 
7904
8127
  // test_cause:
7905
- // ["if(0){0}else if(0){0}", "stmt_if", "else", "", 0]
7906
- // ["if(0){0}else{0}", "stmt_if", "else", "", 0]
8128
+ // ["if(0){0}else if(0){0}", "stmt_if", "(live)", "", 0]
8129
+ // ["if(0){0}else{0}", "stmt_if", "(live)", "", 0]
7907
8130
 
7908
- test_cause("else");
7909
8131
  if (the_if.block.disrupt === true) {
7910
8132
  if (the_if.else.disrupt === true) {
7911
8133
 
7912
8134
  // test_cause:
7913
- // ["if(0){break}else{break}", "stmt_if", "disrupt", "", 0]
8135
+ // ["if(0){break}else{break}", "stmt_if", "(live)", "", 0]
7914
8136
 
7915
- test_cause("disrupt");
7916
8137
  the_if.disrupt = true;
7917
8138
  } else {
7918
8139
 
@@ -7938,9 +8159,8 @@ function jslint_phase3_parse(state) {
7938
8159
  if (token_nxt.id === "(string)") {
7939
8160
 
7940
8161
  // test_cause:
7941
- // ["import \"aa\"", "stmt_import", "import_side_effect", "", 0]
8162
+ // ["import \"aa\"", "stmt_import", "expected_a_b", "aa", 8]
7942
8163
 
7943
- test_cause("import_side_effect");
7944
8164
  warn("expected_a_b", token_nxt, "{", artifact());
7945
8165
  advance();
7946
8166
  semicolon();
@@ -8036,6 +8256,10 @@ function jslint_phase3_parse(state) {
8036
8256
  if (token_nxt.id !== ",") {
8037
8257
  break;
8038
8258
  }
8259
+
8260
+ // test_cause:
8261
+ // ["import {aa,bb} from \"aa\"", "stmt_import", "(live)", "", 0]
8262
+
8039
8263
  advance(",");
8040
8264
  }
8041
8265
  }
@@ -8062,6 +8286,10 @@ function jslint_phase3_parse(state) {
8062
8286
  if (token_nxt.id !== ",") {
8063
8287
  break;
8064
8288
  }
8289
+
8290
+ // test_cause:
8291
+ // ["import aa,{bb} from \"aa\"", "stmt_import", "(live)", "", 0]
8292
+
8065
8293
  advance(",");
8066
8294
  }
8067
8295
  advance("from");
@@ -8079,6 +8307,10 @@ function jslint_phase3_parse(state) {
8079
8307
  // Issue #495 - Add ES2025-syntax "import ... with {...}".
8080
8308
 
8081
8309
  if (token_nxt.id === "with") {
8310
+
8311
+ // test_cause:
8312
+ // ["import aa from \"aa\" with {}", "stmt_import", "(live)", "", 0]
8313
+
8082
8314
  advance("with");
8083
8315
  advance("{");
8084
8316
  prefix_lbrace();
@@ -8106,12 +8338,11 @@ function jslint_phase3_parse(state) {
8106
8338
  case "while":
8107
8339
 
8108
8340
  // test_cause:
8109
- // ["aa:do", "stmt_label", "label", "do", 0]
8110
- // ["aa:for", "stmt_label", "label", "for", 0]
8111
- // ["aa:switch", "stmt_label", "label", "switch", 0]
8112
- // ["aa:while", "stmt_label", "label", "while", 0]
8341
+ // ["aa:do", "stmt_label", "(live)", "", 0]
8342
+ // ["aa:for", "stmt_label", "(live)", "", 0]
8343
+ // ["aa:switch", "stmt_label", "(live)", "", 0]
8344
+ // ["aa:while", "stmt_label", "(live)", "", 0]
8113
8345
 
8114
- test_cause("label", token_nxt.id);
8115
8346
  break;
8116
8347
  default:
8117
8348
 
@@ -8464,11 +8695,12 @@ function jslint_phase3_parse(state) {
8464
8695
  advance(")");
8465
8696
  }
8466
8697
 
8698
+ if (token_nxt.id !== "{") {
8699
+
8467
8700
  // test_cause:
8468
8701
  // ["try{}catch(aa);", "stmt_try", "expected_a_b", ";", 15]
8469
8702
  // ["try{}catch(aa);;", "stmt_try", "expected_a_b", ";", 15]
8470
8703
 
8471
- if (token_nxt.id !== "{") {
8472
8704
  return stop("expected_a_b", token_nxt, "{", artifact());
8473
8705
  }
8474
8706
  the_catch.block = block(ignored);
@@ -8494,10 +8726,11 @@ function jslint_phase3_parse(state) {
8494
8726
  scope_function.finally += 1;
8495
8727
  advance("finally");
8496
8728
 
8729
+ if (token_nxt.id !== "{") {
8730
+
8497
8731
  // test_cause:
8498
8732
  // ["try{}finally;", "stmt_try", "expected_a_b", ";", 13]
8499
8733
 
8500
- if (token_nxt.id !== "{") {
8501
8734
  return stop("expected_a_b", token_nxt, "{", artifact());
8502
8735
  }
8503
8736
  the_try.finally = block();
@@ -8536,24 +8769,22 @@ function jslint_phase3_parse(state) {
8536
8769
  if (for_init) {
8537
8770
 
8538
8771
  // test_cause:
8539
- // ["for(let aa in 0){}", "advance_operator", "for_init", "in", 0]
8540
- // ["for(let aa of 0){}", "advance_operator", "for_init", "of", 0]
8541
- // ["for(let {aa} in 0){}", "advance_operator", "for_init", "in", 0]
8542
- // ["for(let {aa} of 0){}", "advance_operator", "for_init", "of", 0]
8772
+ // ["for(let aa in 0){}", "advance_operator", "(live)", "", 0]
8773
+ // ["for(let aa of 0){}", "advance_operator", "(live)", "", 0]
8774
+ // ["for(let {aa} in 0){}", "advance_operator", "(live)", "", 0]
8775
+ // ["for(let {aa} of 0){}", "advance_operator", "(live)", "", 0]
8543
8776
 
8544
- test_cause("for_init", the_operator.id);
8545
8777
  the_variable.operator = the_operator;
8546
8778
  advance();
8547
8779
  break;
8548
8780
  }
8549
8781
 
8550
8782
  // test_cause:
8551
- // ["let aa in 0", "advance_operator", "not_for_init", "in", 0]
8552
- // ["let aa of 0", "advance_operator", "not_for_init", "of", 0]
8553
- // ["let {aa} in 0", "advance_operator", "not_for_init", "in", 0]
8554
- // ["let {aa} of 0", "advance_operator", "not_for_init", "of", 0]
8783
+ // ["let aa in 0", "advance_operator", "(live)", "", 0]
8784
+ // ["let aa of 0", "advance_operator", "(live)", "", 0]
8785
+ // ["let {aa} in 0", "advance_operator", "(live)", "", 0]
8786
+ // ["let {aa} of 0", "advance_operator", "(live)", "", 0]
8555
8787
 
8556
- test_cause("not_for_init", the_operator.id);
8557
8788
  the_variable.operator = the_operator;
8558
8789
  advance("=");
8559
8790
  break;
@@ -8689,8 +8920,8 @@ function jslint_phase3_parse(state) {
8689
8920
  if (the_while.block.disrupt === true) {
8690
8921
 
8691
8922
  // test_cause:
8692
- // [" while(0){break}", "stmt_while", "weird_loop", "while", 2]
8693
- // ["while(0){break}", "stmt_while", "weird_loop", "while", 1]
8923
+ // ["function aa(){ while(0){break}}", "stmt_while", "weird_loop", "while", 16]
8924
+ // ["function aa(){while(0){break}}", "stmt_while", "weird_loop", "while", 15]
8694
8925
 
8695
8926
  warn("weird_loop", the_while);
8696
8927
  }
@@ -9077,8 +9308,8 @@ function jslint_phase4_walk(state) {
9077
9308
  scope_block_push,
9078
9309
  scope_function_pop,
9079
9310
  scope_function_push,
9311
+ scope_report_push,
9080
9312
  syntax_dict,
9081
- test_cause,
9082
9313
  token_global,
9083
9314
  warn
9084
9315
  } = state;
@@ -9181,10 +9412,9 @@ function jslint_phase4_walk(state) {
9181
9412
  // only the first warning of a token.
9182
9413
 
9183
9414
  // test_cause:
9184
- // ["aa+=0", "check_assignable", "undeclared", "", 0]
9185
- // ["aa=0", "check_assignable", "undeclared", "", 0]
9415
+ // ["aa+=0", "check_assignable", "(live)", "", 0]
9416
+ // ["aa=0", "check_assignable", "(live)", "", 0]
9186
9417
 
9187
- test_cause("undeclared");
9188
9418
  return false;
9189
9419
  }
9190
9420
  if (the_variable.readonly) {
@@ -9194,7 +9424,10 @@ function jslint_phase4_walk(state) {
9194
9424
  // ["const aa=0;aa++", "check_assignable", "bad_assignment_a", "aa", 12]
9195
9425
  // ["const aa=0;aa+=0", "check_assignable", "bad_assignment_a", "aa", 12]
9196
9426
  // ["const aa=0;aa=0", "check_assignable", "bad_assignment_a", "aa", 12]
9197
- // ["function aa(){}aa=0", "check_assignable", "bad_assignment_a", "aa", 16]
9427
+ // ["
9428
+ // function aa(){}
9429
+ // aa=0
9430
+ // ", "check_assignable", "bad_assignment_a", "aa", 1]
9198
9431
 
9199
9432
  warn("bad_assignment_a", name);
9200
9433
  return false;
@@ -9208,6 +9441,7 @@ function jslint_phase4_walk(state) {
9208
9441
  // return its variable, parameter, label or global, or undefined if undeclared.
9209
9442
 
9210
9443
  const id = thing.id;
9444
+ const ii_function = block_stack.indexOf(scope_function);
9211
9445
  let the_label;
9212
9446
  let the_variable;
9213
9447
 
@@ -9241,20 +9475,19 @@ function jslint_phase4_walk(state) {
9241
9475
  if (the_variable?.role === "label") {
9242
9476
 
9243
9477
  // test_cause:
9244
- // ["aa:while(0){aa}", "name_lookup", "skip_label", "aa", 0]
9245
- // ["
9246
- // function aa(){aa:while(aa){break aa;}}
9247
- // ", "name_lookup", "skip_label", "aa", 0]
9478
+ // ["aa:while(0){aa}", "name_lookup", "(live)", "", 0]
9479
+ // ["function aa(){aa:while(aa){break aa;}}", "name_lookup", "(live)", "", 0]
9248
9480
 
9249
- test_cause("skip_label", id);
9250
9481
  the_label = the_variable;
9251
9482
  the_variable = undefined;
9252
9483
  }
9253
- if (the_variable && ii > 0) {
9484
+ if (the_variable && ii > ii_function) {
9254
9485
 
9255
- // If found outside current-scope, mark as closure.
9486
+ // PR-516 - Bugfix - Mark closure only if found outside the current function,
9487
+ // not merely outside the current scope_block, and record it for the report.
9256
9488
 
9257
9489
  the_variable.closure = true;
9490
+ scope_report_push(scope_function, the_variable);
9258
9491
  }
9259
9492
  return the_variable;
9260
9493
  });
@@ -9272,8 +9505,14 @@ function jslint_phase4_walk(state) {
9272
9505
  // ["(function aa(){})aa", "name_lookup", "undeclared_a", "aa", 18]
9273
9506
  // ["aa", "name_lookup", "undeclared_a", "aa", 1]
9274
9507
  // ["class aa{}", "name_lookup", "undeclared_a", "aa", 7]
9275
- // ["function aa(){function bb(){}}bb", "name_lookup", "undeclared_a", "bb", 31]
9276
- // ["function aa(){var bb}bb", "name_lookup", "undeclared_a", "bb", 22]
9508
+ // ["
9509
+ // function aa(){function bb(){}}
9510
+ // bb
9511
+ // ", "name_lookup", "undeclared_a", "bb", 1]
9512
+ // ["
9513
+ // function aa(){var bb}
9514
+ // bb
9515
+ // ", "name_lookup", "undeclared_a", "bb", 1]
9277
9516
  // ["if(0){const aa=0}aa", "name_lookup", "undeclared_a", "aa", 18]
9278
9517
  // ["if(0){function aa(){}}aa", "name_lookup", "undeclared_a", "aa", 23]
9279
9518
  // ["if(0){let aa}aa", "name_lookup", "undeclared_a", "aa", 14]
@@ -9309,6 +9548,7 @@ function jslint_phase4_walk(state) {
9309
9548
  // 3.glo.1 - Mark 'declared', the global-variable, immediately.
9310
9549
 
9311
9550
  token_global.context[id] = the_variable;
9551
+ scope_report_push(scope_function, the_variable);
9312
9552
  }
9313
9553
  if (!the_variable.alive) {
9314
9554
 
@@ -9351,6 +9591,10 @@ function jslint_phase4_walk(state) {
9351
9591
  // 'undefined' is nullish and falsy, so it counts as assigned. '&&=' does not
9352
9592
  // assign it, and still warns unassigned_var_a.
9353
9593
 
9594
+ // test_cause:
9595
+ // ["let aa;aa??=0", "post_a_assignment", "(live)", "", 0]
9596
+ // ["let aa;aa||=0", "post_a_assignment", "(live)", "", 0]
9597
+
9354
9598
  lvalue.variable.assigned = true;
9355
9599
  }
9356
9600
  right = syntax_dict[thing.expression[1].id];
@@ -9368,7 +9612,7 @@ function jslint_phase4_walk(state) {
9368
9612
  ) {
9369
9613
 
9370
9614
  // test_cause:
9371
- // ["aa+=undefined", "post_a_assignment", "unexpected_a", "undefined", 5]
9615
+ // ["aa-=undefined", "post_a_assignment", "unexpected_a", "undefined", 5]
9372
9616
 
9373
9617
  warn("unexpected_a", thing.expression[1]);
9374
9618
  }
@@ -9389,8 +9633,12 @@ function jslint_phase4_walk(state) {
9389
9633
  if (lvalue.id === "." && thing.expression[1].id === "undefined") {
9390
9634
 
9391
9635
  // test_cause:
9392
- // [" aa.aa=undefined", "post_a_assignment", "expected_a_b", "undefined", 2]
9393
- // ["aa.aa=undefined", "post_a_assignment", "expected_a_b", "undefined", 1]
9636
+ // ["
9637
+ // let aa; aa.aa=undefined;
9638
+ // ", "post_a_assignment", "expected_a_b", "undefined", 9]
9639
+ // ["
9640
+ // let aa;aa.aa=undefined;
9641
+ // ", "post_a_assignment", "expected_a_b", "undefined", 8]
9394
9642
 
9395
9643
  warn("expected_a_b", lvalue.expression, "delete", "undefined");
9396
9644
  return;
@@ -9408,6 +9656,10 @@ function jslint_phase4_walk(state) {
9408
9656
  right.id === "undefined" ||
9409
9657
  Number.isNaN(right.value)
9410
9658
  ) {
9659
+
9660
+ // test_cause:
9661
+ // ["let aa=0;aa+=0;", "post_a_pluseq", "unexpected_a", "0", 14]
9662
+
9411
9663
  warn("unexpected_a", right);
9412
9664
  }
9413
9665
  }
@@ -9471,13 +9723,13 @@ function jslint_phase4_walk(state) {
9471
9723
  if (thing.expression[0].value === "") {
9472
9724
 
9473
9725
  // test_cause:
9474
- // ["\"\"+0", "post_b_binary", "expected_a_b", "\"\" +", 3]
9726
+ // ["let aa=\"\"+0;", "post_b_binary", "expected_a_b", "\"\" +", 10]
9475
9727
 
9476
9728
  warn("expected_a_b", thing, "String(...)", "\"\" +");
9477
9729
  } else if (thing.expression[1].value === "") {
9478
9730
 
9479
9731
  // test_cause:
9480
- // ["0+\"\"", "post_b_binary", "expected_a_b", "+ \"\"", 2]
9732
+ // ["let aa=0+\"\";", "post_b_binary", "expected_a_b", "+ \"\"", 9]
9481
9733
 
9482
9734
  warn("expected_a_b", thing, "String(...)", "+ \"\"");
9483
9735
  }
@@ -9533,8 +9785,15 @@ function jslint_phase4_walk(state) {
9533
9785
  thing.id === "**" &&
9534
9786
  thing.expression[0].arity === "unary" &&
9535
9787
  !thing.expression[0].wrapped &&
9788
+
9789
+ // PR-xxx - deadcode-confirmed - A 'void' here never showed its warning, since
9790
+ // <prefix_void> has already warned on the same token, and <warn> drops a
9791
+ // second warning on one token.
9792
+ //
9793
+ // deadcode-revive - Let a token carry more than one warning, and list "void".
9794
+
9536
9795
  [
9537
- "!", "!!", "+", "-", "await", "typeof", "void", "~"
9796
+ "!", "!!", "+", "-", "await", "typeof", "~"
9538
9797
  ].includes(thing.expression[0].id)
9539
9798
  ) {
9540
9799
 
@@ -9543,15 +9802,23 @@ function jslint_phase4_walk(state) {
9543
9802
  // '-aa ** 2' needs parens, while '[aa] ** 2' and '++aa ** 2' do not.
9544
9803
 
9545
9804
  // test_cause:
9546
- // ["aa=!!0**0", "post_b_binary", "wrap_subexpression_a_b", "**", 4]
9547
- // ["aa=!0**0", "post_b_binary", "wrap_subexpression_a_b", "**", 4]
9548
- // ["aa=+0**0", "post_b_binary", "wrap_subexpression_a_b", "**", 4]
9805
+ // ["
9806
+ // /*jslint bitwise*/
9807
+ // let aa;aa=~aa**aa;
9808
+ // ", "post_b_binary", "wrap_subexpression_a_b", "**", 11]
9809
+ // ["
9810
+ // /*jslint convert*/
9811
+ // let aa;aa=!!aa**aa;
9812
+ // ", "post_b_binary", "wrap_subexpression_a_b", "**", 11]
9813
+ // ["
9814
+ // /*jslint convert*/
9815
+ // let aa;aa=+aa**aa;
9816
+ // ", "post_b_binary", "wrap_subexpression_a_b", "**", 11]
9549
9817
  // ["aa=-0**0", "post_b_binary", "wrap_subexpression_a_b", "**", 4]
9550
- // ["aa=void 0**0", "post_b_binary", "wrap_subexpression_a_b", "**", 4]
9551
- // ["aa=~0**0", "post_b_binary", "wrap_subexpression_a_b", "**", 4]
9552
9818
  // ["
9553
9819
  // async function aa(){return await aa**0;}
9554
9820
  // ", "post_b_binary", "wrap_subexpression_a_b", "**", 28]
9821
+ // ["let aa;aa=!aa**aa;", "post_b_binary", "wrap_subexpression_a_b", "**", 11]
9555
9822
 
9556
9823
  warn(
9557
9824
  "wrap_subexpression_a_b",
@@ -9574,8 +9841,8 @@ function jslint_phase4_walk(state) {
9574
9841
  ) {
9575
9842
 
9576
9843
  // test_cause:
9577
- // ["0&&0??0", "post_b_binary", "wrap_subexpression_a_b", "??", 2]
9578
- // ["0??0||0", "post_b_binary", "wrap_subexpression_a_b", "??", 5]
9844
+ // ["aa&&bb??cc", "post_b_binary", "wrap_subexpression_a_b", "??", 3]
9845
+ // ["aa??bb||cc", "post_b_binary", "wrap_subexpression_a_b", "??", 7]
9579
9846
 
9580
9847
  warn("wrap_subexpression_a_b", thang, thang.id, "??");
9581
9848
  }
@@ -9629,6 +9896,18 @@ function jslint_phase4_walk(state) {
9629
9896
  }
9630
9897
  } else if (left.identifier) {
9631
9898
  if (the_new !== undefined) {
9899
+
9900
+ // PR-xxx - deadcode-confirmed - A branch for 'new Function' never showed its
9901
+ // warning. Without option eval, <constant_Function> has already warned on the
9902
+ // same 'Function' token, and <warn> drops a second warning on one token.
9903
+ //
9904
+ // deadcode-revive - Let a token carry more than one warning.
9905
+ //
9906
+ // } else if (left.id === "Function") {
9907
+ // if (!option_dict.eval) {
9908
+ // warn("unexpected_a", left, "new Function");
9909
+ // }
9910
+
9632
9911
  if (
9633
9912
  left.id[0] > "Z" ||
9634
9913
  left.id === "BigInt" ||
@@ -9647,20 +9926,13 @@ function jslint_phase4_walk(state) {
9647
9926
  // ["new aa()", "post_b_lparen", "unexpected_a", "new", 1]
9648
9927
 
9649
9928
  warn("unexpected_a", the_new);
9650
- } else if (left.id === "Function") {
9651
- if (!option_dict.eval) {
9652
-
9653
- // test_cause:
9654
- // ["new Function()", "post_b_lparen", "unexpected_a", "new Function", 5]
9655
-
9656
- warn("unexpected_a", left, "new Function");
9657
- }
9658
9929
  } else if (left.id === "Array") {
9659
9930
  arg = thing.expression;
9660
9931
  if (arg.length !== 2 || arg[1].id === "(string)") {
9661
9932
 
9662
9933
  // test_cause:
9663
9934
  // ["new Array()", "post_b_lparen", "expected_a_b", "new Array", 5]
9935
+ // ["new Array(0,\"bb\")", "post_b_lparen", "expected_a_b", "new Array", 5]
9664
9936
 
9665
9937
  warn("expected_a_b", left, "[]", "new Array");
9666
9938
  }
@@ -9688,7 +9960,7 @@ function jslint_phase4_walk(state) {
9688
9960
  ) {
9689
9961
 
9690
9962
  // test_cause:
9691
- // ["let Aa=Aa()", "post_b_lparen", "expected_a_before_b", "Aa", 8]
9963
+ // ["let Aa;let bb=Aa();", "post_b_lparen", "expected_a_before_b", "Aa", 15]
9692
9964
 
9693
9965
  warn("expected_a_before_b", left, "new", artifact(left));
9694
9966
  }
@@ -9698,9 +9970,8 @@ function jslint_phase4_walk(state) {
9698
9970
  if (left.expression.id === "Date" && left.name.id === "UTC") {
9699
9971
 
9700
9972
  // test_cause:
9701
- // ["new Date.UTC()", "post_b_lparen", "cack", "", 0]
9973
+ // ["new Date.UTC()", "post_b_lparen", "(live)", "", 0]
9702
9974
 
9703
- test_cause("cack");
9704
9975
  cack = !cack;
9705
9976
  }
9706
9977
  if (jslint_rgx_cap.test(left.name.id) !== cack) {
@@ -9713,7 +9984,7 @@ function jslint_phase4_walk(state) {
9713
9984
  } else {
9714
9985
 
9715
9986
  // test_cause:
9716
- // ["let Aa=Aa.Aa()", "post_b_lparen", "expected_a_before_b", "Aa", 8]
9987
+ // ["let Aa;let bb=Aa.Aa();", "post_b_lparen", "expected_a_before_b", "Aa", 15]
9717
9988
 
9718
9989
  warn(
9719
9990
  "expected_a_before_b",
@@ -9853,16 +10124,13 @@ function jslint_phase4_walk(state) {
9853
10124
  if (name.expression) {
9854
10125
 
9855
10126
  // test_cause:
9856
- // ["let aa=0", "post_s_var", "let aa=0", "", 0]
10127
+ // ["function aa([aa=aa]){}", "name_lookup", "temporal_dead_zone_a", "aa", 17]
10128
+ // ["function aa({aa=aa}){}", "name_lookup", "temporal_dead_zone_a", "aa", 17]
10129
+ // ["let aa=0", "post_s_var", "(live)", "", 0]
10130
+ // ["let[aa=bb]=0;let bb", "name_lookup", "temporal_dead_zone_a", "bb", 8]
10131
+ // ["let{aa=bb}=0;let bb", "name_lookup", "temporal_dead_zone_a", "bb", 8]
9857
10132
 
9858
- test_cause("let aa=0");
9859
10133
  walk_expression(name.expression);
9860
- } else {
9861
-
9862
- // test_cause:
9863
- // ["let aa", "post_s_var", "let aa", "", 0]
9864
-
9865
- test_cause("let aa");
9866
10134
  }
9867
10135
 
9868
10136
  // PR-502 - Fix long-running regression where 'let x = x;'
@@ -9889,13 +10157,13 @@ function jslint_phase4_walk(state) {
9889
10157
  } else if (is_equal(thing.expression[0], thing.expression[1])) {
9890
10158
 
9891
10159
  // test_cause:
9892
- // ["aa?aa:0", "post_t_ternary", "expected_a_b", "?", 3]
10160
+ // ["let aa;let bb=(aa?aa:0);", "post_t_ternary", "expected_a_b", "?", 18]
9893
10161
 
9894
10162
  warn("expected_a_b", thing, "||", "?");
9895
10163
  } else if (is_equal(thing.expression[0], thing.expression[2])) {
9896
10164
 
9897
10165
  // test_cause:
9898
- // ["aa?0:aa", "post_t_ternary", "expected_a_b", "?", 3]
10166
+ // ["let aa;let bb=(aa?0:aa);", "post_t_ternary", "expected_a_b", "?", 18]
9899
10167
 
9900
10168
  warn("expected_a_b", thing, "&&", "?");
9901
10169
  } else if (
@@ -9904,7 +10172,7 @@ function jslint_phase4_walk(state) {
9904
10172
  ) {
9905
10173
 
9906
10174
  // test_cause:
9907
- // ["aa?true:false", "post_t_ternary", "expected_a_b", "?", 3]
10175
+ // ["let aa;let bb=(aa?true:false);", "post_t_ternary", "expected_a_b", "?", 18]
9908
10176
 
9909
10177
  warn("expected_a_b", thing, "Boolean(...)", "?");
9910
10178
  } else if (
@@ -9913,7 +10181,7 @@ function jslint_phase4_walk(state) {
9913
10181
  ) {
9914
10182
 
9915
10183
  // test_cause:
9916
- // ["aa?false:true", "post_t_ternary", "expected_a_b", "?", 3]
10184
+ // ["let aa;let bb=(aa?false:true);", "post_t_ternary", "expected_a_b", "?", 18]
9917
10185
 
9918
10186
  warn("expected_a_b", thing, "!", "?");
9919
10187
  } else if (
@@ -9946,12 +10214,22 @@ function jslint_phase4_walk(state) {
9946
10214
  warn("expected_a_b", thing, "Number(...)", "+");
9947
10215
  }
9948
10216
  if (right.id === "(" && right.expression[0].id === "new") {
10217
+
10218
+ // test_cause:
10219
+ // ["
10220
+ // /*jslint convert*/let aa=+new Date();
10221
+ // ", "post_u_plus", "unexpected_a_before_b", "new", 26]
10222
+
9949
10223
  warn("unexpected_a_before_b", thing, "+", "new");
9950
10224
  } else if (
9951
10225
  right.constant ||
9952
10226
  right.id === "{" ||
9953
10227
  (right.id === "[" && right.arity !== "binary")
9954
10228
  ) {
10229
+
10230
+ // test_cause:
10231
+ // ["/*jslint convert*/aa=+{};", "post_u_plus", "unexpected_a", "+", 22]
10232
+
9955
10233
  warn("unexpected_a", thing, "+");
9956
10234
  }
9957
10235
  }
@@ -9965,14 +10243,18 @@ function jslint_phase4_walk(state) {
9965
10243
  }
9966
10244
  } else if (thing.id === "!") {
9967
10245
  if (thing.expression.constant === true) {
10246
+
10247
+ // test_cause:
10248
+ // ["let aa=!0;", "post_u_unary", "unexpected_a", "!", 8]
10249
+
9968
10250
  warn("unexpected_a", thing);
9969
10251
  }
9970
10252
  } else if (thing.id === "!!") {
9971
10253
  if (!option_dict.convert) {
9972
10254
 
9973
10255
  // test_cause:
9974
- // [" !!0", "post_u_unary", "expected_a_b", "!!", 2]
9975
- // ["!!0", "post_u_unary", "expected_a_b", "!!", 1]
10256
+ // ["let aa= !!0;", "post_u_unary", "expected_a_b", "!!", 9]
10257
+ // ["let aa=!!0;", "post_u_unary", "expected_a_b", "!!", 8]
9976
10258
 
9977
10259
  warn("expected_a_b", thing, "Boolean(...)", "!!");
9978
10260
  }
@@ -10112,11 +10394,11 @@ function jslint_phase4_walk(state) {
10112
10394
  }
10113
10395
 
10114
10396
  function pre_b_in(thing) {
10397
+ if (!thing.for_init) {
10115
10398
 
10116
10399
  // test_cause:
10117
10400
  // ["aa in aa", "pre_b_in", "infix_in", "in", 4]
10118
10401
 
10119
- if (!thing.for_init) {
10120
10402
  warn("infix_in", thing);
10121
10403
  }
10122
10404
  }
@@ -10191,11 +10473,10 @@ function jslint_phase4_walk(state) {
10191
10473
  function pre_s_function(thing) {
10192
10474
 
10193
10475
  // test_cause:
10194
- // ["()=>0", "pre_s_function", "", "", 0]
10195
- // ["(function (){}())", "pre_s_function", "", "", 0]
10196
- // ["function aa(){}", "pre_s_function", "", "", 0]
10476
+ // ["()=>0", "pre_s_function", "(live)", "", 0]
10477
+ // ["(function (){}())", "pre_s_function", "(live)", "", 0]
10478
+ // ["function aa(){}", "pre_s_function", "(live)", "", 0]
10197
10479
 
10198
- test_cause("");
10199
10480
  if (thing.arity === "statement" && !scope_block.function_body) {
10200
10481
 
10201
10482
  // test_cause:
@@ -10224,13 +10505,10 @@ function jslint_phase4_walk(state) {
10224
10505
  } else if (thing.extra === "set") {
10225
10506
 
10226
10507
  // PR-514 - Bugfix - A setter's one parameter cannot be a rest-parameter, a
10227
- // SyntaxError. Read <signature>, since <name_list> flattens destructuring and
10228
- // cannot tell a rest-parameter from a valid rest-element inside a destructure.
10508
+ // SyntaxError. Read <parameter_rest>, since <name_list> flattens destructuring
10509
+ // and cannot tell a rest-parameter from a valid rest-element inside one.
10229
10510
 
10230
- if (
10231
- thing.parameter_count !== 1 ||
10232
- thing.signature.startsWith("(...")
10233
- ) {
10511
+ if (thing.parameter_count !== 1 || thing.parameter_rest) {
10234
10512
 
10235
10513
  // test_cause:
10236
10514
  // ["
@@ -10264,10 +10542,9 @@ function jslint_phase4_walk(state) {
10264
10542
  if (Array.isArray(thing)) {
10265
10543
 
10266
10544
  // test_cause:
10267
- // ["(function(){}())", "walk_expression", "isArray", "", 0]
10268
- // ["0&&0", "walk_expression", "isArray", "", 0]
10545
+ // ["(function(){}())", "walk_expression", "(live)", "", 0]
10546
+ // ["0&&0", "walk_expression", "(live)", "", 0]
10269
10547
 
10270
- test_cause("isArray");
10271
10548
  thing.forEach(walk_expression);
10272
10549
  } else {
10273
10550
  preamble(thing);
@@ -10278,10 +10555,8 @@ function jslint_phase4_walk(state) {
10278
10555
  if (thing.id === "function" || thing.id === "=>") {
10279
10556
 
10280
10557
  // test_cause:
10281
- // ["aa=()=>0", "walk_expression", "function", "=>", 0]
10282
- // ["aa=function(){}", "walk_expression", "function", "function", 0]
10283
-
10284
- test_cause("function", thing.id);
10558
+ // ["aa=()=>0", "walk_expression", "(live)", "", 0]
10559
+ // ["aa=function(){}", "walk_expression", "(live)", "", 0]
10285
10560
 
10286
10561
  // Recurse walk_statement.
10287
10562
 
@@ -10292,10 +10567,10 @@ function jslint_phase4_walk(state) {
10292
10567
  ) {
10293
10568
 
10294
10569
  // test_cause:
10295
- // ["aa=++aa", "walk_expression", "unexpected_a", "++", 4]
10296
- // ["aa=--aa", "walk_expression", "unexpected_a", "--", 4]
10297
- // ["aa=aa++", "walk_expression", "unexpected_a", "++", 6]
10298
- // ["aa=aa--", "walk_expression", "unexpected_a", "--", 6]
10570
+ // ["if(++aa){}", "walk_expression", "unexpected_a", "++", 4]
10571
+ // ["if(--aa){}", "walk_expression", "unexpected_a", "--", 4]
10572
+ // ["if(aa++){}", "walk_expression", "unexpected_a", "++", 6]
10573
+ // ["if(aa--){}", "walk_expression", "unexpected_a", "--", 6]
10299
10574
 
10300
10575
  warn("unexpected_a", thing);
10301
10576
  } else if (
@@ -10310,9 +10585,8 @@ function jslint_phase4_walk(state) {
10310
10585
  }
10311
10586
 
10312
10587
  // test_cause:
10313
- // ["aa=0", "walk_expression", "default", "", 0]
10588
+ // ["aa=0", "walk_expression", "(live)", "", 0]
10314
10589
 
10315
- test_cause("default");
10316
10590
  postamble(thing);
10317
10591
  }
10318
10592
  }
@@ -10325,9 +10599,7 @@ function jslint_phase4_walk(state) {
10325
10599
  if (Array.isArray(thing)) {
10326
10600
 
10327
10601
  // test_cause:
10328
- // ["+[]", "walk_statement", "isArray", "", 0]
10329
-
10330
- test_cause("isArray");
10602
+ // ["+[]", "walk_statement", "(live)", "", 0]
10331
10603
 
10332
10604
  // Recurse walk_statement.
10333
10605
 
@@ -10458,7 +10730,6 @@ function jslint_phase5_whitage(state) {
10458
10730
  artifact,
10459
10731
  block_list,
10460
10732
  option_dict,
10461
- test_cause,
10462
10733
  token_global,
10463
10734
  token_list,
10464
10735
  warn
@@ -10513,9 +10784,8 @@ function jslint_phase5_whitage(state) {
10513
10784
  if (id !== "ignore" && name.scope_declared === the_block) {
10514
10785
 
10515
10786
  // test_cause:
10516
- // ["function aa(aa) {return aa;}", "delve", "id", "", 0]
10787
+ // ["function aa(aa) {return aa;}", "delve", "(live)", "", 0]
10517
10788
 
10518
- test_cause("id");
10519
10789
  if (!name.used) {
10520
10790
 
10521
10791
  // test_cause:
@@ -10555,6 +10825,13 @@ function jslint_phase5_whitage(state) {
10555
10825
  !(right === undefined),
10556
10826
  `Expected !(right === undefined).`
10557
10827
  );
10828
+
10829
+ // test_cause:
10830
+ // ["
10831
+ // let aa;
10832
+ // aa();
10833
+ // ", "expected_at", "expected_a_at_b_c", "aa", 3]
10834
+
10558
10835
  warn(
10559
10836
  "expected_a_at_b_c",
10560
10837
  right,
@@ -10605,9 +10882,12 @@ function jslint_phase5_whitage(state) {
10605
10882
  if (right.from !== margin) {
10606
10883
 
10607
10884
  // test_cause:
10608
- // ["let aa={\naa:\n0};", "one_space", "open", "0", 0]
10885
+ // ["
10886
+ // let aa={
10887
+ // aa:
10888
+ // 0};
10889
+ // ", "one_space", "(live)", "", 0]
10609
10890
 
10610
- test_cause("open", right.value);
10611
10891
  expected_at(margin);
10612
10892
  }
10613
10893
  }
@@ -10621,12 +10901,10 @@ function jslint_phase5_whitage(state) {
10621
10901
  function whitage_closer() {
10622
10902
 
10623
10903
  // test_cause:
10624
- // ["String(0);", "whitage_closer", "closer", ")", 0]
10625
- // ["let aa=[0];", "whitage_closer", "closer", "]", 0]
10626
- // ["let aa=`${0}`;", "whitage_closer", "closer", "}", 0]
10627
- // ["let aa={String};", "whitage_closer", "closer", "}", 0]
10628
-
10629
- test_cause("closer", right.id);
10904
+ // ["String(0);", "whitage_closer", "(live)", "", 0]
10905
+ // ["let aa=[0];", "whitage_closer", "(live)", "", 0]
10906
+ // ["let aa=`${0}`;", "whitage_closer", "(live)", "", 0]
10907
+ // ["let aa={String};", "whitage_closer", "(live)", "", 0]
10630
10908
 
10631
10909
  // If right is a closer, then pop the previous state.
10632
10910
 
@@ -10644,9 +10922,11 @@ function jslint_phase5_whitage(state) {
10644
10922
  if (opening && right.id !== ";") {
10645
10923
 
10646
10924
  // test_cause:
10647
- // ["String(\n0);", "whitage_closer", "aa(\n0)", "0", 0]
10925
+ // ["
10926
+ // String(
10927
+ // 0);
10928
+ // ", "whitage_closer", "(live)", "", 0]
10648
10929
 
10649
- test_cause("aa(\n0)", left.value);
10650
10930
  at_margin(
10651
10931
  indentage.dot_depth === 1
10652
10932
 
@@ -10659,9 +10939,8 @@ function jslint_phase5_whitage(state) {
10659
10939
  }
10660
10940
 
10661
10941
  // test_cause:
10662
- // ["String( );", "whitage_closer", "no_space_only", ")", 0]
10942
+ // ["String( );", "whitage_closer", "(live)", "", 0]
10663
10943
 
10664
- test_cause("no_space_only", right.id);
10665
10944
  no_space_only();
10666
10945
  }
10667
10946
 
@@ -10691,17 +10970,15 @@ function jslint_phase5_whitage(state) {
10691
10970
  // test_cause:
10692
10971
  // ["
10693
10972
  // let aa=0;if(aa){aa();}else if(aa){aa();}
10694
- // ", "whitage_default", "stmt_else_if", "else", 0]
10973
+ // ", "whitage_default", "(live)", "", 0]
10695
10974
 
10696
- test_cause("stmt_else_if", left.id);
10697
10975
  one_space_only();
10698
10976
  return;
10699
10977
  }
10700
10978
 
10701
10979
  // test_cause:
10702
- // ["let aa;", "whitage_default", "stmt", "let", 0]
10980
+ // ["let aa;", "whitage_default", "(live)", "", 0]
10703
10981
 
10704
- test_cause("stmt", right.id);
10705
10982
  at_margin(0);
10706
10983
  open = false;
10707
10984
  return;
@@ -10721,9 +10998,8 @@ function jslint_phase5_whitage(state) {
10721
10998
  // ["
10722
10999
  // function aa(){
10723
11000
  // aa();bb:while(aa){aa();}}
10724
- // ", "whitage_default", "{\n label", "bb", 0]
11001
+ // ", "whitage_default", "(live)", "", 0]
10725
11002
 
10726
- test_cause("{\n label", right.id);
10727
11003
  expected_at(0);
10728
11004
  }
10729
11005
  return;
@@ -10735,17 +11011,18 @@ function jslint_phase5_whitage(state) {
10735
11011
  ) {
10736
11012
 
10737
11013
  // test_cause:
10738
- // ["String(0,0);", "whitage_default", "(0,", ",", 0]
11014
+ // ["String(0,0);", "whitage_default", "(live)", "", 0]
10739
11015
 
10740
- test_cause("(0,", left.id);
10741
11016
  one_space();
10742
11017
  return;
10743
11018
  }
10744
11019
 
10745
11020
  // test_cause:
10746
- // ["String(\n0,0);", "whitage_default", "(\n0,", ",", 0]
11021
+ // ["
11022
+ // String(
11023
+ // 0,0);
11024
+ // ", "whitage_default", "(live)", "", 0]
10747
11025
 
10748
- test_cause("(\n0,", left.id);
10749
11026
  return;
10750
11027
  }
10751
11028
 
@@ -10755,17 +11032,18 @@ function jslint_phase5_whitage(state) {
10755
11032
  if (open) {
10756
11033
 
10757
11034
  // test_cause:
10758
- // ["String(\nString?0:1);", "whitage_default", "(\n0?0:0", "?", 0]
11035
+ // ["
11036
+ // String(
11037
+ // String?0:1);
11038
+ // ", "whitage_default", "(live)", "", 0]
10759
11039
 
10760
- test_cause("(\n0?0:0", right.id);
10761
11040
  at_margin(0);
10762
11041
  return;
10763
11042
  }
10764
11043
 
10765
11044
  // test_cause:
10766
- // ["String(String?0:1);", "whitage_default", "(0?0:0", "?", 0]
11045
+ // ["String(String?0:1);", "whitage_default", "use_open", "?", 14]
10767
11046
 
10768
- test_cause("(0?0:0", right.id);
10769
11047
  warn("use_open", right);
10770
11048
  return;
10771
11049
  }
@@ -10787,9 +11065,8 @@ function jslint_phase5_whitage(state) {
10787
11065
  ) {
10788
11066
 
10789
11067
  // test_cause:
10790
- // ["String(...String);", "whitage_default", "...", "...", 0]
11068
+ // ["String(...String);", "whitage_default", "(live)", "", 0]
10791
11069
 
10792
- test_cause("...", left.id);
10793
11070
  no_space_only();
10794
11071
  return;
10795
11072
  }
@@ -10797,9 +11074,8 @@ function jslint_phase5_whitage(state) {
10797
11074
  if (left.line === right.line) {
10798
11075
 
10799
11076
  // test_cause:
10800
- // ["String?.aa();", "whitage_default", "?.", "?.", 0]
11077
+ // ["String?.aa();", "whitage_default", "(live)", "", 0]
10801
11078
 
10802
- test_cause("?.", right.id);
10803
11079
  no_space_only();
10804
11080
  return;
10805
11081
  }
@@ -10820,9 +11096,8 @@ function jslint_phase5_whitage(state) {
10820
11096
  // aa(bb);
10821
11097
  // }
10822
11098
  // }
10823
- // ", "whitage_default", "for(;;)", ";", 0]
11099
+ // ", "whitage_default", "(live)", "", 0]
10824
11100
 
10825
- test_cause("for(;;)", left.id);
10826
11101
  at_margin(0);
10827
11102
  }
10828
11103
  return;
@@ -10832,6 +11107,19 @@ function jslint_phase5_whitage(state) {
10832
11107
  // PR-514 - Bugfix - On one line, <one_space> still lets a comment sit between
10833
11108
  // the 'get' or 'set' and its name.
10834
11109
 
11110
+ if (left.line === right.line) {
11111
+
11112
+ // test_cause:
11113
+ // ["
11114
+ // /*jslint getset*/
11115
+ // String({get aa() {
11116
+ // return;
11117
+ // }});
11118
+ // ", "whitage_default", "(live)", "", 0]
11119
+
11120
+ one_space();
11121
+ } else {
11122
+
10835
11123
  // test_cause:
10836
11124
  // ["
10837
11125
  // /*jslint getset*/
@@ -10842,17 +11130,7 @@ function jslint_phase5_whitage(state) {
10842
11130
  // }
10843
11131
  // });
10844
11132
  // ", "one_space_only", "expected_space_a_b", "aa", 5]
10845
- // ["
10846
- // /*jslint getset*/
10847
- // String({get aa() {
10848
- // return;
10849
- // }});
10850
- // ", "whitage_default", "getset", "", 0]
10851
11133
 
10852
- test_cause("getset");
10853
- if (left.line === right.line) {
10854
- one_space();
10855
- } else {
10856
11134
  one_space_only();
10857
11135
  }
10858
11136
  return;
@@ -10873,9 +11151,8 @@ function jslint_phase5_whitage(state) {
10873
11151
  ) {
10874
11152
 
10875
11153
  // test_cause:
10876
- // ["if(String()){String();}", "whitage_default", "){", "){", 0]
11154
+ // ["if(String()){String();}", "whitage_default", "(live)", "", 0]
10877
11155
 
10878
- test_cause("){", left.id + right.id);
10879
11156
  one_space_only();
10880
11157
  return;
10881
11158
  }
@@ -10912,9 +11189,8 @@ function jslint_phase5_whitage(state) {
10912
11189
  ) {
10913
11190
 
10914
11191
  // test_cause:
10915
- // ["let aa=0;", "whitage_default", "=", "=", 0]
11192
+ // ["let aa=0;", "whitage_default", "(live)", "", 0]
10916
11193
 
10917
- test_cause("=", left.id);
10918
11194
  one_space();
10919
11195
  return;
10920
11196
  }
@@ -10927,15 +11203,14 @@ function jslint_phase5_whitage(state) {
10927
11203
  function whitage_opener() {
10928
11204
 
10929
11205
  // test_cause:
10930
- // ["String();", "whitage_opener", "opener", "(", 0]
10931
- // ["String(0);", "whitage_opener", "opener", "(", 0]
10932
- // ["let aa=[0];", "whitage_opener", "opener", "[", 0]
10933
- // ["let aa=[];", "whitage_opener", "opener", "[", 0]
10934
- // ["let aa=`${0}`;", "whitage_opener", "opener", "${", 0]
10935
- // ["let aa={String};", "whitage_opener", "opener", "{", 0]
10936
- // ["let aa={};", "whitage_opener", "opener", "{", 0]
11206
+ // ["String();", "whitage_opener", "(live)", "", 0]
11207
+ // ["String(0);", "whitage_opener", "(live)", "", 0]
11208
+ // ["let aa=[0];", "whitage_opener", "(live)", "", 0]
11209
+ // ["let aa=[];", "whitage_opener", "(live)", "", 0]
11210
+ // ["let aa=`${0}`;", "whitage_opener", "(live)", "", 0]
11211
+ // ["let aa={String};", "whitage_opener", "(live)", "", 0]
11212
+ // ["let aa={};", "whitage_opener", "(live)", "", 0]
10937
11213
 
10938
- test_cause("opener", left.id);
10939
11214
  opening = left.open || (left.line !== right.line);
10940
11215
  indentage = {
10941
11216
  closer,
@@ -10975,9 +11250,11 @@ function jslint_phase5_whitage(state) {
10975
11250
  if (opening) {
10976
11251
 
10977
11252
  // test_cause:
10978
- // ["String(\n0);", "whitage_opener", "(\n0)", "0", 0]
11253
+ // ["
11254
+ // String(
11255
+ // 0);
11256
+ // ", "whitage_opener", "(live)", "", 0]
10979
11257
 
10980
- test_cause("(\n0)", right.value);
10981
11258
  open = true;
10982
11259
  margin += mode_indent;
10983
11260
  if (right.role === "label") {
@@ -10987,9 +11264,8 @@ function jslint_phase5_whitage(state) {
10987
11264
  // ["
10988
11265
  // function aa(){
10989
11266
  // bb:while(aa){aa();}}
10990
- // ", "whitage_opener", "{\n label", "bb", 0]
11267
+ // ", "whitage_opener", "(live)", "", 0]
10991
11268
 
10992
- test_cause("{\n label", right.id);
10993
11269
  expected_at(0);
10994
11270
  }
10995
11271
  } else if (right.switch) {
@@ -11005,9 +11281,10 @@ function jslint_phase5_whitage(state) {
11005
11281
  ) {
11006
11282
 
11007
11283
  // test_cause:
11008
- // ["function aa(){bb:while(aa){aa();}}", "whitage_opener", "{label", "bb", 0]
11284
+ // ["
11285
+ // function aa(){bb:while(aa){aa();}}
11286
+ // ", "whitage_opener", "expected_line_break_a_b", "aa", 28]
11009
11287
 
11010
- test_cause("{label", right.id);
11011
11288
  warn(
11012
11289
  "expected_line_break_a_b",
11013
11290
  right,
@@ -11018,9 +11295,8 @@ function jslint_phase5_whitage(state) {
11018
11295
  open = false;
11019
11296
 
11020
11297
  // test_cause:
11021
- // ["String(0);", "whitage_opener", "(0)", "0", 0]
11298
+ // ["String(0);", "whitage_opener", "(live)", "", 0]
11022
11299
 
11023
- test_cause("(0)", right.value);
11024
11300
  no_space_only();
11025
11301
  }
11026
11302
 
@@ -11768,6 +12044,10 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
11768
12044
  // </dl>
11769
12045
  // </div>
11770
12046
 
12047
+ // A function's name is a best guess, since most functions have none in the
12048
+ // source. A wrong name in an odd case goes in the CHANGELOG Todo list, and is
12049
+ // fixed only when a user reports it [owner 2026-10-22].
12050
+
11771
12051
  html += "<fieldset id=\"JSLINT_REPORT_FUNCTIONS\">\n";
11772
12052
  html += "<legend>Report: Functions (" + functions.length + ")</legend>\n";
11773
12053
  html += "<div>\n";
@@ -11803,8 +12083,8 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
11803
12083
  html += "</div>\n";
11804
12084
  }
11805
12085
  functions.forEach(function (the_function) {
11806
- let {
11807
- context,
12086
+ const {
12087
+ context_report = [],
11808
12088
  from,
11809
12089
  id,
11810
12090
  level,
@@ -11813,7 +12093,20 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
11813
12093
  name_list = [],
11814
12094
  signature
11815
12095
  } = the_function;
11816
- let list = Object.keys(context);
12096
+
12097
+ // PR-516 - Bugfix - <context_report> mixes own and outer names, so each row
12098
+ // checks <scope_function>.
12099
+
12100
+ function id_list(filter) {
12101
+ return Array.from(
12102
+ new Set(context_report.filter(filter).map(function ({id}) {
12103
+ return id;
12104
+ }))
12105
+ ).sort();
12106
+ }
12107
+ function is_own({scope_function}) {
12108
+ return scope_function === the_function;
12109
+ }
11817
12110
  html += (
11818
12111
  "<div class=\"level level" + htmlEscape(level) + "\">" +
11819
12112
  address(line, from + 1) +
@@ -11836,30 +12129,23 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
11836
12129
  html += detail("parameter", name_list.map(function ({id}) {
11837
12130
  return id;
11838
12131
  }).sort());
11839
- list.sort();
11840
- html += detail("variable", list.filter(function (id) {
11841
- return context[id].role === "variable";
12132
+ html += detail("variable", id_list(function (entry) {
12133
+ return is_own(entry) && entry.role === "variable";
11842
12134
  }));
11843
- html += detail("exception", list.filter(function (id) {
11844
- return context[id].role === "exception";
12135
+ html += detail("exception", id_list(function (entry) {
12136
+ return is_own(entry) && entry.role === "exception";
11845
12137
  }));
11846
- html += detail("closure", list.filter(function (id) {
11847
- return (
11848
- context[id].closure === true &&
11849
- context[id].scope_declared === the_function
11850
- );
12138
+ html += detail("closure", id_list(function (entry) {
12139
+ return is_own(entry) && entry.closure === true;
11851
12140
  }));
11852
- html += detail("outer", list.filter(function (id) {
11853
- return (
11854
- context[id].scope_declared.id !== "(global)" &&
11855
- context[id].scope_declared !== the_function
11856
- );
12141
+ html += detail("outer", id_list(function (entry) {
12142
+ return !is_own(entry) && entry.scope_declared.id !== "(global)";
11857
12143
  }));
11858
- html += detail(module, list.filter(function (id) {
11859
- return context[id].scope_declared.id === "(global)";
12144
+ html += detail(module, id_list(function (entry) {
12145
+ return !is_own(entry) && entry.scope_declared.id === "(global)";
11860
12146
  }));
11861
- html += detail("label", list.filter(function (id) {
11862
- return context[id].role === "label";
12147
+ html += detail("label", id_list(function (entry) {
12148
+ return is_own(entry) && entry.role === "label";
11863
12149
  }));
11864
12150
  html += "</div>\n";
11865
12151
  });
@@ -11870,18 +12156,41 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
11870
12156
 
11871
12157
  async function jstestDescribe(description, testFunction) {
11872
12158
 
11873
- // This function will create-and-run test-group <testFunction>
11874
- // with given <description>.
12159
+ // This function will collect test-group <testFunction>'s tests with given
12160
+ // <description>, then run them.
11875
12161
 
12162
+ const describe = {
12163
+ collected: false,
12164
+ description,
12165
+ itList: []
12166
+ };
12167
+ const describePrv = jstestDescribePrv;
12168
+ let errBody;
11876
12169
  let message;
11877
12170
  let result;
11878
- let timerTimeout;
12171
+
12172
+ // Record <description> before the first await, since describes then
12173
+ // interleave and finish out of source order.
12174
+
12175
+ jstestDescribePrv = description;
11879
12176
 
11880
12177
  // Init jstestTimeStart.
11881
12178
 
11882
12179
  if (jstestTimeStart === undefined) {
11883
- jstestTimeStart = jstestTimeStart || Date.now();
12180
+
12181
+ // PR-xxx - Run each body and each test in an async context, storing {describe}
12182
+ // while a body collects and {describe, record} while a test runs: a body's
12183
+ // <jstestIt> finds its describe even after an await, and an error escaping a
12184
+ // test, e.g. thrown from a timer or an un-awaited rejection, names its test at
12185
+ // exit. The monitor only observes: node still crashes as before.
12186
+ // <process.getBuiltinModule> loads synchronously, so describes cannot race to
12187
+ // create two contexts, and the browser never reaches it.
12188
+
12189
+ const {AsyncLocalStorage} = process.getBuiltinModule("async_hooks");
12190
+ jstestAls = new AsyncLocalStorage();
12191
+ jstestTimeStart = Date.now();
11884
12192
  process.on("exit", jstestOnExit);
12193
+ process.on("uncaughtExceptionMonitor", jstestOnCrash);
11885
12194
  }
11886
12195
 
11887
12196
  // PR-457 - Wait awhile for imports to initialize.
@@ -11890,87 +12199,234 @@ async function jstestDescribe(description, testFunction) {
11890
12199
  setTimeout(resolve);
11891
12200
  });
11892
12201
 
11893
- // Init jstestItList.
12202
+ // PR-xxx - Collect, then run: await the whole body, async or not, before any
12203
+ // test starts. A body that throws fails as one more test, wrapped, so a falsy
12204
+ // throw still fails.
11894
12205
 
11895
- jstestItList = [];
11896
- testFunction();
12206
+ try {
12207
+ await jstestAls.run({describe}, testFunction);
12208
+ } catch (err) {
12209
+ errBody = [err, "jstestDescribe body"];
12210
+ }
12211
+ describe.collected = true;
11897
12212
 
11898
- // Wait for jstestItList to resolve.
12213
+ // PR-xxx - Assert this describe's tests, then this describe, are in ASCII
12214
+ // order. Then add one failed result for a body that threw. Record them before
12215
+ // any test runs, so a hung sibling cannot hide them at exit.
11899
12216
 
11900
- timerTimeout = setTimeout(noop, 0x7fffffff);
11901
- result = await Promise.all(jstestItList);
11902
- clearTimeout(timerTimeout);
12217
+ result = [
12218
+ jstestOrderCheck(describe.itList.map(function (record) {
12219
+ return record.description;
12220
+ })),
12221
+ jstestOrderCheck([describePrv, description]),
12222
+ errBody
12223
+ ].filter(Boolean).map(function ([err, descriptionIt]) {
12224
+ return {
12225
+ describe: description,
12226
+ description: descriptionIt,
12227
+ err,
12228
+ status: "failed"
12229
+ };
12230
+ });
12231
+ jstestItRecordList.push(...result);
12232
+ await Promise.all(describe.itList.map(async function (record) {
12233
+ let settle = {
12234
+ status: "passed"
12235
+ };
12236
+ try {
12237
+ await jstestAls.run({describe, record}, record.testFunction);
12238
+ } catch (err) {
12239
+ settle = {
12240
+ err,
12241
+ status: "failed"
12242
+ };
12243
+ }
12244
+
12245
+ // PR-xxx - A test settles once, so a crash <jstestOnCrash> recorded while it
12246
+ // ran stands, even when a user's own uncaughtException handler lets it finish.
12247
+
12248
+ if (record.status === "pending") {
12249
+ Object.assign(record, settle);
12250
+ }
12251
+ }));
12252
+ result.unshift(...describe.itList);
12253
+
12254
+ // PR-xxx - Print nothing for a describe whose tests the filter all skipped.
12255
+
12256
+ if (result.length === 0) {
12257
+ return;
12258
+ }
11903
12259
 
11904
12260
  // Print test results.
11905
12261
 
11906
12262
  message = (
11907
12263
  "\n " + (Date.now() - jstestTimeStart) + "ms" +
11908
12264
  " - test describe - " + description + "\n" +
11909
- result.map(function ([
11910
- err, description, mode
11911
- ]) {
12265
+ result.map(function (record) {
11912
12266
  jstestItCount += 1;
11913
- if (err) {
11914
- jstestCountFailed += 1;
11915
- err = (
12267
+ record.printed = true;
12268
+ return (
12269
+ (record.status === "passed")
12270
+ ? (
12271
+ " \u001b[32m\u2714 " + jstestItCount + ". test it - " +
12272
+ record.description + "\u001b[39m"
12273
+ )
12274
+ : (
11916
12275
  " \u001b[31m\u2718 " + jstestItCount + ". test it - " +
11917
- description + "\n" + err.stack + "\u001b[39m"
11918
- );
11919
- if (mode === "pass") {
11920
- jstestCountFailed -= 1;
11921
- err = "";
11922
- }
11923
- }
11924
- return err || (
11925
- " \u001b[32m\u2714 " + jstestItCount + ". test it - " +
11926
- description + "\u001b[39m"
12276
+ record.description + "\n" +
12277
+ jstestErrText(record.err) + "\u001b[39m"
12278
+ )
11927
12279
  );
11928
12280
  }).join("\n")
11929
12281
  );
11930
12282
  console.error(message);
11931
12283
  }
11932
12284
 
11933
- function jstestIt(description, testFunction, mode) {
12285
+ function jstestErrText(err) {
11934
12286
 
11935
- // This function will create-and-run test-case <testFunction>
11936
- // inside current test-group with given <description>.
12287
+ // This function will return the stack of thrown <err>, else <err> as text,
12288
+ // for any thrown value, even a falsy one or a null-prototype object.
11937
12289
 
11938
- jstestCountTotal += 1;
11939
- jstestItList.push(new Promise(async function (resolve) {
11940
- let err;
11941
- try {
11942
- await testFunction();
11943
- } catch (errCaught) {
11944
- err = errCaught;
11945
- }
11946
- resolve([err, description, mode]);
11947
- }));
12290
+ try {
12291
+ return String(err?.stack ?? err);
12292
+ } catch (ignore) {
12293
+ return "[" + typeof err + "]";
12294
+ }
11948
12295
  }
11949
12296
 
11950
- function jstestOnExit(exitCode, mode) {
12297
+ function jstestIt(description, testFunction) {
12298
+
12299
+ // This function will register test-case <testFunction> with given
12300
+ // <description> in the current describe, to run once its body settles.
12301
+
12302
+ const describe = jstestAls?.getStore()?.describe;
12303
+
12304
+ // PR-xxx - Throw outside a describe body, or after it settled, since no
12305
+ // describe would run or report this test.
12306
+
12307
+ if (!describe || describe.collected) {
12308
+ throw new Error(
12309
+ "jstestIt " + JSON.stringify(description) +
12310
+ " called outside a jstestDescribe body, or after it settled"
12311
+ );
12312
+ }
12313
+
12314
+ // PR-xxx - Run only a test whose "<describe> - <it>" matches opt-in regexp
12315
+ // npm_config_mode_test_filter, e.g.
12316
+ // npm_config_mode_test_filter="jstestXxx.*pending" npm test
12317
+ // Prefer the env form, since npm 11 warns the flag form --mode-test-filter
12318
+ // stops working in npm 12.
12319
+
12320
+ if (!new RegExp(
12321
+ process.env.npm_config_mode_test_filter || ""
12322
+ ).test(describe.description + " - " + description)) {
12323
+ return;
12324
+ }
12325
+
12326
+ // PR-xxx - Record this test as pending from registration, so <jstestReport>
12327
+ // sees it even if its describe never runs or prints.
12328
+
12329
+ jstestItRecordList.push({
12330
+ describe: describe.description,
12331
+ description,
12332
+ status: "pending",
12333
+ testFunction
12334
+ });
12335
+ describe.itList.push(jstestItRecordList.at(-1));
12336
+ }
12337
+
12338
+ function jstestOnCrash(err) {
12339
+
12340
+ // This function will mark the test whose async context let uncaught <err>
12341
+ // escape as crashed, and list it at exit even if its describe printed.
12342
+
12343
+ const record = jstestAls.getStore()?.record;
12344
+ if (record) {
12345
+ record.err = err;
12346
+ record.printed = false;
12347
+ record.status = "crashed";
12348
+ }
12349
+ }
12350
+
12351
+ function jstestOnExit(exitCode) {
11951
12352
 
11952
12353
  // This function will on process-exit, print test-report
11953
12354
  // and exit with non-zero exit-code if any test failed.
11954
12355
 
11955
- let message = (
11956
- (
11957
- (jstestCountFailed || mode === "testsFailed")
12356
+ const {countFailed, text} = jstestReport();
12357
+ console.error(text);
12358
+ process.exitCode = exitCode || countFailed;
12359
+ }
12360
+
12361
+ function jstestOrderCheck(descriptionList) {
12362
+
12363
+ // This function will return a failed result for the first description in
12364
+ // <descriptionList> not strictly after the one before it, else undefined.
12365
+ // Strict means a duplicate fails too, as two identical lines cannot be told
12366
+ // apart in the output. Not '>=', which is false for a non-string name such as
12367
+ // undefined, so that name would pass.
12368
+
12369
+ for (const [ii, description] of descriptionList.entries()) {
12370
+ if (ii > 0 && !(descriptionList[ii - 1] < description)) {
12371
+ const now = JSON.stringify(description);
12372
+ const prv = JSON.stringify(descriptionList[ii - 1]);
12373
+ return [
12374
+ new Error(
12375
+ (prv === now)
12376
+ ? `duplicate description ${now}`
12377
+ : `${now} must sort before ${prv}`
12378
+ ),
12379
+ "jstestDescribe and jstestIt descriptions in ASCII order"
12380
+ ];
12381
+ }
12382
+ }
12383
+ }
12384
+
12385
+ function jstestReport() {
12386
+
12387
+ // This function will return the test-report <text> and its <countFailed>,
12388
+ // without side effects.
12389
+
12390
+ // PR-xxx - List and count as failed each test its describe never printed: one
12391
+ // still pending, e.g. hung until a watchdog ended the process, or one that
12392
+ // failed while a sibling hung, whose error was otherwise never shown.
12393
+
12394
+ const countFailed = jstestItRecordList.filter(function ({status}) {
12395
+ return status !== "passed";
12396
+ }).length;
12397
+ const unprintedList = jstestItRecordList.filter(function (record) {
12398
+ return !record.printed && record.status !== "passed";
12399
+ });
12400
+ return {
12401
+ countFailed,
12402
+ text: (
12403
+ countFailed
11958
12404
  ? "\n\u001b[31m"
11959
12405
  : "\n\u001b[32m"
11960
12406
  ) +
11961
- " tests total - " + jstestCountTotal + "\n" +
11962
- " tests failed - " + jstestCountFailed + "\n" +
12407
+ unprintedList.map(function ({
12408
+ describe,
12409
+ description,
12410
+ err,
12411
+ status
12412
+ }, ii) {
12413
+ return (
12414
+ " \u2718 " + (jstestItCount + ii + 1) + ". test it " + status +
12415
+ " - " + describe + " - " + description + "\n" + (
12416
+ (status === "pending")
12417
+ ? ""
12418
+ : jstestErrText(err) + "\n"
12419
+ )
12420
+ );
12421
+ }).join("") +
12422
+ " tests total - " + jstestItRecordList.length + "\n" +
12423
+ " tests failed - " + countFailed + "\n" +
11963
12424
  "\n" +
11964
12425
  " time finished - " +
11965
12426
  Number(Date.now() - jstestTimeStart).toLocaleString() +
11966
12427
  " ms\n" +
11967
12428
  "\u001b[39m"
11968
- );
11969
- if (mode !== "testsFailed") {
11970
- console.error(message);
11971
- }
11972
- process.exitCode = exitCode || jstestCountFailed;
11973
- return message;
12429
+ };
11974
12430
  }
11975
12431
 
11976
12432
  async function moduleFsInit() {
@@ -13511,8 +13967,6 @@ jslint_export = Object.freeze(
13511
13967
  htmlEscape,
13512
13968
  jslint,
13513
13969
  jslint_apidoc,
13514
- jslint_assert,
13515
- jslint_autofix_warning_list,
13516
13970
  jslint_charset_ascii,
13517
13971
  jslint_cli,
13518
13972
  jslint_edition,
@@ -13525,7 +13979,8 @@ jslint_export = Object.freeze(
13525
13979
  jslint_report,
13526
13980
  jstestDescribe,
13527
13981
  jstestIt,
13528
- jstestOnExit,
13982
+ jstestOrderCheck,
13983
+ jstestReport,
13529
13984
  moduleFsInit,
13530
13985
  noop,
13531
13986
  objectDeepCopyWithKeysSorted,