@jslint-org/jslint 2021.12.20 → 2022.5.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 +7 -1
- package/CHANGELOG.md +255 -0
- package/README.md +191 -37
- package/asset_codemirror_rollup.js +11458 -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 +774 -383
- package/jslint_wrapper_cjs.cjs +50 -0
- package/jslint_wrapper_vscode.js +178 -0
- package/package.json +8 -4
- package/jslint.cjs +0 -14
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,50 +93,52 @@
|
|
|
92
93
|
// WARNING: JSLint will hurt your feelings.
|
|
93
94
|
|
|
94
95
|
/*jslint beta, node*/
|
|
95
|
-
|
|
96
96
|
/*property
|
|
97
|
-
|
|
97
|
+
excludeList,
|
|
98
|
+
globExclude,
|
|
99
|
+
import_meta_url, includeList,
|
|
100
|
+
pathnameList,
|
|
98
101
|
JSLINT_BETA, NODE_V8_COVERAGE, a, all, argv, arity, artifact,
|
|
99
102
|
assertErrorThrownAsync, assertJsonEqual, assertOrThrow, assign, async, b,
|
|
100
103
|
beta, bitwise, block, body, browser, c, calls, catch, catch_list,
|
|
101
|
-
catch_stack, causes, char, children, clear, closer,
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
formatted_message, free, freeze, from, froms,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
104
|
+
catch_stack, causes, char, children, clear, closer, closure, code, column,
|
|
105
|
+
concat, consoleError, console_error, console_log, constant, context,
|
|
106
|
+
convert, count, coverageDir, create, cwd, d, dead, debugInline, default,
|
|
107
|
+
delta, devel, directive, directive_list, directive_quiet, directives,
|
|
108
|
+
dirname, disrupt, dot, edition, elem_list, ellipsis, else, end, endOffset,
|
|
109
|
+
endsWith, entries, env, error, eval, every, example_list, exec, execArgv,
|
|
110
|
+
exit, exitCode, export_dict, exports, expression, extra, file, fileList,
|
|
111
|
+
fileURLToPath, filter, finally, flag, floor, for, forEach,
|
|
112
|
+
formatted_message, free, freeze, from, froms, fsWriteFileWithParents,
|
|
113
|
+
fud_stmt, functionName, function_list, function_stack, functions, get,
|
|
114
|
+
getset, github_repo, global, global_dict, global_list, holeList, htmlEscape,
|
|
115
|
+
id, identifier, import, import_list, inc, indent2, index, indexOf, init,
|
|
116
|
+
initial, isArray, isBlockCoverage, isHole, isNaN, is_equal, is_fart,
|
|
117
|
+
is_weird, join, jslint, jslint_apidoc, jslint_assert, jslint_charset_ascii,
|
|
118
|
+
jslint_cli, jslint_edition, jslint_phase1_split, jslint_phase2_lex,
|
|
119
|
+
jslint_phase3_parse, jslint_phase4_walk, jslint_phase5_whitage,
|
|
120
|
+
jslint_report, json, jstestDescribe, jstestIt, jstestOnExit, keys, label,
|
|
121
|
+
lbp, led_infix, length, level, line, lineList, line_list, line_offset,
|
|
122
|
+
line_source, lines, linesCovered, linesTotal, live, log, long, loop, m, map,
|
|
123
|
+
margin, match, max, message, meta, min, mkdir, modeCoverageIgnoreFile,
|
|
124
|
+
modeIndex, mode_cli, mode_conditional, mode_json, mode_module, mode_noop,
|
|
125
|
+
mode_property, mode_shebang, mode_stop, module, moduleFsInit, moduleName,
|
|
126
|
+
module_list, name, names, node, noop, now, nr, nud_prefix,
|
|
127
|
+
objectDeepCopyWithKeysSorted, ok, on, open, opening, option, option_dict,
|
|
128
|
+
order, package_name, padEnd, padStart, parameters, parent, parentIi, parse,
|
|
129
|
+
pathname, platform, pop, processArgv, process_argv, process_env,
|
|
130
|
+
process_exit, promises, property, property_dict, push, quote, ranges,
|
|
131
|
+
readFile, readdir, readonly, recursive, reduce, repeat, replace, resolve,
|
|
132
|
+
result, reverse, role, round, scriptId, search, set, shebang, shift,
|
|
133
|
+
signature, single, slice, some, sort, source, spawn, splice, split, stack,
|
|
134
|
+
stack_trace, start, startOffset, startsWith, statement, statement_prv,
|
|
135
|
+
stdio, stop, stop_at, stringify, switch, syntax_dict, tenure, test,
|
|
136
|
+
test_cause, test_internal_error, this, thru, toString, token, token_global,
|
|
137
|
+
token_list, token_nxt, token_tree, tokens, trace, tree, trim, trimEnd,
|
|
138
|
+
trimRight, try, type, unlink, unordered, unshift, url, used,
|
|
139
|
+
v8CoverageListMerge, v8CoverageReportCreate, value, variable, version,
|
|
140
|
+
versions, warn, warn_at, warning, warning_list, warnings, white, wrapped,
|
|
141
|
+
writeFile
|
|
139
142
|
*/
|
|
140
143
|
|
|
141
144
|
// init debugInline
|
|
@@ -165,11 +168,99 @@ let jslint_charset_ascii = (
|
|
|
165
168
|
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
|
166
169
|
+ "`abcdefghijklmnopqrstuvwxyz{|}~\u007f"
|
|
167
170
|
);
|
|
168
|
-
let jslint_edition = "
|
|
171
|
+
let jslint_edition = "v2022.5.20";
|
|
169
172
|
let jslint_export; // The jslint object to be exported.
|
|
170
173
|
let jslint_fudge = 1; // Fudge starting line and starting
|
|
171
174
|
// ... column to 1.
|
|
172
175
|
let jslint_import_meta_url = ""; // import.meta.url used by cli.
|
|
176
|
+
let jslint_rgx_cap = (
|
|
177
|
+
/^[A-Z]/
|
|
178
|
+
);
|
|
179
|
+
let jslint_rgx_crlf = (
|
|
180
|
+
/\n|\r\n?/
|
|
181
|
+
);
|
|
182
|
+
let jslint_rgx_digits_bits = (
|
|
183
|
+
/^[01_]*/
|
|
184
|
+
);
|
|
185
|
+
let jslint_rgx_digits_decimals = (
|
|
186
|
+
/^[0-9_]*/
|
|
187
|
+
);
|
|
188
|
+
let jslint_rgx_digits_hexs = (
|
|
189
|
+
/^[0-9A-F_]*/i
|
|
190
|
+
);
|
|
191
|
+
let jslint_rgx_digits_octals = (
|
|
192
|
+
/^[0-7_]*/
|
|
193
|
+
);
|
|
194
|
+
let jslint_rgx_directive = (
|
|
195
|
+
/^(jslint|property|global)\s+(.*)$/
|
|
196
|
+
);
|
|
197
|
+
let jslint_rgx_directive_part = (
|
|
198
|
+
/([a-zA-Z$_][a-zA-Z0-9$_]*)(?::\s*(true|false))?,?\s*|$/g
|
|
199
|
+
);
|
|
200
|
+
let jslint_rgx_identifier = (
|
|
201
|
+
/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/
|
|
202
|
+
);
|
|
203
|
+
let jslint_rgx_json_number = (
|
|
204
|
+
|
|
205
|
+
// https://datatracker.ietf.org/doc/html/rfc7159#section-6
|
|
206
|
+
// number = [ minus ] int [ frac ] [ exp ]
|
|
207
|
+
|
|
208
|
+
/^-?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][\-+]?\d+)?$/
|
|
209
|
+
);
|
|
210
|
+
let jslint_rgx_mega = (
|
|
211
|
+
|
|
212
|
+
// Vim-hack - vim-editor has trouble parsing naked '`' in regexp
|
|
213
|
+
|
|
214
|
+
/[\u0060\\]|\$\{/
|
|
215
|
+
);
|
|
216
|
+
let jslint_rgx_module = (
|
|
217
|
+
/^[a-zA-Z0-9_$:.@\-\/]+$/
|
|
218
|
+
);
|
|
219
|
+
let jslint_rgx_numeric_separator_illegal = (
|
|
220
|
+
/__|_$|_n$/m
|
|
221
|
+
);
|
|
222
|
+
let jslint_rgx_slash_star_or_slash = (
|
|
223
|
+
/\/\*|\/$/
|
|
224
|
+
);
|
|
225
|
+
let jslint_rgx_tab = (
|
|
226
|
+
/\t/g
|
|
227
|
+
);
|
|
228
|
+
let jslint_rgx_todo = (
|
|
229
|
+
/\b(?:todo|TO\s?DO|HACK)\b/
|
|
230
|
+
);
|
|
231
|
+
let jslint_rgx_token = new RegExp(
|
|
232
|
+
"^("
|
|
233
|
+
+ "(\\s+)"
|
|
234
|
+
+ "|([a-zA-Z_$][a-zA-Z0-9_$]*)"
|
|
235
|
+
+ "|[(){}\\[\\],:;'\"~\\`]"
|
|
236
|
+
+ "|\\?[?.]?"
|
|
237
|
+
+ "|=(?:==?|>)?"
|
|
238
|
+
+ "|\\.+"
|
|
239
|
+
+ "|\\*[*\\/=]?"
|
|
240
|
+
+ "|\\/[*\\/]?"
|
|
241
|
+
+ "|\\+[=+]?"
|
|
242
|
+
+ "|-[=\\-]?"
|
|
243
|
+
+ "|[\\^%]=?"
|
|
244
|
+
+ "|&[&=]?"
|
|
245
|
+
+ "|\\"
|
|
246
|
+
+ "|[|=]?"
|
|
247
|
+
+ "|>{1,3}=?"
|
|
248
|
+
+ "|<<?=?"
|
|
249
|
+
+ "|!(?:!|==?)?"
|
|
250
|
+
|
|
251
|
+
// PR-351 - Add BigInt support.
|
|
252
|
+
// PR-390 - Add numeric-separator support.
|
|
253
|
+
|
|
254
|
+
+ "|((?:0_?|[1-9][0-9_]*)n?)"
|
|
255
|
+
+ ")"
|
|
256
|
+
+ "(.*)$"
|
|
257
|
+
);
|
|
258
|
+
let jslint_rgx_url_search_window_jslint = (
|
|
259
|
+
/[&?]window_jslint=1(?:$|&)/m
|
|
260
|
+
);
|
|
261
|
+
let jslint_rgx_weird_property = (
|
|
262
|
+
/^_|\$|Sync$|_$/m
|
|
263
|
+
);
|
|
173
264
|
let jstestCountFailed = 0;
|
|
174
265
|
let jstestCountTotal = 0;
|
|
175
266
|
let jstestItCount = 0;
|
|
@@ -265,6 +356,224 @@ async function fsWriteFileWithParents(pathname, data) {
|
|
|
265
356
|
console.error("wrote file " + pathname);
|
|
266
357
|
}
|
|
267
358
|
|
|
359
|
+
function globExclude({
|
|
360
|
+
excludeList = [],
|
|
361
|
+
includeList = [],
|
|
362
|
+
pathnameList = []
|
|
363
|
+
}) {
|
|
364
|
+
|
|
365
|
+
// This function will
|
|
366
|
+
// 1. Exclude pathnames in <pathnameList> that don't match glob-patterns in
|
|
367
|
+
// <includeList>.
|
|
368
|
+
// 2. Exclude pathnames in <pathnameList> that match glob-patterns in
|
|
369
|
+
// <excludeList>.
|
|
370
|
+
|
|
371
|
+
function globAssertNotWeird(list, name) {
|
|
372
|
+
|
|
373
|
+
// This function will check if <list> of strings contain weird characters.
|
|
374
|
+
|
|
375
|
+
[
|
|
376
|
+
[
|
|
377
|
+
"\n", (
|
|
378
|
+
/^.*?([\u0000-\u0007\r]).*/gm
|
|
379
|
+
)
|
|
380
|
+
],
|
|
381
|
+
[
|
|
382
|
+
"\r", (
|
|
383
|
+
/^.*?([\n]).*/gm
|
|
384
|
+
)
|
|
385
|
+
]
|
|
386
|
+
].forEach(function ([
|
|
387
|
+
separator, rgx
|
|
388
|
+
]) {
|
|
389
|
+
list.join(separator).replace(rgx, function (match0, char) {
|
|
390
|
+
throw new Error(
|
|
391
|
+
"Weird character "
|
|
392
|
+
+ JSON.stringify(char)
|
|
393
|
+
+ " found in " + name + " "
|
|
394
|
+
+ JSON.stringify(match0)
|
|
395
|
+
);
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function globToRegexp(pattern) {
|
|
401
|
+
|
|
402
|
+
// This function will translate glob <pattern> to javascript-regexp,
|
|
403
|
+
// which javascript can then use to "glob" pathnames.
|
|
404
|
+
|
|
405
|
+
let ii = 0;
|
|
406
|
+
let isClass = false;
|
|
407
|
+
let strClass = "";
|
|
408
|
+
let strRegex = "";
|
|
409
|
+
pattern = pattern.replace((
|
|
410
|
+
/\/\/+/g
|
|
411
|
+
), "/");
|
|
412
|
+
pattern = pattern.replace((
|
|
413
|
+
/\*\*\*+/g
|
|
414
|
+
), "**");
|
|
415
|
+
pattern.replace((
|
|
416
|
+
/\\\\|\\\[|\\\]|\[|\]|./g
|
|
417
|
+
), function (match0) {
|
|
418
|
+
switch (match0) {
|
|
419
|
+
case "[":
|
|
420
|
+
if (isClass) {
|
|
421
|
+
strClass += "[";
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
strClass += "\u0000";
|
|
425
|
+
strRegex += "\u0000";
|
|
426
|
+
isClass = true;
|
|
427
|
+
return;
|
|
428
|
+
case "]":
|
|
429
|
+
if (isClass) {
|
|
430
|
+
isClass = false;
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
strRegex += "]";
|
|
434
|
+
return;
|
|
435
|
+
default:
|
|
436
|
+
if (isClass) {
|
|
437
|
+
strClass += match0;
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
strRegex += match0;
|
|
441
|
+
}
|
|
442
|
+
return "";
|
|
443
|
+
});
|
|
444
|
+
strClass += "\u0000";
|
|
445
|
+
|
|
446
|
+
// An expression "[!...]" matches a single character, namely any character that
|
|
447
|
+
// is not matched by the expression obtained by removing the first '!' from it.
|
|
448
|
+
// (Thus, "[!a-]" matches any single character except 'a', and '-'.)
|
|
449
|
+
|
|
450
|
+
strClass = strClass.replace((
|
|
451
|
+
/\u0000!/g
|
|
452
|
+
), "\u0000^");
|
|
453
|
+
|
|
454
|
+
// One may include '-' in its literal meaning by making it the first or last
|
|
455
|
+
// character between the brackets.
|
|
456
|
+
|
|
457
|
+
strClass = strClass.replace((
|
|
458
|
+
/\u0000-/g
|
|
459
|
+
), "\u0000\\-");
|
|
460
|
+
strClass = strClass.replace((
|
|
461
|
+
/-\u0000/g
|
|
462
|
+
), "\\-\u0000");
|
|
463
|
+
|
|
464
|
+
// Escape brackets '[', ']' in character class.
|
|
465
|
+
|
|
466
|
+
strClass = strClass.replace((
|
|
467
|
+
/[\[\]]/g
|
|
468
|
+
), "\\$&");
|
|
469
|
+
|
|
470
|
+
// https://stackoverflow.com/questions/3561493
|
|
471
|
+
// /is-there-a-regexp-escape-function-in-javascript
|
|
472
|
+
// $()*+-./?[\]^{|}
|
|
473
|
+
|
|
474
|
+
strRegex = strRegex.replace((
|
|
475
|
+
// ignore [-/]
|
|
476
|
+
/[$()*+.?\[\\\]\^{|}]/g
|
|
477
|
+
), "\\$&");
|
|
478
|
+
|
|
479
|
+
// Expand wildcard '**/*'.
|
|
480
|
+
|
|
481
|
+
strRegex = strRegex.replace((
|
|
482
|
+
/\\\*\\\*\/(?:\\\*)+/g
|
|
483
|
+
), ".*?");
|
|
484
|
+
|
|
485
|
+
// Expand wildcard '**'.
|
|
486
|
+
|
|
487
|
+
strRegex = strRegex.replace((
|
|
488
|
+
/(^|\/)\\\*\\\*(\/|$)/gm
|
|
489
|
+
), "$1.*?$2");
|
|
490
|
+
|
|
491
|
+
// Expand wildcard '*'.
|
|
492
|
+
|
|
493
|
+
strRegex = strRegex.replace((
|
|
494
|
+
/(?:\\\*)+/g
|
|
495
|
+
), "[^\\/]*?");
|
|
496
|
+
|
|
497
|
+
// Expand wildcard '?'.
|
|
498
|
+
|
|
499
|
+
strRegex = strRegex.replace((
|
|
500
|
+
/\\\?/g
|
|
501
|
+
), "[^\\/]");
|
|
502
|
+
|
|
503
|
+
// Expand directory-with-trailing-slash '.../'.
|
|
504
|
+
|
|
505
|
+
strRegex = strRegex.replace((
|
|
506
|
+
/\/$/gm
|
|
507
|
+
), "\\/.*?");
|
|
508
|
+
|
|
509
|
+
// Merge strClass into strRegex.
|
|
510
|
+
|
|
511
|
+
ii = 0;
|
|
512
|
+
strClass = strClass.split("\u0000");
|
|
513
|
+
strRegex = strRegex.replace((
|
|
514
|
+
/\u0000/g
|
|
515
|
+
), function () {
|
|
516
|
+
ii += 1;
|
|
517
|
+
if (strClass[ii] === "") {
|
|
518
|
+
return "";
|
|
519
|
+
}
|
|
520
|
+
return "[" + strClass[ii] + "]";
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
// Change strRegex from string to regexp.
|
|
524
|
+
|
|
525
|
+
strRegex = new RegExp("^" + strRegex + "$", "gm");
|
|
526
|
+
return strRegex;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Validate excludeList, includeList, pathnameList.
|
|
530
|
+
|
|
531
|
+
globAssertNotWeird(excludeList, "pattern");
|
|
532
|
+
globAssertNotWeird(includeList, "pattern");
|
|
533
|
+
globAssertNotWeird(pathnameList, "pathname");
|
|
534
|
+
|
|
535
|
+
// Optimization
|
|
536
|
+
// Concat pathnames into a single, newline-separated string,
|
|
537
|
+
// whose pathnames can all be filtered with a single, regexp-pass.
|
|
538
|
+
|
|
539
|
+
pathnameList = pathnameList.join("\n");
|
|
540
|
+
|
|
541
|
+
// 1. Exclude pathnames in <pathnameList> that don't match glob-patterns in
|
|
542
|
+
// <includeList>.
|
|
543
|
+
|
|
544
|
+
if (includeList.length > 0) {
|
|
545
|
+
includeList = includeList.map(globToRegexp);
|
|
546
|
+
includeList.forEach(function (pattern) {
|
|
547
|
+
pathnameList = pathnameList.replace(pattern, "\u0000$&");
|
|
548
|
+
});
|
|
549
|
+
pathnameList = pathnameList.replace((
|
|
550
|
+
/^[^\u0000].*/gm
|
|
551
|
+
), "");
|
|
552
|
+
pathnameList = pathnameList.replace((
|
|
553
|
+
/^\u0000+/gm
|
|
554
|
+
), "");
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// 2. Exclude pathnames in <pathnameList> that match glob-patterns in
|
|
558
|
+
// <excludeList>.
|
|
559
|
+
|
|
560
|
+
excludeList = excludeList.map(globToRegexp);
|
|
561
|
+
excludeList.forEach(function (pattern) {
|
|
562
|
+
pathnameList = pathnameList.replace(pattern, "");
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// Split newline-separated pathnames back to list.
|
|
566
|
+
|
|
567
|
+
pathnameList = pathnameList.split("\n").filter(function (elem) {
|
|
568
|
+
return elem;
|
|
569
|
+
});
|
|
570
|
+
return {
|
|
571
|
+
excludeList,
|
|
572
|
+
includeList,
|
|
573
|
+
pathnameList
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
268
577
|
function htmlEscape(str) {
|
|
269
578
|
|
|
270
579
|
// This function will make <str> html-safe by escaping & < >.
|
|
@@ -305,10 +614,7 @@ function jslint(
|
|
|
305
614
|
let import_list = []; // The array collecting all import-from strings.
|
|
306
615
|
let line_list = String( // The array containing source lines.
|
|
307
616
|
"\n" + source
|
|
308
|
-
).split(
|
|
309
|
-
// rx_crlf
|
|
310
|
-
/\n|\r\n?/
|
|
311
|
-
).map(function (line_source) {
|
|
617
|
+
).split(jslint_rgx_crlf).map(function (line_source) {
|
|
312
618
|
return {
|
|
313
619
|
line_source
|
|
314
620
|
};
|
|
@@ -353,8 +659,6 @@ function jslint(
|
|
|
353
659
|
}
|
|
354
660
|
|
|
355
661
|
function is_equal(aa, bb) {
|
|
356
|
-
let aa_value;
|
|
357
|
-
let bb_value;
|
|
358
662
|
|
|
359
663
|
// test_cause:
|
|
360
664
|
// ["0&&0", "is_equal", "", "", 0]
|
|
@@ -375,6 +679,7 @@ function jslint(
|
|
|
375
679
|
|
|
376
680
|
// test_cause:
|
|
377
681
|
// ["`${0}`&&`${0}`", "is_equal", "recurse_isArray", "", 0]
|
|
682
|
+
// ["`${0}`&&`${1}`", "is_equal", "recurse_isArray", "", 0]
|
|
378
683
|
|
|
379
684
|
test_cause("recurse_isArray");
|
|
380
685
|
return is_equal(value, bb[index]);
|
|
@@ -388,21 +693,19 @@ function jslint(
|
|
|
388
693
|
// }
|
|
389
694
|
|
|
390
695
|
jslint_assert(!Array.isArray(bb), `Expected !Array.isArray(bb).`);
|
|
391
|
-
|
|
696
|
+
switch (aa.id === bb.id && aa.id) {
|
|
697
|
+
case "(number)":
|
|
698
|
+
case "(string)":
|
|
392
699
|
return aa.value === bb.value;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
bb_value = bb.value[0];
|
|
403
|
-
}
|
|
404
|
-
if (typeof aa_value === "string") {
|
|
405
|
-
return aa_value === bb_value;
|
|
700
|
+
|
|
701
|
+
// PR-394 - Bugfix
|
|
702
|
+
// Fix jslint falsely believing megastring literals `0` and `1` are similar.
|
|
703
|
+
|
|
704
|
+
case "`":
|
|
705
|
+
if (!is_equal(aa.value, bb.value)) {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
break;
|
|
406
709
|
}
|
|
407
710
|
if (is_weird(aa) || is_weird(bb)) {
|
|
408
711
|
|
|
@@ -685,6 +988,12 @@ function jslint(
|
|
|
685
988
|
// case "function_in_loop":
|
|
686
989
|
// mm = `Don't create functions within a loop.`;
|
|
687
990
|
// break;
|
|
991
|
+
|
|
992
|
+
// PR-390 - Add numeric-separator check.
|
|
993
|
+
|
|
994
|
+
case "illegal_num_separator":
|
|
995
|
+
mm = `Illegal numeric separator '_' at column ${column}.`;
|
|
996
|
+
break;
|
|
688
997
|
case "infix_in":
|
|
689
998
|
mm = (
|
|
690
999
|
`Unexpected 'in'. Compare with undefined,`
|
|
@@ -837,6 +1146,15 @@ function jslint(
|
|
|
837
1146
|
case "use_double":
|
|
838
1147
|
mm = `Use double quotes, not single quotes.`;
|
|
839
1148
|
break;
|
|
1149
|
+
|
|
1150
|
+
// PR-386 - Fix issue #382 - Make fart-related warnings more readable.
|
|
1151
|
+
|
|
1152
|
+
case "use_function_not_fart":
|
|
1153
|
+
mm = (
|
|
1154
|
+
`Use 'function (...)', not '(...) =>' when arrow functions`
|
|
1155
|
+
+ ` become too complex.`
|
|
1156
|
+
);
|
|
1157
|
+
break;
|
|
840
1158
|
case "use_open":
|
|
841
1159
|
mm = (
|
|
842
1160
|
`Wrap a ternary expression in parens,`
|
|
@@ -870,6 +1188,12 @@ function jslint(
|
|
|
870
1188
|
case "wrap_condition":
|
|
871
1189
|
mm = `Wrap the condition in parens.`;
|
|
872
1190
|
break;
|
|
1191
|
+
|
|
1192
|
+
// PR-386 - Fix issue #382 - Make fart-related warnings more readable.
|
|
1193
|
+
|
|
1194
|
+
case "wrap_fart_parameter":
|
|
1195
|
+
mm = `Wrap the parameter before '=>' in parens.`;
|
|
1196
|
+
break;
|
|
873
1197
|
case "wrap_immediate":
|
|
874
1198
|
mm = (
|
|
875
1199
|
`Wrap an immediate function invocation in parentheses to assist`
|
|
@@ -877,9 +1201,6 @@ function jslint(
|
|
|
877
1201
|
+ ` result of a function, and not the function itself.`
|
|
878
1202
|
);
|
|
879
1203
|
break;
|
|
880
|
-
case "wrap_parameter":
|
|
881
|
-
mm = `Wrap the parameter in parens.`;
|
|
882
|
-
break;
|
|
883
1204
|
case "wrap_regexp":
|
|
884
1205
|
mm = `Wrap this regexp in parens to avoid confusion.`;
|
|
885
1206
|
break;
|
|
@@ -1441,6 +1762,7 @@ async function jslint_cli({
|
|
|
1441
1762
|
console_error,
|
|
1442
1763
|
console_log,
|
|
1443
1764
|
file,
|
|
1765
|
+
import_meta_url,
|
|
1444
1766
|
mode_cli,
|
|
1445
1767
|
mode_noop,
|
|
1446
1768
|
option,
|
|
@@ -1455,8 +1777,8 @@ async function jslint_cli({
|
|
|
1455
1777
|
let command;
|
|
1456
1778
|
let data;
|
|
1457
1779
|
let exit_code = 0;
|
|
1458
|
-
let mode_plugin_vim;
|
|
1459
1780
|
let mode_report;
|
|
1781
|
+
let mode_wrapper_vim;
|
|
1460
1782
|
let result;
|
|
1461
1783
|
|
|
1462
1784
|
function jslint_from_file({
|
|
@@ -1529,7 +1851,7 @@ async function jslint_cli({
|
|
|
1529
1851
|
if (result_from_file.warnings.length > 0) {
|
|
1530
1852
|
exit_code = 1;
|
|
1531
1853
|
console_error(
|
|
1532
|
-
|
|
1854
|
+
mode_wrapper_vim
|
|
1533
1855
|
|
|
1534
1856
|
// PR-349 - Print warnings in format readable by vim.
|
|
1535
1857
|
|
|
@@ -1609,11 +1931,26 @@ async function jslint_cli({
|
|
|
1609
1931
|
return count;
|
|
1610
1932
|
}
|
|
1611
1933
|
|
|
1934
|
+
// PR-396 - window.jslint
|
|
1935
|
+
// Check import.meta.url for directive to export jslint to window-object.
|
|
1936
|
+
// Useful for ES5-era browser-scripts that rely on window.jslint,
|
|
1937
|
+
// like CodeMirror.
|
|
1938
|
+
//
|
|
1939
|
+
// Example usage:
|
|
1940
|
+
// <script type="module" src="./jslint.mjs?window_jslint=1"></script>
|
|
1941
|
+
|
|
1942
|
+
import_meta_url = import_meta_url || jslint_import_meta_url;
|
|
1943
|
+
if (
|
|
1944
|
+
jslint_rgx_url_search_window_jslint.test(import_meta_url)
|
|
1945
|
+
&& (typeof globalThis === "object" && globalThis)
|
|
1946
|
+
) {
|
|
1947
|
+
globalThis.jslint = jslint;
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1612
1950
|
// Feature-detect nodejs.
|
|
1613
1951
|
|
|
1614
1952
|
if (!(
|
|
1615
|
-
typeof process === "object"
|
|
1616
|
-
&& process
|
|
1953
|
+
(typeof process === "object" && process)
|
|
1617
1954
|
&& process.versions
|
|
1618
1955
|
&& typeof process.versions.node === "string"
|
|
1619
1956
|
&& !mode_noop
|
|
@@ -1639,7 +1976,7 @@ async function jslint_cli({
|
|
|
1639
1976
|
).test(process_argv[1])
|
|
1640
1977
|
|| mode_cli
|
|
1641
1978
|
)
|
|
1642
|
-
&& moduleUrl.fileURLToPath(
|
|
1979
|
+
&& moduleUrl.fileURLToPath(import_meta_url)
|
|
1643
1980
|
=== modulePath.resolve(process_argv[1])
|
|
1644
1981
|
)
|
|
1645
1982
|
&& !mode_cli
|
|
@@ -1662,17 +1999,17 @@ async function jslint_cli({
|
|
|
1662
1999
|
}));
|
|
1663
2000
|
return;
|
|
1664
2001
|
|
|
1665
|
-
//
|
|
2002
|
+
// PR-363 - Add command jslint_report.
|
|
1666
2003
|
|
|
1667
|
-
case "
|
|
1668
|
-
|
|
2004
|
+
case "jslint_report":
|
|
2005
|
+
mode_report = command[1];
|
|
1669
2006
|
process_argv = process_argv.slice(1);
|
|
1670
2007
|
break;
|
|
1671
2008
|
|
|
1672
|
-
//
|
|
2009
|
+
// COMMIT-b26d6df2 - Add command jslint_wrapper_vim.
|
|
1673
2010
|
|
|
1674
|
-
case "
|
|
1675
|
-
|
|
2011
|
+
case "jslint_wrapper_vim":
|
|
2012
|
+
mode_wrapper_vim = true;
|
|
1676
2013
|
process_argv = process_argv.slice(1);
|
|
1677
2014
|
break;
|
|
1678
2015
|
|
|
@@ -1680,6 +2017,7 @@ async function jslint_cli({
|
|
|
1680
2017
|
|
|
1681
2018
|
case "v8_coverage_report":
|
|
1682
2019
|
await v8CoverageReportCreate({
|
|
2020
|
+
consoleError: console_error,
|
|
1683
2021
|
coverageDir: command[1],
|
|
1684
2022
|
processArgv: process_argv.slice(3)
|
|
1685
2023
|
});
|
|
@@ -1688,9 +2026,9 @@ async function jslint_cli({
|
|
|
1688
2026
|
|
|
1689
2027
|
// PR-349 - Detect cli-option --mode-vim-plugin.
|
|
1690
2028
|
|
|
1691
|
-
|
|
2029
|
+
mode_wrapper_vim = (
|
|
1692
2030
|
process_argv.slice(2).indexOf("--mode-vim-plugin") >= 0
|
|
1693
|
-
||
|
|
2031
|
+
|| mode_wrapper_vim
|
|
1694
2032
|
);
|
|
1695
2033
|
|
|
1696
2034
|
// Normalize file relative to process.cwd().
|
|
@@ -1784,7 +2122,9 @@ async function jslint_cli({
|
|
|
1784
2122
|
option
|
|
1785
2123
|
});
|
|
1786
2124
|
if (mode_report) {
|
|
1787
|
-
|
|
2125
|
+
result = jslint.jslint_report(result);
|
|
2126
|
+
result = `<body class="JSLINT_ JSLINT_REPORT_">\n${result}</body>\n`;
|
|
2127
|
+
await fsWriteFileWithParents(mode_report, result);
|
|
1788
2128
|
}
|
|
1789
2129
|
process_exit(exit_code);
|
|
1790
2130
|
return exit_code;
|
|
@@ -1826,37 +2166,16 @@ function jslint_phase2_lex(state) {
|
|
|
1826
2166
|
let line_mega; // The starting line of megastring.
|
|
1827
2167
|
let line_source = ""; // The remaining line source string.
|
|
1828
2168
|
let line_whole = ""; // The whole line source string.
|
|
2169
|
+
let mode_digits_empty_string = 1;
|
|
2170
|
+
let mode_digits_numeric_separator = 2;
|
|
1829
2171
|
let mode_directive = true; // true if directives are still allowed.
|
|
1830
2172
|
let mode_mega = false; // true if currently parsing a megastring
|
|
1831
2173
|
// ... literal.
|
|
1832
2174
|
let mode_regexp; // true if regular expression literal seen on
|
|
1833
2175
|
// ... this line.
|
|
1834
|
-
let
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
+ "|([a-zA-Z_$][a-zA-Z0-9_$]*)"
|
|
1838
|
-
+ "|[(){}\\[\\],:;'\"~\\`]"
|
|
1839
|
-
+ "|\\?[?.]?"
|
|
1840
|
-
+ "|=(?:==?|>)?"
|
|
1841
|
-
+ "|\\.+"
|
|
1842
|
-
+ "|\\*[*\\/=]?"
|
|
1843
|
-
+ "|\\/[*\\/]?"
|
|
1844
|
-
+ "|\\+[=+]?"
|
|
1845
|
-
+ "|-[=\\-]?"
|
|
1846
|
-
+ "|[\\^%]=?"
|
|
1847
|
-
+ "|&[&=]?"
|
|
1848
|
-
+ "|\\"
|
|
1849
|
-
+ "|[|=]?"
|
|
1850
|
-
+ "|>{1,3}=?"
|
|
1851
|
-
+ "|<<?=?"
|
|
1852
|
-
+ "|!(?:!|==?)?"
|
|
1853
|
-
|
|
1854
|
-
// PR-351 - Add BigInt support.
|
|
1855
|
-
|
|
1856
|
-
+ "|(0n?|[1-9][0-9]*n?)"
|
|
1857
|
-
+ ")"
|
|
1858
|
-
+ "(.*)$"
|
|
1859
|
-
);
|
|
2176
|
+
let paren_backtrack_list = []; // List of most recent "(" tokens at any
|
|
2177
|
+
// ... paren-depth.
|
|
2178
|
+
let paren_depth = 0; // Keeps track of current paren-depth.
|
|
1860
2179
|
let snippet = ""; // A piece of string.
|
|
1861
2180
|
let token_1; // The first token.
|
|
1862
2181
|
let token_prv = token_global; // The previous token including
|
|
@@ -1938,7 +2257,7 @@ function jslint_phase2_lex(state) {
|
|
|
1938
2257
|
|
|
1939
2258
|
warn_at("unexpected_a", line, column, char);
|
|
1940
2259
|
}
|
|
1941
|
-
if (read_digits("x") > 5) {
|
|
2260
|
+
if (read_digits("x", undefined) > 5) {
|
|
1942
2261
|
|
|
1943
2262
|
// test_cause:
|
|
1944
2263
|
// ["\"\\u{123456}\"", "char_after_escape", "too_many_digits", "", 11]
|
|
@@ -1955,7 +2274,7 @@ function jslint_phase2_lex(state) {
|
|
|
1955
2274
|
return char_after();
|
|
1956
2275
|
}
|
|
1957
2276
|
char_before();
|
|
1958
|
-
if (read_digits("x",
|
|
2277
|
+
if (read_digits("x", mode_digits_empty_string) < 4) {
|
|
1959
2278
|
|
|
1960
2279
|
// test_cause:
|
|
1961
2280
|
// ["\"\\u0\"", "char_after_escape", "expected_four_digits", "", 5]
|
|
@@ -1990,6 +2309,26 @@ function jslint_phase2_lex(state) {
|
|
|
1990
2309
|
return char;
|
|
1991
2310
|
}
|
|
1992
2311
|
|
|
2312
|
+
function check_numeric_separator(digits, column) {
|
|
2313
|
+
|
|
2314
|
+
// This function will check for illegal numeric-separator in <digits>.
|
|
2315
|
+
|
|
2316
|
+
digits.replace((
|
|
2317
|
+
jslint_rgx_numeric_separator_illegal
|
|
2318
|
+
), function (ignore, ii) {
|
|
2319
|
+
|
|
2320
|
+
// test_cause:
|
|
2321
|
+
// ["0x0_0_;", "check_numeric_separator", "illegal_num_separator", "", 6]
|
|
2322
|
+
// ["0x0_0__0;", "check_numeric_separator", "illegal_num_separator", "", 6]
|
|
2323
|
+
// ["aa=1_2_;", "check_numeric_separator", "illegal_num_separator", "", 7]
|
|
2324
|
+
// ["aa=1_2__3;", "check_numeric_separator", "illegal_num_separator", "", 7]
|
|
2325
|
+
// ["aa=1_2_n;", "check_numeric_separator", "illegal_num_separator", "", 7]
|
|
2326
|
+
|
|
2327
|
+
warn_at("illegal_num_separator", line, column + ii + 1);
|
|
2328
|
+
return "";
|
|
2329
|
+
});
|
|
2330
|
+
}
|
|
2331
|
+
|
|
1993
2332
|
function lex_comment() {
|
|
1994
2333
|
let body;
|
|
1995
2334
|
let ii = 0;
|
|
@@ -2028,12 +2367,12 @@ function jslint_phase2_lex(state) {
|
|
|
2028
2367
|
// Lex/loop through each line until "*/".
|
|
2029
2368
|
|
|
2030
2369
|
while (true) {
|
|
2031
|
-
//
|
|
2370
|
+
// jslint_rgx_star_slash
|
|
2032
2371
|
ii = line_source.indexOf("*/");
|
|
2033
2372
|
if (ii >= 0) {
|
|
2034
2373
|
break;
|
|
2035
2374
|
}
|
|
2036
|
-
//
|
|
2375
|
+
// jslint_rgx_slash_star
|
|
2037
2376
|
ii = line_source.indexOf("/*");
|
|
2038
2377
|
if (ii >= 0) {
|
|
2039
2378
|
|
|
@@ -2053,8 +2392,7 @@ function jslint_phase2_lex(state) {
|
|
|
2053
2392
|
}
|
|
2054
2393
|
}
|
|
2055
2394
|
jj = line_source.slice(0, ii).search(
|
|
2056
|
-
|
|
2057
|
-
/\/\*|\/$/
|
|
2395
|
+
jslint_rgx_slash_star_or_slash
|
|
2058
2396
|
);
|
|
2059
2397
|
if (jj >= 0) {
|
|
2060
2398
|
|
|
@@ -2072,13 +2410,7 @@ function jslint_phase2_lex(state) {
|
|
|
2072
2410
|
|
|
2073
2411
|
// Uncompleted work comment.
|
|
2074
2412
|
|
|
2075
|
-
if (
|
|
2076
|
-
!option_dict.devel
|
|
2077
|
-
&& (
|
|
2078
|
-
// rx_todo
|
|
2079
|
-
/\b(?:todo|TO\s?DO|HACK)\b/
|
|
2080
|
-
).test(snippet)
|
|
2081
|
-
) {
|
|
2413
|
+
if (!option_dict.devel && jslint_rgx_todo.test(snippet)) {
|
|
2082
2414
|
|
|
2083
2415
|
// test_cause:
|
|
2084
2416
|
// ["//todo", "lex_comment", "todo_comment", "(comment)", 1] //jslint-quiet
|
|
@@ -2090,10 +2422,7 @@ function jslint_phase2_lex(state) {
|
|
|
2090
2422
|
|
|
2091
2423
|
[
|
|
2092
2424
|
the_comment.directive, body
|
|
2093
|
-
] = Array.from(snippet.match(
|
|
2094
|
-
// rx_directive
|
|
2095
|
-
/^(jslint|property|global)\s+(.*)$/
|
|
2096
|
-
) || []).slice(1);
|
|
2425
|
+
] = Array.from(snippet.match(jslint_rgx_directive) || []).slice(1);
|
|
2097
2426
|
if (the_comment.directive === undefined) {
|
|
2098
2427
|
return the_comment;
|
|
2099
2428
|
}
|
|
@@ -2115,10 +2444,12 @@ function jslint_phase2_lex(state) {
|
|
|
2115
2444
|
// Lex/loop through each directive in /*...*/
|
|
2116
2445
|
|
|
2117
2446
|
ii = 0;
|
|
2118
|
-
body.replace((
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2447
|
+
body.replace(jslint_rgx_directive_part, function (
|
|
2448
|
+
match0,
|
|
2449
|
+
key,
|
|
2450
|
+
val,
|
|
2451
|
+
jj
|
|
2452
|
+
) {
|
|
2122
2453
|
if (ii !== jj) {
|
|
2123
2454
|
|
|
2124
2455
|
// test_cause:
|
|
@@ -2192,13 +2523,7 @@ function jslint_phase2_lex(state) {
|
|
|
2192
2523
|
// string.
|
|
2193
2524
|
|
|
2194
2525
|
while (true) {
|
|
2195
|
-
match = line_source.match(
|
|
2196
|
-
|
|
2197
|
-
// Vim-hack - vim-editor has trouble parsing '`' in regexp
|
|
2198
|
-
|
|
2199
|
-
// rx_mega
|
|
2200
|
-
/[\u0060\\]|\$\{/
|
|
2201
|
-
) || {
|
|
2526
|
+
match = line_source.match(jslint_rgx_mega) || {
|
|
2202
2527
|
"0": "",
|
|
2203
2528
|
index: 0
|
|
2204
2529
|
};
|
|
@@ -2275,12 +2600,16 @@ function jslint_phase2_lex(state) {
|
|
|
2275
2600
|
|
|
2276
2601
|
function lex_number() {
|
|
2277
2602
|
let prefix = snippet;
|
|
2603
|
+
|
|
2604
|
+
// PR-390 - Add numeric-separator check.
|
|
2605
|
+
|
|
2606
|
+
check_numeric_separator(prefix, column - prefix.length);
|
|
2278
2607
|
char_after();
|
|
2279
2608
|
switch (prefix === "0" && char) {
|
|
2280
2609
|
case "b":
|
|
2281
2610
|
case "o":
|
|
2282
2611
|
case "x":
|
|
2283
|
-
read_digits(char);
|
|
2612
|
+
read_digits(char, mode_digits_numeric_separator);
|
|
2284
2613
|
|
|
2285
2614
|
// PR-351 - Ignore BigInt suffix 'n'.
|
|
2286
2615
|
|
|
@@ -2290,14 +2619,14 @@ function jslint_phase2_lex(state) {
|
|
|
2290
2619
|
break;
|
|
2291
2620
|
default:
|
|
2292
2621
|
if (char === ".") {
|
|
2293
|
-
read_digits("d");
|
|
2622
|
+
read_digits("d", mode_digits_numeric_separator);
|
|
2294
2623
|
}
|
|
2295
2624
|
if (char === "E" || char === "e") {
|
|
2296
2625
|
char_after(char);
|
|
2297
2626
|
if (char !== "+" && char !== "-") {
|
|
2298
2627
|
char_before();
|
|
2299
2628
|
}
|
|
2300
|
-
read_digits("d");
|
|
2629
|
+
read_digits("d", mode_digits_numeric_separator);
|
|
2301
2630
|
}
|
|
2302
2631
|
}
|
|
2303
2632
|
|
|
@@ -2567,7 +2896,7 @@ function jslint_phase2_lex(state) {
|
|
|
2567
2896
|
}
|
|
2568
2897
|
break;
|
|
2569
2898
|
case "{":
|
|
2570
|
-
if (read_digits("d",
|
|
2899
|
+
if (read_digits("d", mode_digits_empty_string) === 0) {
|
|
2571
2900
|
|
|
2572
2901
|
// test_cause:
|
|
2573
2902
|
// ["aa=/aa{/", "lex_regexp_group", "expected_a_before_b", ",", 8]
|
|
@@ -2580,7 +2909,7 @@ function jslint_phase2_lex(state) {
|
|
|
2580
2909
|
// ["aa=/.{,/", "lex_regexp_group", "comma", "", 0]
|
|
2581
2910
|
|
|
2582
2911
|
test_cause("comma");
|
|
2583
|
-
read_digits("d",
|
|
2912
|
+
read_digits("d", mode_digits_empty_string);
|
|
2584
2913
|
}
|
|
2585
2914
|
if (char_after("}") === "?") {
|
|
2586
2915
|
|
|
@@ -2873,7 +3202,7 @@ function jslint_phase2_lex(state) {
|
|
|
2873
3202
|
}
|
|
2874
3203
|
}
|
|
2875
3204
|
from = column;
|
|
2876
|
-
match = line_source.match(
|
|
3205
|
+
match = line_source.match(jslint_rgx_token);
|
|
2877
3206
|
|
|
2878
3207
|
// match[1] token
|
|
2879
3208
|
// match[2] whitespace
|
|
@@ -3193,7 +3522,7 @@ node --input-type=module --eval '
|
|
|
3193
3522
|
// /\*jslint beta, node*\/
|
|
3194
3523
|
import moduleHttps from "https";
|
|
3195
3524
|
(async function () {
|
|
3196
|
-
let dict =
|
|
3525
|
+
let dict = Object.create(null);
|
|
3197
3526
|
let result = "";
|
|
3198
3527
|
await new Promise(function (resolve) {
|
|
3199
3528
|
moduleHttps.get((
|
|
@@ -3256,41 +3585,48 @@ import moduleHttps from "https";
|
|
|
3256
3585
|
return true;
|
|
3257
3586
|
}
|
|
3258
3587
|
|
|
3259
|
-
function read_digits(base,
|
|
3588
|
+
function read_digits(base, mode) {
|
|
3260
3589
|
let digits = line_source.match(
|
|
3261
3590
|
base === "b"
|
|
3262
|
-
?
|
|
3263
|
-
// rx_bits
|
|
3264
|
-
/^[01]*/
|
|
3265
|
-
)
|
|
3591
|
+
? jslint_rgx_digits_bits
|
|
3266
3592
|
: base === "o"
|
|
3267
|
-
?
|
|
3268
|
-
// rx_octals
|
|
3269
|
-
/^[0-7]*/
|
|
3270
|
-
)
|
|
3593
|
+
? jslint_rgx_digits_octals
|
|
3271
3594
|
: base === "x"
|
|
3272
|
-
?
|
|
3273
|
-
|
|
3274
|
-
/^[0-9A-F]*/i
|
|
3275
|
-
)
|
|
3276
|
-
: (
|
|
3277
|
-
// rx_digits
|
|
3278
|
-
/^[0-9]*/
|
|
3279
|
-
)
|
|
3595
|
+
? jslint_rgx_digits_hexs
|
|
3596
|
+
: jslint_rgx_digits_decimals
|
|
3280
3597
|
)[0];
|
|
3281
|
-
|
|
3282
|
-
|
|
3598
|
+
if (
|
|
3599
|
+
(mode !== mode_digits_empty_string && digits.length === 0)
|
|
3600
|
+
|| digits[0] === "_"
|
|
3601
|
+
) {
|
|
3283
3602
|
|
|
3284
3603
|
// test_cause:
|
|
3285
3604
|
// ["0x", "read_digits", "expected_digits_after_a", "0x", 2]
|
|
3605
|
+
// ["0x_", "read_digits", "expected_digits_after_a", "0x", 2]
|
|
3286
3606
|
|
|
3287
3607
|
warn_at("expected_digits_after_a", line, column, snippet);
|
|
3288
3608
|
}
|
|
3289
|
-
|
|
3290
|
-
|
|
3609
|
+
|
|
3610
|
+
// PR-390 - Add numeric-separator check.
|
|
3611
|
+
|
|
3612
|
+
if (mode === mode_digits_numeric_separator) {
|
|
3613
|
+
check_numeric_separator(digits, column);
|
|
3614
|
+
} else if (digits.indexOf("_") >= 0) {
|
|
3615
|
+
|
|
3616
|
+
// test_cause:
|
|
3617
|
+
// ["\"\\u{1_2}\"", "read_digits", "illegal_num_separator", "", 6]
|
|
3618
|
+
|
|
3619
|
+
warn_at(
|
|
3620
|
+
"illegal_num_separator",
|
|
3621
|
+
line,
|
|
3622
|
+
column + digits.indexOf("_") + 1
|
|
3623
|
+
);
|
|
3624
|
+
}
|
|
3625
|
+
column += digits.length;
|
|
3626
|
+
line_source = line_source.slice(digits.length);
|
|
3291
3627
|
snippet += digits;
|
|
3292
3628
|
char_after();
|
|
3293
|
-
return length;
|
|
3629
|
+
return digits.length;
|
|
3294
3630
|
}
|
|
3295
3631
|
|
|
3296
3632
|
function read_line() {
|
|
@@ -3361,6 +3697,7 @@ import moduleHttps from "https";
|
|
|
3361
3697
|
test_cause("line_disable");
|
|
3362
3698
|
line_source = "";
|
|
3363
3699
|
}
|
|
3700
|
+
// jslint_rgx_tab
|
|
3364
3701
|
if (line_source.indexOf("\t") >= 0) {
|
|
3365
3702
|
if (!option_dict.white) {
|
|
3366
3703
|
|
|
@@ -3369,10 +3706,7 @@ import moduleHttps from "https";
|
|
|
3369
3706
|
|
|
3370
3707
|
warn_at("use_spaces", line, line_source.indexOf("\t") + 1);
|
|
3371
3708
|
}
|
|
3372
|
-
line_source = line_source.replace(
|
|
3373
|
-
// rx_tab
|
|
3374
|
-
/\t/g
|
|
3375
|
-
), " ");
|
|
3709
|
+
line_source = line_source.replace(jslint_rgx_tab, " ");
|
|
3376
3710
|
}
|
|
3377
3711
|
if (!option_dict.white && line_source.endsWith(" ")) {
|
|
3378
3712
|
|
|
@@ -3392,9 +3726,11 @@ import moduleHttps from "https";
|
|
|
3392
3726
|
from,
|
|
3393
3727
|
id,
|
|
3394
3728
|
identifier: Boolean(identifier),
|
|
3729
|
+
is_fart: false,
|
|
3395
3730
|
line,
|
|
3396
3731
|
nr: token_list.length,
|
|
3397
|
-
thru: column
|
|
3732
|
+
thru: column,
|
|
3733
|
+
value
|
|
3398
3734
|
};
|
|
3399
3735
|
token_list.push(the_token);
|
|
3400
3736
|
|
|
@@ -3404,12 +3740,6 @@ import moduleHttps from "https";
|
|
|
3404
3740
|
mode_directive = false;
|
|
3405
3741
|
}
|
|
3406
3742
|
|
|
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
3743
|
// If this token is an identifier that touches a preceding number, or
|
|
3414
3744
|
// a "/", comment, or regular expression literal that touches a preceding
|
|
3415
3745
|
// comment or regular expression literal, then give a missing space warning.
|
|
@@ -3443,6 +3773,29 @@ import moduleHttps from "https";
|
|
|
3443
3773
|
the_token.dot = true;
|
|
3444
3774
|
}
|
|
3445
3775
|
|
|
3776
|
+
// PR-385 - Bugfix - Fixes issue #382 - failure to detect destructured fart.
|
|
3777
|
+
// Farts are now detected by keeping a list of most recent "(" tokens at any
|
|
3778
|
+
// given depth. When a "=>" token is encountered, the most recent "(" token at
|
|
3779
|
+
// current depth is marked as a fart.
|
|
3780
|
+
|
|
3781
|
+
switch (id) {
|
|
3782
|
+
case "(":
|
|
3783
|
+
paren_backtrack_list[paren_depth] = the_token;
|
|
3784
|
+
paren_depth += 1;
|
|
3785
|
+
break;
|
|
3786
|
+
case ")":
|
|
3787
|
+
paren_depth -= 1;
|
|
3788
|
+
break;
|
|
3789
|
+
case "=>":
|
|
3790
|
+
if (
|
|
3791
|
+
token_prv_expr.id === ")"
|
|
3792
|
+
&& paren_backtrack_list[paren_depth]
|
|
3793
|
+
) {
|
|
3794
|
+
paren_backtrack_list[paren_depth].is_fart = true;
|
|
3795
|
+
}
|
|
3796
|
+
break;
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3446
3799
|
// The previous token is used to detect adjacency problems.
|
|
3447
3800
|
|
|
3448
3801
|
token_prv = the_token;
|
|
@@ -3527,9 +3880,6 @@ function jslint_phase3_parse(state) {
|
|
|
3527
3880
|
let catchage = catch_stack[0]; // The current catch-block.
|
|
3528
3881
|
let functionage = token_global; // The current function.
|
|
3529
3882
|
let mode_var; // "var" if using var; "let" if using let.
|
|
3530
|
-
let rx_identifier = (
|
|
3531
|
-
/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/
|
|
3532
|
-
);
|
|
3533
3883
|
let token_ii = 0; // The number of the next token.
|
|
3534
3884
|
let token_now = token_global; // The current token being examined in
|
|
3535
3885
|
// ... the parse.
|
|
@@ -3546,7 +3896,7 @@ function jslint_phase3_parse(state) {
|
|
|
3546
3896
|
anon = token_now.id;
|
|
3547
3897
|
} else if (
|
|
3548
3898
|
token_now.id === "(string)"
|
|
3549
|
-
&&
|
|
3899
|
+
&& jslint_rgx_identifier.test(token_now.value)
|
|
3550
3900
|
) {
|
|
3551
3901
|
anon = token_now.value;
|
|
3552
3902
|
}
|
|
@@ -3558,7 +3908,7 @@ function jslint_phase3_parse(state) {
|
|
|
3558
3908
|
match === undefined
|
|
3559
3909
|
|
|
3560
3910
|
// test_cause:
|
|
3561
|
-
// ["
|
|
3911
|
+
// ["{0:0}", "advance", "expected_a_b", "0", 2]
|
|
3562
3912
|
|
|
3563
3913
|
? stop("expected_a_b", token_nxt, id, artifact())
|
|
3564
3914
|
|
|
@@ -3607,7 +3957,7 @@ function jslint_phase3_parse(state) {
|
|
|
3607
3957
|
// other assignment operators can modify, but they cannot initialize.
|
|
3608
3958
|
|
|
3609
3959
|
const the_symbol = symbol(id, 20);
|
|
3610
|
-
the_symbol.
|
|
3960
|
+
the_symbol.led_infix = function (left) {
|
|
3611
3961
|
const the_token = token_now;
|
|
3612
3962
|
let right;
|
|
3613
3963
|
the_token.arity = "assignment";
|
|
@@ -3919,7 +4269,7 @@ function jslint_phase3_parse(state) {
|
|
|
3919
4269
|
|
|
3920
4270
|
const the_symbol = symbol(id);
|
|
3921
4271
|
the_symbol.constant = true;
|
|
3922
|
-
the_symbol.
|
|
4272
|
+
the_symbol.nud_prefix = (
|
|
3923
4273
|
typeof value === "function"
|
|
3924
4274
|
? value
|
|
3925
4275
|
: function () {
|
|
@@ -4113,7 +4463,7 @@ function jslint_phase3_parse(state) {
|
|
|
4113
4463
|
// Create an infix operator.
|
|
4114
4464
|
|
|
4115
4465
|
const the_symbol = symbol(id, bp);
|
|
4116
|
-
the_symbol.
|
|
4466
|
+
the_symbol.led_infix = function (left) {
|
|
4117
4467
|
const the_token = token_now;
|
|
4118
4468
|
the_token.arity = "binary";
|
|
4119
4469
|
if (f !== undefined) {
|
|
@@ -4171,12 +4521,12 @@ function jslint_phase3_parse(state) {
|
|
|
4171
4521
|
return the_token;
|
|
4172
4522
|
}
|
|
4173
4523
|
|
|
4174
|
-
function infix_fart_unwrapped(
|
|
4524
|
+
function infix_fart_unwrapped() {
|
|
4175
4525
|
|
|
4176
4526
|
// test_cause:
|
|
4177
|
-
// ["aa=>0", "infix_fart_unwrapped", "
|
|
4527
|
+
// ["aa=>0", "infix_fart_unwrapped", "wrap_fart_parameter", "=>", 3]
|
|
4178
4528
|
|
|
4179
|
-
return stop("
|
|
4529
|
+
return stop("wrap_fart_parameter", token_now);
|
|
4180
4530
|
}
|
|
4181
4531
|
|
|
4182
4532
|
function infix_grave(left) {
|
|
@@ -4196,7 +4546,7 @@ function jslint_phase3_parse(state) {
|
|
|
4196
4546
|
let the_subscript = parse_expression(0);
|
|
4197
4547
|
if (the_subscript.id === "(string)" || the_subscript.id === "`") {
|
|
4198
4548
|
name = survey(the_subscript);
|
|
4199
|
-
if (
|
|
4549
|
+
if (jslint_rgx_identifier.test(name)) {
|
|
4200
4550
|
|
|
4201
4551
|
// test_cause:
|
|
4202
4552
|
// ["aa[`aa`]", "infix_lbracket", "subscript_a", "aa", 4]
|
|
@@ -4339,13 +4689,13 @@ function jslint_phase3_parse(state) {
|
|
|
4339
4689
|
// Create a right associative infix operator.
|
|
4340
4690
|
|
|
4341
4691
|
const the_symbol = symbol(id, bp);
|
|
4342
|
-
the_symbol.
|
|
4692
|
+
the_symbol.led_infix = function parse_infixr_led(left) {
|
|
4343
4693
|
const the_token = token_now;
|
|
4344
4694
|
|
|
4345
4695
|
// test_cause:
|
|
4346
|
-
// ["0**0", "parse_infixr_led", "
|
|
4696
|
+
// ["0**0", "parse_infixr_led", "led_infix", "", 0]
|
|
4347
4697
|
|
|
4348
|
-
test_cause("
|
|
4698
|
+
test_cause("led_infix");
|
|
4349
4699
|
the_token.arity = "binary";
|
|
4350
4700
|
the_token.expression = [left, parse_expression(bp - 1)];
|
|
4351
4701
|
return the_token;
|
|
@@ -4353,39 +4703,70 @@ function jslint_phase3_parse(state) {
|
|
|
4353
4703
|
return the_symbol;
|
|
4354
4704
|
}
|
|
4355
4705
|
|
|
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
4706
|
function parse_expression(rbp, initial) {
|
|
4372
4707
|
|
|
4373
4708
|
// 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.
|
|
4709
|
+
// is looking for ad hoc lint patterns. We add .fud_stmt to Pratt's model, which
|
|
4710
|
+
// is like .nud_prefix except that it is only used on the first token of a
|
|
4711
|
+
// statement. Having .fud_stmt makes it much easier to define statement-oriented
|
|
4712
|
+
// languages like JavaScript. I retained Pratt's nomenclature.
|
|
4378
4713
|
// They are elements of the parsing method called Top Down Operator Precedence.
|
|
4379
4714
|
|
|
4380
|
-
// .
|
|
4381
|
-
// .
|
|
4382
|
-
// .
|
|
4383
|
-
// lbp
|
|
4384
|
-
//
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
//
|
|
4388
|
-
//
|
|
4715
|
+
// .nud_prefix Null denotation. The prefix handler.
|
|
4716
|
+
// .fud_stmt First null denotation. The statement handler.
|
|
4717
|
+
// .led_infix Left denotation. The infix/postfix handler.
|
|
4718
|
+
// lbp Left binding power of infix operator. It tells us how strongly
|
|
4719
|
+
// the operator binds to the argument at its left.
|
|
4720
|
+
// rbp Right binding power.
|
|
4721
|
+
|
|
4722
|
+
// It processes a nud_prefix (variable, constant, prefix operator). It will then
|
|
4723
|
+
// process leds (infix operators) until the bind powers cause it to stop (it
|
|
4724
|
+
// consumes tokens until it meets a token whose lbp <= rbp). Specifically, it
|
|
4725
|
+
// means that it collects all tokens that bind together before returning to the
|
|
4726
|
+
// operator that called it. It returns the expression's parse tree.
|
|
4727
|
+
|
|
4728
|
+
// For example, "3 + 1 * 2 * 4 + 5"
|
|
4729
|
+
// parses into
|
|
4730
|
+
// {
|
|
4731
|
+
// "id": "+",
|
|
4732
|
+
// "expression": [
|
|
4733
|
+
// {
|
|
4734
|
+
// "id": "+",
|
|
4735
|
+
// "expression": [
|
|
4736
|
+
// {
|
|
4737
|
+
// "id": "(number)",
|
|
4738
|
+
// "value": "3"
|
|
4739
|
+
// },
|
|
4740
|
+
// {
|
|
4741
|
+
// "id": "*",
|
|
4742
|
+
// "expression": [
|
|
4743
|
+
// {
|
|
4744
|
+
// "id": "*",
|
|
4745
|
+
// "expression": [
|
|
4746
|
+
// {
|
|
4747
|
+
// "id": "(number)",
|
|
4748
|
+
// "value": "1"
|
|
4749
|
+
// },
|
|
4750
|
+
// {
|
|
4751
|
+
// "id": "(number)",
|
|
4752
|
+
// "value": "2"
|
|
4753
|
+
// }
|
|
4754
|
+
// ]
|
|
4755
|
+
// },
|
|
4756
|
+
// {
|
|
4757
|
+
// "id": "(number)",
|
|
4758
|
+
// "value": "4"
|
|
4759
|
+
// }
|
|
4760
|
+
// ]
|
|
4761
|
+
// }
|
|
4762
|
+
// ]
|
|
4763
|
+
// },
|
|
4764
|
+
// {
|
|
4765
|
+
// "id": "(number)",
|
|
4766
|
+
// "value": "5"
|
|
4767
|
+
// }
|
|
4768
|
+
// ]
|
|
4769
|
+
// }
|
|
4389
4770
|
|
|
4390
4771
|
let left;
|
|
4391
4772
|
let the_symbol;
|
|
@@ -4397,13 +4778,13 @@ function jslint_phase3_parse(state) {
|
|
|
4397
4778
|
advance();
|
|
4398
4779
|
}
|
|
4399
4780
|
the_symbol = syntax_dict[token_now.id];
|
|
4400
|
-
if (the_symbol !== undefined && the_symbol.
|
|
4781
|
+
if (the_symbol !== undefined && the_symbol.nud_prefix !== undefined) {
|
|
4401
4782
|
|
|
4402
4783
|
// test_cause:
|
|
4403
4784
|
// ["0", "parse_expression", "symbol", "", 0]
|
|
4404
4785
|
|
|
4405
4786
|
test_cause("symbol");
|
|
4406
|
-
left = the_symbol.
|
|
4787
|
+
left = the_symbol.nud_prefix();
|
|
4407
4788
|
} else if (token_now.identifier) {
|
|
4408
4789
|
|
|
4409
4790
|
// test_cause:
|
|
@@ -4428,32 +4809,38 @@ function jslint_phase3_parse(state) {
|
|
|
4428
4809
|
the_symbol = syntax_dict[token_nxt.id];
|
|
4429
4810
|
if (
|
|
4430
4811
|
the_symbol === undefined
|
|
4431
|
-
|| the_symbol.
|
|
4812
|
+
|| the_symbol.led_infix === undefined
|
|
4432
4813
|
|| the_symbol.lbp <= rbp
|
|
4433
4814
|
) {
|
|
4434
4815
|
break;
|
|
4435
4816
|
}
|
|
4436
4817
|
advance();
|
|
4437
|
-
left = the_symbol.
|
|
4818
|
+
left = the_symbol.led_infix(left);
|
|
4438
4819
|
}
|
|
4439
4820
|
return left;
|
|
4440
4821
|
}
|
|
4441
4822
|
|
|
4442
|
-
function parse_fart(
|
|
4823
|
+
function parse_fart() {
|
|
4824
|
+
let parameters;
|
|
4825
|
+
let signature;
|
|
4443
4826
|
let the_fart;
|
|
4827
|
+
[parameters, signature] = prefix_function_arg();
|
|
4444
4828
|
advance("=>");
|
|
4445
4829
|
the_fart = token_now;
|
|
4446
4830
|
the_fart.arity = "binary";
|
|
4447
4831
|
the_fart.name = "=>";
|
|
4448
4832
|
the_fart.level = functionage.level + 1;
|
|
4449
4833
|
function_list.push(the_fart);
|
|
4450
|
-
if (functionage.loop > 0) {
|
|
4451
4834
|
|
|
4452
|
-
//
|
|
4453
|
-
//
|
|
4835
|
+
// PR-384 - Relax warning "function_in_loop".
|
|
4836
|
+
//
|
|
4837
|
+
// if (functionage.loop > 0) {
|
|
4454
4838
|
|
|
4455
|
-
|
|
4456
|
-
|
|
4839
|
+
// // test_cause:
|
|
4840
|
+
// // ["while(0){aa.map(()=>0);}", "parse_fart", "function_in_loop", "=>", 19]
|
|
4841
|
+
//
|
|
4842
|
+
// warn("function_in_loop", the_fart);
|
|
4843
|
+
// }
|
|
4457
4844
|
|
|
4458
4845
|
// Give the function properties storing its names and for observing the depth
|
|
4459
4846
|
// of loops and switches.
|
|
@@ -4461,6 +4848,8 @@ function jslint_phase3_parse(state) {
|
|
|
4461
4848
|
the_fart.context = empty();
|
|
4462
4849
|
the_fart.finally = 0;
|
|
4463
4850
|
the_fart.loop = 0;
|
|
4851
|
+
the_fart.parameters = parameters;
|
|
4852
|
+
the_fart.signature = signature;
|
|
4464
4853
|
the_fart.switch = 0;
|
|
4465
4854
|
the_fart.try = 0;
|
|
4466
4855
|
|
|
@@ -4468,23 +4857,42 @@ function jslint_phase3_parse(state) {
|
|
|
4468
4857
|
|
|
4469
4858
|
function_stack.push(functionage);
|
|
4470
4859
|
functionage = the_fart;
|
|
4471
|
-
the_fart.parameters
|
|
4472
|
-
|
|
4473
|
-
|
|
4860
|
+
the_fart.parameters.forEach(function enroll_parameter(name) {
|
|
4861
|
+
if (name.identifier) {
|
|
4862
|
+
enroll(name, "parameter", true);
|
|
4863
|
+
} else {
|
|
4864
|
+
|
|
4865
|
+
// PR-385 - Bugfix - Fixes issue #382 - fix warnings against destructured fart.
|
|
4474
4866
|
|
|
4475
4867
|
// test_cause:
|
|
4476
|
-
// ["(aa)=>
|
|
4868
|
+
// ["([aa])=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
|
|
4869
|
+
// ["({aa})=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
|
|
4477
4870
|
|
|
4478
|
-
|
|
4479
|
-
|
|
4871
|
+
warn("use_function_not_fart", the_fart);
|
|
4872
|
+
|
|
4873
|
+
// Recurse enroll_parameter().
|
|
4874
|
+
|
|
4875
|
+
name.names.forEach(enroll_parameter);
|
|
4876
|
+
}
|
|
4480
4877
|
});
|
|
4481
4878
|
if (token_nxt.id === "{") {
|
|
4482
4879
|
|
|
4483
4880
|
// test_cause:
|
|
4484
|
-
// ["()=>{}", "parse_fart", "
|
|
4881
|
+
// ["()=>{}", "parse_fart", "use_function_not_fart", "=>", 3]
|
|
4485
4882
|
|
|
4486
|
-
warn("
|
|
4883
|
+
warn("use_function_not_fart", the_fart);
|
|
4487
4884
|
the_fart.block = block("body");
|
|
4885
|
+
} else if (
|
|
4886
|
+
syntax_dict[token_nxt.id] !== undefined
|
|
4887
|
+
&& syntax_dict[token_nxt.id].fud_stmt !== undefined
|
|
4888
|
+
) {
|
|
4889
|
+
|
|
4890
|
+
// PR-384 - Bugfix - Fixes issue #379 - warn against naked-statement in fart.
|
|
4891
|
+
|
|
4892
|
+
// test_cause:
|
|
4893
|
+
// ["()=>delete aa", "parse_fart", "unexpected_a_after_b", "=>", 5]
|
|
4894
|
+
|
|
4895
|
+
stop("unexpected_a_after_b", token_nxt, token_nxt.id, "=>");
|
|
4488
4896
|
} else {
|
|
4489
4897
|
the_fart.expression = parse_expression(0);
|
|
4490
4898
|
}
|
|
@@ -4499,13 +4907,7 @@ function jslint_phase3_parse(state) {
|
|
|
4499
4907
|
let negative;
|
|
4500
4908
|
switch (token_nxt.id) {
|
|
4501
4909
|
case "(number)":
|
|
4502
|
-
if (!(
|
|
4503
|
-
|
|
4504
|
-
// https://datatracker.ietf.org/doc/html/rfc7159#section-6
|
|
4505
|
-
// number = [ minus ] int [ frac ] [ exp ]
|
|
4506
|
-
|
|
4507
|
-
/^-?(?:0|[1-9]\d*?)(?:\.\d*?)?(?:[eE][+\-]?\d+?)?$/
|
|
4508
|
-
).test(token_nxt.value)) {
|
|
4910
|
+
if (!jslint_rgx_json_number.test(token_nxt.value)) {
|
|
4509
4911
|
|
|
4510
4912
|
// test_cause:
|
|
4511
4913
|
// ["[-.0]", "parse_json", "unexpected_a", ".", 3]
|
|
@@ -4707,7 +5109,7 @@ function jslint_phase3_parse(state) {
|
|
|
4707
5109
|
the_symbol = syntax_dict[first.id];
|
|
4708
5110
|
if (
|
|
4709
5111
|
the_symbol !== undefined
|
|
4710
|
-
&& the_symbol.
|
|
5112
|
+
&& the_symbol.fud_stmt !== undefined
|
|
4711
5113
|
|
|
4712
5114
|
// PR-318 - Bugfix - Fixes issues #316, #317 - dynamic-import().
|
|
4713
5115
|
|
|
@@ -4716,7 +5118,7 @@ function jslint_phase3_parse(state) {
|
|
|
4716
5118
|
the_symbol.disrupt = false;
|
|
4717
5119
|
the_symbol.statement = true;
|
|
4718
5120
|
token_now.arity = "statement";
|
|
4719
|
-
the_statement = the_symbol.
|
|
5121
|
+
the_statement = the_symbol.fud_stmt();
|
|
4720
5122
|
functionage.statement_prv = the_statement;
|
|
4721
5123
|
} else {
|
|
4722
5124
|
|
|
@@ -4786,7 +5188,7 @@ function jslint_phase3_parse(state) {
|
|
|
4786
5188
|
// Create one of the postassign operators.
|
|
4787
5189
|
|
|
4788
5190
|
const the_symbol = symbol(id, 150);
|
|
4789
|
-
the_symbol.
|
|
5191
|
+
the_symbol.led_infix = function (left) {
|
|
4790
5192
|
token_now.expression = left;
|
|
4791
5193
|
token_now.arity = "postassign";
|
|
4792
5194
|
check_mutation(token_now.expression);
|
|
@@ -4800,7 +5202,7 @@ function jslint_phase3_parse(state) {
|
|
|
4800
5202
|
// Create one of the preassign operators.
|
|
4801
5203
|
|
|
4802
5204
|
const the_symbol = symbol(id);
|
|
4803
|
-
the_symbol.
|
|
5205
|
+
the_symbol.nud_prefix = function () {
|
|
4804
5206
|
const the_token = token_now;
|
|
4805
5207
|
the_token.arity = "preassign";
|
|
4806
5208
|
the_token.expression = parse_expression(150);
|
|
@@ -4815,7 +5217,7 @@ function jslint_phase3_parse(state) {
|
|
|
4815
5217
|
// Create a prefix operator.
|
|
4816
5218
|
|
|
4817
5219
|
const the_symbol = symbol(id);
|
|
4818
|
-
the_symbol.
|
|
5220
|
+
the_symbol.nud_prefix = function () {
|
|
4819
5221
|
const the_token = token_now;
|
|
4820
5222
|
the_token.arity = "unary";
|
|
4821
5223
|
if (typeof f === "function") {
|
|
@@ -4997,6 +5399,9 @@ function jslint_phase3_parse(state) {
|
|
|
4997
5399
|
if (name.identifier) {
|
|
4998
5400
|
enroll(name, "parameter", false);
|
|
4999
5401
|
} else {
|
|
5402
|
+
|
|
5403
|
+
// Recurse enroll_parameter().
|
|
5404
|
+
|
|
5000
5405
|
name.names.forEach(enroll_parameter);
|
|
5001
5406
|
}
|
|
5002
5407
|
});
|
|
@@ -5457,25 +5862,14 @@ function jslint_phase3_parse(state) {
|
|
|
5457
5862
|
}
|
|
5458
5863
|
|
|
5459
5864
|
function prefix_lparen() {
|
|
5460
|
-
|
|
5461
|
-
const the_paren = token_now;
|
|
5865
|
+
let the_paren = token_now;
|
|
5462
5866
|
let the_value;
|
|
5463
5867
|
|
|
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]
|
|
5868
|
+
// PR-385 - Bugfix - Fixes issue #382 - failure to detect destructured fart.
|
|
5475
5869
|
|
|
5476
|
-
|
|
5870
|
+
if (token_now.is_fart) {
|
|
5477
5871
|
the_paren.free = false;
|
|
5478
|
-
return parse_fart(
|
|
5872
|
+
return parse_fart();
|
|
5479
5873
|
}
|
|
5480
5874
|
|
|
5481
5875
|
// test_cause:
|
|
@@ -5493,31 +5887,6 @@ function jslint_phase3_parse(state) {
|
|
|
5493
5887
|
}
|
|
5494
5888
|
the_value.wrapped = true;
|
|
5495
5889
|
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
5890
|
return the_value;
|
|
5522
5891
|
}
|
|
5523
5892
|
|
|
@@ -5598,12 +5967,12 @@ function jslint_phase3_parse(state) {
|
|
|
5598
5967
|
anon = "anonymous";
|
|
5599
5968
|
}
|
|
5600
5969
|
|
|
5601
|
-
function stmt(id,
|
|
5970
|
+
function stmt(id, fud_stmt) {
|
|
5602
5971
|
|
|
5603
5972
|
// Create a statement.
|
|
5604
5973
|
|
|
5605
5974
|
const the_symbol = symbol(id);
|
|
5606
|
-
the_symbol.
|
|
5975
|
+
the_symbol.fud_stmt = fud_stmt;
|
|
5607
5976
|
return the_symbol;
|
|
5608
5977
|
}
|
|
5609
5978
|
|
|
@@ -6038,10 +6407,7 @@ function jslint_phase3_parse(state) {
|
|
|
6038
6407
|
advance("from");
|
|
6039
6408
|
advance("(string)");
|
|
6040
6409
|
the_import.import = token_now;
|
|
6041
|
-
if (!(
|
|
6042
|
-
// rx_module
|
|
6043
|
-
/^[a-zA-Z0-9_$:.@\-\/]+$/
|
|
6044
|
-
).test(token_now.value)) {
|
|
6410
|
+
if (!jslint_rgx_module.test(token_now.value)) {
|
|
6045
6411
|
|
|
6046
6412
|
// test_cause:
|
|
6047
6413
|
// ["import aa from \"!aa\"", "stmt_import", "bad_module_name_a", "!aa", 16]
|
|
@@ -6652,13 +7018,13 @@ function jslint_phase3_parse(state) {
|
|
|
6652
7018
|
|
|
6653
7019
|
if (id === "(string)") {
|
|
6654
7020
|
id = name.value;
|
|
6655
|
-
if (!
|
|
7021
|
+
if (!jslint_rgx_identifier.test(id)) {
|
|
6656
7022
|
return id;
|
|
6657
7023
|
}
|
|
6658
7024
|
} else if (id === "`") {
|
|
6659
7025
|
if (name.value.length === 1) {
|
|
6660
7026
|
id = name.value[0].value;
|
|
6661
|
-
if (!
|
|
7027
|
+
if (!jslint_rgx_identifier.test(id)) {
|
|
6662
7028
|
return id;
|
|
6663
7029
|
}
|
|
6664
7030
|
}
|
|
@@ -6691,10 +7057,7 @@ function jslint_phase3_parse(state) {
|
|
|
6691
7057
|
} else if (
|
|
6692
7058
|
!option_dict.name
|
|
6693
7059
|
&& name.identifier
|
|
6694
|
-
&& (
|
|
6695
|
-
// rx_weird_property
|
|
6696
|
-
/^_|\$|Sync$|_$/m
|
|
6697
|
-
).test(id)
|
|
7060
|
+
&& jslint_rgx_weird_property.test(id)
|
|
6698
7061
|
) {
|
|
6699
7062
|
|
|
6700
7063
|
// test_cause:
|
|
@@ -6732,7 +7095,7 @@ function jslint_phase3_parse(state) {
|
|
|
6732
7095
|
// Create a ternary operator.
|
|
6733
7096
|
|
|
6734
7097
|
const the_symbol = symbol(id1, 30);
|
|
6735
|
-
the_symbol.
|
|
7098
|
+
the_symbol.led_infix = function parse_ternary_led(left) {
|
|
6736
7099
|
const the_token = token_now;
|
|
6737
7100
|
let second;
|
|
6738
7101
|
second = parse_expression(20);
|
|
@@ -7448,10 +7811,7 @@ function jslint_phase4_walk(state) {
|
|
|
7448
7811
|
test_cause("cack");
|
|
7449
7812
|
cack = !cack;
|
|
7450
7813
|
}
|
|
7451
|
-
if ((
|
|
7452
|
-
// rx_cap
|
|
7453
|
-
/^[A-Z]/
|
|
7454
|
-
).test(left.name.id) !== cack) {
|
|
7814
|
+
if (jslint_rgx_cap.test(left.name.id) !== cack) {
|
|
7455
7815
|
if (the_new !== undefined) {
|
|
7456
7816
|
|
|
7457
7817
|
// test_cause:
|
|
@@ -7628,6 +7988,11 @@ function jslint_phase4_walk(state) {
|
|
|
7628
7988
|
|| thing.expression[0].constant === true
|
|
7629
7989
|
|| is_equal(thing.expression[1], thing.expression[2])
|
|
7630
7990
|
) {
|
|
7991
|
+
|
|
7992
|
+
// test_cause:
|
|
7993
|
+
// ["let aa=(aa?`${0}`:`${0}`);", "post_t", "unexpected_a", "?", 11]
|
|
7994
|
+
// ["let aa=(aa?`0`:`0`);", "post_t", "unexpected_a", "?", 11]
|
|
7995
|
+
|
|
7631
7996
|
warn("unexpected_a", thing);
|
|
7632
7997
|
} else if (is_equal(thing.expression[0], thing.expression[1])) {
|
|
7633
7998
|
|
|
@@ -8847,6 +9212,7 @@ function jslint_report({
|
|
|
8847
9212
|
|
|
8848
9213
|
// This function will create human-readable, html-report
|
|
8849
9214
|
// for warnings, properties, and functions from jslint-result-object.
|
|
9215
|
+
//
|
|
8850
9216
|
// Example usage:
|
|
8851
9217
|
// let result = jslint("console.log('hello world')");
|
|
8852
9218
|
// let html = jslint_report(result);
|
|
@@ -8879,7 +9245,6 @@ function jslint_report({
|
|
|
8879
9245
|
);
|
|
8880
9246
|
}
|
|
8881
9247
|
|
|
8882
|
-
html += "<div class=\"JSLINT_\" id=\"JSLINT_REPORT_HTML\">\n";
|
|
8883
9248
|
html += String(`
|
|
8884
9249
|
<style class="JSLINT_REPORT_STYLE">
|
|
8885
9250
|
/* jslint utility2:true */
|
|
@@ -9028,19 +9393,38 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
|
|
|
9028
9393
|
/7xoEqvL+2E8VOyCTuT/7j269Zy4jUtN+g4="
|
|
9029
9394
|
) format("woff2");
|
|
9030
9395
|
}
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9396
|
+
.JSLINT_,
|
|
9397
|
+
.JSLINT_ address,
|
|
9398
|
+
.JSLINT_ button,
|
|
9399
|
+
.JSLINT_ cite,
|
|
9400
|
+
.JSLINT_ dd,
|
|
9401
|
+
.JSLINT_ dfn,
|
|
9402
|
+
.JSLINT_ dl,
|
|
9403
|
+
.JSLINT_ dt,
|
|
9404
|
+
.JSLINT_ fieldset,
|
|
9405
|
+
.JSLINT_ fieldset > div,
|
|
9406
|
+
.JSLINT_ input,
|
|
9407
|
+
.JSLINT_ label,
|
|
9408
|
+
.JSLINT_ legend,
|
|
9409
|
+
.JSLINT_ ol,
|
|
9410
|
+
.JSLINT_ samp,
|
|
9411
|
+
.JSLINT_ style,
|
|
9412
|
+
.JSLINT_ textarea,
|
|
9413
|
+
.JSLINT_ ul {
|
|
9034
9414
|
border: 0;
|
|
9035
9415
|
box-sizing: border-box;
|
|
9036
9416
|
margin: 0;
|
|
9037
9417
|
padding: 0;
|
|
9038
9418
|
}
|
|
9419
|
+
/* disable text inflation algorithm used on some smartphones and tablets */
|
|
9039
9420
|
.JSLINT_ {
|
|
9040
9421
|
-ms-text-size-adjust: none;
|
|
9041
9422
|
-webkit-text-size-adjust: none;
|
|
9042
9423
|
text-size-adjust: none;
|
|
9043
9424
|
}
|
|
9425
|
+
.JSLINT_REPORT_ div {
|
|
9426
|
+
box-sizing: border-box;
|
|
9427
|
+
}
|
|
9044
9428
|
/*csslint ignore:end*/
|
|
9045
9429
|
|
|
9046
9430
|
/* css - jslint_report - font */
|
|
@@ -9074,7 +9458,7 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
|
|
|
9074
9458
|
}
|
|
9075
9459
|
|
|
9076
9460
|
/* css - jslint_report - general */
|
|
9077
|
-
|
|
9461
|
+
.JSLINT_ {
|
|
9078
9462
|
background: antiquewhite;
|
|
9079
9463
|
}
|
|
9080
9464
|
.JSLINT_ fieldset {
|
|
@@ -9320,6 +9704,9 @@ body {
|
|
|
9320
9704
|
: "global"
|
|
9321
9705
|
);
|
|
9322
9706
|
if (global.length + froms.length + exports.length > 0) {
|
|
9707
|
+
if (functions.length === 0) {
|
|
9708
|
+
html += "<br>\n";
|
|
9709
|
+
}
|
|
9323
9710
|
html += "<div class=\"level level0\">\n";
|
|
9324
9711
|
html += detail(module, global);
|
|
9325
9712
|
html += detail("import from", froms);
|
|
@@ -9408,7 +9795,6 @@ body {
|
|
|
9408
9795
|
});
|
|
9409
9796
|
html += "</div>\n";
|
|
9410
9797
|
html += "</fieldset>\n";
|
|
9411
|
-
html += "</div>\n";
|
|
9412
9798
|
return html;
|
|
9413
9799
|
}
|
|
9414
9800
|
|
|
@@ -9484,14 +9870,14 @@ function jstestIt(description, testFunction, mode) {
|
|
|
9484
9870
|
}));
|
|
9485
9871
|
}
|
|
9486
9872
|
|
|
9487
|
-
function jstestOnExit(exitCode,
|
|
9873
|
+
function jstestOnExit(exitCode, mode) {
|
|
9488
9874
|
|
|
9489
9875
|
// This function will on process-exit, print test-report
|
|
9490
9876
|
// and exit with non-zero exit-code if any test failed.
|
|
9491
9877
|
|
|
9492
9878
|
let message = (
|
|
9493
9879
|
(
|
|
9494
|
-
(jstestCountFailed ||
|
|
9880
|
+
(jstestCountFailed || mode === "testsFailed")
|
|
9495
9881
|
? "\n\u001b[31m"
|
|
9496
9882
|
: "\n\u001b[32m"
|
|
9497
9883
|
)
|
|
@@ -9499,11 +9885,10 @@ function jstestOnExit(exitCode, processExit, countFailed) {
|
|
|
9499
9885
|
+ " tests failed - " + jstestCountFailed + "\n"
|
|
9500
9886
|
+ "\u001b[39m"
|
|
9501
9887
|
);
|
|
9502
|
-
if (
|
|
9888
|
+
if (mode !== "testsFailed") {
|
|
9503
9889
|
console.error(message);
|
|
9504
|
-
processExit = process.exit;
|
|
9505
9890
|
}
|
|
9506
|
-
|
|
9891
|
+
process.exitCode = exitCode || jstestCountFailed;
|
|
9507
9892
|
return message;
|
|
9508
9893
|
}
|
|
9509
9894
|
|
|
@@ -9569,7 +9954,7 @@ function objectDeepCopyWithKeysSorted(obj) {
|
|
|
9569
9954
|
|
|
9570
9955
|
// Recursively deep-copy obj with keys sorted.
|
|
9571
9956
|
|
|
9572
|
-
sorted =
|
|
9957
|
+
sorted = Object.create(null);
|
|
9573
9958
|
Object.keys(obj).sort().forEach(function (key) {
|
|
9574
9959
|
sorted[key] = objectDeepCopyWithKeysSorted(obj[key]);
|
|
9575
9960
|
});
|
|
@@ -10225,11 +10610,11 @@ async function v8CoverageReportCreate({
|
|
|
10225
10610
|
// 3. Create html-coverage-reports in <coverageDir>.
|
|
10226
10611
|
|
|
10227
10612
|
let cwd;
|
|
10613
|
+
let excludeList = [];
|
|
10228
10614
|
let exitCode = 0;
|
|
10229
10615
|
let fileDict;
|
|
10230
|
-
let
|
|
10231
|
-
let
|
|
10232
|
-
let fileIncludeNodeModules;
|
|
10616
|
+
let includeList = [];
|
|
10617
|
+
let modeIncludeNodeModules;
|
|
10233
10618
|
let processArgElem;
|
|
10234
10619
|
let promiseList = [];
|
|
10235
10620
|
let v8CoverageObj;
|
|
@@ -10254,9 +10639,19 @@ async function v8CoverageReportCreate({
|
|
|
10254
10639
|
<style>
|
|
10255
10640
|
/* jslint utility2:true */
|
|
10256
10641
|
/*csslint ignore:start*/
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10642
|
+
.coverage,
|
|
10643
|
+
.coverage a,
|
|
10644
|
+
.coverage div,
|
|
10645
|
+
.coverage pre,
|
|
10646
|
+
.coverage span,
|
|
10647
|
+
.coverage table,
|
|
10648
|
+
.coverage tbody,
|
|
10649
|
+
.coverage td,
|
|
10650
|
+
.coverage th,
|
|
10651
|
+
.coverage thead,
|
|
10652
|
+
.coverage tr {
|
|
10653
|
+
box-sizing: border-box;
|
|
10654
|
+
font-family: monospace;
|
|
10260
10655
|
}
|
|
10261
10656
|
/*csslint ignore:end*/
|
|
10262
10657
|
|
|
@@ -10402,6 +10797,7 @@ body {
|
|
|
10402
10797
|
}
|
|
10403
10798
|
txtBorder = (
|
|
10404
10799
|
"+" + "-".repeat(padPathname + 2) + "+"
|
|
10800
|
+
+ "-".repeat(padLines + 2) + "+"
|
|
10405
10801
|
+ "-".repeat(padLines + 2) + "+\n"
|
|
10406
10802
|
);
|
|
10407
10803
|
txt = "";
|
|
@@ -10409,7 +10805,8 @@ body {
|
|
|
10409
10805
|
txt += txtBorder;
|
|
10410
10806
|
txt += (
|
|
10411
10807
|
"| " + String("Files covered").padEnd(padPathname, " ") + " | "
|
|
10412
|
-
+ String("Lines").padStart(padLines, " ") + "
|
|
10808
|
+
+ String("Lines").padStart(padLines, " ") + " | "
|
|
10809
|
+
+ String("Remaining").padStart(padLines, " ") + " |\n"
|
|
10413
10810
|
);
|
|
10414
10811
|
txt += txtBorder;
|
|
10415
10812
|
fileList.forEach(function ({
|
|
@@ -10489,7 +10886,8 @@ body {
|
|
|
10489
10886
|
+ String("./" + pathname).padEnd(padPathname, " ") + " | "
|
|
10490
10887
|
+ String(
|
|
10491
10888
|
modeCoverageIgnoreFile + " " + coveragePct + " %"
|
|
10492
|
-
).padStart(padLines, " ") + "
|
|
10889
|
+
).padStart(padLines, " ") + " | "
|
|
10890
|
+
+ " ".repeat(padLines) + " |\n"
|
|
10493
10891
|
);
|
|
10494
10892
|
txt += (
|
|
10495
10893
|
"| " + "*".repeat(
|
|
@@ -10497,6 +10895,9 @@ body {
|
|
|
10497
10895
|
).padEnd(padPathname, "_") + " | "
|
|
10498
10896
|
+ String(
|
|
10499
10897
|
linesCovered + " / " + linesTotal
|
|
10898
|
+
).padStart(padLines, " ") + " | "
|
|
10899
|
+
+ String(
|
|
10900
|
+
(linesTotal - linesCovered) + " / " + linesTotal
|
|
10500
10901
|
).padStart(padLines, " ") + " |\n"
|
|
10501
10902
|
);
|
|
10502
10903
|
txt += txtBorder;
|
|
@@ -10660,21 +11061,6 @@ ${String(count || "-0").padStart(7, " ")}
|
|
|
10660
11061
|
), txt));
|
|
10661
11062
|
}
|
|
10662
11063
|
|
|
10663
|
-
function pathnameRelativeCwd(pathname) {
|
|
10664
|
-
|
|
10665
|
-
// This function will if <pathname> is inside <cwd>,
|
|
10666
|
-
// return it relative to <cwd>, else empty-string.
|
|
10667
|
-
|
|
10668
|
-
pathname = modulePath.resolve(pathname).replace((
|
|
10669
|
-
/\\/g
|
|
10670
|
-
), "/");
|
|
10671
|
-
if (!pathname.startsWith(cwd)) {
|
|
10672
|
-
return;
|
|
10673
|
-
}
|
|
10674
|
-
pathname = pathname.slice(cwd.length);
|
|
10675
|
-
return pathname;
|
|
10676
|
-
}
|
|
10677
|
-
|
|
10678
11064
|
/*
|
|
10679
11065
|
function sentinel() {}
|
|
10680
11066
|
*/
|
|
@@ -10706,28 +11092,28 @@ function sentinel() {}
|
|
|
10706
11092
|
processArgElem[1] = processArgElem.slice(1).join("=");
|
|
10707
11093
|
switch (processArgElem[0]) {
|
|
10708
11094
|
|
|
10709
|
-
// PR-371
|
|
11095
|
+
// PR-371
|
|
11096
|
+
// Add cli-option `--exclude=...`.
|
|
10710
11097
|
|
|
10711
11098
|
case "--exclude":
|
|
10712
|
-
|
|
10713
|
-
processArgElem[1].split(",")
|
|
10714
|
-
);
|
|
11099
|
+
excludeList.push(processArgElem[1]);
|
|
10715
11100
|
break;
|
|
10716
11101
|
|
|
10717
|
-
// PR-371
|
|
11102
|
+
// PR-371
|
|
11103
|
+
// Add cli-option `--include=...`
|
|
10718
11104
|
|
|
10719
|
-
case "--
|
|
10720
|
-
|
|
10721
|
-
/0|false|null|undefined/
|
|
10722
|
-
).test(processArgElem[1]);
|
|
11105
|
+
case "--include":
|
|
11106
|
+
includeList.push(processArgElem[1]);
|
|
10723
11107
|
break;
|
|
10724
11108
|
|
|
10725
|
-
// PR-
|
|
11109
|
+
// PR-400
|
|
11110
|
+
// Disable default-coverage of directory `node_modules`,
|
|
11111
|
+
// but allow override with cli-option `--include-node-modules=1`.
|
|
10726
11112
|
|
|
10727
|
-
case "--include":
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
);
|
|
11113
|
+
case "--include-node-modules":
|
|
11114
|
+
modeIncludeNodeModules = !(
|
|
11115
|
+
/0|false|null|undefined/
|
|
11116
|
+
).test(processArgElem[1]);
|
|
10731
11117
|
break;
|
|
10732
11118
|
}
|
|
10733
11119
|
}
|
|
@@ -10781,9 +11167,11 @@ function sentinel() {}
|
|
|
10781
11167
|
).test(file);
|
|
10782
11168
|
});
|
|
10783
11169
|
v8CoverageObj = await Promise.all(v8CoverageObj.map(async function (file) {
|
|
10784
|
-
let data
|
|
11170
|
+
let data;
|
|
11171
|
+
let pathnameDict = Object.create(null);
|
|
11172
|
+
data = await moduleFs.promises.readFile(coverageDir + file, "utf8");
|
|
10785
11173
|
data = JSON.parse(data);
|
|
10786
|
-
data.result
|
|
11174
|
+
data.result.forEach(function (scriptCov) {
|
|
10787
11175
|
let pathname = scriptCov.url;
|
|
10788
11176
|
|
|
10789
11177
|
// Filter out internal coverages.
|
|
@@ -10794,38 +11182,40 @@ function sentinel() {}
|
|
|
10794
11182
|
|
|
10795
11183
|
// Normalize pathname.
|
|
10796
11184
|
|
|
10797
|
-
pathname =
|
|
10798
|
-
|
|
11185
|
+
pathname = moduleUrl.fileURLToPath(pathname);
|
|
11186
|
+
pathname = modulePath.resolve(pathname).replace((
|
|
11187
|
+
/\\/g
|
|
11188
|
+
), "/");
|
|
10799
11189
|
|
|
10800
11190
|
// Filter files outside of cwd.
|
|
10801
11191
|
|
|
10802
|
-
|
|
10803
|
-
|
|
11192
|
+
if (pathname.indexOf("[") >= 0 || !pathname.startsWith(cwd)) {
|
|
11193
|
+
return;
|
|
11194
|
+
}
|
|
10804
11195
|
|
|
10805
|
-
//
|
|
11196
|
+
// Normalize pathname relative to cwd.
|
|
10806
11197
|
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
).test(pathname)
|
|
10812
|
-
)
|
|
11198
|
+
pathname = pathname.slice(cwd.length);
|
|
11199
|
+
scriptCov.url = pathname;
|
|
11200
|
+
pathnameDict[pathname] = scriptCov;
|
|
11201
|
+
});
|
|
10813
11202
|
|
|
10814
|
-
// PR-
|
|
11203
|
+
// PR-400
|
|
11204
|
+
// Filter directory `node_modules`.
|
|
10815
11205
|
|
|
10816
|
-
|
|
11206
|
+
if (!modeIncludeNodeModules) {
|
|
11207
|
+
excludeList.push("node_modules/");
|
|
11208
|
+
}
|
|
10817
11209
|
|
|
10818
|
-
// PR-
|
|
11210
|
+
// PR-400
|
|
11211
|
+
// Filter files by glob-patterns in excludeList, includeList.
|
|
10819
11212
|
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
|
|
10824
|
-
|
|
10825
|
-
|
|
10826
|
-
}
|
|
10827
|
-
scriptCov.url = pathname;
|
|
10828
|
-
return true;
|
|
11213
|
+
data.result = globExclude({
|
|
11214
|
+
excludeList,
|
|
11215
|
+
includeList,
|
|
11216
|
+
pathnameList: Object.keys(pathnameDict)
|
|
11217
|
+
}).pathnameList.map(function (pathname) {
|
|
11218
|
+
return pathnameDict[pathname];
|
|
10829
11219
|
});
|
|
10830
11220
|
return data;
|
|
10831
11221
|
}));
|
|
@@ -10834,7 +11224,7 @@ function sentinel() {}
|
|
|
10834
11224
|
|
|
10835
11225
|
v8CoverageObj = v8CoverageListMerge(v8CoverageObj);
|
|
10836
11226
|
|
|
10837
|
-
//
|
|
11227
|
+
// Debug v8CoverageObj.
|
|
10838
11228
|
|
|
10839
11229
|
await fsWriteFileWithParents(
|
|
10840
11230
|
coverageDir + "v8_coverage_merged.json",
|
|
@@ -10843,7 +11233,7 @@ function sentinel() {}
|
|
|
10843
11233
|
|
|
10844
11234
|
// 3. Create html-coverage-reports in <coverageDir>.
|
|
10845
11235
|
|
|
10846
|
-
fileDict =
|
|
11236
|
+
fileDict = Object.create(null);
|
|
10847
11237
|
await Promise.all(v8CoverageObj.result.map(async function ({
|
|
10848
11238
|
functions,
|
|
10849
11239
|
url: pathname
|
|
@@ -10974,6 +11364,7 @@ jslint_export = Object.freeze(Object.assign(jslint, {
|
|
|
10974
11364
|
assertOrThrow,
|
|
10975
11365
|
debugInline,
|
|
10976
11366
|
fsWriteFileWithParents,
|
|
11367
|
+
globExclude,
|
|
10977
11368
|
htmlEscape,
|
|
10978
11369
|
jslint,
|
|
10979
11370
|
jslint_apidoc,
|