@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 +1 -1
- package/README.md +6 -6
- package/jslint.mjs +193 -131
- package/jslint_wrapper_cjs.cjs +19 -0
- package/package.json +3 -3
- package/jslint.cjs +0 -14
package/.npmignore
CHANGED
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ Douglas Crockford <douglas@crockford.com>
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
# Status
|
|
6
|
-
| Branch | [master<br>(
|
|
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 | [](https://github.com/jslint-org/jslint/actions?query=branch%3Amaster) | [](https://github.com/jslint-org/jslint/actions?query=branch%3Abeta) | [](https://github.com/jslint-org/jslint/actions?query=branch%3Aalpha) |
|
|
9
9
|
| Coverage | [](https://jslint-org.github.io/jslint/branch-master/.artifact/coverage/index.html) | [](https://jslint-org.github.io/jslint/branch-beta/.artifact/coverage/index.html) | [](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. [
|
|
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
|
-
#
|
|
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), [`
|
|
340
|
-
2. Add vim-command `:source ~/.vim/
|
|
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
|
-

|
|
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,
|
|
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,
|
|
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,
|
|
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 = "
|
|
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
|
-
|
|
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
|
-
//
|
|
1679
|
+
// PR-363 - Add command jslint_report.
|
|
1666
1680
|
|
|
1667
|
-
case "
|
|
1668
|
-
|
|
1681
|
+
case "jslint_report":
|
|
1682
|
+
mode_report = command[1];
|
|
1669
1683
|
process_argv = process_argv.slice(1);
|
|
1670
1684
|
break;
|
|
1671
1685
|
|
|
1672
|
-
//
|
|
1686
|
+
// COMMIT-b26d6df2 - Add command jslint_wrapper_vim.
|
|
1673
1687
|
|
|
1674
|
-
case "
|
|
1675
|
-
|
|
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
|
-
|
|
1706
|
+
mode_wrapper_vim = (
|
|
1692
1707
|
process_argv.slice(2).indexOf("--mode-vim-plugin") >= 0
|
|
1693
|
-
||
|
|
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
|
-
// ["
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
4211
|
+
function infix_fart_unwrapped() {
|
|
4175
4212
|
|
|
4176
4213
|
// test_cause:
|
|
4177
|
-
// ["aa=>0", "infix_fart_unwrapped", "
|
|
4214
|
+
// ["aa=>0", "infix_fart_unwrapped", "wrap_fart_parameter", "=>", 3]
|
|
4178
4215
|
|
|
4179
|
-
return stop("
|
|
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.
|
|
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", "
|
|
4383
|
+
// ["0**0", "parse_infixr_led", "led_infix", "", 0]
|
|
4347
4384
|
|
|
4348
|
-
test_cause("
|
|
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 .
|
|
4375
|
-
// like .
|
|
4376
|
-
// Having .
|
|
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
|
-
// .
|
|
4381
|
-
// .
|
|
4382
|
-
// .
|
|
4383
|
-
// lbp
|
|
4384
|
-
//
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
//
|
|
4388
|
-
//
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
4505
|
+
left = the_symbol.led_infix(left);
|
|
4438
4506
|
}
|
|
4439
4507
|
return left;
|
|
4440
4508
|
}
|
|
4441
4509
|
|
|
4442
|
-
function parse_fart(
|
|
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
|
-
//
|
|
4453
|
-
//
|
|
4522
|
+
// PR-384 - Relax warning "function_in_loop".
|
|
4523
|
+
//
|
|
4524
|
+
// if (functionage.loop > 0) {
|
|
4454
4525
|
|
|
4455
|
-
|
|
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
|
|
4472
|
-
|
|
4473
|
-
|
|
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)=>
|
|
4555
|
+
// ["([aa])=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
|
|
4556
|
+
// ["({aa})=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
|
|
4477
4557
|
|
|
4478
|
-
|
|
4479
|
-
|
|
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", "
|
|
4568
|
+
// ["()=>{}", "parse_fart", "use_function_not_fart", "=>", 3]
|
|
4485
4569
|
|
|
4486
|
-
warn("
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
5461
|
-
const the_paren = token_now;
|
|
5558
|
+
let the_paren = token_now;
|
|
5462
5559
|
let the_value;
|
|
5463
5560
|
|
|
5464
|
-
//
|
|
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
|
-
|
|
5563
|
+
if (token_now.is_fart) {
|
|
5477
5564
|
the_paren.free = false;
|
|
5478
|
-
return parse_fart(
|
|
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,
|
|
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.
|
|
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.
|
|
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": "./
|
|
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": "./
|
|
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": "
|
|
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
|
-
);
|