sqlmath 0.0.5 → 2022.4.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +1 -0
- package/CHANGELOG.md +29 -0
- package/README.md +3 -3
- package/_binary_sqlmath_napi8_darwin_x64.node +0 -0
- package/_binary_sqlmath_napi8_linux_x64.node +0 -0
- package/_binary_sqlmath_napi8_win32_x64.node +0 -0
- package/_binary_sqlmath_shell_darwin_x64 +0 -0
- package/_binary_sqlmath_shell_linux_x64 +0 -0
- package/_binary_sqlmath_shell_win32_x64.exe +0 -0
- package/jslint.mjs +451 -321
- package/package.json +5 -5
- package/sqlmath.mjs +193 -107
- package/sqlmath_custom.mjs +4 -0
package/jslint.mjs
CHANGED
|
@@ -94,48 +94,47 @@
|
|
|
94
94
|
/*jslint beta, node*/
|
|
95
95
|
|
|
96
96
|
/*property
|
|
97
|
-
mode_conditional,
|
|
98
97
|
JSLINT_BETA, NODE_V8_COVERAGE, a, all, argv, arity, artifact,
|
|
99
98
|
assertErrorThrownAsync, assertJsonEqual, assertOrThrow, assign, async, b,
|
|
100
99
|
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
|
-
|
|
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_list, directive_quiet, directives,
|
|
104
|
+
dirname, disrupt, dot, edition, elem_list, ellipsis, else, end, endOffset,
|
|
105
|
+
endsWith, entries, env, error, eval, every, example_list, exec, execArgv,
|
|
106
|
+
exit, exitCode, export_dict, exports, expression, extra, file, fileList,
|
|
107
|
+
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, global, global_dict, global_list, holeList, htmlEscape,
|
|
111
|
+
id, identifier, import, import_list, inc, indent2, index, indexOf, init,
|
|
112
|
+
initial, isArray, isBlockCoverage, isHole, isNaN, is_equal, is_fart,
|
|
113
|
+
is_weird, join, jslint, jslint_apidoc, jslint_assert, jslint_charset_ascii,
|
|
114
|
+
jslint_cli, jslint_edition, jslint_phase1_split, jslint_phase2_lex,
|
|
115
|
+
jslint_phase3_parse, jslint_phase4_walk, jslint_phase5_whitage,
|
|
116
|
+
jslint_report, json, jstestDescribe, jstestIt, jstestOnExit, keys, label,
|
|
117
|
+
lbp, led_infix, length, level, line, lineList, line_list, line_offset,
|
|
118
|
+
line_source, lines, linesCovered, linesTotal, live, log, long, loop, m, map,
|
|
119
|
+
margin, match, max, message, meta, min, mkdir, modeCoverageIgnoreFile,
|
|
120
|
+
modeIndex, mode_cli, mode_conditional, mode_json, mode_module, mode_noop,
|
|
121
|
+
mode_property, mode_shebang, mode_stop, module, moduleFsInit, moduleName,
|
|
122
|
+
module_list, name, names, node, noop, now, nr, nud_prefix,
|
|
123
|
+
objectDeepCopyWithKeysSorted, ok, on, open, opening, option, option_dict,
|
|
124
|
+
order, package_name, padEnd, padStart, parameters, parent, parentIi, parse,
|
|
125
|
+
pathname, platform, pop, processArgv, process_argv, process_env,
|
|
126
|
+
process_exit, promises, property, property_dict, push, quote, ranges,
|
|
127
|
+
readFile, readdir, readonly, recursive, reduce, repeat, replace, resolve,
|
|
128
|
+
result, reverse, role, round, scriptId, search, set, shebang, shift,
|
|
129
|
+
signature, single, slice, some, sort, source, spawn, splice, split, stack,
|
|
130
|
+
stack_trace, start, startOffset, startsWith, statement, statement_prv,
|
|
131
|
+
stdio, stop, stop_at, stringify, switch, syntax_dict, tenure, test,
|
|
132
|
+
test_cause, test_internal_error, this, thru, toString, token, token_global,
|
|
133
|
+
token_list, token_nxt, token_tree, tokens, trace, tree, trim, trimEnd,
|
|
134
|
+
trimRight, try, type, unlink, unordered, unshift, url, used,
|
|
135
|
+
v8CoverageListMerge, v8CoverageReportCreate, value, variable, version,
|
|
136
|
+
versions, warn, warn_at, warning, warning_list, warnings, white, wrapped,
|
|
137
|
+
writeFile
|
|
139
138
|
*/
|
|
140
139
|
|
|
141
140
|
// init debugInline
|
|
@@ -165,11 +164,96 @@ let jslint_charset_ascii = (
|
|
|
165
164
|
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
|
166
165
|
+ "`abcdefghijklmnopqrstuvwxyz{|}~\u007f"
|
|
167
166
|
);
|
|
168
|
-
let jslint_edition = "
|
|
167
|
+
let jslint_edition = "v2022.5.1-beta";
|
|
169
168
|
let jslint_export; // The jslint object to be exported.
|
|
170
169
|
let jslint_fudge = 1; // Fudge starting line and starting
|
|
171
170
|
// ... column to 1.
|
|
172
171
|
let jslint_import_meta_url = ""; // import.meta.url used by cli.
|
|
172
|
+
let jslint_rgx_cap = (
|
|
173
|
+
/^[A-Z]/
|
|
174
|
+
);
|
|
175
|
+
let jslint_rgx_crlf = (
|
|
176
|
+
/\n|\r\n?/
|
|
177
|
+
);
|
|
178
|
+
let jslint_rgx_digits_bits = (
|
|
179
|
+
/^[01_]*/
|
|
180
|
+
);
|
|
181
|
+
let jslint_rgx_digits_decimals = (
|
|
182
|
+
/^[0-9_]*/
|
|
183
|
+
);
|
|
184
|
+
let jslint_rgx_digits_hexs = (
|
|
185
|
+
/^[0-9A-F_]*/i
|
|
186
|
+
);
|
|
187
|
+
let jslint_rgx_digits_octals = (
|
|
188
|
+
/^[0-7_]*/
|
|
189
|
+
);
|
|
190
|
+
let jslint_rgx_directive = (
|
|
191
|
+
/^(jslint|property|global)\s+(.*)$/
|
|
192
|
+
);
|
|
193
|
+
let jslint_rgx_directive_part = (
|
|
194
|
+
/([a-zA-Z$_][a-zA-Z0-9$_]*)(?::\s*(true|false))?,?\s*|$/g
|
|
195
|
+
);
|
|
196
|
+
let jslint_rgx_identifier = (
|
|
197
|
+
/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/
|
|
198
|
+
);
|
|
199
|
+
let jslint_rgx_json_number = (
|
|
200
|
+
|
|
201
|
+
// https://datatracker.ietf.org/doc/html/rfc7159#section-6
|
|
202
|
+
// number = [ minus ] int [ frac ] [ exp ]
|
|
203
|
+
|
|
204
|
+
/^-?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][\-+]?\d+)?$/
|
|
205
|
+
);
|
|
206
|
+
let jslint_rgx_mega = (
|
|
207
|
+
|
|
208
|
+
// Vim-hack - vim-editor has trouble parsing naked '`' in regexp
|
|
209
|
+
|
|
210
|
+
/[\u0060\\]|\$\{/
|
|
211
|
+
);
|
|
212
|
+
let jslint_rgx_module = (
|
|
213
|
+
/^[a-zA-Z0-9_$:.@\-\/]+$/
|
|
214
|
+
);
|
|
215
|
+
let jslint_rgx_numeric_separator_illegal = (
|
|
216
|
+
/__|_$|_n$/m
|
|
217
|
+
);
|
|
218
|
+
let jslint_rgx_slash_star_or_slash = (
|
|
219
|
+
/\/\*|\/$/
|
|
220
|
+
);
|
|
221
|
+
let jslint_rgx_tab = (
|
|
222
|
+
/\t/g
|
|
223
|
+
);
|
|
224
|
+
let jslint_rgx_todo = (
|
|
225
|
+
/\b(?:todo|TO\s?DO|HACK)\b/
|
|
226
|
+
);
|
|
227
|
+
let jslint_rgx_token = new RegExp(
|
|
228
|
+
"^("
|
|
229
|
+
+ "(\\s+)"
|
|
230
|
+
+ "|([a-zA-Z_$][a-zA-Z0-9_$]*)"
|
|
231
|
+
+ "|[(){}\\[\\],:;'\"~\\`]"
|
|
232
|
+
+ "|\\?[?.]?"
|
|
233
|
+
+ "|=(?:==?|>)?"
|
|
234
|
+
+ "|\\.+"
|
|
235
|
+
+ "|\\*[*\\/=]?"
|
|
236
|
+
+ "|\\/[*\\/]?"
|
|
237
|
+
+ "|\\+[=+]?"
|
|
238
|
+
+ "|-[=\\-]?"
|
|
239
|
+
+ "|[\\^%]=?"
|
|
240
|
+
+ "|&[&=]?"
|
|
241
|
+
+ "|\\"
|
|
242
|
+
+ "|[|=]?"
|
|
243
|
+
+ "|>{1,3}=?"
|
|
244
|
+
+ "|<<?=?"
|
|
245
|
+
+ "|!(?:!|==?)?"
|
|
246
|
+
|
|
247
|
+
// PR-351 - Add BigInt support.
|
|
248
|
+
// PR-390 - Add numeric-separator support.
|
|
249
|
+
|
|
250
|
+
+ "|((?:0_?|[1-9][0-9_]*)n?)"
|
|
251
|
+
+ ")"
|
|
252
|
+
+ "(.*)$"
|
|
253
|
+
);
|
|
254
|
+
let jslint_rgx_weird_property = (
|
|
255
|
+
/^_|\$|Sync$|_$/m
|
|
256
|
+
);
|
|
173
257
|
let jstestCountFailed = 0;
|
|
174
258
|
let jstestCountTotal = 0;
|
|
175
259
|
let jstestItCount = 0;
|
|
@@ -202,11 +286,12 @@ function assertJsonEqual(aa, bb, message) {
|
|
|
202
286
|
|
|
203
287
|
// This function will assert JSON.stringify(<aa>) === JSON.stringify(<bb>).
|
|
204
288
|
|
|
205
|
-
aa = JSON.stringify(objectDeepCopyWithKeysSorted(aa));
|
|
206
|
-
bb = JSON.stringify(objectDeepCopyWithKeysSorted(bb));
|
|
289
|
+
aa = JSON.stringify(objectDeepCopyWithKeysSorted(aa), undefined, 1);
|
|
290
|
+
bb = JSON.stringify(objectDeepCopyWithKeysSorted(bb), undefined, 1);
|
|
207
291
|
if (aa !== bb) {
|
|
208
292
|
throw new Error(
|
|
209
|
-
|
|
293
|
+
"\n" + aa + "\n!==\n" + bb
|
|
294
|
+
+ (
|
|
210
295
|
typeof message === "string"
|
|
211
296
|
? " - " + message
|
|
212
297
|
: message
|
|
@@ -304,10 +389,7 @@ function jslint(
|
|
|
304
389
|
let import_list = []; // The array collecting all import-from strings.
|
|
305
390
|
let line_list = String( // The array containing source lines.
|
|
306
391
|
"\n" + source
|
|
307
|
-
).split(
|
|
308
|
-
// rx_crlf
|
|
309
|
-
/\n|\r\n?/
|
|
310
|
-
).map(function (line_source) {
|
|
392
|
+
).split(jslint_rgx_crlf).map(function (line_source) {
|
|
311
393
|
return {
|
|
312
394
|
line_source
|
|
313
395
|
};
|
|
@@ -352,8 +434,6 @@ function jslint(
|
|
|
352
434
|
}
|
|
353
435
|
|
|
354
436
|
function is_equal(aa, bb) {
|
|
355
|
-
let aa_value;
|
|
356
|
-
let bb_value;
|
|
357
437
|
|
|
358
438
|
// test_cause:
|
|
359
439
|
// ["0&&0", "is_equal", "", "", 0]
|
|
@@ -374,6 +454,7 @@ function jslint(
|
|
|
374
454
|
|
|
375
455
|
// test_cause:
|
|
376
456
|
// ["`${0}`&&`${0}`", "is_equal", "recurse_isArray", "", 0]
|
|
457
|
+
// ["`${0}`&&`${1}`", "is_equal", "recurse_isArray", "", 0]
|
|
377
458
|
|
|
378
459
|
test_cause("recurse_isArray");
|
|
379
460
|
return is_equal(value, bb[index]);
|
|
@@ -387,21 +468,19 @@ function jslint(
|
|
|
387
468
|
// }
|
|
388
469
|
|
|
389
470
|
jslint_assert(!Array.isArray(bb), `Expected !Array.isArray(bb).`);
|
|
390
|
-
|
|
471
|
+
switch (aa.id === bb.id && aa.id) {
|
|
472
|
+
case "(number)":
|
|
473
|
+
case "(string)":
|
|
391
474
|
return aa.value === bb.value;
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
bb_value = bb.value[0];
|
|
402
|
-
}
|
|
403
|
-
if (typeof aa_value === "string") {
|
|
404
|
-
return aa_value === bb_value;
|
|
475
|
+
|
|
476
|
+
// PR-394 - Bugfix
|
|
477
|
+
// Fix jslint falsely believing megastring literals `0` and `1` are similar.
|
|
478
|
+
|
|
479
|
+
case "`":
|
|
480
|
+
if (!is_equal(aa.value, bb.value)) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
break;
|
|
405
484
|
}
|
|
406
485
|
if (is_weird(aa) || is_weird(bb)) {
|
|
407
486
|
|
|
@@ -678,8 +757,17 @@ function jslint(
|
|
|
678
757
|
`Expected 'Object.freeze('. All export values should be frozen.`
|
|
679
758
|
);
|
|
680
759
|
break;
|
|
681
|
-
|
|
682
|
-
|
|
760
|
+
|
|
761
|
+
// PR-378 - Relax warning "function_in_loop".
|
|
762
|
+
//
|
|
763
|
+
// case "function_in_loop":
|
|
764
|
+
// mm = `Don't create functions within a loop.`;
|
|
765
|
+
// break;
|
|
766
|
+
|
|
767
|
+
// PR-390 - Add numeric-separator check.
|
|
768
|
+
|
|
769
|
+
case "illegal_num_separator":
|
|
770
|
+
mm = `Illegal numeric separator '_' at column ${column}.`;
|
|
683
771
|
break;
|
|
684
772
|
case "infix_in":
|
|
685
773
|
mm = (
|
|
@@ -833,6 +921,15 @@ function jslint(
|
|
|
833
921
|
case "use_double":
|
|
834
922
|
mm = `Use double quotes, not single quotes.`;
|
|
835
923
|
break;
|
|
924
|
+
|
|
925
|
+
// PR-386 - Fix issue #382 - Make fart-related warnings more readable.
|
|
926
|
+
|
|
927
|
+
case "use_function_not_fart":
|
|
928
|
+
mm = (
|
|
929
|
+
`Use 'function (...)', not '(...) =>' when arrow functions`
|
|
930
|
+
+ ` become too complex.`
|
|
931
|
+
);
|
|
932
|
+
break;
|
|
836
933
|
case "use_open":
|
|
837
934
|
mm = (
|
|
838
935
|
`Wrap a ternary expression in parens,`
|
|
@@ -866,6 +963,12 @@ function jslint(
|
|
|
866
963
|
case "wrap_condition":
|
|
867
964
|
mm = `Wrap the condition in parens.`;
|
|
868
965
|
break;
|
|
966
|
+
|
|
967
|
+
// PR-386 - Fix issue #382 - Make fart-related warnings more readable.
|
|
968
|
+
|
|
969
|
+
case "wrap_fart_parameter":
|
|
970
|
+
mm = `Wrap the parameter before '=>' in parens.`;
|
|
971
|
+
break;
|
|
869
972
|
case "wrap_immediate":
|
|
870
973
|
mm = (
|
|
871
974
|
`Wrap an immediate function invocation in parentheses to assist`
|
|
@@ -873,9 +976,6 @@ function jslint(
|
|
|
873
976
|
+ ` result of a function, and not the function itself.`
|
|
874
977
|
);
|
|
875
978
|
break;
|
|
876
|
-
case "wrap_parameter":
|
|
877
|
-
mm = `Wrap the parameter in parens.`;
|
|
878
|
-
break;
|
|
879
979
|
case "wrap_regexp":
|
|
880
980
|
mm = `Wrap this regexp in parens to avoid confusion.`;
|
|
881
981
|
break;
|
|
@@ -1451,8 +1551,8 @@ async function jslint_cli({
|
|
|
1451
1551
|
let command;
|
|
1452
1552
|
let data;
|
|
1453
1553
|
let exit_code = 0;
|
|
1454
|
-
let mode_plugin_vim;
|
|
1455
1554
|
let mode_report;
|
|
1555
|
+
let mode_wrapper_vim;
|
|
1456
1556
|
let result;
|
|
1457
1557
|
|
|
1458
1558
|
function jslint_from_file({
|
|
@@ -1525,7 +1625,7 @@ async function jslint_cli({
|
|
|
1525
1625
|
if (result_from_file.warnings.length > 0) {
|
|
1526
1626
|
exit_code = 1;
|
|
1527
1627
|
console_error(
|
|
1528
|
-
|
|
1628
|
+
mode_wrapper_vim
|
|
1529
1629
|
|
|
1530
1630
|
// PR-349 - Print warnings in format readable by vim.
|
|
1531
1631
|
|
|
@@ -1658,17 +1758,17 @@ async function jslint_cli({
|
|
|
1658
1758
|
}));
|
|
1659
1759
|
return;
|
|
1660
1760
|
|
|
1661
|
-
//
|
|
1761
|
+
// PR-363 - Add command jslint_report.
|
|
1662
1762
|
|
|
1663
|
-
case "
|
|
1664
|
-
|
|
1763
|
+
case "jslint_report":
|
|
1764
|
+
mode_report = command[1];
|
|
1665
1765
|
process_argv = process_argv.slice(1);
|
|
1666
1766
|
break;
|
|
1667
1767
|
|
|
1668
|
-
//
|
|
1768
|
+
// COMMIT-b26d6df2 - Add command jslint_wrapper_vim.
|
|
1669
1769
|
|
|
1670
|
-
case "
|
|
1671
|
-
|
|
1770
|
+
case "jslint_wrapper_vim":
|
|
1771
|
+
mode_wrapper_vim = true;
|
|
1672
1772
|
process_argv = process_argv.slice(1);
|
|
1673
1773
|
break;
|
|
1674
1774
|
|
|
@@ -1676,6 +1776,7 @@ async function jslint_cli({
|
|
|
1676
1776
|
|
|
1677
1777
|
case "v8_coverage_report":
|
|
1678
1778
|
await v8CoverageReportCreate({
|
|
1779
|
+
consoleError: console_error,
|
|
1679
1780
|
coverageDir: command[1],
|
|
1680
1781
|
processArgv: process_argv.slice(3)
|
|
1681
1782
|
});
|
|
@@ -1684,9 +1785,9 @@ async function jslint_cli({
|
|
|
1684
1785
|
|
|
1685
1786
|
// PR-349 - Detect cli-option --mode-vim-plugin.
|
|
1686
1787
|
|
|
1687
|
-
|
|
1788
|
+
mode_wrapper_vim = (
|
|
1688
1789
|
process_argv.slice(2).indexOf("--mode-vim-plugin") >= 0
|
|
1689
|
-
||
|
|
1790
|
+
|| mode_wrapper_vim
|
|
1690
1791
|
);
|
|
1691
1792
|
|
|
1692
1793
|
// Normalize file relative to process.cwd().
|
|
@@ -1822,37 +1923,16 @@ function jslint_phase2_lex(state) {
|
|
|
1822
1923
|
let line_mega; // The starting line of megastring.
|
|
1823
1924
|
let line_source = ""; // The remaining line source string.
|
|
1824
1925
|
let line_whole = ""; // The whole line source string.
|
|
1926
|
+
let mode_digits_empty_string = 1;
|
|
1927
|
+
let mode_digits_numeric_separator = 2;
|
|
1825
1928
|
let mode_directive = true; // true if directives are still allowed.
|
|
1826
1929
|
let mode_mega = false; // true if currently parsing a megastring
|
|
1827
1930
|
// ... literal.
|
|
1828
1931
|
let mode_regexp; // true if regular expression literal seen on
|
|
1829
1932
|
// ... this line.
|
|
1830
|
-
let
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
+ "|([a-zA-Z_$][a-zA-Z0-9_$]*)"
|
|
1834
|
-
+ "|[(){}\\[\\],:;'\"~\\`]"
|
|
1835
|
-
+ "|\\?[?.]?"
|
|
1836
|
-
+ "|=(?:==?|>)?"
|
|
1837
|
-
+ "|\\.+"
|
|
1838
|
-
+ "|\\*[*\\/=]?"
|
|
1839
|
-
+ "|\\/[*\\/]?"
|
|
1840
|
-
+ "|\\+[=+]?"
|
|
1841
|
-
+ "|-[=\\-]?"
|
|
1842
|
-
+ "|[\\^%]=?"
|
|
1843
|
-
+ "|&[&=]?"
|
|
1844
|
-
+ "|\\"
|
|
1845
|
-
+ "|[|=]?"
|
|
1846
|
-
+ "|>{1,3}=?"
|
|
1847
|
-
+ "|<<?=?"
|
|
1848
|
-
+ "|!(?:!|==?)?"
|
|
1849
|
-
|
|
1850
|
-
// PR-351 - Add BigInt support.
|
|
1851
|
-
|
|
1852
|
-
+ "|(0n?|[1-9][0-9]*n?)"
|
|
1853
|
-
+ ")"
|
|
1854
|
-
+ "(.*)$"
|
|
1855
|
-
);
|
|
1933
|
+
let paren_backtrack_list = []; // List of most recent "(" tokens at any
|
|
1934
|
+
// ... paren-depth.
|
|
1935
|
+
let paren_depth = 0; // Keeps track of current paren-depth.
|
|
1856
1936
|
let snippet = ""; // A piece of string.
|
|
1857
1937
|
let token_1; // The first token.
|
|
1858
1938
|
let token_prv = token_global; // The previous token including
|
|
@@ -1934,7 +2014,7 @@ function jslint_phase2_lex(state) {
|
|
|
1934
2014
|
|
|
1935
2015
|
warn_at("unexpected_a", line, column, char);
|
|
1936
2016
|
}
|
|
1937
|
-
if (read_digits("x") > 5) {
|
|
2017
|
+
if (read_digits("x", undefined) > 5) {
|
|
1938
2018
|
|
|
1939
2019
|
// test_cause:
|
|
1940
2020
|
// ["\"\\u{123456}\"", "char_after_escape", "too_many_digits", "", 11]
|
|
@@ -1951,7 +2031,7 @@ function jslint_phase2_lex(state) {
|
|
|
1951
2031
|
return char_after();
|
|
1952
2032
|
}
|
|
1953
2033
|
char_before();
|
|
1954
|
-
if (read_digits("x",
|
|
2034
|
+
if (read_digits("x", mode_digits_empty_string) < 4) {
|
|
1955
2035
|
|
|
1956
2036
|
// test_cause:
|
|
1957
2037
|
// ["\"\\u0\"", "char_after_escape", "expected_four_digits", "", 5]
|
|
@@ -1986,6 +2066,26 @@ function jslint_phase2_lex(state) {
|
|
|
1986
2066
|
return char;
|
|
1987
2067
|
}
|
|
1988
2068
|
|
|
2069
|
+
function check_numeric_separator(digits, column) {
|
|
2070
|
+
|
|
2071
|
+
// This function will check for illegal numeric-separator in <digits>.
|
|
2072
|
+
|
|
2073
|
+
digits.replace((
|
|
2074
|
+
jslint_rgx_numeric_separator_illegal
|
|
2075
|
+
), function (ignore, ii) {
|
|
2076
|
+
|
|
2077
|
+
// test_cause:
|
|
2078
|
+
// ["0x0_0_;", "check_numeric_separator", "illegal_num_separator", "", 6]
|
|
2079
|
+
// ["0x0_0__0;", "check_numeric_separator", "illegal_num_separator", "", 6]
|
|
2080
|
+
// ["aa=1_2_;", "check_numeric_separator", "illegal_num_separator", "", 7]
|
|
2081
|
+
// ["aa=1_2__3;", "check_numeric_separator", "illegal_num_separator", "", 7]
|
|
2082
|
+
// ["aa=1_2_n;", "check_numeric_separator", "illegal_num_separator", "", 7]
|
|
2083
|
+
|
|
2084
|
+
warn_at("illegal_num_separator", line, column + ii + 1);
|
|
2085
|
+
return "";
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
|
|
1989
2089
|
function lex_comment() {
|
|
1990
2090
|
let body;
|
|
1991
2091
|
let ii = 0;
|
|
@@ -2024,12 +2124,12 @@ function jslint_phase2_lex(state) {
|
|
|
2024
2124
|
// Lex/loop through each line until "*/".
|
|
2025
2125
|
|
|
2026
2126
|
while (true) {
|
|
2027
|
-
//
|
|
2127
|
+
// jslint_rgx_star_slash
|
|
2028
2128
|
ii = line_source.indexOf("*/");
|
|
2029
2129
|
if (ii >= 0) {
|
|
2030
2130
|
break;
|
|
2031
2131
|
}
|
|
2032
|
-
//
|
|
2132
|
+
// jslint_rgx_slash_star
|
|
2033
2133
|
ii = line_source.indexOf("/*");
|
|
2034
2134
|
if (ii >= 0) {
|
|
2035
2135
|
|
|
@@ -2049,8 +2149,7 @@ function jslint_phase2_lex(state) {
|
|
|
2049
2149
|
}
|
|
2050
2150
|
}
|
|
2051
2151
|
jj = line_source.slice(0, ii).search(
|
|
2052
|
-
|
|
2053
|
-
/\/\*|\/$/
|
|
2152
|
+
jslint_rgx_slash_star_or_slash
|
|
2054
2153
|
);
|
|
2055
2154
|
if (jj >= 0) {
|
|
2056
2155
|
|
|
@@ -2068,13 +2167,7 @@ function jslint_phase2_lex(state) {
|
|
|
2068
2167
|
|
|
2069
2168
|
// Uncompleted work comment.
|
|
2070
2169
|
|
|
2071
|
-
if (
|
|
2072
|
-
!option_dict.devel
|
|
2073
|
-
&& (
|
|
2074
|
-
// rx_todo
|
|
2075
|
-
/\b(?:todo|TO\s?DO|HACK)\b/
|
|
2076
|
-
).test(snippet)
|
|
2077
|
-
) {
|
|
2170
|
+
if (!option_dict.devel && jslint_rgx_todo.test(snippet)) {
|
|
2078
2171
|
|
|
2079
2172
|
// test_cause:
|
|
2080
2173
|
// ["//todo", "lex_comment", "todo_comment", "(comment)", 1] //jslint-quiet
|
|
@@ -2086,10 +2179,7 @@ function jslint_phase2_lex(state) {
|
|
|
2086
2179
|
|
|
2087
2180
|
[
|
|
2088
2181
|
the_comment.directive, body
|
|
2089
|
-
] = Array.from(snippet.match(
|
|
2090
|
-
// rx_directive
|
|
2091
|
-
/^(jslint|property|global)\s+(.*)$/
|
|
2092
|
-
) || []).slice(1);
|
|
2182
|
+
] = Array.from(snippet.match(jslint_rgx_directive) || []).slice(1);
|
|
2093
2183
|
if (the_comment.directive === undefined) {
|
|
2094
2184
|
return the_comment;
|
|
2095
2185
|
}
|
|
@@ -2111,10 +2201,12 @@ function jslint_phase2_lex(state) {
|
|
|
2111
2201
|
// Lex/loop through each directive in /*...*/
|
|
2112
2202
|
|
|
2113
2203
|
ii = 0;
|
|
2114
|
-
body.replace((
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2204
|
+
body.replace(jslint_rgx_directive_part, function (
|
|
2205
|
+
match0,
|
|
2206
|
+
key,
|
|
2207
|
+
val,
|
|
2208
|
+
jj
|
|
2209
|
+
) {
|
|
2118
2210
|
if (ii !== jj) {
|
|
2119
2211
|
|
|
2120
2212
|
// test_cause:
|
|
@@ -2188,13 +2280,7 @@ function jslint_phase2_lex(state) {
|
|
|
2188
2280
|
// string.
|
|
2189
2281
|
|
|
2190
2282
|
while (true) {
|
|
2191
|
-
match = line_source.match(
|
|
2192
|
-
|
|
2193
|
-
// Vim-hack - vim-editor has trouble parsing '`' in regexp
|
|
2194
|
-
|
|
2195
|
-
// rx_mega
|
|
2196
|
-
/[\u0060\\]|\$\{/
|
|
2197
|
-
) || {
|
|
2283
|
+
match = line_source.match(jslint_rgx_mega) || {
|
|
2198
2284
|
"0": "",
|
|
2199
2285
|
index: 0
|
|
2200
2286
|
};
|
|
@@ -2271,12 +2357,16 @@ function jslint_phase2_lex(state) {
|
|
|
2271
2357
|
|
|
2272
2358
|
function lex_number() {
|
|
2273
2359
|
let prefix = snippet;
|
|
2360
|
+
|
|
2361
|
+
// PR-390 - Add numeric-separator check.
|
|
2362
|
+
|
|
2363
|
+
check_numeric_separator(prefix, column - prefix.length);
|
|
2274
2364
|
char_after();
|
|
2275
2365
|
switch (prefix === "0" && char) {
|
|
2276
2366
|
case "b":
|
|
2277
2367
|
case "o":
|
|
2278
2368
|
case "x":
|
|
2279
|
-
read_digits(char);
|
|
2369
|
+
read_digits(char, mode_digits_numeric_separator);
|
|
2280
2370
|
|
|
2281
2371
|
// PR-351 - Ignore BigInt suffix 'n'.
|
|
2282
2372
|
|
|
@@ -2286,14 +2376,14 @@ function jslint_phase2_lex(state) {
|
|
|
2286
2376
|
break;
|
|
2287
2377
|
default:
|
|
2288
2378
|
if (char === ".") {
|
|
2289
|
-
read_digits("d");
|
|
2379
|
+
read_digits("d", mode_digits_numeric_separator);
|
|
2290
2380
|
}
|
|
2291
2381
|
if (char === "E" || char === "e") {
|
|
2292
2382
|
char_after(char);
|
|
2293
2383
|
if (char !== "+" && char !== "-") {
|
|
2294
2384
|
char_before();
|
|
2295
2385
|
}
|
|
2296
|
-
read_digits("d");
|
|
2386
|
+
read_digits("d", mode_digits_numeric_separator);
|
|
2297
2387
|
}
|
|
2298
2388
|
}
|
|
2299
2389
|
|
|
@@ -2563,7 +2653,7 @@ function jslint_phase2_lex(state) {
|
|
|
2563
2653
|
}
|
|
2564
2654
|
break;
|
|
2565
2655
|
case "{":
|
|
2566
|
-
if (read_digits("d",
|
|
2656
|
+
if (read_digits("d", mode_digits_empty_string) === 0) {
|
|
2567
2657
|
|
|
2568
2658
|
// test_cause:
|
|
2569
2659
|
// ["aa=/aa{/", "lex_regexp_group", "expected_a_before_b", ",", 8]
|
|
@@ -2576,7 +2666,7 @@ function jslint_phase2_lex(state) {
|
|
|
2576
2666
|
// ["aa=/.{,/", "lex_regexp_group", "comma", "", 0]
|
|
2577
2667
|
|
|
2578
2668
|
test_cause("comma");
|
|
2579
|
-
read_digits("d",
|
|
2669
|
+
read_digits("d", mode_digits_empty_string);
|
|
2580
2670
|
}
|
|
2581
2671
|
if (char_after("}") === "?") {
|
|
2582
2672
|
|
|
@@ -2869,7 +2959,7 @@ function jslint_phase2_lex(state) {
|
|
|
2869
2959
|
}
|
|
2870
2960
|
}
|
|
2871
2961
|
from = column;
|
|
2872
|
-
match = line_source.match(
|
|
2962
|
+
match = line_source.match(jslint_rgx_token);
|
|
2873
2963
|
|
|
2874
2964
|
// match[1] token
|
|
2875
2965
|
// match[2] whitespace
|
|
@@ -3189,7 +3279,7 @@ node --input-type=module --eval '
|
|
|
3189
3279
|
// /\*jslint beta, node*\/
|
|
3190
3280
|
import moduleHttps from "https";
|
|
3191
3281
|
(async function () {
|
|
3192
|
-
let dict =
|
|
3282
|
+
let dict = Object.create(null);
|
|
3193
3283
|
let result = "";
|
|
3194
3284
|
await new Promise(function (resolve) {
|
|
3195
3285
|
moduleHttps.get((
|
|
@@ -3252,41 +3342,48 @@ import moduleHttps from "https";
|
|
|
3252
3342
|
return true;
|
|
3253
3343
|
}
|
|
3254
3344
|
|
|
3255
|
-
function read_digits(base,
|
|
3345
|
+
function read_digits(base, mode) {
|
|
3256
3346
|
let digits = line_source.match(
|
|
3257
3347
|
base === "b"
|
|
3258
|
-
?
|
|
3259
|
-
// rx_bits
|
|
3260
|
-
/^[01]*/
|
|
3261
|
-
)
|
|
3348
|
+
? jslint_rgx_digits_bits
|
|
3262
3349
|
: base === "o"
|
|
3263
|
-
?
|
|
3264
|
-
// rx_octals
|
|
3265
|
-
/^[0-7]*/
|
|
3266
|
-
)
|
|
3350
|
+
? jslint_rgx_digits_octals
|
|
3267
3351
|
: base === "x"
|
|
3268
|
-
?
|
|
3269
|
-
|
|
3270
|
-
/^[0-9A-F]*/i
|
|
3271
|
-
)
|
|
3272
|
-
: (
|
|
3273
|
-
// rx_digits
|
|
3274
|
-
/^[0-9]*/
|
|
3275
|
-
)
|
|
3352
|
+
? jslint_rgx_digits_hexs
|
|
3353
|
+
: jslint_rgx_digits_decimals
|
|
3276
3354
|
)[0];
|
|
3277
|
-
|
|
3278
|
-
|
|
3355
|
+
if (
|
|
3356
|
+
(mode !== mode_digits_empty_string && digits.length === 0)
|
|
3357
|
+
|| digits[0] === "_"
|
|
3358
|
+
) {
|
|
3279
3359
|
|
|
3280
3360
|
// test_cause:
|
|
3281
3361
|
// ["0x", "read_digits", "expected_digits_after_a", "0x", 2]
|
|
3362
|
+
// ["0x_", "read_digits", "expected_digits_after_a", "0x", 2]
|
|
3282
3363
|
|
|
3283
3364
|
warn_at("expected_digits_after_a", line, column, snippet);
|
|
3284
3365
|
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3366
|
+
|
|
3367
|
+
// PR-390 - Add numeric-separator check.
|
|
3368
|
+
|
|
3369
|
+
if (mode === mode_digits_numeric_separator) {
|
|
3370
|
+
check_numeric_separator(digits, column);
|
|
3371
|
+
} else if (digits.indexOf("_") >= 0) {
|
|
3372
|
+
|
|
3373
|
+
// test_cause:
|
|
3374
|
+
// ["\"\\u{1_2}\"", "read_digits", "illegal_num_separator", "", 6]
|
|
3375
|
+
|
|
3376
|
+
warn_at(
|
|
3377
|
+
"illegal_num_separator",
|
|
3378
|
+
line,
|
|
3379
|
+
column + digits.indexOf("_") + 1
|
|
3380
|
+
);
|
|
3381
|
+
}
|
|
3382
|
+
column += digits.length;
|
|
3383
|
+
line_source = line_source.slice(digits.length);
|
|
3287
3384
|
snippet += digits;
|
|
3288
3385
|
char_after();
|
|
3289
|
-
return length;
|
|
3386
|
+
return digits.length;
|
|
3290
3387
|
}
|
|
3291
3388
|
|
|
3292
3389
|
function read_line() {
|
|
@@ -3357,6 +3454,7 @@ import moduleHttps from "https";
|
|
|
3357
3454
|
test_cause("line_disable");
|
|
3358
3455
|
line_source = "";
|
|
3359
3456
|
}
|
|
3457
|
+
// jslint_rgx_tab
|
|
3360
3458
|
if (line_source.indexOf("\t") >= 0) {
|
|
3361
3459
|
if (!option_dict.white) {
|
|
3362
3460
|
|
|
@@ -3365,10 +3463,7 @@ import moduleHttps from "https";
|
|
|
3365
3463
|
|
|
3366
3464
|
warn_at("use_spaces", line, line_source.indexOf("\t") + 1);
|
|
3367
3465
|
}
|
|
3368
|
-
line_source = line_source.replace(
|
|
3369
|
-
// rx_tab
|
|
3370
|
-
/\t/g
|
|
3371
|
-
), " ");
|
|
3466
|
+
line_source = line_source.replace(jslint_rgx_tab, " ");
|
|
3372
3467
|
}
|
|
3373
3468
|
if (!option_dict.white && line_source.endsWith(" ")) {
|
|
3374
3469
|
|
|
@@ -3388,9 +3483,11 @@ import moduleHttps from "https";
|
|
|
3388
3483
|
from,
|
|
3389
3484
|
id,
|
|
3390
3485
|
identifier: Boolean(identifier),
|
|
3486
|
+
is_fart: false,
|
|
3391
3487
|
line,
|
|
3392
3488
|
nr: token_list.length,
|
|
3393
|
-
thru: column
|
|
3489
|
+
thru: column,
|
|
3490
|
+
value
|
|
3394
3491
|
};
|
|
3395
3492
|
token_list.push(the_token);
|
|
3396
3493
|
|
|
@@ -3400,12 +3497,6 @@ import moduleHttps from "https";
|
|
|
3400
3497
|
mode_directive = false;
|
|
3401
3498
|
}
|
|
3402
3499
|
|
|
3403
|
-
// If the token is to have a value, give it one.
|
|
3404
|
-
|
|
3405
|
-
if (value !== undefined) {
|
|
3406
|
-
the_token.value = value;
|
|
3407
|
-
}
|
|
3408
|
-
|
|
3409
3500
|
// If this token is an identifier that touches a preceding number, or
|
|
3410
3501
|
// a "/", comment, or regular expression literal that touches a preceding
|
|
3411
3502
|
// comment or regular expression literal, then give a missing space warning.
|
|
@@ -3439,6 +3530,29 @@ import moduleHttps from "https";
|
|
|
3439
3530
|
the_token.dot = true;
|
|
3440
3531
|
}
|
|
3441
3532
|
|
|
3533
|
+
// PR-385 - Bugfix - Fixes issue #382 - failure to detect destructured fart.
|
|
3534
|
+
// Farts are now detected by keeping a list of most recent "(" tokens at any
|
|
3535
|
+
// given depth. When a "=>" token is encountered, the most recent "(" token at
|
|
3536
|
+
// current depth is marked as a fart.
|
|
3537
|
+
|
|
3538
|
+
switch (id) {
|
|
3539
|
+
case "(":
|
|
3540
|
+
paren_backtrack_list[paren_depth] = the_token;
|
|
3541
|
+
paren_depth += 1;
|
|
3542
|
+
break;
|
|
3543
|
+
case ")":
|
|
3544
|
+
paren_depth -= 1;
|
|
3545
|
+
break;
|
|
3546
|
+
case "=>":
|
|
3547
|
+
if (
|
|
3548
|
+
token_prv_expr.id === ")"
|
|
3549
|
+
&& paren_backtrack_list[paren_depth]
|
|
3550
|
+
) {
|
|
3551
|
+
paren_backtrack_list[paren_depth].is_fart = true;
|
|
3552
|
+
}
|
|
3553
|
+
break;
|
|
3554
|
+
}
|
|
3555
|
+
|
|
3442
3556
|
// The previous token is used to detect adjacency problems.
|
|
3443
3557
|
|
|
3444
3558
|
token_prv = the_token;
|
|
@@ -3523,9 +3637,6 @@ function jslint_phase3_parse(state) {
|
|
|
3523
3637
|
let catchage = catch_stack[0]; // The current catch-block.
|
|
3524
3638
|
let functionage = token_global; // The current function.
|
|
3525
3639
|
let mode_var; // "var" if using var; "let" if using let.
|
|
3526
|
-
let rx_identifier = (
|
|
3527
|
-
/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/
|
|
3528
|
-
);
|
|
3529
3640
|
let token_ii = 0; // The number of the next token.
|
|
3530
3641
|
let token_now = token_global; // The current token being examined in
|
|
3531
3642
|
// ... the parse.
|
|
@@ -3542,7 +3653,7 @@ function jslint_phase3_parse(state) {
|
|
|
3542
3653
|
anon = token_now.id;
|
|
3543
3654
|
} else if (
|
|
3544
3655
|
token_now.id === "(string)"
|
|
3545
|
-
&&
|
|
3656
|
+
&& jslint_rgx_identifier.test(token_now.value)
|
|
3546
3657
|
) {
|
|
3547
3658
|
anon = token_now.value;
|
|
3548
3659
|
}
|
|
@@ -3554,7 +3665,7 @@ function jslint_phase3_parse(state) {
|
|
|
3554
3665
|
match === undefined
|
|
3555
3666
|
|
|
3556
3667
|
// test_cause:
|
|
3557
|
-
// ["
|
|
3668
|
+
// ["{0:0}", "advance", "expected_a_b", "0", 2]
|
|
3558
3669
|
|
|
3559
3670
|
? stop("expected_a_b", token_nxt, id, artifact())
|
|
3560
3671
|
|
|
@@ -3603,7 +3714,7 @@ function jslint_phase3_parse(state) {
|
|
|
3603
3714
|
// other assignment operators can modify, but they cannot initialize.
|
|
3604
3715
|
|
|
3605
3716
|
const the_symbol = symbol(id, 20);
|
|
3606
|
-
the_symbol.
|
|
3717
|
+
the_symbol.led_infix = function (left) {
|
|
3607
3718
|
const the_token = token_now;
|
|
3608
3719
|
let right;
|
|
3609
3720
|
the_token.arity = "assignment";
|
|
@@ -3915,7 +4026,7 @@ function jslint_phase3_parse(state) {
|
|
|
3915
4026
|
|
|
3916
4027
|
const the_symbol = symbol(id);
|
|
3917
4028
|
the_symbol.constant = true;
|
|
3918
|
-
the_symbol.
|
|
4029
|
+
the_symbol.nud_prefix = (
|
|
3919
4030
|
typeof value === "function"
|
|
3920
4031
|
? value
|
|
3921
4032
|
: function () {
|
|
@@ -4109,7 +4220,7 @@ function jslint_phase3_parse(state) {
|
|
|
4109
4220
|
// Create an infix operator.
|
|
4110
4221
|
|
|
4111
4222
|
const the_symbol = symbol(id, bp);
|
|
4112
|
-
the_symbol.
|
|
4223
|
+
the_symbol.led_infix = function (left) {
|
|
4113
4224
|
const the_token = token_now;
|
|
4114
4225
|
the_token.arity = "binary";
|
|
4115
4226
|
if (f !== undefined) {
|
|
@@ -4167,12 +4278,12 @@ function jslint_phase3_parse(state) {
|
|
|
4167
4278
|
return the_token;
|
|
4168
4279
|
}
|
|
4169
4280
|
|
|
4170
|
-
function infix_fart_unwrapped(
|
|
4281
|
+
function infix_fart_unwrapped() {
|
|
4171
4282
|
|
|
4172
4283
|
// test_cause:
|
|
4173
|
-
// ["aa=>0", "infix_fart_unwrapped", "
|
|
4284
|
+
// ["aa=>0", "infix_fart_unwrapped", "wrap_fart_parameter", "=>", 3]
|
|
4174
4285
|
|
|
4175
|
-
return stop("
|
|
4286
|
+
return stop("wrap_fart_parameter", token_now);
|
|
4176
4287
|
}
|
|
4177
4288
|
|
|
4178
4289
|
function infix_grave(left) {
|
|
@@ -4192,7 +4303,7 @@ function jslint_phase3_parse(state) {
|
|
|
4192
4303
|
let the_subscript = parse_expression(0);
|
|
4193
4304
|
if (the_subscript.id === "(string)" || the_subscript.id === "`") {
|
|
4194
4305
|
name = survey(the_subscript);
|
|
4195
|
-
if (
|
|
4306
|
+
if (jslint_rgx_identifier.test(name)) {
|
|
4196
4307
|
|
|
4197
4308
|
// test_cause:
|
|
4198
4309
|
// ["aa[`aa`]", "infix_lbracket", "subscript_a", "aa", 4]
|
|
@@ -4335,13 +4446,13 @@ function jslint_phase3_parse(state) {
|
|
|
4335
4446
|
// Create a right associative infix operator.
|
|
4336
4447
|
|
|
4337
4448
|
const the_symbol = symbol(id, bp);
|
|
4338
|
-
the_symbol.
|
|
4449
|
+
the_symbol.led_infix = function parse_infixr_led(left) {
|
|
4339
4450
|
const the_token = token_now;
|
|
4340
4451
|
|
|
4341
4452
|
// test_cause:
|
|
4342
|
-
// ["0**0", "parse_infixr_led", "
|
|
4453
|
+
// ["0**0", "parse_infixr_led", "led_infix", "", 0]
|
|
4343
4454
|
|
|
4344
|
-
test_cause("
|
|
4455
|
+
test_cause("led_infix");
|
|
4345
4456
|
the_token.arity = "binary";
|
|
4346
4457
|
the_token.expression = [left, parse_expression(bp - 1)];
|
|
4347
4458
|
return the_token;
|
|
@@ -4349,39 +4460,70 @@ function jslint_phase3_parse(state) {
|
|
|
4349
4460
|
return the_symbol;
|
|
4350
4461
|
}
|
|
4351
4462
|
|
|
4352
|
-
function lookahead() {
|
|
4353
|
-
|
|
4354
|
-
// Look ahead one token without advancing, skipping comments.
|
|
4355
|
-
|
|
4356
|
-
let cadet;
|
|
4357
|
-
let ii = token_ii;
|
|
4358
|
-
while (true) {
|
|
4359
|
-
cadet = token_list[ii];
|
|
4360
|
-
if (cadet.id !== "(comment)") {
|
|
4361
|
-
return cadet;
|
|
4362
|
-
}
|
|
4363
|
-
ii += 1;
|
|
4364
|
-
}
|
|
4365
|
-
}
|
|
4366
|
-
|
|
4367
4463
|
function parse_expression(rbp, initial) {
|
|
4368
4464
|
|
|
4369
4465
|
// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
|
|
4370
|
-
// is looking for ad hoc lint patterns. We add .
|
|
4371
|
-
// like .
|
|
4372
|
-
// Having .
|
|
4373
|
-
// JavaScript. I retained Pratt's nomenclature.
|
|
4466
|
+
// is looking for ad hoc lint patterns. We add .fud_stmt to Pratt's model, which
|
|
4467
|
+
// is like .nud_prefix except that it is only used on the first token of a
|
|
4468
|
+
// statement. Having .fud_stmt makes it much easier to define statement-oriented
|
|
4469
|
+
// languages like JavaScript. I retained Pratt's nomenclature.
|
|
4374
4470
|
// They are elements of the parsing method called Top Down Operator Precedence.
|
|
4375
4471
|
|
|
4376
|
-
// .
|
|
4377
|
-
// .
|
|
4378
|
-
// .
|
|
4379
|
-
// lbp
|
|
4380
|
-
//
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
//
|
|
4384
|
-
//
|
|
4472
|
+
// .nud_prefix Null denotation. The prefix handler.
|
|
4473
|
+
// .fud_stmt First null denotation. The statement handler.
|
|
4474
|
+
// .led_infix Left denotation. The infix/postfix handler.
|
|
4475
|
+
// lbp Left binding power of infix operator. It tells us how strongly
|
|
4476
|
+
// the operator binds to the argument at its left.
|
|
4477
|
+
// rbp Right binding power.
|
|
4478
|
+
|
|
4479
|
+
// It processes a nud_prefix (variable, constant, prefix operator). It will then
|
|
4480
|
+
// process leds (infix operators) until the bind powers cause it to stop (it
|
|
4481
|
+
// consumes tokens until it meets a token whose lbp <= rbp). Specifically, it
|
|
4482
|
+
// means that it collects all tokens that bind together before returning to the
|
|
4483
|
+
// operator that called it. It returns the expression's parse tree.
|
|
4484
|
+
|
|
4485
|
+
// For example, "3 + 1 * 2 * 4 + 5"
|
|
4486
|
+
// parses into
|
|
4487
|
+
// {
|
|
4488
|
+
// "id": "+",
|
|
4489
|
+
// "expression": [
|
|
4490
|
+
// {
|
|
4491
|
+
// "id": "+",
|
|
4492
|
+
// "expression": [
|
|
4493
|
+
// {
|
|
4494
|
+
// "id": "(number)",
|
|
4495
|
+
// "value": "3"
|
|
4496
|
+
// },
|
|
4497
|
+
// {
|
|
4498
|
+
// "id": "*",
|
|
4499
|
+
// "expression": [
|
|
4500
|
+
// {
|
|
4501
|
+
// "id": "*",
|
|
4502
|
+
// "expression": [
|
|
4503
|
+
// {
|
|
4504
|
+
// "id": "(number)",
|
|
4505
|
+
// "value": "1"
|
|
4506
|
+
// },
|
|
4507
|
+
// {
|
|
4508
|
+
// "id": "(number)",
|
|
4509
|
+
// "value": "2"
|
|
4510
|
+
// }
|
|
4511
|
+
// ]
|
|
4512
|
+
// },
|
|
4513
|
+
// {
|
|
4514
|
+
// "id": "(number)",
|
|
4515
|
+
// "value": "4"
|
|
4516
|
+
// }
|
|
4517
|
+
// ]
|
|
4518
|
+
// }
|
|
4519
|
+
// ]
|
|
4520
|
+
// },
|
|
4521
|
+
// {
|
|
4522
|
+
// "id": "(number)",
|
|
4523
|
+
// "value": "5"
|
|
4524
|
+
// }
|
|
4525
|
+
// ]
|
|
4526
|
+
// }
|
|
4385
4527
|
|
|
4386
4528
|
let left;
|
|
4387
4529
|
let the_symbol;
|
|
@@ -4393,13 +4535,13 @@ function jslint_phase3_parse(state) {
|
|
|
4393
4535
|
advance();
|
|
4394
4536
|
}
|
|
4395
4537
|
the_symbol = syntax_dict[token_now.id];
|
|
4396
|
-
if (the_symbol !== undefined && the_symbol.
|
|
4538
|
+
if (the_symbol !== undefined && the_symbol.nud_prefix !== undefined) {
|
|
4397
4539
|
|
|
4398
4540
|
// test_cause:
|
|
4399
4541
|
// ["0", "parse_expression", "symbol", "", 0]
|
|
4400
4542
|
|
|
4401
4543
|
test_cause("symbol");
|
|
4402
|
-
left = the_symbol.
|
|
4544
|
+
left = the_symbol.nud_prefix();
|
|
4403
4545
|
} else if (token_now.identifier) {
|
|
4404
4546
|
|
|
4405
4547
|
// test_cause:
|
|
@@ -4424,32 +4566,38 @@ function jslint_phase3_parse(state) {
|
|
|
4424
4566
|
the_symbol = syntax_dict[token_nxt.id];
|
|
4425
4567
|
if (
|
|
4426
4568
|
the_symbol === undefined
|
|
4427
|
-
|| the_symbol.
|
|
4569
|
+
|| the_symbol.led_infix === undefined
|
|
4428
4570
|
|| the_symbol.lbp <= rbp
|
|
4429
4571
|
) {
|
|
4430
4572
|
break;
|
|
4431
4573
|
}
|
|
4432
4574
|
advance();
|
|
4433
|
-
left = the_symbol.
|
|
4575
|
+
left = the_symbol.led_infix(left);
|
|
4434
4576
|
}
|
|
4435
4577
|
return left;
|
|
4436
4578
|
}
|
|
4437
4579
|
|
|
4438
|
-
function parse_fart(
|
|
4580
|
+
function parse_fart() {
|
|
4581
|
+
let parameters;
|
|
4582
|
+
let signature;
|
|
4439
4583
|
let the_fart;
|
|
4584
|
+
[parameters, signature] = prefix_function_arg();
|
|
4440
4585
|
advance("=>");
|
|
4441
4586
|
the_fart = token_now;
|
|
4442
4587
|
the_fart.arity = "binary";
|
|
4443
4588
|
the_fart.name = "=>";
|
|
4444
4589
|
the_fart.level = functionage.level + 1;
|
|
4445
4590
|
function_list.push(the_fart);
|
|
4446
|
-
if (functionage.loop > 0) {
|
|
4447
4591
|
|
|
4448
|
-
//
|
|
4449
|
-
//
|
|
4592
|
+
// PR-384 - Relax warning "function_in_loop".
|
|
4593
|
+
//
|
|
4594
|
+
// if (functionage.loop > 0) {
|
|
4450
4595
|
|
|
4451
|
-
|
|
4452
|
-
|
|
4596
|
+
// // test_cause:
|
|
4597
|
+
// // ["while(0){aa.map(()=>0);}", "parse_fart", "function_in_loop", "=>", 19]
|
|
4598
|
+
//
|
|
4599
|
+
// warn("function_in_loop", the_fart);
|
|
4600
|
+
// }
|
|
4453
4601
|
|
|
4454
4602
|
// Give the function properties storing its names and for observing the depth
|
|
4455
4603
|
// of loops and switches.
|
|
@@ -4457,6 +4605,8 @@ function jslint_phase3_parse(state) {
|
|
|
4457
4605
|
the_fart.context = empty();
|
|
4458
4606
|
the_fart.finally = 0;
|
|
4459
4607
|
the_fart.loop = 0;
|
|
4608
|
+
the_fart.parameters = parameters;
|
|
4609
|
+
the_fart.signature = signature;
|
|
4460
4610
|
the_fart.switch = 0;
|
|
4461
4611
|
the_fart.try = 0;
|
|
4462
4612
|
|
|
@@ -4464,23 +4614,42 @@ function jslint_phase3_parse(state) {
|
|
|
4464
4614
|
|
|
4465
4615
|
function_stack.push(functionage);
|
|
4466
4616
|
functionage = the_fart;
|
|
4467
|
-
the_fart.parameters
|
|
4468
|
-
|
|
4469
|
-
|
|
4617
|
+
the_fart.parameters.forEach(function enroll_parameter(name) {
|
|
4618
|
+
if (name.identifier) {
|
|
4619
|
+
enroll(name, "parameter", true);
|
|
4620
|
+
} else {
|
|
4621
|
+
|
|
4622
|
+
// PR-385 - Bugfix - Fixes issue #382 - fix warnings against destructured fart.
|
|
4470
4623
|
|
|
4471
4624
|
// test_cause:
|
|
4472
|
-
// ["(aa)=>
|
|
4625
|
+
// ["([aa])=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
|
|
4626
|
+
// ["({aa})=>0", "enroll_parameter", "use_function_not_fart", "=>", 7]
|
|
4627
|
+
|
|
4628
|
+
warn("use_function_not_fart", the_fart);
|
|
4629
|
+
|
|
4630
|
+
// Recurse enroll_parameter().
|
|
4473
4631
|
|
|
4474
|
-
|
|
4475
|
-
|
|
4632
|
+
name.names.forEach(enroll_parameter);
|
|
4633
|
+
}
|
|
4476
4634
|
});
|
|
4477
4635
|
if (token_nxt.id === "{") {
|
|
4478
4636
|
|
|
4479
4637
|
// test_cause:
|
|
4480
|
-
// ["()=>{}", "parse_fart", "
|
|
4638
|
+
// ["()=>{}", "parse_fart", "use_function_not_fart", "=>", 3]
|
|
4481
4639
|
|
|
4482
|
-
warn("
|
|
4640
|
+
warn("use_function_not_fart", the_fart);
|
|
4483
4641
|
the_fart.block = block("body");
|
|
4642
|
+
} else if (
|
|
4643
|
+
syntax_dict[token_nxt.id] !== undefined
|
|
4644
|
+
&& syntax_dict[token_nxt.id].fud_stmt !== undefined
|
|
4645
|
+
) {
|
|
4646
|
+
|
|
4647
|
+
// PR-384 - Bugfix - Fixes issue #379 - warn against naked-statement in fart.
|
|
4648
|
+
|
|
4649
|
+
// test_cause:
|
|
4650
|
+
// ["()=>delete aa", "parse_fart", "unexpected_a_after_b", "=>", 5]
|
|
4651
|
+
|
|
4652
|
+
stop("unexpected_a_after_b", token_nxt, token_nxt.id, "=>");
|
|
4484
4653
|
} else {
|
|
4485
4654
|
the_fart.expression = parse_expression(0);
|
|
4486
4655
|
}
|
|
@@ -4495,13 +4664,7 @@ function jslint_phase3_parse(state) {
|
|
|
4495
4664
|
let negative;
|
|
4496
4665
|
switch (token_nxt.id) {
|
|
4497
4666
|
case "(number)":
|
|
4498
|
-
if (!(
|
|
4499
|
-
|
|
4500
|
-
// https://datatracker.ietf.org/doc/html/rfc7159#section-6
|
|
4501
|
-
// number = [ minus ] int [ frac ] [ exp ]
|
|
4502
|
-
|
|
4503
|
-
/^-?(?:0|[1-9]\d*?)(?:\.\d*?)?(?:[eE][+\-]?\d+?)?$/
|
|
4504
|
-
).test(token_nxt.value)) {
|
|
4667
|
+
if (!jslint_rgx_json_number.test(token_nxt.value)) {
|
|
4505
4668
|
|
|
4506
4669
|
// test_cause:
|
|
4507
4670
|
// ["[-.0]", "parse_json", "unexpected_a", ".", 3]
|
|
@@ -4703,7 +4866,7 @@ function jslint_phase3_parse(state) {
|
|
|
4703
4866
|
the_symbol = syntax_dict[first.id];
|
|
4704
4867
|
if (
|
|
4705
4868
|
the_symbol !== undefined
|
|
4706
|
-
&& the_symbol.
|
|
4869
|
+
&& the_symbol.fud_stmt !== undefined
|
|
4707
4870
|
|
|
4708
4871
|
// PR-318 - Bugfix - Fixes issues #316, #317 - dynamic-import().
|
|
4709
4872
|
|
|
@@ -4712,7 +4875,7 @@ function jslint_phase3_parse(state) {
|
|
|
4712
4875
|
the_symbol.disrupt = false;
|
|
4713
4876
|
the_symbol.statement = true;
|
|
4714
4877
|
token_now.arity = "statement";
|
|
4715
|
-
the_statement = the_symbol.
|
|
4878
|
+
the_statement = the_symbol.fud_stmt();
|
|
4716
4879
|
functionage.statement_prv = the_statement;
|
|
4717
4880
|
} else {
|
|
4718
4881
|
|
|
@@ -4782,7 +4945,7 @@ function jslint_phase3_parse(state) {
|
|
|
4782
4945
|
// Create one of the postassign operators.
|
|
4783
4946
|
|
|
4784
4947
|
const the_symbol = symbol(id, 150);
|
|
4785
|
-
the_symbol.
|
|
4948
|
+
the_symbol.led_infix = function (left) {
|
|
4786
4949
|
token_now.expression = left;
|
|
4787
4950
|
token_now.arity = "postassign";
|
|
4788
4951
|
check_mutation(token_now.expression);
|
|
@@ -4796,7 +4959,7 @@ function jslint_phase3_parse(state) {
|
|
|
4796
4959
|
// Create one of the preassign operators.
|
|
4797
4960
|
|
|
4798
4961
|
const the_symbol = symbol(id);
|
|
4799
|
-
the_symbol.
|
|
4962
|
+
the_symbol.nud_prefix = function () {
|
|
4800
4963
|
const the_token = token_now;
|
|
4801
4964
|
the_token.arity = "preassign";
|
|
4802
4965
|
the_token.expression = parse_expression(150);
|
|
@@ -4811,7 +4974,7 @@ function jslint_phase3_parse(state) {
|
|
|
4811
4974
|
// Create a prefix operator.
|
|
4812
4975
|
|
|
4813
4976
|
const the_symbol = symbol(id);
|
|
4814
|
-
the_symbol.
|
|
4977
|
+
the_symbol.nud_prefix = function () {
|
|
4815
4978
|
const the_token = token_now;
|
|
4816
4979
|
the_token.arity = "unary";
|
|
4817
4980
|
if (typeof f === "function") {
|
|
@@ -4932,18 +5095,20 @@ function jslint_phase3_parse(state) {
|
|
|
4932
5095
|
// }
|
|
4933
5096
|
// jslint_assert(!mode_mega, `Expected !mode_mega.`);
|
|
4934
5097
|
|
|
4935
|
-
//
|
|
4936
|
-
//
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
//
|
|
4941
|
-
//
|
|
4942
|
-
//
|
|
4943
|
-
//
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
5098
|
+
// PR-378 - Relax warning "function_in_loop".
|
|
5099
|
+
//
|
|
5100
|
+
// // Don't create functions in loops. It is inefficient, and it can lead to
|
|
5101
|
+
// // scoping errors.
|
|
5102
|
+
//
|
|
5103
|
+
// if (functionage.loop > 0) {
|
|
5104
|
+
//
|
|
5105
|
+
// // test_cause:
|
|
5106
|
+
// // ["
|
|
5107
|
+
// // while(0){aa.map(function(){});}
|
|
5108
|
+
// // ", "prefix_function", "function_in_loop", "function", 17]
|
|
5109
|
+
//
|
|
5110
|
+
// warn("function_in_loop", the_function);
|
|
5111
|
+
// }
|
|
4947
5112
|
|
|
4948
5113
|
// Give the function properties for storing its names and for observing the
|
|
4949
5114
|
// depth of loops and switches.
|
|
@@ -4991,6 +5156,9 @@ function jslint_phase3_parse(state) {
|
|
|
4991
5156
|
if (name.identifier) {
|
|
4992
5157
|
enroll(name, "parameter", false);
|
|
4993
5158
|
} else {
|
|
5159
|
+
|
|
5160
|
+
// Recurse enroll_parameter().
|
|
5161
|
+
|
|
4994
5162
|
name.names.forEach(enroll_parameter);
|
|
4995
5163
|
}
|
|
4996
5164
|
});
|
|
@@ -5451,25 +5619,14 @@ function jslint_phase3_parse(state) {
|
|
|
5451
5619
|
}
|
|
5452
5620
|
|
|
5453
5621
|
function prefix_lparen() {
|
|
5454
|
-
|
|
5455
|
-
const the_paren = token_now;
|
|
5622
|
+
let the_paren = token_now;
|
|
5456
5623
|
let the_value;
|
|
5457
5624
|
|
|
5458
|
-
//
|
|
5459
|
-
// with one token of lookahead.
|
|
5625
|
+
// PR-385 - Bugfix - Fixes issue #382 - failure to detect destructured fart.
|
|
5460
5626
|
|
|
5461
|
-
if (
|
|
5462
|
-
token_nxt.id === ")"
|
|
5463
|
-
|| token_nxt.id === "..."
|
|
5464
|
-
|| (token_nxt.identifier && (cadet === "," || cadet === "="))
|
|
5465
|
-
) {
|
|
5466
|
-
|
|
5467
|
-
// test_cause:
|
|
5468
|
-
// ["()=>0", "prefix_lparen", "fart", "", 0]
|
|
5469
|
-
|
|
5470
|
-
test_cause("fart");
|
|
5627
|
+
if (token_now.is_fart) {
|
|
5471
5628
|
the_paren.free = false;
|
|
5472
|
-
return parse_fart(
|
|
5629
|
+
return parse_fart();
|
|
5473
5630
|
}
|
|
5474
5631
|
|
|
5475
5632
|
// test_cause:
|
|
@@ -5487,31 +5644,6 @@ function jslint_phase3_parse(state) {
|
|
|
5487
5644
|
}
|
|
5488
5645
|
the_value.wrapped = true;
|
|
5489
5646
|
advance(")", the_paren);
|
|
5490
|
-
if (token_nxt.id === "=>") {
|
|
5491
|
-
if (the_value.arity !== "variable") {
|
|
5492
|
-
if (the_value.id === "{" || the_value.id === "[") {
|
|
5493
|
-
|
|
5494
|
-
// test_cause:
|
|
5495
|
-
// ["([])=>0", "prefix_lparen", "expected_a_before_b", "(", 1]
|
|
5496
|
-
// ["({})=>0", "prefix_lparen", "expected_a_before_b", "(", 1]
|
|
5497
|
-
|
|
5498
|
-
warn("expected_a_before_b", the_paren, "function", "(");
|
|
5499
|
-
|
|
5500
|
-
// test_cause:
|
|
5501
|
-
// ["([])=>0", "prefix_lparen", "expected_a_b", "=>", 5]
|
|
5502
|
-
// ["({})=>0", "prefix_lparen", "expected_a_b", "=>", 5]
|
|
5503
|
-
|
|
5504
|
-
return stop("expected_a_b", token_nxt, "{", "=>");
|
|
5505
|
-
}
|
|
5506
|
-
|
|
5507
|
-
// test_cause:
|
|
5508
|
-
// ["(0)=>0", "prefix_lparen", "expected_identifier_a", "0", 2]
|
|
5509
|
-
|
|
5510
|
-
return stop("expected_identifier_a", the_value);
|
|
5511
|
-
}
|
|
5512
|
-
the_paren.expression = [the_value];
|
|
5513
|
-
return parse_fart([the_paren.expression, "(" + the_value.id + ")"]);
|
|
5514
|
-
}
|
|
5515
5647
|
return the_value;
|
|
5516
5648
|
}
|
|
5517
5649
|
|
|
@@ -5592,12 +5724,12 @@ function jslint_phase3_parse(state) {
|
|
|
5592
5724
|
anon = "anonymous";
|
|
5593
5725
|
}
|
|
5594
5726
|
|
|
5595
|
-
function stmt(id,
|
|
5727
|
+
function stmt(id, fud_stmt) {
|
|
5596
5728
|
|
|
5597
5729
|
// Create a statement.
|
|
5598
5730
|
|
|
5599
5731
|
const the_symbol = symbol(id);
|
|
5600
|
-
the_symbol.
|
|
5732
|
+
the_symbol.fud_stmt = fud_stmt;
|
|
5601
5733
|
return the_symbol;
|
|
5602
5734
|
}
|
|
5603
5735
|
|
|
@@ -6032,10 +6164,7 @@ function jslint_phase3_parse(state) {
|
|
|
6032
6164
|
advance("from");
|
|
6033
6165
|
advance("(string)");
|
|
6034
6166
|
the_import.import = token_now;
|
|
6035
|
-
if (!(
|
|
6036
|
-
// rx_module
|
|
6037
|
-
/^[a-zA-Z0-9_$:.@\-\/]+$/
|
|
6038
|
-
).test(token_now.value)) {
|
|
6167
|
+
if (!jslint_rgx_module.test(token_now.value)) {
|
|
6039
6168
|
|
|
6040
6169
|
// test_cause:
|
|
6041
6170
|
// ["import aa from \"!aa\"", "stmt_import", "bad_module_name_a", "!aa", 16]
|
|
@@ -6646,13 +6775,13 @@ function jslint_phase3_parse(state) {
|
|
|
6646
6775
|
|
|
6647
6776
|
if (id === "(string)") {
|
|
6648
6777
|
id = name.value;
|
|
6649
|
-
if (!
|
|
6778
|
+
if (!jslint_rgx_identifier.test(id)) {
|
|
6650
6779
|
return id;
|
|
6651
6780
|
}
|
|
6652
6781
|
} else if (id === "`") {
|
|
6653
6782
|
if (name.value.length === 1) {
|
|
6654
6783
|
id = name.value[0].value;
|
|
6655
|
-
if (!
|
|
6784
|
+
if (!jslint_rgx_identifier.test(id)) {
|
|
6656
6785
|
return id;
|
|
6657
6786
|
}
|
|
6658
6787
|
}
|
|
@@ -6685,10 +6814,7 @@ function jslint_phase3_parse(state) {
|
|
|
6685
6814
|
} else if (
|
|
6686
6815
|
!option_dict.name
|
|
6687
6816
|
&& name.identifier
|
|
6688
|
-
&& (
|
|
6689
|
-
// rx_weird_property
|
|
6690
|
-
/^_|\$|Sync$|_$/m
|
|
6691
|
-
).test(id)
|
|
6817
|
+
&& jslint_rgx_weird_property.test(id)
|
|
6692
6818
|
) {
|
|
6693
6819
|
|
|
6694
6820
|
// test_cause:
|
|
@@ -6726,7 +6852,7 @@ function jslint_phase3_parse(state) {
|
|
|
6726
6852
|
// Create a ternary operator.
|
|
6727
6853
|
|
|
6728
6854
|
const the_symbol = symbol(id1, 30);
|
|
6729
|
-
the_symbol.
|
|
6855
|
+
the_symbol.led_infix = function parse_ternary_led(left) {
|
|
6730
6856
|
const the_token = token_now;
|
|
6731
6857
|
let second;
|
|
6732
6858
|
second = parse_expression(20);
|
|
@@ -7442,10 +7568,7 @@ function jslint_phase4_walk(state) {
|
|
|
7442
7568
|
test_cause("cack");
|
|
7443
7569
|
cack = !cack;
|
|
7444
7570
|
}
|
|
7445
|
-
if ((
|
|
7446
|
-
// rx_cap
|
|
7447
|
-
/^[A-Z]/
|
|
7448
|
-
).test(left.name.id) !== cack) {
|
|
7571
|
+
if (jslint_rgx_cap.test(left.name.id) !== cack) {
|
|
7449
7572
|
if (the_new !== undefined) {
|
|
7450
7573
|
|
|
7451
7574
|
// test_cause:
|
|
@@ -7622,6 +7745,11 @@ function jslint_phase4_walk(state) {
|
|
|
7622
7745
|
|| thing.expression[0].constant === true
|
|
7623
7746
|
|| is_equal(thing.expression[1], thing.expression[2])
|
|
7624
7747
|
) {
|
|
7748
|
+
|
|
7749
|
+
// test_cause:
|
|
7750
|
+
// ["let aa=(aa?`${0}`:`${0}`);", "post_t", "unexpected_a", "?", 11]
|
|
7751
|
+
// ["let aa=(aa?`0`:`0`);", "post_t", "unexpected_a", "?", 11]
|
|
7752
|
+
|
|
7625
7753
|
warn("unexpected_a", thing);
|
|
7626
7754
|
} else if (is_equal(thing.expression[0], thing.expression[1])) {
|
|
7627
7755
|
|
|
@@ -9314,6 +9442,9 @@ body {
|
|
|
9314
9442
|
: "global"
|
|
9315
9443
|
);
|
|
9316
9444
|
if (global.length + froms.length + exports.length > 0) {
|
|
9445
|
+
if (functions.length === 0) {
|
|
9446
|
+
html += "<br>\n";
|
|
9447
|
+
}
|
|
9317
9448
|
html += "<div class=\"level level0\">\n";
|
|
9318
9449
|
html += detail(module, global);
|
|
9319
9450
|
html += detail("import from", froms);
|
|
@@ -9478,14 +9609,14 @@ function jstestIt(description, testFunction, mode) {
|
|
|
9478
9609
|
}));
|
|
9479
9610
|
}
|
|
9480
9611
|
|
|
9481
|
-
function jstestOnExit(exitCode,
|
|
9612
|
+
function jstestOnExit(exitCode, mode) {
|
|
9482
9613
|
|
|
9483
9614
|
// This function will on process-exit, print test-report
|
|
9484
9615
|
// and exit with non-zero exit-code if any test failed.
|
|
9485
9616
|
|
|
9486
9617
|
let message = (
|
|
9487
9618
|
(
|
|
9488
|
-
(jstestCountFailed ||
|
|
9619
|
+
(jstestCountFailed || mode === "testsFailed")
|
|
9489
9620
|
? "\n\u001b[31m"
|
|
9490
9621
|
: "\n\u001b[32m"
|
|
9491
9622
|
)
|
|
@@ -9493,11 +9624,10 @@ function jstestOnExit(exitCode, processExit, countFailed) {
|
|
|
9493
9624
|
+ " tests failed - " + jstestCountFailed + "\n"
|
|
9494
9625
|
+ "\u001b[39m"
|
|
9495
9626
|
);
|
|
9496
|
-
if (
|
|
9627
|
+
if (mode !== "testsFailed") {
|
|
9497
9628
|
console.error(message);
|
|
9498
|
-
processExit = process.exit;
|
|
9499
9629
|
}
|
|
9500
|
-
|
|
9630
|
+
process.exitCode = exitCode || jstestCountFailed;
|
|
9501
9631
|
return message;
|
|
9502
9632
|
}
|
|
9503
9633
|
|
|
@@ -9563,7 +9693,7 @@ function objectDeepCopyWithKeysSorted(obj) {
|
|
|
9563
9693
|
|
|
9564
9694
|
// Recursively deep-copy obj with keys sorted.
|
|
9565
9695
|
|
|
9566
|
-
sorted =
|
|
9696
|
+
sorted = Object.create(null);
|
|
9567
9697
|
Object.keys(obj).sort().forEach(function (key) {
|
|
9568
9698
|
sorted[key] = objectDeepCopyWithKeysSorted(obj[key]);
|
|
9569
9699
|
});
|
|
@@ -10837,7 +10967,7 @@ function sentinel() {}
|
|
|
10837
10967
|
|
|
10838
10968
|
// 3. Create html-coverage-reports in <coverageDir>.
|
|
10839
10969
|
|
|
10840
|
-
fileDict =
|
|
10970
|
+
fileDict = Object.create(null);
|
|
10841
10971
|
await Promise.all(v8CoverageObj.result.map(async function ({
|
|
10842
10972
|
functions,
|
|
10843
10973
|
url: pathname
|