@jslint-org/jslint 2021.12.20 → 2022.2.20

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/.npmignore CHANGED
@@ -2,5 +2,5 @@
2
2
  .*
3
3
  !.npmignore
4
4
 
5
- !jslint.cjs
6
5
  !jslint.mjs
6
+ !jslint_wrapper_cjs.cjs
package/README.md CHANGED
@@ -3,7 +3,7 @@ Douglas Crockford <douglas@crockford.com>
3
3
 
4
4
 
5
5
  # Status
6
- | Branch | [master<br>(v2021.12.20)](https://github.com/jslint-org/jslint/tree/master) | [beta<br>(Web Demo)](https://github.com/jslint-org/jslint/tree/beta) | [alpha<br>(Development)](https://github.com/jslint-org/jslint/tree/alpha) |
6
+ | Branch | [master<br>(v2022.2.20)](https://github.com/jslint-org/jslint/tree/master) | [beta<br>(Web Demo)](https://github.com/jslint-org/jslint/tree/beta) | [alpha<br>(Development)](https://github.com/jslint-org/jslint/tree/alpha) |
7
7
  |--:|:--:|:--:|:--:|
8
8
  | CI | [![ci](https://github.com/jslint-org/jslint/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/jslint-org/jslint/actions?query=branch%3Amaster) | [![ci](https://github.com/jslint-org/jslint/actions/workflows/ci.yml/badge.svg?branch=beta)](https://github.com/jslint-org/jslint/actions?query=branch%3Abeta) | [![ci](https://github.com/jslint-org/jslint/actions/workflows/ci.yml/badge.svg?branch=alpha)](https://github.com/jslint-org/jslint/actions?query=branch%3Aalpha) |
9
9
  | Coverage | [![coverage](https://jslint-org.github.io/jslint/branch-master/.artifact/coverage/coverage_badge.svg)](https://jslint-org.github.io/jslint/branch-master/.artifact/coverage/index.html) | [![coverage](https://jslint-org.github.io/jslint/branch-beta/.artifact/coverage/coverage_badge.svg)](https://jslint-org.github.io/jslint/branch-beta/.artifact/coverage/index.html) | [![coverage](https://jslint-org.github.io/jslint/branch-alpha/.artifact/coverage/coverage_badge.svg)](https://jslint-org.github.io/jslint/branch-alpha/.artifact/coverage/index.html) |
@@ -35,7 +35,7 @@ Douglas Crockford <douglas@crockford.com>
35
35
  - [To create V8 coverage report from Node.js / Npm program in shell:](#to-create-v8-coverage-report-from-nodejs--npm-program-in-shell)
36
36
  - [To create V8 coverage report from Node.js / Npm program in javascript:](#to-create-v8-coverage-report-from-nodejs--npm-program-in-javascript)
37
37
 
38
- 7. [Plugin Vim](#plugin-vim)
38
+ 7. [Quickstart JSLint in Vim](#quickstart-jslint-in-vim)
39
39
  - [To run JSLint in Vim:](#to-run-jslint-in-vim)
40
40
 
41
41
  8. [Description](#description)
@@ -331,19 +331,19 @@ import jslint from "../jslint.mjs";
331
331
 
332
332
 
333
333
  <br><br>
334
- # Plugin Vim
334
+ # Quickstart JSLint in Vim
335
335
 
336
336
 
337
337
  <br><br>
338
338
  ### To run JSLint in Vim:
339
- 1. Download and save [`jslint.mjs`](https://www.jslint.com/jslint.mjs), [`jslint.vim`](https://www.jslint.com/jslint.vim) to directory `~/.vim/`
340
- 2. Add vim-command `:source ~/.vim/jslint.vim` to file `~/.vimrc`
339
+ 1. Download and save [`jslint.mjs`](https://www.jslint.com/jslint.mjs), [`jslint_wrapper_vim.vim`](https://www.jslint.com/jslint_wrapper_vim.vim) to directory `~/.vim/`
340
+ 2. Add vim-command `:source ~/.vim/jslint_wrapper_vim.vim` to file `~/.vimrc`
341
341
  3. Vim can now jslint files (via nodejs):
342
342
  - with vim-command `:SaveAndJslint`
343
343
  - with vim-key-combo `<Ctrl-S> <Ctrl-J>`
344
344
  - screenshot
345
345
 
346
- ![screenshot.png](asset_image_jslint_vim_plugin.png)
346
+ ![screenshot.png](asset_image_jslint_wrapper_vim.png)
347
347
 
348
348
 
349
349
  <br><br>
package/jslint.mjs CHANGED
@@ -94,6 +94,8 @@
94
94
  /*jslint beta, node*/
95
95
 
96
96
  /*property
97
+ fud_stmt,
98
+ is_fart,
97
99
  mode_conditional,
98
100
  JSLINT_BETA, NODE_V8_COVERAGE, a, all, argv, arity, artifact,
99
101
  assertErrorThrownAsync, assertJsonEqual, assertOrThrow, assign, async, b,
@@ -107,7 +109,7 @@
107
109
  example_list, exec, execArgv, exit, export_dict, exports, expression, extra,
108
110
  file, fileList, fileURLToPath, filter, finally, flag, floor, for, forEach,
109
111
  formatted_message, free, freeze, from, froms,
110
- fsWriteFileWithParents, fud, functionName, function_list, function_stack,
112
+ fsWriteFileWithParents, functionName, function_list, function_stack,
111
113
  functions, get, getset, github_repo, global, global_dict, global_list,
112
114
  holeList, htmlEscape, id, identifier, import, import_list, inc, indent2,
113
115
  index, indexOf, init, initial, isArray, isBlockCoverage, isHole, isNaN,
@@ -115,13 +117,13 @@
115
117
  jslint_charset_ascii, jslint_cli, jslint_edition, jslint_phase1_split,
116
118
  jslint_phase2_lex, jslint_phase3_parse, jslint_phase4_walk,
117
119
  jslint_phase5_whitage, jslint_report, json, jstestDescribe, jstestIt,
118
- jstestOnExit, keys, label, lbp, led, length, level, line, lineList,
120
+ jstestOnExit, keys, label, lbp, led_infix, length, level, line, lineList,
119
121
  line_list, line_offset, line_source, lines, linesCovered, linesTotal, live,
120
122
  log, long, loop, m, main, map, margin, match, max, message, meta, min,
121
123
  mkdir, modeCoverageIgnoreFile, modeIndex, mode_cli, mode_json, mode_module,
122
124
  mode_noop, mode_property, mode_shebang, mode_stop, module, moduleFsInit,
123
125
  moduleName, module_list, name, names, node, noop, now,
124
- nr, nud, objectDeepCopyWithKeysSorted, ok, on, open, opening, option,
126
+ nr, nud_prefix, objectDeepCopyWithKeysSorted, ok, on, open, opening, option,
125
127
  option_dict, order, package_name, padEnd, padStart, parameters, parent,
126
128
  parentIi, parse, pathname, platform, pop, processArgv, process_argv,
127
129
  process_env, process_exit, process_version, promises, property,
@@ -165,7 +167,7 @@ let jslint_charset_ascii = (
165
167
  + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
166
168
  + "`abcdefghijklmnopqrstuvwxyz{|}~\u007f"
167
169
  );
168
- let jslint_edition = "v2021.12.20";
170
+ let jslint_edition = "v2022.2.20";
169
171
  let jslint_export; // The jslint object to be exported.
170
172
  let jslint_fudge = 1; // Fudge starting line and starting
171
173
  // ... column to 1.
@@ -837,6 +839,15 @@ function jslint(
837
839
  case "use_double":
838
840
  mm = `Use double quotes, not single quotes.`;
839
841
  break;
842
+
843
+ // PR-386 - Fix issue #382 - Make fart-related warnings more readable.
844
+
845
+ case "use_function_not_fart":
846
+ mm = (
847
+ `Use 'function (...)', not '(...) =>' when arrow functions`
848
+ + ` become too complex.`
849
+ );
850
+ break;
840
851
  case "use_open":
841
852
  mm = (
842
853
  `Wrap a ternary expression in parens,`
@@ -870,6 +881,12 @@ function jslint(
870
881
  case "wrap_condition":
871
882
  mm = `Wrap the condition in parens.`;
872
883
  break;
884
+
885
+ // PR-386 - Fix issue #382 - Make fart-related warnings more readable.
886
+
887
+ case "wrap_fart_parameter":
888
+ mm = `Wrap the parameter before '=>' in parens.`;
889
+ break;
873
890
  case "wrap_immediate":
874
891
  mm = (
875
892
  `Wrap an immediate function invocation in parentheses to assist`
@@ -877,9 +894,6 @@ function jslint(
877
894
  + ` result of a function, and not the function itself.`
878
895
  );
879
896
  break;
880
- case "wrap_parameter":
881
- mm = `Wrap the parameter in parens.`;
882
- break;
883
897
  case "wrap_regexp":
884
898
  mm = `Wrap this regexp in parens to avoid confusion.`;
885
899
  break;
@@ -1455,8 +1469,8 @@ async function jslint_cli({
1455
1469
  let command;
1456
1470
  let data;
1457
1471
  let exit_code = 0;
1458
- let mode_plugin_vim;
1459
1472
  let mode_report;
1473
+ let mode_wrapper_vim;
1460
1474
  let result;
1461
1475
 
1462
1476
  function jslint_from_file({
@@ -1529,7 +1543,7 @@ async function jslint_cli({
1529
1543
  if (result_from_file.warnings.length > 0) {
1530
1544
  exit_code = 1;
1531
1545
  console_error(
1532
- mode_plugin_vim
1546
+ mode_wrapper_vim
1533
1547
 
1534
1548
  // PR-349 - Print warnings in format readable by vim.
1535
1549
 
@@ -1662,17 +1676,17 @@ async function jslint_cli({
1662
1676
  }));
1663
1677
  return;
1664
1678
 
1665
- // COMMIT-b26d6df2 - Add command jslint_plugin_vim.
1679
+ // PR-363 - Add command jslint_report.
1666
1680
 
1667
- case "jslint_plugin_vim":
1668
- mode_plugin_vim = true;
1681
+ case "jslint_report":
1682
+ mode_report = command[1];
1669
1683
  process_argv = process_argv.slice(1);
1670
1684
  break;
1671
1685
 
1672
- // PR-363 - Add command jslint_report.
1686
+ // COMMIT-b26d6df2 - Add command jslint_wrapper_vim.
1673
1687
 
1674
- case "jslint_report":
1675
- mode_report = command[1];
1688
+ case "jslint_wrapper_vim":
1689
+ mode_wrapper_vim = true;
1676
1690
  process_argv = process_argv.slice(1);
1677
1691
  break;
1678
1692
 
@@ -1680,6 +1694,7 @@ async function jslint_cli({
1680
1694
 
1681
1695
  case "v8_coverage_report":
1682
1696
  await v8CoverageReportCreate({
1697
+ consoleError: console_error,
1683
1698
  coverageDir: command[1],
1684
1699
  processArgv: process_argv.slice(3)
1685
1700
  });
@@ -1688,9 +1703,9 @@ async function jslint_cli({
1688
1703
 
1689
1704
  // PR-349 - Detect cli-option --mode-vim-plugin.
1690
1705
 
1691
- mode_plugin_vim = (
1706
+ mode_wrapper_vim = (
1692
1707
  process_argv.slice(2).indexOf("--mode-vim-plugin") >= 0
1693
- || mode_plugin_vim
1708
+ || mode_wrapper_vim
1694
1709
  );
1695
1710
 
1696
1711
  // Normalize file relative to process.cwd().
@@ -1831,6 +1846,9 @@ function jslint_phase2_lex(state) {
1831
1846
  // ... literal.
1832
1847
  let mode_regexp; // true if regular expression literal seen on
1833
1848
  // ... this line.
1849
+ let paren_backtrack_list = []; // List of most recent "(" tokens at any
1850
+ // ... paren-depth.
1851
+ let paren_depth = 0; // Keeps track of current paren-depth.
1834
1852
  let rx_token = new RegExp(
1835
1853
  "^("
1836
1854
  + "(\\s+)"
@@ -3193,7 +3211,7 @@ node --input-type=module --eval '
3193
3211
  // /\*jslint beta, node*\/
3194
3212
  import moduleHttps from "https";
3195
3213
  (async function () {
3196
- let dict = {};
3214
+ let dict = Object.create(null);
3197
3215
  let result = "";
3198
3216
  await new Promise(function (resolve) {
3199
3217
  moduleHttps.get((
@@ -3392,9 +3410,11 @@ import moduleHttps from "https";
3392
3410
  from,
3393
3411
  id,
3394
3412
  identifier: Boolean(identifier),
3413
+ is_fart: false,
3395
3414
  line,
3396
3415
  nr: token_list.length,
3397
- thru: column
3416
+ thru: column,
3417
+ value
3398
3418
  };
3399
3419
  token_list.push(the_token);
3400
3420
 
@@ -3404,12 +3424,6 @@ import moduleHttps from "https";
3404
3424
  mode_directive = false;
3405
3425
  }
3406
3426
 
3407
- // If the token is to have a value, give it one.
3408
-
3409
- if (value !== undefined) {
3410
- the_token.value = value;
3411
- }
3412
-
3413
3427
  // If this token is an identifier that touches a preceding number, or
3414
3428
  // a "/", comment, or regular expression literal that touches a preceding
3415
3429
  // comment or regular expression literal, then give a missing space warning.
@@ -3443,6 +3457,29 @@ import moduleHttps from "https";
3443
3457
  the_token.dot = true;
3444
3458
  }
3445
3459
 
3460
+ // PR-385 - Bugfix - Fixes issue #382 - failure to detect destructured fart.
3461
+ // Farts are now detected by keeping a list of most recent "(" tokens at any
3462
+ // given depth. When a "=>" token is encountered, the most recent "(" token at
3463
+ // current depth is marked as a fart.
3464
+
3465
+ switch (id) {
3466
+ case "(":
3467
+ paren_backtrack_list[paren_depth] = the_token;
3468
+ paren_depth += 1;
3469
+ break;
3470
+ case ")":
3471
+ paren_depth -= 1;
3472
+ break;
3473
+ case "=>":
3474
+ if (
3475
+ token_prv_expr.id === ")"
3476
+ && paren_backtrack_list[paren_depth]
3477
+ ) {
3478
+ paren_backtrack_list[paren_depth].is_fart = true;
3479
+ }
3480
+ break;
3481
+ }
3482
+
3446
3483
  // The previous token is used to detect adjacency problems.
3447
3484
 
3448
3485
  token_prv = the_token;
@@ -3558,7 +3595,7 @@ function jslint_phase3_parse(state) {
3558
3595
  match === undefined
3559
3596
 
3560
3597
  // test_cause:
3561
- // ["()", "advance", "expected_a_b", "(end)", 1]
3598
+ // ["{0:0}", "advance", "expected_a_b", "0", 2]
3562
3599
 
3563
3600
  ? stop("expected_a_b", token_nxt, id, artifact())
3564
3601
 
@@ -3607,7 +3644,7 @@ function jslint_phase3_parse(state) {
3607
3644
  // other assignment operators can modify, but they cannot initialize.
3608
3645
 
3609
3646
  const the_symbol = symbol(id, 20);
3610
- the_symbol.led = function (left) {
3647
+ the_symbol.led_infix = function (left) {
3611
3648
  const the_token = token_now;
3612
3649
  let right;
3613
3650
  the_token.arity = "assignment";
@@ -3919,7 +3956,7 @@ function jslint_phase3_parse(state) {
3919
3956
 
3920
3957
  const the_symbol = symbol(id);
3921
3958
  the_symbol.constant = true;
3922
- the_symbol.nud = (
3959
+ the_symbol.nud_prefix = (
3923
3960
  typeof value === "function"
3924
3961
  ? value
3925
3962
  : function () {
@@ -4113,7 +4150,7 @@ function jslint_phase3_parse(state) {
4113
4150
  // Create an infix operator.
4114
4151
 
4115
4152
  const the_symbol = symbol(id, bp);
4116
- the_symbol.led = function (left) {
4153
+ the_symbol.led_infix = function (left) {
4117
4154
  const the_token = token_now;
4118
4155
  the_token.arity = "binary";
4119
4156
  if (f !== undefined) {
@@ -4171,12 +4208,12 @@ function jslint_phase3_parse(state) {
4171
4208
  return the_token;
4172
4209
  }
4173
4210
 
4174
- function infix_fart_unwrapped(left) {
4211
+ function infix_fart_unwrapped() {
4175
4212
 
4176
4213
  // test_cause:
4177
- // ["aa=>0", "infix_fart_unwrapped", "wrap_parameter", "aa", 1]
4214
+ // ["aa=>0", "infix_fart_unwrapped", "wrap_fart_parameter", "=>", 3]
4178
4215
 
4179
- return stop("wrap_parameter", left);
4216
+ return stop("wrap_fart_parameter", token_now);
4180
4217
  }
4181
4218
 
4182
4219
  function infix_grave(left) {
@@ -4339,13 +4376,13 @@ function jslint_phase3_parse(state) {
4339
4376
  // Create a right associative infix operator.
4340
4377
 
4341
4378
  const the_symbol = symbol(id, bp);
4342
- the_symbol.led = function parse_infixr_led(left) {
4379
+ the_symbol.led_infix = function parse_infixr_led(left) {
4343
4380
  const the_token = token_now;
4344
4381
 
4345
4382
  // test_cause:
4346
- // ["0**0", "parse_infixr_led", "led", "", 0]
4383
+ // ["0**0", "parse_infixr_led", "led_infix", "", 0]
4347
4384
 
4348
- test_cause("led");
4385
+ test_cause("led_infix");
4349
4386
  the_token.arity = "binary";
4350
4387
  the_token.expression = [left, parse_expression(bp - 1)];
4351
4388
  return the_token;
@@ -4353,39 +4390,70 @@ function jslint_phase3_parse(state) {
4353
4390
  return the_symbol;
4354
4391
  }
4355
4392
 
4356
- function lookahead() {
4357
-
4358
- // Look ahead one token without advancing, skipping comments.
4359
-
4360
- let cadet;
4361
- let ii = token_ii;
4362
- while (true) {
4363
- cadet = token_list[ii];
4364
- if (cadet.id !== "(comment)") {
4365
- return cadet;
4366
- }
4367
- ii += 1;
4368
- }
4369
- }
4370
-
4371
4393
  function parse_expression(rbp, initial) {
4372
4394
 
4373
4395
  // This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
4374
- // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is
4375
- // like .nud except that it is only used on the first token of a statement.
4376
- // Having .fud makes it much easier to define statement-oriented languages like
4377
- // JavaScript. I retained Pratt's nomenclature.
4396
+ // is looking for ad hoc lint patterns. We add .fud_stmt to Pratt's model, which
4397
+ // is like .nud_prefix except that it is only used on the first token of a
4398
+ // statement. Having .fud_stmt makes it much easier to define statement-oriented
4399
+ // languages like JavaScript. I retained Pratt's nomenclature.
4378
4400
  // They are elements of the parsing method called Top Down Operator Precedence.
4379
4401
 
4380
- // .nud Null denotation
4381
- // .fud First null denotation
4382
- // .led Left denotation
4383
- // lbp Left binding power
4384
- // rbp Right binding power
4385
-
4386
- // It processes a nud (variable, constant, prefix operator). It will then
4387
- // process leds (infix operators) until the bind powers cause it to stop. It
4388
- // returns the expression's parse tree.
4402
+ // .nud_prefix Null denotation. The prefix handler.
4403
+ // .fud_stmt First null denotation. The statement handler.
4404
+ // .led_infix Left denotation. The infix/postfix handler.
4405
+ // lbp Left binding power of infix operator. It tells us how strongly
4406
+ // the operator binds to the argument at its left.
4407
+ // rbp Right binding power.
4408
+
4409
+ // It processes a nud_prefix (variable, constant, prefix operator). It will then
4410
+ // process leds (infix operators) until the bind powers cause it to stop (it
4411
+ // consumes tokens until it meets a token whose lbp <= rbp). Specifically, it
4412
+ // means that it collects all tokens that bind together before returning to the
4413
+ // operator that called it. It returns the expression's parse tree.
4414
+
4415
+ // For example, "3 + 1 * 2 * 4 + 5"
4416
+ // parses into
4417
+ // {
4418
+ // "id": "+",
4419
+ // "expression": [
4420
+ // {
4421
+ // "id": "+",
4422
+ // "expression": [
4423
+ // {
4424
+ // "id": "(number)",
4425
+ // "value": "3"
4426
+ // },
4427
+ // {
4428
+ // "id": "*",
4429
+ // "expression": [
4430
+ // {
4431
+ // "id": "*",
4432
+ // "expression": [
4433
+ // {
4434
+ // "id": "(number)",
4435
+ // "value": "1"
4436
+ // },
4437
+ // {
4438
+ // "id": "(number)",
4439
+ // "value": "2"
4440
+ // }
4441
+ // ]
4442
+ // },
4443
+ // {
4444
+ // "id": "(number)",
4445
+ // "value": "4"
4446
+ // }
4447
+ // ]
4448
+ // }
4449
+ // ]
4450
+ // },
4451
+ // {
4452
+ // "id": "(number)",
4453
+ // "value": "5"
4454
+ // }
4455
+ // ]
4456
+ // }
4389
4457
 
4390
4458
  let left;
4391
4459
  let the_symbol;
@@ -4397,13 +4465,13 @@ function jslint_phase3_parse(state) {
4397
4465
  advance();
4398
4466
  }
4399
4467
  the_symbol = syntax_dict[token_now.id];
4400
- if (the_symbol !== undefined && the_symbol.nud !== undefined) {
4468
+ if (the_symbol !== undefined && the_symbol.nud_prefix !== undefined) {
4401
4469
 
4402
4470
  // test_cause:
4403
4471
  // ["0", "parse_expression", "symbol", "", 0]
4404
4472
 
4405
4473
  test_cause("symbol");
4406
- left = the_symbol.nud();
4474
+ left = the_symbol.nud_prefix();
4407
4475
  } else if (token_now.identifier) {
4408
4476
 
4409
4477
  // test_cause:
@@ -4428,32 +4496,38 @@ function jslint_phase3_parse(state) {
4428
4496
  the_symbol = syntax_dict[token_nxt.id];
4429
4497
  if (
4430
4498
  the_symbol === undefined
4431
- || the_symbol.led === undefined
4499
+ || the_symbol.led_infix === undefined
4432
4500
  || the_symbol.lbp <= rbp
4433
4501
  ) {
4434
4502
  break;
4435
4503
  }
4436
4504
  advance();
4437
- left = the_symbol.led(left);
4505
+ left = the_symbol.led_infix(left);
4438
4506
  }
4439
4507
  return left;
4440
4508
  }
4441
4509
 
4442
- function parse_fart(pl) {
4510
+ function parse_fart() {
4511
+ let parameters;
4512
+ let signature;
4443
4513
  let the_fart;
4514
+ [parameters, signature] = prefix_function_arg();
4444
4515
  advance("=>");
4445
4516
  the_fart = token_now;
4446
4517
  the_fart.arity = "binary";
4447
4518
  the_fart.name = "=>";
4448
4519
  the_fart.level = functionage.level + 1;
4449
4520
  function_list.push(the_fart);
4450
- if (functionage.loop > 0) {
4451
4521
 
4452
- // test_cause:
4453
- // ["while(0){aa.map(()=>0);}", "parse_fart", "function_in_loop", "=>", 19]
4522
+ // PR-384 - Relax warning "function_in_loop".
4523
+ //
4524
+ // if (functionage.loop > 0) {
4454
4525
 
4455
- warn("function_in_loop", the_fart);
4456
- }
4526
+ // // test_cause:
4527
+ // // ["while(0){aa.map(()=>0);}", "parse_fart", "function_in_loop", "=>", 19]
4528
+ //
4529
+ // warn("function_in_loop", the_fart);
4530
+ // }
4457
4531
 
4458
4532
  // Give the function properties storing its names and for observing the depth
4459
4533
  // of loops and switches.
@@ -4461,6 +4535,8 @@ function jslint_phase3_parse(state) {
4461
4535
  the_fart.context = empty();
4462
4536
  the_fart.finally = 0;
4463
4537
  the_fart.loop = 0;
4538
+ the_fart.parameters = parameters;
4539
+ the_fart.signature = signature;
4464
4540
  the_fart.switch = 0;
4465
4541
  the_fart.try = 0;
4466
4542
 
@@ -4468,23 +4544,42 @@ function jslint_phase3_parse(state) {
4468
4544
 
4469
4545
  function_stack.push(functionage);
4470
4546
  functionage = the_fart;
4471
- the_fart.parameters = pl[0];
4472
- the_fart.signature = pl[1];
4473
- the_fart.parameters.forEach(function (name) {
4547
+ the_fart.parameters.forEach(function enroll_parameter(name) {
4548
+ if (name.identifier) {
4549
+ enroll(name, "parameter", true);
4550
+ } else {
4551
+
4552
+ // PR-385 - Bugfix - Fixes issue #382 - fix warnings against destructured fart.
4474
4553
 
4475
4554
  // test_cause:
4476
- // ["(aa)=>{}", "parse_fart", "parameter", "", 0]
4555
+ // ["([aa])=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
4556
+ // ["({aa})=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
4477
4557
 
4478
- test_cause("parameter");
4479
- enroll(name, "parameter", true);
4558
+ warn("use_function_not_fart", the_fart);
4559
+
4560
+ // Recurse enroll_parameter().
4561
+
4562
+ name.names.forEach(enroll_parameter);
4563
+ }
4480
4564
  });
4481
4565
  if (token_nxt.id === "{") {
4482
4566
 
4483
4567
  // test_cause:
4484
- // ["()=>{}", "parse_fart", "expected_a_b", "=>", 3]
4568
+ // ["()=>{}", "parse_fart", "use_function_not_fart", "=>", 3]
4485
4569
 
4486
- warn("expected_a_b", the_fart, "function", "=>");
4570
+ warn("use_function_not_fart", the_fart);
4487
4571
  the_fart.block = block("body");
4572
+ } else if (
4573
+ syntax_dict[token_nxt.id] !== undefined
4574
+ && syntax_dict[token_nxt.id].fud_stmt !== undefined
4575
+ ) {
4576
+
4577
+ // PR-384 - Bugfix - Fixes issue #379 - warn against naked-statement in fart.
4578
+
4579
+ // test_cause:
4580
+ // ["()=>delete aa", "parse_fart", "unexpected_a_after_b", "=>", 5]
4581
+
4582
+ stop("unexpected_a_after_b", token_nxt, token_nxt.id, "=>");
4488
4583
  } else {
4489
4584
  the_fart.expression = parse_expression(0);
4490
4585
  }
@@ -4707,7 +4802,7 @@ function jslint_phase3_parse(state) {
4707
4802
  the_symbol = syntax_dict[first.id];
4708
4803
  if (
4709
4804
  the_symbol !== undefined
4710
- && the_symbol.fud !== undefined
4805
+ && the_symbol.fud_stmt !== undefined
4711
4806
 
4712
4807
  // PR-318 - Bugfix - Fixes issues #316, #317 - dynamic-import().
4713
4808
 
@@ -4716,7 +4811,7 @@ function jslint_phase3_parse(state) {
4716
4811
  the_symbol.disrupt = false;
4717
4812
  the_symbol.statement = true;
4718
4813
  token_now.arity = "statement";
4719
- the_statement = the_symbol.fud();
4814
+ the_statement = the_symbol.fud_stmt();
4720
4815
  functionage.statement_prv = the_statement;
4721
4816
  } else {
4722
4817
 
@@ -4786,7 +4881,7 @@ function jslint_phase3_parse(state) {
4786
4881
  // Create one of the postassign operators.
4787
4882
 
4788
4883
  const the_symbol = symbol(id, 150);
4789
- the_symbol.led = function (left) {
4884
+ the_symbol.led_infix = function (left) {
4790
4885
  token_now.expression = left;
4791
4886
  token_now.arity = "postassign";
4792
4887
  check_mutation(token_now.expression);
@@ -4800,7 +4895,7 @@ function jslint_phase3_parse(state) {
4800
4895
  // Create one of the preassign operators.
4801
4896
 
4802
4897
  const the_symbol = symbol(id);
4803
- the_symbol.nud = function () {
4898
+ the_symbol.nud_prefix = function () {
4804
4899
  const the_token = token_now;
4805
4900
  the_token.arity = "preassign";
4806
4901
  the_token.expression = parse_expression(150);
@@ -4815,7 +4910,7 @@ function jslint_phase3_parse(state) {
4815
4910
  // Create a prefix operator.
4816
4911
 
4817
4912
  const the_symbol = symbol(id);
4818
- the_symbol.nud = function () {
4913
+ the_symbol.nud_prefix = function () {
4819
4914
  const the_token = token_now;
4820
4915
  the_token.arity = "unary";
4821
4916
  if (typeof f === "function") {
@@ -4997,6 +5092,9 @@ function jslint_phase3_parse(state) {
4997
5092
  if (name.identifier) {
4998
5093
  enroll(name, "parameter", false);
4999
5094
  } else {
5095
+
5096
+ // Recurse enroll_parameter().
5097
+
5000
5098
  name.names.forEach(enroll_parameter);
5001
5099
  }
5002
5100
  });
@@ -5457,25 +5555,14 @@ function jslint_phase3_parse(state) {
5457
5555
  }
5458
5556
 
5459
5557
  function prefix_lparen() {
5460
- const cadet = lookahead().id;
5461
- const the_paren = token_now;
5558
+ let the_paren = token_now;
5462
5559
  let the_value;
5463
5560
 
5464
- // We can distinguish between a parameter list for => and a wrapped expression
5465
- // with one token of lookahead.
5466
-
5467
- if (
5468
- token_nxt.id === ")"
5469
- || token_nxt.id === "..."
5470
- || (token_nxt.identifier && (cadet === "," || cadet === "="))
5471
- ) {
5472
-
5473
- // test_cause:
5474
- // ["()=>0", "prefix_lparen", "fart", "", 0]
5561
+ // PR-385 - Bugfix - Fixes issue #382 - failure to detect destructured fart.
5475
5562
 
5476
- test_cause("fart");
5563
+ if (token_now.is_fart) {
5477
5564
  the_paren.free = false;
5478
- return parse_fart(prefix_function_arg());
5565
+ return parse_fart();
5479
5566
  }
5480
5567
 
5481
5568
  // test_cause:
@@ -5493,31 +5580,6 @@ function jslint_phase3_parse(state) {
5493
5580
  }
5494
5581
  the_value.wrapped = true;
5495
5582
  advance(")", the_paren);
5496
- if (token_nxt.id === "=>") {
5497
- if (the_value.arity !== "variable") {
5498
- if (the_value.id === "{" || the_value.id === "[") {
5499
-
5500
- // test_cause:
5501
- // ["([])=>0", "prefix_lparen", "expected_a_before_b", "(", 1]
5502
- // ["({})=>0", "prefix_lparen", "expected_a_before_b", "(", 1]
5503
-
5504
- warn("expected_a_before_b", the_paren, "function", "(");
5505
-
5506
- // test_cause:
5507
- // ["([])=>0", "prefix_lparen", "expected_a_b", "=>", 5]
5508
- // ["({})=>0", "prefix_lparen", "expected_a_b", "=>", 5]
5509
-
5510
- return stop("expected_a_b", token_nxt, "{", "=>");
5511
- }
5512
-
5513
- // test_cause:
5514
- // ["(0)=>0", "prefix_lparen", "expected_identifier_a", "0", 2]
5515
-
5516
- return stop("expected_identifier_a", the_value);
5517
- }
5518
- the_paren.expression = [the_value];
5519
- return parse_fart([the_paren.expression, "(" + the_value.id + ")"]);
5520
- }
5521
5583
  return the_value;
5522
5584
  }
5523
5585
 
@@ -5598,12 +5660,12 @@ function jslint_phase3_parse(state) {
5598
5660
  anon = "anonymous";
5599
5661
  }
5600
5662
 
5601
- function stmt(id, fud) {
5663
+ function stmt(id, fud_stmt) {
5602
5664
 
5603
5665
  // Create a statement.
5604
5666
 
5605
5667
  const the_symbol = symbol(id);
5606
- the_symbol.fud = fud;
5668
+ the_symbol.fud_stmt = fud_stmt;
5607
5669
  return the_symbol;
5608
5670
  }
5609
5671
 
@@ -6732,7 +6794,7 @@ function jslint_phase3_parse(state) {
6732
6794
  // Create a ternary operator.
6733
6795
 
6734
6796
  const the_symbol = symbol(id1, 30);
6735
- the_symbol.led = function parse_ternary_led(left) {
6797
+ the_symbol.led_infix = function parse_ternary_led(left) {
6736
6798
  const the_token = token_now;
6737
6799
  let second;
6738
6800
  second = parse_expression(20);
@@ -9569,7 +9631,7 @@ function objectDeepCopyWithKeysSorted(obj) {
9569
9631
 
9570
9632
  // Recursively deep-copy obj with keys sorted.
9571
9633
 
9572
- sorted = {};
9634
+ sorted = Object.create(null);
9573
9635
  Object.keys(obj).sort().forEach(function (key) {
9574
9636
  sorted[key] = objectDeepCopyWithKeysSorted(obj[key]);
9575
9637
  });
@@ -10843,7 +10905,7 @@ function sentinel() {}
10843
10905
 
10844
10906
  // 3. Create html-coverage-reports in <coverageDir>.
10845
10907
 
10846
- fileDict = {};
10908
+ fileDict = Object.create(null);
10847
10909
  await Promise.all(v8CoverageObj.result.map(async function ({
10848
10910
  functions,
10849
10911
  url: pathname
@@ -0,0 +1,19 @@
1
+ /*jslint beta, node*/
2
+ /*property
3
+ module, readFileSync, replace, runInNewContext
4
+ */
5
+ require("vm").runInNewContext(
6
+ (
7
+ "\"use strict\";"
8
+ + require("fs").readFileSync(__dirname + "/jslint.mjs", "utf8").replace(
9
+ "\nexport default Object.freeze(jslint_export);",
10
+ "\nmodule.exports = jslint_export;"
11
+ ).replace(
12
+ "\njslint_import_meta_url = import.meta.url;",
13
+ "\n// jslint_import_meta_url = import.meta.url;"
14
+ )
15
+ ),
16
+ {
17
+ module
18
+ }
19
+ );
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "counter": 7,
6
6
  "description": "JSLint, The JavaScript Code Quality and Coverage Tool",
7
7
  "exports": {
8
- "default": "./jslint.cjs",
8
+ "default": "./jslint_wrapper_cjs.cjs",
9
9
  "import": "./jslint.mjs"
10
10
  },
11
11
  "fileCount": 28,
@@ -17,7 +17,7 @@
17
17
  "zero-dependency"
18
18
  ],
19
19
  "license": "UNLICENSE",
20
- "main": "./jslint.cjs",
20
+ "main": "./jslint_wrapper_cjs.cjs",
21
21
  "module": "./jslint.mjs",
22
22
  "name": "@jslint-org/jslint",
23
23
  "repository": {
@@ -29,5 +29,5 @@
29
29
  "test2": "sh jslint_ci.sh shCiBase"
30
30
  },
31
31
  "type": "module",
32
- "version": "2021.12.20"
32
+ "version": "2022.2.20"
33
33
  }
package/jslint.cjs DELETED
@@ -1,14 +0,0 @@
1
- /*jslint beta, node*/
2
- /*property
3
- readFileSync, replace, runInNewContext
4
- */
5
- require("vm").runInNewContext(
6
- require("fs").readFileSync(__dirname + "/jslint.mjs", "utf8").replace(
7
- "\nexport default Object.freeze(jslint_export);",
8
- "\nexports = jslint_export;"
9
- ).replace(
10
- "\njslint_import_meta_url = import.meta.url;",
11
- "\n// jslint_import_meta_url = import.meta.url;"
12
- ),
13
- module
14
- );