@jslint-org/jslint 2022.3.30 → 2022.7.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 +6 -0
- package/CHANGELOG.md +270 -0
- package/README.md +543 -50
- package/asset_codemirror_rollup.js +11470 -0
- package/asset_font_daley_bold.woff2 +0 -0
- package/asset_image_folder_open_solid.svg +1 -0
- package/asset_image_github_brands.svg +1 -0
- package/asset_image_jslint_wrapper_vim.png +0 -0
- package/asset_image_jslint_wrapper_vscode.png +0 -0
- package/asset_image_json_160.svg +104 -0
- package/asset_image_logo_512.png +0 -0
- package/asset_image_logo_512.svg +39 -0
- package/jslint.mjs +504 -184
- package/jslint_wrapper_cjs.cjs +28 -0
- package/jslint_wrapper_vscode.js +227 -0
- package/package.json +6 -2
package/jslint.mjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// #!/usr/bin/env node
|
|
2
2
|
// JSLint
|
|
3
|
-
// Original Author: Douglas Crockford (https://www.jslint.com).
|
|
4
3
|
|
|
4
|
+
// The Unlicense
|
|
5
|
+
//
|
|
5
6
|
// This is free and unencumbered software released into the public domain.
|
|
6
|
-
|
|
7
|
+
//
|
|
7
8
|
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
8
9
|
// distribute this software, either in source code form or as a compiled
|
|
9
10
|
// binary, for any purpose, commercial or non-commercial, and by any
|
|
10
11
|
// means.
|
|
11
|
-
|
|
12
|
+
//
|
|
12
13
|
// In jurisdictions that recognize copyright laws, the author or authors
|
|
13
14
|
// of this software dedicate any and all copyright interest in the
|
|
14
15
|
// software to the public domain. We make this dedication for the benefit
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
// successors. We intend this dedication to be an overt act of
|
|
17
18
|
// relinquishment in perpetuity of all present and future rights to this
|
|
18
19
|
// software under copyright law.
|
|
19
|
-
|
|
20
|
+
//
|
|
20
21
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
21
22
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
22
23
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
25
26
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
26
27
|
// OTHER DEALINGS IN THE SOFTWARE.
|
|
27
|
-
|
|
28
|
+
//
|
|
28
29
|
// For more information, please refer to <https://unlicense.org/>
|
|
29
30
|
|
|
30
31
|
|
|
@@ -92,49 +93,46 @@
|
|
|
92
93
|
// WARNING: JSLint will hurt your feelings.
|
|
93
94
|
|
|
94
95
|
/*jslint beta, node*/
|
|
95
|
-
|
|
96
96
|
/*property
|
|
97
|
-
fud_stmt,
|
|
98
|
-
is_fart,
|
|
99
|
-
mode_conditional,
|
|
100
97
|
JSLINT_BETA, NODE_V8_COVERAGE, a, all, argv, arity, artifact,
|
|
101
98
|
assertErrorThrownAsync, assertJsonEqual, assertOrThrow, assign, async, b,
|
|
102
99
|
beta, bitwise, block, body, browser, c, calls, catch, catch_list,
|
|
103
|
-
catch_stack, causes, char, children, clear, closer,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
formatted_message, free, freeze, from, froms,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
holeList, htmlEscape, id, identifier, import, import_list,
|
|
115
|
-
|
|
116
|
-
is_equal, is_weird, join, jslint,
|
|
117
|
-
|
|
118
|
-
jslint_phase2_lex, jslint_phase3_parse,
|
|
119
|
-
jslint_phase5_whitage, jslint_report, json,
|
|
120
|
-
jstestOnExit, keys, label, lbp, led_infix, length,
|
|
121
|
-
|
|
122
|
-
log, long, loop, m,
|
|
123
|
-
mkdir, modeCoverageIgnoreFile, modeIndex, mode_cli,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
100
|
+
catch_stack, causes, char, children, clear, closer, closure, code, column,
|
|
101
|
+
concat, consoleError, console_error, console_log, constant, context,
|
|
102
|
+
convert, count, coverageDir, create, cwd, d, dead, debugInline, default,
|
|
103
|
+
delta, devel, directive, directive_ignore_line, directive_list, directives,
|
|
104
|
+
dirname, disrupt, dot, edition, elem_list, ellipsis, else, end, endOffset,
|
|
105
|
+
endsWith, entries, env, error, eval, every, example_list, excludeList, exec,
|
|
106
|
+
execArgv, exit, exitCode, export_dict, exports, expression, extra, file,
|
|
107
|
+
fileList, fileURLToPath, filter, finally, flag, floor, for, forEach,
|
|
108
|
+
formatted_message, free, freeze, from, froms, fsWriteFileWithParents,
|
|
109
|
+
fud_stmt, functionName, function_list, function_stack, functions, get,
|
|
110
|
+
getset, github_repo, globExclude, global, global_dict, global_list,
|
|
111
|
+
holeList, htmlEscape, id, identifier, import, import_list, import_meta_url,
|
|
112
|
+
inc, includeList, indent2, index, indexOf, init, initial, isArray,
|
|
113
|
+
isBlockCoverage, isHole, isNaN, is_equal, is_fart, is_weird, join, jslint,
|
|
114
|
+
jslint_apidoc, jslint_assert, jslint_charset_ascii, jslint_cli,
|
|
115
|
+
jslint_edition, jslint_phase1_split, jslint_phase2_lex, jslint_phase3_parse,
|
|
116
|
+
jslint_phase4_walk, jslint_phase5_whitage, jslint_report, json,
|
|
117
|
+
jstestDescribe, jstestIt, jstestOnExit, keys, label, lbp, led_infix, length,
|
|
118
|
+
level, line, lineList, line_list, line_offset, line_source, lines,
|
|
119
|
+
linesCovered, linesTotal, live, log, long, loop, m, map, margin, match, max,
|
|
120
|
+
message, meta, min, mkdir, modeCoverageIgnoreFile, modeIndex, mode_cli,
|
|
121
|
+
mode_conditional, mode_json, mode_module, mode_noop, mode_property,
|
|
122
|
+
mode_shebang, mode_stop, module, moduleFsInit, moduleName, module_list,
|
|
123
|
+
name, names, node, nomen, noop, now, nr, nud_prefix,
|
|
124
|
+
objectDeepCopyWithKeysSorted, ok, on, open, opening, option, option_dict,
|
|
125
|
+
order, package_name, padEnd, padStart, parameters, parent, parentIi, parse,
|
|
126
|
+
pathname, pathnameList, platform, pop, processArgv, process_argv,
|
|
127
|
+
process_env, process_exit, promises, property, property_dict, push, quote,
|
|
128
|
+
ranges, readFile, readdir, readonly, recursive, reduce, repeat, replace,
|
|
129
|
+
resolve, result, reverse, role, round, scriptId, search, set, shebang,
|
|
130
|
+
shift, signature, single, slice, some, sort, source, spawn, splice, split,
|
|
131
|
+
stack, stack_trace, start, startOffset, startsWith, statement,
|
|
132
|
+
statement_prv, stdio, stop, stop_at, stringify, subscript, switch,
|
|
133
|
+
syntax_dict, tenure, test, test_cause, test_internal_error, this, thru,
|
|
134
|
+
toString, token, token_global, token_list, token_nxt, token_tree, tokens,
|
|
135
|
+
trace, tree, trim, trimEnd, trimRight, try, type, unlink, unordered,
|
|
138
136
|
unshift, url, used, v8CoverageListMerge, v8CoverageReportCreate, value,
|
|
139
137
|
variable, version, versions, warn, warn_at, warning, warning_list, warnings,
|
|
140
138
|
white, wrapped, writeFile
|
|
@@ -142,20 +140,20 @@
|
|
|
142
140
|
|
|
143
141
|
// init debugInline
|
|
144
142
|
let debugInline = (function () {
|
|
145
|
-
let
|
|
143
|
+
let __consoleError = function () {
|
|
146
144
|
return;
|
|
147
145
|
};
|
|
148
146
|
function debug(...argv) {
|
|
149
147
|
|
|
150
148
|
// This function will print <argv> to stderr and then return <argv>[0].
|
|
151
149
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
__consoleError("\n\ndebugInline");
|
|
151
|
+
__consoleError(...argv);
|
|
152
|
+
__consoleError("\n");
|
|
155
153
|
return argv[0];
|
|
156
154
|
}
|
|
157
155
|
debug(); // Coverage-hack.
|
|
158
|
-
|
|
156
|
+
__consoleError = console.error; //jslint-ignore-line
|
|
159
157
|
return debug;
|
|
160
158
|
}());
|
|
161
159
|
let jslint_charset_ascii = (
|
|
@@ -167,7 +165,7 @@ let jslint_charset_ascii = (
|
|
|
167
165
|
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
|
168
166
|
+ "`abcdefghijklmnopqrstuvwxyz{|}~\u007f"
|
|
169
167
|
);
|
|
170
|
-
let jslint_edition = "v2022.
|
|
168
|
+
let jslint_edition = "v2022.7.20";
|
|
171
169
|
let jslint_export; // The jslint object to be exported.
|
|
172
170
|
let jslint_fudge = 1; // Fudge starting line and starting
|
|
173
171
|
// ... column to 1.
|
|
@@ -254,6 +252,9 @@ let jslint_rgx_token = new RegExp(
|
|
|
254
252
|
+ ")"
|
|
255
253
|
+ "(.*)$"
|
|
256
254
|
);
|
|
255
|
+
let jslint_rgx_url_search_window_jslint = (
|
|
256
|
+
/[&?]window_jslint=1(?:$|&)/m
|
|
257
|
+
);
|
|
257
258
|
let jslint_rgx_weird_property = (
|
|
258
259
|
/^_|\$|Sync$|_$/m
|
|
259
260
|
);
|
|
@@ -352,6 +353,226 @@ async function fsWriteFileWithParents(pathname, data) {
|
|
|
352
353
|
console.error("wrote file " + pathname);
|
|
353
354
|
}
|
|
354
355
|
|
|
356
|
+
function globExclude({
|
|
357
|
+
excludeList = [],
|
|
358
|
+
includeList = [],
|
|
359
|
+
pathnameList = []
|
|
360
|
+
}) {
|
|
361
|
+
|
|
362
|
+
// This function will
|
|
363
|
+
// 1. Exclude pathnames in <pathnameList> that don't match glob-patterns in
|
|
364
|
+
// <includeList>.
|
|
365
|
+
// 2. Exclude pathnames in <pathnameList> that match glob-patterns in
|
|
366
|
+
// <excludeList>.
|
|
367
|
+
|
|
368
|
+
function globAssertNotWeird(list, name) {
|
|
369
|
+
|
|
370
|
+
// This function will check if <list> of strings contain weird characters.
|
|
371
|
+
|
|
372
|
+
[
|
|
373
|
+
[
|
|
374
|
+
"\n", (
|
|
375
|
+
/^.*?([\u0000-\u0007\r]).*/gm
|
|
376
|
+
)
|
|
377
|
+
],
|
|
378
|
+
[
|
|
379
|
+
"\r", (
|
|
380
|
+
/^.*?([\n]).*/gm
|
|
381
|
+
)
|
|
382
|
+
]
|
|
383
|
+
].forEach(function ([
|
|
384
|
+
separator, rgx
|
|
385
|
+
]) {
|
|
386
|
+
list.join(separator).replace(rgx, function (match0, char) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
"Weird character "
|
|
389
|
+
+ JSON.stringify(char)
|
|
390
|
+
+ " found in " + name + " "
|
|
391
|
+
+ JSON.stringify(match0)
|
|
392
|
+
);
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function globToRegexp(pattern) {
|
|
398
|
+
|
|
399
|
+
// This function will translate glob <pattern> to javascript-regexp,
|
|
400
|
+
// which javascript can then use to "glob" pathnames.
|
|
401
|
+
|
|
402
|
+
let ii = 0;
|
|
403
|
+
let isClass = false;
|
|
404
|
+
let strClass = "";
|
|
405
|
+
let strRegex = "";
|
|
406
|
+
pattern = pattern.replace((
|
|
407
|
+
/\/\/+/g
|
|
408
|
+
), "/");
|
|
409
|
+
pattern = pattern.replace((
|
|
410
|
+
/\*\*\*+/g
|
|
411
|
+
), "**");
|
|
412
|
+
pattern.replace((
|
|
413
|
+
/\\\\|\\\[|\\\]|\[|\]|./g
|
|
414
|
+
), function (match0) {
|
|
415
|
+
switch (match0) {
|
|
416
|
+
case "[":
|
|
417
|
+
if (isClass) {
|
|
418
|
+
strClass += "[";
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
strClass += "\u0000";
|
|
422
|
+
strRegex += "\u0000";
|
|
423
|
+
isClass = true;
|
|
424
|
+
return;
|
|
425
|
+
case "]":
|
|
426
|
+
if (isClass) {
|
|
427
|
+
isClass = false;
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
strRegex += "]";
|
|
431
|
+
return;
|
|
432
|
+
default:
|
|
433
|
+
if (isClass) {
|
|
434
|
+
strClass += match0;
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
strRegex += match0;
|
|
438
|
+
}
|
|
439
|
+
return "";
|
|
440
|
+
});
|
|
441
|
+
strClass += "\u0000";
|
|
442
|
+
|
|
443
|
+
// An expression "[!...]" matches a single character, namely any character that
|
|
444
|
+
// is not matched by the expression obtained by removing the first '!' from it.
|
|
445
|
+
// (Thus, "[!a-]" matches any single character except 'a', and '-'.)
|
|
446
|
+
|
|
447
|
+
strClass = strClass.replace((
|
|
448
|
+
/\u0000!/g
|
|
449
|
+
), "\u0000^");
|
|
450
|
+
|
|
451
|
+
// One may include '-' in its literal meaning by making it the first or last
|
|
452
|
+
// character between the brackets.
|
|
453
|
+
|
|
454
|
+
strClass = strClass.replace((
|
|
455
|
+
/\u0000-/g
|
|
456
|
+
), "\u0000\\-");
|
|
457
|
+
strClass = strClass.replace((
|
|
458
|
+
/-\u0000/g
|
|
459
|
+
), "\\-\u0000");
|
|
460
|
+
|
|
461
|
+
// Escape brackets '[', ']' in character class.
|
|
462
|
+
|
|
463
|
+
strClass = strClass.replace((
|
|
464
|
+
/[\[\]]/g
|
|
465
|
+
), "\\$&");
|
|
466
|
+
|
|
467
|
+
// https://stackoverflow.com/questions/3561493
|
|
468
|
+
// /is-there-a-regexp-escape-function-in-javascript
|
|
469
|
+
// $()*+-./?[\]^{|}
|
|
470
|
+
|
|
471
|
+
strRegex = strRegex.replace((
|
|
472
|
+
|
|
473
|
+
// Ignore [-/].
|
|
474
|
+
|
|
475
|
+
/[$()*+.?\[\\\]\^{|}]/g
|
|
476
|
+
), "\\$&");
|
|
477
|
+
|
|
478
|
+
// Expand wildcard '**/*'.
|
|
479
|
+
|
|
480
|
+
strRegex = strRegex.replace((
|
|
481
|
+
/\\\*\\\*\/(?:\\\*)+/g
|
|
482
|
+
), ".*?");
|
|
483
|
+
|
|
484
|
+
// Expand wildcard '**'.
|
|
485
|
+
|
|
486
|
+
strRegex = strRegex.replace((
|
|
487
|
+
/(^|\/)\\\*\\\*(\/|$)/gm
|
|
488
|
+
), "$1.*?$2");
|
|
489
|
+
|
|
490
|
+
// Expand wildcard '*'.
|
|
491
|
+
|
|
492
|
+
strRegex = strRegex.replace((
|
|
493
|
+
/(?:\\\*)+/g
|
|
494
|
+
), "[^\\/]*?");
|
|
495
|
+
|
|
496
|
+
// Expand wildcard '?'.
|
|
497
|
+
|
|
498
|
+
strRegex = strRegex.replace((
|
|
499
|
+
/\\\?/g
|
|
500
|
+
), "[^\\/]");
|
|
501
|
+
|
|
502
|
+
// Expand directory-with-trailing-slash '.../'.
|
|
503
|
+
|
|
504
|
+
strRegex = strRegex.replace((
|
|
505
|
+
/\/$/gm
|
|
506
|
+
), "\\/.*?");
|
|
507
|
+
|
|
508
|
+
// Merge strClass into strRegex.
|
|
509
|
+
|
|
510
|
+
ii = 0;
|
|
511
|
+
strClass = strClass.split("\u0000");
|
|
512
|
+
strRegex = strRegex.replace((
|
|
513
|
+
/\u0000/g
|
|
514
|
+
), function () {
|
|
515
|
+
ii += 1;
|
|
516
|
+
if (strClass[ii] === "") {
|
|
517
|
+
return "";
|
|
518
|
+
}
|
|
519
|
+
return "[" + strClass[ii] + "]";
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
// Change strRegex from string to regexp.
|
|
523
|
+
|
|
524
|
+
strRegex = new RegExp("^" + strRegex + "$", "gm");
|
|
525
|
+
return strRegex;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Validate excludeList, includeList, pathnameList.
|
|
529
|
+
|
|
530
|
+
globAssertNotWeird(excludeList, "pattern");
|
|
531
|
+
globAssertNotWeird(includeList, "pattern");
|
|
532
|
+
globAssertNotWeird(pathnameList, "pathname");
|
|
533
|
+
|
|
534
|
+
// Optimization
|
|
535
|
+
// Concat pathnames into a single, newline-separated string,
|
|
536
|
+
// whose pathnames can all be filtered with a single, regexp-pass.
|
|
537
|
+
|
|
538
|
+
pathnameList = pathnameList.join("\n");
|
|
539
|
+
|
|
540
|
+
// 1. Exclude pathnames in <pathnameList> that don't match glob-patterns in
|
|
541
|
+
// <includeList>.
|
|
542
|
+
|
|
543
|
+
if (includeList.length > 0) {
|
|
544
|
+
includeList = includeList.map(globToRegexp);
|
|
545
|
+
includeList.forEach(function (pattern) {
|
|
546
|
+
pathnameList = pathnameList.replace(pattern, "\u0000$&");
|
|
547
|
+
});
|
|
548
|
+
pathnameList = pathnameList.replace((
|
|
549
|
+
/^[^\u0000].*/gm
|
|
550
|
+
), "");
|
|
551
|
+
pathnameList = pathnameList.replace((
|
|
552
|
+
/^\u0000+/gm
|
|
553
|
+
), "");
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// 2. Exclude pathnames in <pathnameList> that match glob-patterns in
|
|
557
|
+
// <excludeList>.
|
|
558
|
+
|
|
559
|
+
excludeList = excludeList.map(globToRegexp);
|
|
560
|
+
excludeList.forEach(function (pattern) {
|
|
561
|
+
pathnameList = pathnameList.replace(pattern, "");
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
// Split newline-separated pathnames back to list.
|
|
565
|
+
|
|
566
|
+
pathnameList = pathnameList.split("\n").filter(function (elem) {
|
|
567
|
+
return elem;
|
|
568
|
+
});
|
|
569
|
+
return {
|
|
570
|
+
excludeList,
|
|
571
|
+
includeList,
|
|
572
|
+
pathnameList
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
|
|
355
576
|
function htmlEscape(str) {
|
|
356
577
|
|
|
357
578
|
// This function will make <str> html-safe by escaping & < >.
|
|
@@ -437,8 +658,6 @@ function jslint(
|
|
|
437
658
|
}
|
|
438
659
|
|
|
439
660
|
function is_equal(aa, bb) {
|
|
440
|
-
let aa_value;
|
|
441
|
-
let bb_value;
|
|
442
661
|
|
|
443
662
|
// test_cause:
|
|
444
663
|
// ["0&&0", "is_equal", "", "", 0]
|
|
@@ -459,6 +678,7 @@ function jslint(
|
|
|
459
678
|
|
|
460
679
|
// test_cause:
|
|
461
680
|
// ["`${0}`&&`${0}`", "is_equal", "recurse_isArray", "", 0]
|
|
681
|
+
// ["`${0}`&&`${1}`", "is_equal", "recurse_isArray", "", 0]
|
|
462
682
|
|
|
463
683
|
test_cause("recurse_isArray");
|
|
464
684
|
return is_equal(value, bb[index]);
|
|
@@ -472,21 +692,19 @@ function jslint(
|
|
|
472
692
|
// }
|
|
473
693
|
|
|
474
694
|
jslint_assert(!Array.isArray(bb), `Expected !Array.isArray(bb).`);
|
|
475
|
-
|
|
695
|
+
switch (aa.id === bb.id && aa.id) {
|
|
696
|
+
case "(number)":
|
|
697
|
+
case "(string)":
|
|
476
698
|
return aa.value === bb.value;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
bb_value = bb.value[0];
|
|
487
|
-
}
|
|
488
|
-
if (typeof aa_value === "string") {
|
|
489
|
-
return aa_value === bb_value;
|
|
699
|
+
|
|
700
|
+
// PR-394 - Bugfix
|
|
701
|
+
// Fix jslint falsely believing megastring literals `0` and `1` are similar.
|
|
702
|
+
|
|
703
|
+
case "`":
|
|
704
|
+
if (!is_equal(aa.value, bb.value)) {
|
|
705
|
+
return false;
|
|
706
|
+
}
|
|
707
|
+
break;
|
|
490
708
|
}
|
|
491
709
|
if (is_weird(aa) || is_weird(bb)) {
|
|
492
710
|
|
|
@@ -497,10 +715,11 @@ function jslint(
|
|
|
497
715
|
return false;
|
|
498
716
|
}
|
|
499
717
|
if (aa.arity === bb.arity && aa.id === bb.id) {
|
|
500
|
-
if (aa.id === ".") {
|
|
718
|
+
if (aa.id === "." || aa.id === "?.") {
|
|
501
719
|
|
|
502
720
|
// test_cause:
|
|
503
721
|
// ["aa.bb&&aa.bb", "is_equal", "recurse_arity_id", "", 0]
|
|
722
|
+
// ["aa?.bb&&aa?.bb", "is_equal", "recurse_arity_id", "", 0]
|
|
504
723
|
|
|
505
724
|
test_cause("recurse_arity_id");
|
|
506
725
|
return (
|
|
@@ -641,11 +860,22 @@ function jslint(
|
|
|
641
860
|
c,
|
|
642
861
|
d
|
|
643
862
|
);
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
863
|
+
|
|
864
|
+
// Issue #408
|
|
865
|
+
// Warnings that should be ignored sometimes suppress legitimate warnings.
|
|
866
|
+
|
|
867
|
+
if (the_warning.directive_ignore_line) {
|
|
868
|
+
return the_warning;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// If there is already a warning on this token, suppress the new one. It is
|
|
872
|
+
// likely that the first warning will be the most meaningful.
|
|
873
|
+
|
|
874
|
+
if (the_token.warning) {
|
|
647
875
|
warning_list.pop();
|
|
876
|
+
return the_warning;
|
|
648
877
|
}
|
|
878
|
+
the_token.warning = the_warning;
|
|
649
879
|
return the_warning;
|
|
650
880
|
}
|
|
651
881
|
|
|
@@ -795,6 +1025,7 @@ function jslint(
|
|
|
795
1025
|
break;
|
|
796
1026
|
|
|
797
1027
|
// PR-347 - Disable warning "missing_browser".
|
|
1028
|
+
//
|
|
798
1029
|
// case "missing_browser":
|
|
799
1030
|
// mm = `/*global*/ requires the Assume a browser option.`;
|
|
800
1031
|
// break;
|
|
@@ -879,6 +1110,7 @@ function jslint(
|
|
|
879
1110
|
break;
|
|
880
1111
|
|
|
881
1112
|
// PR-347 - Disable warning "unexpected_directive_a".
|
|
1113
|
+
//
|
|
882
1114
|
// case "unexpected_directive_a":
|
|
883
1115
|
// mm = `When using modules, don't use directive '/\u002a${a}'.`;
|
|
884
1116
|
// break;
|
|
@@ -1000,12 +1232,12 @@ function jslint(
|
|
|
1000
1232
|
if (option_dict.trace) {
|
|
1001
1233
|
warning.stack_trace = new Error().stack;
|
|
1002
1234
|
}
|
|
1003
|
-
if (warning.
|
|
1235
|
+
if (warning.directive_ignore_line) {
|
|
1004
1236
|
|
|
1005
1237
|
// test_cause:
|
|
1006
|
-
// ["0 //jslint-
|
|
1238
|
+
// ["0 //jslint-ignore-line", "semicolon", "directive_ignore_line", "", 0]
|
|
1007
1239
|
|
|
1008
|
-
test_cause("
|
|
1240
|
+
test_cause("directive_ignore_line");
|
|
1009
1241
|
return warning;
|
|
1010
1242
|
}
|
|
1011
1243
|
warning_list.push(warning);
|
|
@@ -1039,7 +1271,7 @@ function jslint(
|
|
|
1039
1271
|
mode_json: false, // true if parsing JSON.
|
|
1040
1272
|
mode_module: false, // true if import or export was used.
|
|
1041
1273
|
mode_property: false, // true if directive /*property*/ is
|
|
1042
|
-
// used.
|
|
1274
|
+
// ... used.
|
|
1043
1275
|
mode_shebang: false, // true if #! is seen on the first line.
|
|
1044
1276
|
option_dict,
|
|
1045
1277
|
property_dict,
|
|
@@ -1109,6 +1341,7 @@ function jslint(
|
|
|
1109
1341
|
);
|
|
1110
1342
|
|
|
1111
1343
|
// PR-347 - Disable warning "missing_browser".
|
|
1344
|
+
//
|
|
1112
1345
|
// if (!option_dict.browser) {
|
|
1113
1346
|
// directive_list.forEach(function (comment) {
|
|
1114
1347
|
// if (comment.directive === "global") {
|
|
@@ -1543,6 +1776,7 @@ async function jslint_cli({
|
|
|
1543
1776
|
console_error,
|
|
1544
1777
|
console_log,
|
|
1545
1778
|
file,
|
|
1779
|
+
import_meta_url,
|
|
1546
1780
|
mode_cli,
|
|
1547
1781
|
mode_noop,
|
|
1548
1782
|
option,
|
|
@@ -1711,11 +1945,26 @@ async function jslint_cli({
|
|
|
1711
1945
|
return count;
|
|
1712
1946
|
}
|
|
1713
1947
|
|
|
1948
|
+
// PR-396 - window.jslint
|
|
1949
|
+
// Check import.meta.url for directive to export jslint to window-object.
|
|
1950
|
+
// Useful for ES5-era browser-scripts that rely on window.jslint,
|
|
1951
|
+
// like CodeMirror.
|
|
1952
|
+
//
|
|
1953
|
+
// Example usage:
|
|
1954
|
+
// <script type="module" src="./jslint.mjs?window_jslint=1"></script>
|
|
1955
|
+
|
|
1956
|
+
import_meta_url = import_meta_url || jslint_import_meta_url;
|
|
1957
|
+
if (
|
|
1958
|
+
jslint_rgx_url_search_window_jslint.test(import_meta_url)
|
|
1959
|
+
&& (typeof globalThis === "object" && globalThis)
|
|
1960
|
+
) {
|
|
1961
|
+
globalThis.jslint = jslint;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1714
1964
|
// Feature-detect nodejs.
|
|
1715
1965
|
|
|
1716
1966
|
if (!(
|
|
1717
|
-
typeof process === "object"
|
|
1718
|
-
&& process
|
|
1967
|
+
(typeof process === "object" && process)
|
|
1719
1968
|
&& process.versions
|
|
1720
1969
|
&& typeof process.versions.node === "string"
|
|
1721
1970
|
&& !mode_noop
|
|
@@ -1741,7 +1990,7 @@ async function jslint_cli({
|
|
|
1741
1990
|
).test(process_argv[1])
|
|
1742
1991
|
|| mode_cli
|
|
1743
1992
|
)
|
|
1744
|
-
&& moduleUrl.fileURLToPath(
|
|
1993
|
+
&& moduleUrl.fileURLToPath(import_meta_url)
|
|
1745
1994
|
=== modulePath.resolve(process_argv[1])
|
|
1746
1995
|
)
|
|
1747
1996
|
&& !mode_cli
|
|
@@ -1887,7 +2136,9 @@ async function jslint_cli({
|
|
|
1887
2136
|
option
|
|
1888
2137
|
});
|
|
1889
2138
|
if (mode_report) {
|
|
1890
|
-
|
|
2139
|
+
result = jslint.jslint_report(result);
|
|
2140
|
+
result = `<body class="JSLINT_ JSLINT_REPORT_">\n${result}</body>\n`;
|
|
2141
|
+
await fsWriteFileWithParents(mode_report, result);
|
|
1891
2142
|
}
|
|
1892
2143
|
process_exit(exit_code);
|
|
1893
2144
|
return exit_code;
|
|
@@ -2176,7 +2427,7 @@ function jslint_phase2_lex(state) {
|
|
|
2176
2427
|
if (!option_dict.devel && jslint_rgx_todo.test(snippet)) {
|
|
2177
2428
|
|
|
2178
2429
|
// test_cause:
|
|
2179
|
-
// ["//todo", "lex_comment", "todo_comment", "(comment)", 1] //jslint-
|
|
2430
|
+
// ["//todo", "lex_comment", "todo_comment", "(comment)", 1] //jslint-ignore-line
|
|
2180
2431
|
|
|
2181
2432
|
warn("todo_comment", the_comment);
|
|
2182
2433
|
}
|
|
@@ -2236,6 +2487,7 @@ function jslint_phase2_lex(state) {
|
|
|
2236
2487
|
global_dict[key] = "user-defined";
|
|
2237
2488
|
|
|
2238
2489
|
// PR-347 - Disable warning "unexpected_directive_a".
|
|
2490
|
+
//
|
|
2239
2491
|
// state.mode_module = the_comment;
|
|
2240
2492
|
|
|
2241
2493
|
break;
|
|
@@ -2462,6 +2714,7 @@ function jslint_phase2_lex(state) {
|
|
|
2462
2714
|
return char_after("]");
|
|
2463
2715
|
|
|
2464
2716
|
// PR-362 - Relax regexp-warning against using <space>.
|
|
2717
|
+
//
|
|
2465
2718
|
// case " ":
|
|
2466
2719
|
//
|
|
2467
2720
|
// // test_cause:
|
|
@@ -2542,6 +2795,7 @@ function jslint_phase2_lex(state) {
|
|
|
2542
2795
|
return;
|
|
2543
2796
|
|
|
2544
2797
|
// PR-362 - Relax regexp-warning against using <space>.
|
|
2798
|
+
//
|
|
2545
2799
|
// case " ":
|
|
2546
2800
|
//
|
|
2547
2801
|
// // test_cause:
|
|
@@ -3051,9 +3305,10 @@ function jslint_phase2_lex(state) {
|
|
|
3051
3305
|
case "getset": // Allow get() and set().
|
|
3052
3306
|
case "indent2": // Use 2-space indent.
|
|
3053
3307
|
case "long": // Allow long lines.
|
|
3054
|
-
case "name": // Allow weird property names.
|
|
3055
3308
|
case "node": // Assume Node.js environment.
|
|
3309
|
+
case "nomen": // Allow weird property names.
|
|
3056
3310
|
case "single": // Allow single-quote strings.
|
|
3311
|
+
case "subscript": // Allow identifier in subscript-notation.
|
|
3057
3312
|
case "test_cause": // Test jslint's causes.
|
|
3058
3313
|
case "test_internal_error": // Test jslint's internal-error
|
|
3059
3314
|
// ... handling-ability.
|
|
@@ -3066,6 +3321,16 @@ function jslint_phase2_lex(state) {
|
|
|
3066
3321
|
case "white": // Allow messy whitespace.
|
|
3067
3322
|
option_dict[key] = val;
|
|
3068
3323
|
break;
|
|
3324
|
+
|
|
3325
|
+
// PR-404 - Alias "evil" to jslint-directive "eval" for backwards-compat.
|
|
3326
|
+
|
|
3327
|
+
case "evil":
|
|
3328
|
+
return option_set_item("eval", val);
|
|
3329
|
+
|
|
3330
|
+
// PR-404 - Alias "nomen" to jslint-directive "name" for backwards-compat.
|
|
3331
|
+
|
|
3332
|
+
case "name":
|
|
3333
|
+
return option_set_item("nomen", val);
|
|
3069
3334
|
default:
|
|
3070
3335
|
return false;
|
|
3071
3336
|
}
|
|
@@ -3087,12 +3352,16 @@ console.log(JSON.stringify(Object.keys(window).sort(), undefined, 4));
|
|
|
3087
3352
|
|
|
3088
3353
|
"AbortController",
|
|
3089
3354
|
// "Buffer",
|
|
3090
|
-
"
|
|
3355
|
+
// "Crypto",
|
|
3356
|
+
// "CryptoKey",
|
|
3091
3357
|
"Event",
|
|
3092
3358
|
"EventTarget",
|
|
3093
3359
|
"MessageChannel",
|
|
3094
3360
|
"MessageEvent",
|
|
3095
3361
|
"MessagePort",
|
|
3362
|
+
// "Request",
|
|
3363
|
+
// "Response",
|
|
3364
|
+
// "SubtleCrypto",
|
|
3096
3365
|
"TextDecoder",
|
|
3097
3366
|
"TextEncoder",
|
|
3098
3367
|
"URL",
|
|
@@ -3106,7 +3375,9 @@ console.log(JSON.stringify(Object.keys(window).sort(), undefined, 4));
|
|
|
3106
3375
|
"clearInterval",
|
|
3107
3376
|
"clearTimeout",
|
|
3108
3377
|
// "console",
|
|
3378
|
+
// "crypto",
|
|
3109
3379
|
// "exports",
|
|
3380
|
+
// "fetch",
|
|
3110
3381
|
// "global",
|
|
3111
3382
|
// "module",
|
|
3112
3383
|
"performance",
|
|
@@ -3116,7 +3387,6 @@ console.log(JSON.stringify(Object.keys(window).sort(), undefined, 4));
|
|
|
3116
3387
|
// "setImmediate",
|
|
3117
3388
|
"setInterval",
|
|
3118
3389
|
"setTimeout",
|
|
3119
|
-
"structuredClone",
|
|
3120
3390
|
|
|
3121
3391
|
// Web worker only.
|
|
3122
3392
|
// https://github.com/mdn/content/blob/main/files/en-us/web/api
|
|
@@ -3154,10 +3424,12 @@ console.log(JSON.stringify(Object.keys(window).sort(), undefined, 4));
|
|
|
3154
3424
|
"location",
|
|
3155
3425
|
// "name",
|
|
3156
3426
|
"navigator",
|
|
3427
|
+
"postMessage",
|
|
3157
3428
|
// "screen",
|
|
3158
3429
|
"sessionStorage",
|
|
3159
3430
|
// "setInterval",
|
|
3160
3431
|
// "setTimeout",
|
|
3432
|
+
"structuredClone",
|
|
3161
3433
|
"window"
|
|
3162
3434
|
], "browser");
|
|
3163
3435
|
break;
|
|
@@ -3219,6 +3491,7 @@ import https from "https";
|
|
|
3219
3491
|
|
|
3220
3492
|
case "ecma":
|
|
3221
3493
|
object_assign_from_list(global_dict, [
|
|
3494
|
+
"AggregateError",
|
|
3222
3495
|
"Array",
|
|
3223
3496
|
"ArrayBuffer",
|
|
3224
3497
|
"Atomics",
|
|
@@ -3289,7 +3562,7 @@ import moduleHttps from "https";
|
|
|
3289
3562
|
let result = "";
|
|
3290
3563
|
await new Promise(function (resolve) {
|
|
3291
3564
|
moduleHttps.get((
|
|
3292
|
-
"https://raw.githubusercontent.com/nodejs/node/
|
|
3565
|
+
"https://raw.githubusercontent.com/nodejs/node/v16.x/doc/api"
|
|
3293
3566
|
+ "/globals.md"
|
|
3294
3567
|
), function (res) {
|
|
3295
3568
|
res.on("data", function (chunk) {
|
|
@@ -3312,12 +3585,16 @@ import moduleHttps from "https";
|
|
|
3312
3585
|
object_assign_from_list(global_dict, [
|
|
3313
3586
|
"AbortController",
|
|
3314
3587
|
"Buffer",
|
|
3315
|
-
"
|
|
3588
|
+
// "Crypto",
|
|
3589
|
+
// "CryptoKey",
|
|
3316
3590
|
"Event",
|
|
3317
3591
|
"EventTarget",
|
|
3318
3592
|
"MessageChannel",
|
|
3319
3593
|
"MessageEvent",
|
|
3320
3594
|
"MessagePort",
|
|
3595
|
+
// "Request",
|
|
3596
|
+
// "Response",
|
|
3597
|
+
// "SubtleCrypto",
|
|
3321
3598
|
"TextDecoder",
|
|
3322
3599
|
"TextEncoder",
|
|
3323
3600
|
"URL",
|
|
@@ -3331,7 +3608,9 @@ import moduleHttps from "https";
|
|
|
3331
3608
|
"clearInterval",
|
|
3332
3609
|
"clearTimeout",
|
|
3333
3610
|
"console",
|
|
3611
|
+
// "crypto",
|
|
3334
3612
|
"exports",
|
|
3613
|
+
// "fetch",
|
|
3335
3614
|
"global",
|
|
3336
3615
|
"module",
|
|
3337
3616
|
"performance",
|
|
@@ -3340,8 +3619,7 @@ import moduleHttps from "https";
|
|
|
3340
3619
|
"require",
|
|
3341
3620
|
"setImmediate",
|
|
3342
3621
|
"setInterval",
|
|
3343
|
-
"setTimeout"
|
|
3344
|
-
"structuredClone"
|
|
3622
|
+
"setTimeout"
|
|
3345
3623
|
], "Node.js");
|
|
3346
3624
|
break;
|
|
3347
3625
|
}
|
|
@@ -3408,7 +3686,7 @@ import moduleHttps from "https";
|
|
|
3408
3686
|
) {
|
|
3409
3687
|
|
|
3410
3688
|
// test_cause:
|
|
3411
|
-
// ["/////////////////////////////////////////////////////////////////////////////////", "read_line", "too_long", "", 1] //jslint-
|
|
3689
|
+
// ["/////////////////////////////////////////////////////////////////////////////////", "read_line", "too_long", "", 1] //jslint-ignore-line
|
|
3412
3690
|
|
|
3413
3691
|
warn_at("too_long", line);
|
|
3414
3692
|
}
|
|
@@ -3426,7 +3704,7 @@ import moduleHttps from "https";
|
|
|
3426
3704
|
// Scan each line for following ignore-directives:
|
|
3427
3705
|
// "/*jslint-disable*/"
|
|
3428
3706
|
// "/*jslint-enable*/"
|
|
3429
|
-
// "//jslint-
|
|
3707
|
+
// "//jslint-ignore-line"
|
|
3430
3708
|
|
|
3431
3709
|
if (line_source === "/*jslint-disable*/") {
|
|
3432
3710
|
|
|
@@ -3444,13 +3722,16 @@ import moduleHttps from "https";
|
|
|
3444
3722
|
stop_at("unopened_enable", line);
|
|
3445
3723
|
}
|
|
3446
3724
|
line_disable = undefined;
|
|
3447
|
-
} else if (
|
|
3725
|
+
} else if (
|
|
3726
|
+
line_source.endsWith(" //jslint-ignore-line")
|
|
3727
|
+
|| line_source.endsWith(" //jslint-quiet")
|
|
3728
|
+
) {
|
|
3448
3729
|
|
|
3449
3730
|
// test_cause:
|
|
3450
|
-
// ["0 //jslint-
|
|
3731
|
+
// ["0 //jslint-ignore-line", "read_line", "jslint_ignore_line", "", 0]
|
|
3451
3732
|
|
|
3452
|
-
test_cause("
|
|
3453
|
-
line_list[line].
|
|
3733
|
+
test_cause("jslint_ignore_line");
|
|
3734
|
+
line_list[line].directive_ignore_line = true;
|
|
3454
3735
|
}
|
|
3455
3736
|
if (line_disable !== undefined) {
|
|
3456
3737
|
|
|
@@ -4250,6 +4531,8 @@ function jslint_phase3_parse(state) {
|
|
|
4250
4531
|
left.id !== "["
|
|
4251
4532
|
|| (
|
|
4252
4533
|
name.id !== "concat"
|
|
4534
|
+
&& name.id !== "flat"
|
|
4535
|
+
&& name.id !== "flatMap"
|
|
4253
4536
|
&& name.id !== "forEach"
|
|
4254
4537
|
&& name.id !== "join"
|
|
4255
4538
|
&& name.id !== "map"
|
|
@@ -4309,7 +4592,10 @@ function jslint_phase3_parse(state) {
|
|
|
4309
4592
|
let the_subscript = parse_expression(0);
|
|
4310
4593
|
if (the_subscript.id === "(string)" || the_subscript.id === "`") {
|
|
4311
4594
|
name = survey(the_subscript);
|
|
4312
|
-
|
|
4595
|
+
|
|
4596
|
+
// PR-404 - Add new directive "subscript" to play nice with Google Closure.
|
|
4597
|
+
|
|
4598
|
+
if (!option_dict.subscript && jslint_rgx_identifier.test(name)) {
|
|
4313
4599
|
|
|
4314
4600
|
// test_cause:
|
|
4315
4601
|
// ["aa[`aa`]", "infix_lbracket", "subscript_a", "aa", 4]
|
|
@@ -5038,10 +5324,13 @@ function jslint_phase3_parse(state) {
|
|
|
5038
5324
|
functionage.async += 1;
|
|
5039
5325
|
}
|
|
5040
5326
|
if (the_await.arity === "statement") {
|
|
5041
|
-
|
|
5327
|
+
|
|
5328
|
+
// PR-405 - Bugfix - fix expression after "await" mis-identified as statement.
|
|
5329
|
+
|
|
5330
|
+
the_await.expression = parse_expression(150);
|
|
5042
5331
|
semicolon();
|
|
5043
5332
|
} else {
|
|
5044
|
-
the_await.expression = parse_expression();
|
|
5333
|
+
the_await.expression = parse_expression(150);
|
|
5045
5334
|
}
|
|
5046
5335
|
return the_await;
|
|
5047
5336
|
}
|
|
@@ -6107,6 +6396,7 @@ function jslint_phase3_parse(state) {
|
|
|
6107
6396
|
let names;
|
|
6108
6397
|
|
|
6109
6398
|
// PR-347 - Disable warning "unexpected_directive_a".
|
|
6399
|
+
//
|
|
6110
6400
|
// if (typeof state.mode_module === "object") {
|
|
6111
6401
|
//
|
|
6112
6402
|
// // test_cause:
|
|
@@ -6464,12 +6754,16 @@ function jslint_phase3_parse(state) {
|
|
|
6464
6754
|
// Restore previous catch-scope after catch-block.
|
|
6465
6755
|
|
|
6466
6756
|
catchage = catch_stack.pop();
|
|
6467
|
-
} else {
|
|
6468
6757
|
|
|
6469
|
-
//
|
|
6470
|
-
//
|
|
6758
|
+
// PR-404 - Relax warning about missing `catch` in `try...finally` statement.
|
|
6759
|
+
//
|
|
6760
|
+
// } else {
|
|
6761
|
+
//
|
|
6762
|
+
// // test_cause:
|
|
6763
|
+
// // ["try{}finally{break;}", "stmt_try", "expected_a_before_b", "finally", 6]
|
|
6764
|
+
//
|
|
6765
|
+
// warn("expected_a_before_b", token_nxt, "catch", artifact());
|
|
6471
6766
|
|
|
6472
|
-
warn("expected_a_before_b", token_nxt, "catch", artifact());
|
|
6473
6767
|
}
|
|
6474
6768
|
if (token_nxt.id === "finally") {
|
|
6475
6769
|
functionage.finally += 1;
|
|
@@ -6590,12 +6884,14 @@ function jslint_phase3_parse(state) {
|
|
|
6590
6884
|
return stop("expected_identifier_a");
|
|
6591
6885
|
}
|
|
6592
6886
|
|
|
6593
|
-
// PR-363 - Bugfix
|
|
6594
|
-
// <uninitialized 'bb'> in code
|
|
6887
|
+
// PR-363 - Bugfix
|
|
6888
|
+
// Add test against false-warning <uninitialized 'bb'> in code
|
|
6889
|
+
// '/*jslint node*/\nlet {aa:bb} = {}; bb();'.
|
|
6890
|
+
//
|
|
6891
|
+
// token_nxt.label = name;
|
|
6892
|
+
// the_variable.names.push(token_nxt);
|
|
6893
|
+
// enroll(token_nxt, "variable", mode_const);
|
|
6595
6894
|
|
|
6596
|
-
// token_nxt.label = name;
|
|
6597
|
-
// the_variable.names.push(token_nxt);
|
|
6598
|
-
// enroll(token_nxt, "variable", mode_const);
|
|
6599
6895
|
name = token_nxt;
|
|
6600
6896
|
the_variable.names.push(name);
|
|
6601
6897
|
survey(name);
|
|
@@ -6818,7 +7114,7 @@ function jslint_phase3_parse(state) {
|
|
|
6818
7114
|
warn("unregistered_property_a", name);
|
|
6819
7115
|
}
|
|
6820
7116
|
} else if (
|
|
6821
|
-
!option_dict.
|
|
7117
|
+
!option_dict.nomen
|
|
6822
7118
|
&& name.identifier
|
|
6823
7119
|
&& jslint_rgx_weird_property.test(id)
|
|
6824
7120
|
) {
|
|
@@ -7751,6 +8047,11 @@ function jslint_phase4_walk(state) {
|
|
|
7751
8047
|
|| thing.expression[0].constant === true
|
|
7752
8048
|
|| is_equal(thing.expression[1], thing.expression[2])
|
|
7753
8049
|
) {
|
|
8050
|
+
|
|
8051
|
+
// test_cause:
|
|
8052
|
+
// ["let aa=(aa?`${0}`:`${0}`);", "post_t", "unexpected_a", "?", 11]
|
|
8053
|
+
// ["let aa=(aa?`0`:`0`);", "post_t", "unexpected_a", "?", 11]
|
|
8054
|
+
|
|
7754
8055
|
warn("unexpected_a", thing);
|
|
7755
8056
|
} else if (is_equal(thing.expression[0], thing.expression[1])) {
|
|
7756
8057
|
|
|
@@ -8226,9 +8527,6 @@ function jslint_phase4_walk(state) {
|
|
|
8226
8527
|
// ["+[]", "walk_statement", "unexpected_expression_a", "+", 1]
|
|
8227
8528
|
// ["+new aa()", "walk_statement", "unexpected_expression_a", "+", 1]
|
|
8228
8529
|
// ["0", "walk_statement", "unexpected_expression_a", "0", 1]
|
|
8229
|
-
// ["
|
|
8230
|
-
// async function aa(){await 0;}
|
|
8231
|
-
// ", "walk_statement", "unexpected_expression_a", "0", 27]
|
|
8232
8530
|
// ["typeof 0", "walk_statement", "unexpected_expression_a", "typeof", 1]
|
|
8233
8531
|
|
|
8234
8532
|
warn("unexpected_expression_a", thing);
|
|
@@ -8970,6 +9268,7 @@ function jslint_report({
|
|
|
8970
9268
|
|
|
8971
9269
|
// This function will create human-readable, html-report
|
|
8972
9270
|
// for warnings, properties, and functions from jslint-result-object.
|
|
9271
|
+
//
|
|
8973
9272
|
// Example usage:
|
|
8974
9273
|
// let result = jslint("console.log('hello world')");
|
|
8975
9274
|
// let html = jslint_report(result);
|
|
@@ -9002,7 +9301,6 @@ function jslint_report({
|
|
|
9002
9301
|
);
|
|
9003
9302
|
}
|
|
9004
9303
|
|
|
9005
|
-
html += "<div class=\"JSLINT_\" id=\"JSLINT_REPORT_HTML\">\n";
|
|
9006
9304
|
html += String(`
|
|
9007
9305
|
<style class="JSLINT_REPORT_STYLE">
|
|
9008
9306
|
/* jslint utility2:true */
|
|
@@ -9151,19 +9449,38 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
|
|
|
9151
9449
|
/7xoEqvL+2E8VOyCTuT/7j269Zy4jUtN+g4="
|
|
9152
9450
|
) format("woff2");
|
|
9153
9451
|
}
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9452
|
+
.JSLINT_,
|
|
9453
|
+
.JSLINT_ address,
|
|
9454
|
+
.JSLINT_ button,
|
|
9455
|
+
.JSLINT_ cite,
|
|
9456
|
+
.JSLINT_ dd,
|
|
9457
|
+
.JSLINT_ dfn,
|
|
9458
|
+
.JSLINT_ dl,
|
|
9459
|
+
.JSLINT_ dt,
|
|
9460
|
+
.JSLINT_ fieldset,
|
|
9461
|
+
.JSLINT_ fieldset > div,
|
|
9462
|
+
.JSLINT_ input,
|
|
9463
|
+
.JSLINT_ label,
|
|
9464
|
+
.JSLINT_ legend,
|
|
9465
|
+
.JSLINT_ ol,
|
|
9466
|
+
.JSLINT_ samp,
|
|
9467
|
+
.JSLINT_ style,
|
|
9468
|
+
.JSLINT_ textarea,
|
|
9469
|
+
.JSLINT_ ul {
|
|
9157
9470
|
border: 0;
|
|
9158
9471
|
box-sizing: border-box;
|
|
9159
9472
|
margin: 0;
|
|
9160
9473
|
padding: 0;
|
|
9161
9474
|
}
|
|
9475
|
+
/* disable text inflation algorithm used on some smartphones and tablets */
|
|
9162
9476
|
.JSLINT_ {
|
|
9163
9477
|
-ms-text-size-adjust: none;
|
|
9164
9478
|
-webkit-text-size-adjust: none;
|
|
9165
9479
|
text-size-adjust: none;
|
|
9166
9480
|
}
|
|
9481
|
+
.JSLINT_REPORT_ div {
|
|
9482
|
+
box-sizing: border-box;
|
|
9483
|
+
}
|
|
9167
9484
|
/*csslint ignore:end*/
|
|
9168
9485
|
|
|
9169
9486
|
/* css - jslint_report - font */
|
|
@@ -9197,7 +9514,7 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
|
|
|
9197
9514
|
}
|
|
9198
9515
|
|
|
9199
9516
|
/* css - jslint_report - general */
|
|
9200
|
-
|
|
9517
|
+
.JSLINT_ {
|
|
9201
9518
|
background: antiquewhite;
|
|
9202
9519
|
}
|
|
9203
9520
|
.JSLINT_ fieldset {
|
|
@@ -9534,7 +9851,6 @@ body {
|
|
|
9534
9851
|
});
|
|
9535
9852
|
html += "</div>\n";
|
|
9536
9853
|
html += "</fieldset>\n";
|
|
9537
|
-
html += "</div>\n";
|
|
9538
9854
|
return html;
|
|
9539
9855
|
}
|
|
9540
9856
|
|
|
@@ -9545,6 +9861,7 @@ async function jstestDescribe(description, testFunction) {
|
|
|
9545
9861
|
|
|
9546
9862
|
let message;
|
|
9547
9863
|
let result;
|
|
9864
|
+
let timerTimeout;
|
|
9548
9865
|
|
|
9549
9866
|
// Init jstestTimeStart.
|
|
9550
9867
|
|
|
@@ -9560,7 +9877,9 @@ async function jstestDescribe(description, testFunction) {
|
|
|
9560
9877
|
|
|
9561
9878
|
// Wait for jstestItList to resolve.
|
|
9562
9879
|
|
|
9880
|
+
timerTimeout = setTimeout(noop, 0x7fffffff);
|
|
9563
9881
|
result = await Promise.all(jstestItList);
|
|
9882
|
+
clearTimeout(timerTimeout);
|
|
9564
9883
|
|
|
9565
9884
|
// Print test results.
|
|
9566
9885
|
|
|
@@ -9610,14 +9929,14 @@ function jstestIt(description, testFunction, mode) {
|
|
|
9610
9929
|
}));
|
|
9611
9930
|
}
|
|
9612
9931
|
|
|
9613
|
-
function jstestOnExit(exitCode,
|
|
9932
|
+
function jstestOnExit(exitCode, mode) {
|
|
9614
9933
|
|
|
9615
9934
|
// This function will on process-exit, print test-report
|
|
9616
9935
|
// and exit with non-zero exit-code if any test failed.
|
|
9617
9936
|
|
|
9618
9937
|
let message = (
|
|
9619
9938
|
(
|
|
9620
|
-
(jstestCountFailed ||
|
|
9939
|
+
(jstestCountFailed || mode === "testsFailed")
|
|
9621
9940
|
? "\n\u001b[31m"
|
|
9622
9941
|
: "\n\u001b[32m"
|
|
9623
9942
|
)
|
|
@@ -9625,11 +9944,10 @@ function jstestOnExit(exitCode, processExit, countFailed) {
|
|
|
9625
9944
|
+ " tests failed - " + jstestCountFailed + "\n"
|
|
9626
9945
|
+ "\u001b[39m"
|
|
9627
9946
|
);
|
|
9628
|
-
if (
|
|
9947
|
+
if (mode !== "testsFailed") {
|
|
9629
9948
|
console.error(message);
|
|
9630
|
-
processExit = process.exit;
|
|
9631
9949
|
}
|
|
9632
|
-
|
|
9950
|
+
process.exitCode = exitCode || jstestCountFailed;
|
|
9633
9951
|
return message;
|
|
9634
9952
|
}
|
|
9635
9953
|
|
|
@@ -9927,7 +10245,7 @@ function v8CoverageListMerge(processCovs) {
|
|
|
9927
10245
|
let resultTree;
|
|
9928
10246
|
let rightChildren;
|
|
9929
10247
|
|
|
9930
|
-
// TODO(perf): Binary search (check overhead) //jslint-
|
|
10248
|
+
// TODO(perf): Binary search (check overhead) //jslint-ignore-line
|
|
9931
10249
|
|
|
9932
10250
|
while (ii < tree.children.length) {
|
|
9933
10251
|
child = tree.children[ii];
|
|
@@ -10005,7 +10323,7 @@ function v8CoverageListMerge(processCovs) {
|
|
|
10005
10323
|
|
|
10006
10324
|
// This function will normalize-and-sort <funcCov>.ranges.
|
|
10007
10325
|
// Sorts the ranges (pre-order sort).
|
|
10008
|
-
// TODO: Tree-based normalization of the ranges. //jslint-
|
|
10326
|
+
// TODO: Tree-based normalization of the ranges. //jslint-ignore-line
|
|
10009
10327
|
// @param funcCov Function coverage to normalize.
|
|
10010
10328
|
|
|
10011
10329
|
funcCov.ranges = treeToRanges(treeFromSortedRanges(
|
|
@@ -10351,11 +10669,11 @@ async function v8CoverageReportCreate({
|
|
|
10351
10669
|
// 3. Create html-coverage-reports in <coverageDir>.
|
|
10352
10670
|
|
|
10353
10671
|
let cwd;
|
|
10672
|
+
let excludeList = [];
|
|
10354
10673
|
let exitCode = 0;
|
|
10355
10674
|
let fileDict;
|
|
10356
|
-
let
|
|
10357
|
-
let
|
|
10358
|
-
let fileIncludeNodeModules;
|
|
10675
|
+
let includeList = [];
|
|
10676
|
+
let modeIncludeNodeModules;
|
|
10359
10677
|
let processArgElem;
|
|
10360
10678
|
let promiseList = [];
|
|
10361
10679
|
let v8CoverageObj;
|
|
@@ -10380,9 +10698,19 @@ async function v8CoverageReportCreate({
|
|
|
10380
10698
|
<style>
|
|
10381
10699
|
/* jslint utility2:true */
|
|
10382
10700
|
/*csslint ignore:start*/
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10701
|
+
.coverage,
|
|
10702
|
+
.coverage a,
|
|
10703
|
+
.coverage div,
|
|
10704
|
+
.coverage pre,
|
|
10705
|
+
.coverage span,
|
|
10706
|
+
.coverage table,
|
|
10707
|
+
.coverage tbody,
|
|
10708
|
+
.coverage td,
|
|
10709
|
+
.coverage th,
|
|
10710
|
+
.coverage thead,
|
|
10711
|
+
.coverage tr {
|
|
10712
|
+
box-sizing: border-box;
|
|
10713
|
+
font-family: monospace;
|
|
10386
10714
|
}
|
|
10387
10715
|
/*csslint ignore:end*/
|
|
10388
10716
|
|
|
@@ -10528,6 +10856,7 @@ body {
|
|
|
10528
10856
|
}
|
|
10529
10857
|
txtBorder = (
|
|
10530
10858
|
"+" + "-".repeat(padPathname + 2) + "+"
|
|
10859
|
+
+ "-".repeat(padLines + 2) + "+"
|
|
10531
10860
|
+ "-".repeat(padLines + 2) + "+\n"
|
|
10532
10861
|
);
|
|
10533
10862
|
txt = "";
|
|
@@ -10535,7 +10864,8 @@ body {
|
|
|
10535
10864
|
txt += txtBorder;
|
|
10536
10865
|
txt += (
|
|
10537
10866
|
"| " + String("Files covered").padEnd(padPathname, " ") + " | "
|
|
10538
|
-
+ String("Lines").padStart(padLines, " ") + "
|
|
10867
|
+
+ String("Lines").padStart(padLines, " ") + " | "
|
|
10868
|
+
+ String("Remaining").padStart(padLines, " ") + " |\n"
|
|
10539
10869
|
);
|
|
10540
10870
|
txt += txtBorder;
|
|
10541
10871
|
fileList.forEach(function ({
|
|
@@ -10615,7 +10945,8 @@ body {
|
|
|
10615
10945
|
+ String("./" + pathname).padEnd(padPathname, " ") + " | "
|
|
10616
10946
|
+ String(
|
|
10617
10947
|
modeCoverageIgnoreFile + " " + coveragePct + " %"
|
|
10618
|
-
).padStart(padLines, " ") + "
|
|
10948
|
+
).padStart(padLines, " ") + " | "
|
|
10949
|
+
+ " ".repeat(padLines) + " |\n"
|
|
10619
10950
|
);
|
|
10620
10951
|
txt += (
|
|
10621
10952
|
"| " + "*".repeat(
|
|
@@ -10623,6 +10954,9 @@ body {
|
|
|
10623
10954
|
).padEnd(padPathname, "_") + " | "
|
|
10624
10955
|
+ String(
|
|
10625
10956
|
linesCovered + " / " + linesTotal
|
|
10957
|
+
).padStart(padLines, " ") + " | "
|
|
10958
|
+
+ String(
|
|
10959
|
+
(linesTotal - linesCovered) + " / " + linesTotal
|
|
10626
10960
|
).padStart(padLines, " ") + " |\n"
|
|
10627
10961
|
);
|
|
10628
10962
|
txt += txtBorder;
|
|
@@ -10786,21 +11120,6 @@ ${String(count || "-0").padStart(7, " ")}
|
|
|
10786
11120
|
), txt));
|
|
10787
11121
|
}
|
|
10788
11122
|
|
|
10789
|
-
function pathnameRelativeCwd(pathname) {
|
|
10790
|
-
|
|
10791
|
-
// This function will if <pathname> is inside <cwd>,
|
|
10792
|
-
// return it relative to <cwd>, else empty-string.
|
|
10793
|
-
|
|
10794
|
-
pathname = modulePath.resolve(pathname).replace((
|
|
10795
|
-
/\\/g
|
|
10796
|
-
), "/");
|
|
10797
|
-
if (!pathname.startsWith(cwd)) {
|
|
10798
|
-
return;
|
|
10799
|
-
}
|
|
10800
|
-
pathname = pathname.slice(cwd.length);
|
|
10801
|
-
return pathname;
|
|
10802
|
-
}
|
|
10803
|
-
|
|
10804
11123
|
/*
|
|
10805
11124
|
function sentinel() {}
|
|
10806
11125
|
*/
|
|
@@ -10832,28 +11151,26 @@ function sentinel() {}
|
|
|
10832
11151
|
processArgElem[1] = processArgElem.slice(1).join("=");
|
|
10833
11152
|
switch (processArgElem[0]) {
|
|
10834
11153
|
|
|
10835
|
-
// PR-371 -
|
|
11154
|
+
// PR-371 - Add cli-option `--exclude=...`.
|
|
10836
11155
|
|
|
10837
11156
|
case "--exclude":
|
|
10838
|
-
|
|
10839
|
-
processArgElem[1].split(",")
|
|
10840
|
-
);
|
|
11157
|
+
excludeList.push(processArgElem[1]);
|
|
10841
11158
|
break;
|
|
10842
11159
|
|
|
10843
|
-
// PR-371 -
|
|
11160
|
+
// PR-371 - Add cli-option `--include=...`
|
|
10844
11161
|
|
|
10845
|
-
case "--
|
|
10846
|
-
|
|
10847
|
-
/0|false|null|undefined/
|
|
10848
|
-
).test(processArgElem[1]);
|
|
11162
|
+
case "--include":
|
|
11163
|
+
includeList.push(processArgElem[1]);
|
|
10849
11164
|
break;
|
|
10850
11165
|
|
|
10851
|
-
// PR-
|
|
11166
|
+
// PR-400
|
|
11167
|
+
// Disable default-coverage of directory `node_modules`,
|
|
11168
|
+
// but allow override with cli-option `--include-node-modules=1`.
|
|
10852
11169
|
|
|
10853
|
-
case "--include":
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
);
|
|
11170
|
+
case "--include-node-modules":
|
|
11171
|
+
modeIncludeNodeModules = !(
|
|
11172
|
+
/0|false|null|undefined/
|
|
11173
|
+
).test(processArgElem[1]);
|
|
10857
11174
|
break;
|
|
10858
11175
|
}
|
|
10859
11176
|
}
|
|
@@ -10907,9 +11224,11 @@ function sentinel() {}
|
|
|
10907
11224
|
).test(file);
|
|
10908
11225
|
});
|
|
10909
11226
|
v8CoverageObj = await Promise.all(v8CoverageObj.map(async function (file) {
|
|
10910
|
-
let data
|
|
11227
|
+
let data;
|
|
11228
|
+
let pathnameDict = Object.create(null);
|
|
11229
|
+
data = await moduleFs.promises.readFile(coverageDir + file, "utf8");
|
|
10911
11230
|
data = JSON.parse(data);
|
|
10912
|
-
data.result
|
|
11231
|
+
data.result.forEach(function (scriptCov) {
|
|
10913
11232
|
let pathname = scriptCov.url;
|
|
10914
11233
|
|
|
10915
11234
|
// Filter out internal coverages.
|
|
@@ -10920,38 +11239,38 @@ function sentinel() {}
|
|
|
10920
11239
|
|
|
10921
11240
|
// Normalize pathname.
|
|
10922
11241
|
|
|
10923
|
-
pathname =
|
|
10924
|
-
|
|
11242
|
+
pathname = moduleUrl.fileURLToPath(pathname);
|
|
11243
|
+
pathname = modulePath.resolve(pathname).replace((
|
|
11244
|
+
/\\/g
|
|
11245
|
+
), "/");
|
|
10925
11246
|
|
|
10926
11247
|
// Filter files outside of cwd.
|
|
10927
11248
|
|
|
10928
|
-
|
|
10929
|
-
|
|
11249
|
+
if (pathname.indexOf("[") >= 0 || !pathname.startsWith(cwd)) {
|
|
11250
|
+
return;
|
|
11251
|
+
}
|
|
10930
11252
|
|
|
10931
|
-
//
|
|
11253
|
+
// Normalize pathname relative to cwd.
|
|
10932
11254
|
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
).test(pathname)
|
|
10938
|
-
)
|
|
11255
|
+
pathname = pathname.slice(cwd.length);
|
|
11256
|
+
scriptCov.url = pathname;
|
|
11257
|
+
pathnameDict[pathname] = scriptCov;
|
|
11258
|
+
});
|
|
10939
11259
|
|
|
10940
|
-
// PR-
|
|
11260
|
+
// PR-400 - Filter directory `node_modules`.
|
|
10941
11261
|
|
|
10942
|
-
|
|
11262
|
+
if (!modeIncludeNodeModules) {
|
|
11263
|
+
excludeList.push("node_modules/");
|
|
11264
|
+
}
|
|
10943
11265
|
|
|
10944
|
-
// PR-
|
|
11266
|
+
// PR-400 - Filter files by glob-patterns in excludeList, includeList.
|
|
10945
11267
|
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
}
|
|
10953
|
-
scriptCov.url = pathname;
|
|
10954
|
-
return true;
|
|
11268
|
+
data.result = globExclude({
|
|
11269
|
+
excludeList,
|
|
11270
|
+
includeList,
|
|
11271
|
+
pathnameList: Object.keys(pathnameDict)
|
|
11272
|
+
}).pathnameList.map(function (pathname) {
|
|
11273
|
+
return pathnameDict[pathname];
|
|
10955
11274
|
});
|
|
10956
11275
|
return data;
|
|
10957
11276
|
}));
|
|
@@ -10960,7 +11279,7 @@ function sentinel() {}
|
|
|
10960
11279
|
|
|
10961
11280
|
v8CoverageObj = v8CoverageListMerge(v8CoverageObj);
|
|
10962
11281
|
|
|
10963
|
-
//
|
|
11282
|
+
// Debug v8CoverageObj.
|
|
10964
11283
|
|
|
10965
11284
|
await fsWriteFileWithParents(
|
|
10966
11285
|
coverageDir + "v8_coverage_merged.json",
|
|
@@ -11100,6 +11419,7 @@ jslint_export = Object.freeze(Object.assign(jslint, {
|
|
|
11100
11419
|
assertOrThrow,
|
|
11101
11420
|
debugInline,
|
|
11102
11421
|
fsWriteFileWithParents,
|
|
11422
|
+
globExclude,
|
|
11103
11423
|
htmlEscape,
|
|
11104
11424
|
jslint,
|
|
11105
11425
|
jslint_apidoc,
|