Skip to content

Commit 20ffadf

Browse files
aduh95targos
authored andcommitted
repl: refactor to use more primordials
PR-URL: #36264 Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent b68b13a commit 20ffadf

File tree

4 files changed

+239
-147
lines changed

4 files changed

+239
-147
lines changed

lib/internal/repl/await.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
'use strict';
22

33
const {
4+
ArrayFrom,
5+
ArrayPrototypeJoin,
6+
ArrayPrototypePop,
7+
ArrayPrototypePush,
8+
FunctionPrototype,
49
ObjectKeys,
510
} = primordials;
611

@@ -19,7 +24,7 @@ const parser = acorn.Parser.extend(
1924
staticClassFeatures
2025
);
2126

22-
const noop = () => {};
27+
const noop = FunctionPrototype;
2328
const visitorsWithoutAncestors = {
2429
ClassDeclaration(node, state, c) {
2530
if (state.ancestors[state.ancestors.length - 2] === state.body) {
@@ -76,18 +81,18 @@ for (const nodeType of ObjectKeys(walk.base)) {
7681
visitors[nodeType] = (node, state, c) => {
7782
const isNew = node !== state.ancestors[state.ancestors.length - 1];
7883
if (isNew) {
79-
state.ancestors.push(node);
84+
ArrayPrototypePush(state.ancestors, node);
8085
}
8186
callback(node, state, c);
8287
if (isNew) {
83-
state.ancestors.pop();
88+
ArrayPrototypePop(state.ancestors);
8489
}
8590
};
8691
}
8792

8893
function processTopLevelAwait(src) {
8994
const wrapped = `(async () => { ${src} })()`;
90-
const wrappedArray = wrapped.split('');
95+
const wrappedArray = ArrayFrom(wrapped);
9196
let root;
9297
try {
9398
root = parser.parse(wrapped, { ecmaVersion: 'latest' });
@@ -142,7 +147,7 @@ function processTopLevelAwait(src) {
142147
state.append(last.expression, ')');
143148
}
144149

145-
return wrappedArray.join('');
150+
return ArrayPrototypeJoin(wrappedArray, '');
146151
}
147152

148153
module.exports = {

lib/internal/repl/history.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
'use strict';
22

33
const {
4+
ArrayPrototypeJoin,
45
Boolean,
6+
FunctionPrototype,
7+
StringPrototypeSplit,
8+
StringPrototypeTrim,
59
} = primordials;
610

711
const { Interface } = require('readline');
@@ -13,6 +17,8 @@ let debug = require('internal/util/debuglog').debuglog('repl', (fn) => {
1317
});
1418
const { clearTimeout, setTimeout } = require('timers');
1519

20+
const noop = FunctionPrototype;
21+
1622
// XXX(chrisdickinson): The 15ms debounce value is somewhat arbitrary.
1723
// The debounce is to guard against code pasted into the REPL.
1824
const kDebounceHistoryMS = 15;
@@ -27,7 +33,7 @@ function _writeToOutput(repl, message) {
2733
function setupHistory(repl, historyPath, ready) {
2834
// Empty string disables persistent history
2935
if (typeof historyPath === 'string')
30-
historyPath = historyPath.trim();
36+
historyPath = StringPrototypeTrim(historyPath);
3137

3238
if (historyPath === '') {
3339
repl._historyPrev = _replHistoryMessage;
@@ -84,7 +90,7 @@ function setupHistory(repl, historyPath, ready) {
8490
}
8591

8692
if (data) {
87-
repl.history = data.split(/[\n\r]+/, repl.historySize);
93+
repl.history = StringPrototypeSplit(data, /[\n\r]+/, repl.historySize);
8894
} else {
8995
repl.history = [];
9096
}
@@ -128,7 +134,7 @@ function setupHistory(repl, historyPath, ready) {
128134
return;
129135
}
130136
writing = true;
131-
const historyData = repl.history.join(os.EOL);
137+
const historyData = ArrayPrototypeJoin(repl.history, os.EOL);
132138
fs.write(repl._historyHandle, historyData, 0, 'utf8', onwritten);
133139
}
134140

@@ -151,7 +157,7 @@ function setupHistory(repl, historyPath, ready) {
151157
return;
152158
}
153159
repl.off('line', online);
154-
fs.close(repl._historyHandle, () => {});
160+
fs.close(repl._historyHandle, noop);
155161
}
156162
}
157163

lib/internal/repl/utils.js

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
'use strict';
22

33
const {
4+
ArrayPrototypeFilter,
5+
ArrayPrototypeIncludes,
6+
ArrayPrototypeMap,
7+
Boolean,
8+
FunctionPrototypeBind,
49
MathMin,
10+
RegExpPrototypeTest,
11+
SafeSet,
512
SafeStringIterator,
6-
Set,
13+
StringPrototypeEndsWith,
14+
StringPrototypeIndexOf,
15+
StringPrototypeLastIndexOf,
16+
StringPrototypeReplace,
17+
StringPrototypeSlice,
18+
StringPrototypeStartsWith,
19+
StringPrototypeToLowerCase,
20+
StringPrototypeTrim,
721
Symbol,
822
} = primordials;
923

@@ -60,7 +74,9 @@ function isRecoverableError(e, code) {
6074
// curly brace with parenthesis. Note: only the open parenthesis is added
6175
// here as the point is to test for potentially valid but incomplete
6276
// expressions.
63-
if (/^\s*\{/.test(code) && isRecoverableError(e, `(${code}`)) return true;
77+
if (RegExpPrototypeTest(/^\s*\{/, code) &&
78+
isRecoverableError(e, `(${code}`))
79+
return true;
6480

6581
let recoverable = false;
6682

@@ -100,9 +116,11 @@ function isRecoverableError(e, code) {
100116
break;
101117

102118
case 'Unterminated string constant':
103-
const token = this.input.slice(this.lastTokStart, this.pos);
119+
const token = StringPrototypeSlice(this.input,
120+
this.lastTokStart, this.pos);
104121
// See https://www.ecma-international.org/ecma-262/#sec-line-terminators
105-
if (/\\(?:\r\n?|\n|\u2028|\u2029)$/.test(token)) {
122+
if (RegExpPrototypeTest(/\\(?:\r\n?|\n|\u2028|\u2029)$/,
123+
token)) {
106124
recoverable = true;
107125
}
108126
}
@@ -236,15 +254,15 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
236254
hasCompletions = true;
237255

238256
// If there is a common prefix to all matches, then apply that portion.
239-
const completions = rawCompletions.filter((e) => e);
257+
const completions = ArrayPrototypeFilter(rawCompletions, Boolean);
240258
const prefix = commonPrefix(completions);
241259

242260
// No common prefix found.
243261
if (prefix.length <= completeOn.length) {
244262
return;
245263
}
246264

247-
const suffix = prefix.slice(completeOn.length);
265+
const suffix = StringPrototypeSlice(prefix, completeOn.length);
248266

249267
if (insertPreview) {
250268
repl._insertString(suffix);
@@ -272,16 +290,22 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
272290
}
273291

274292
function isInStrictMode(repl) {
275-
return repl.replMode === REPL_MODE_STRICT || process.execArgv
276-
.map((e) => e.toLowerCase().replace(/_/g, '-'))
277-
.includes('--use-strict');
293+
return repl.replMode === REPL_MODE_STRICT || ArrayPrototypeIncludes(
294+
ArrayPrototypeMap(process.execArgv,
295+
(e) => StringPrototypeReplace(
296+
StringPrototypeToLowerCase(e),
297+
/_/g,
298+
'-'
299+
)),
300+
'--use-strict');
278301
}
279302

280303
// This returns a code preview for arbitrary input code.
281304
function getInputPreview(input, callback) {
282305
// For similar reasons as `defaultEval`, wrap expressions starting with a
283306
// curly brace with parenthesis.
284-
if (input.startsWith('{') && !input.endsWith(';') && !wrapped) {
307+
if (StringPrototypeStartsWith(input, '{') &&
308+
!StringPrototypeEndsWith(input, ';') && !wrapped) {
285309
input = `(${input})`;
286310
wrapped = true;
287311
}
@@ -347,7 +371,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
347371
return;
348372
}
349373

350-
const line = repl.line.trim();
374+
const line = StringPrototypeTrim(repl.line);
351375

352376
// Do not preview in case the line only contains whitespace.
353377
if (line === '') {
@@ -413,9 +437,9 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
413437

414438
// Line breaks are very rare and probably only occur in case of error
415439
// messages with line breaks.
416-
const lineBreakPos = inspected.indexOf('\n');
440+
const lineBreakPos = StringPrototypeIndexOf(inspected, '\n');
417441
if (lineBreakPos !== -1) {
418-
inspected = `${inspected.slice(0, lineBreakPos)}`;
442+
inspected = `${StringPrototypeSlice(inspected, 0, lineBreakPos)}`;
419443
}
420444

421445
const result = repl.useColors ?
@@ -453,7 +477,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
453477
// Refresh prints the whole screen again and the preview will be removed
454478
// during that procedure. Print the preview again. This also makes sure
455479
// the preview is always correct after resizing the terminal window.
456-
const originalRefresh = repl._refreshLine.bind(repl);
480+
const originalRefresh = FunctionPrototypeBind(repl._refreshLine, repl);
457481
repl._refreshLine = () => {
458482
inputPreview = null;
459483
originalRefresh();
@@ -463,7 +487,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
463487
let insertCompletionPreview = true;
464488
// Insert the longest common suffix of the current input in case the user
465489
// moves to the right while already being at the current input end.
466-
const originalMoveCursor = repl._moveCursor.bind(repl);
490+
const originalMoveCursor = FunctionPrototypeBind(repl._moveCursor, repl);
467491
repl._moveCursor = (dx) => {
468492
const currentCursor = repl.cursor;
469493
originalMoveCursor(dx);
@@ -477,7 +501,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
477501

478502
// This is the only function that interferes with the completion insertion.
479503
// Monkey patch it to prevent inserting the completion when it shouldn't be.
480-
const originalClearLine = repl.clearLine.bind(repl);
504+
const originalClearLine = FunctionPrototypeBind(repl.clearLine, repl);
481505
repl.clearLine = () => {
482506
insertCompletionPreview = false;
483507
originalClearLine();
@@ -493,7 +517,7 @@ function setupReverseSearch(repl) {
493517
return { reverseSearch() { return false; } };
494518
}
495519

496-
const alreadyMatched = new Set();
520+
const alreadyMatched = new SafeSet();
497521
const labels = {
498522
r: 'bck-i-search: ',
499523
s: 'fwd-i-search: '
@@ -557,18 +581,18 @@ function setupReverseSearch(repl) {
557581
if (cursor === -1) {
558582
cursor = entry.length;
559583
}
560-
cursor = entry.lastIndexOf(input, cursor - 1);
584+
cursor = StringPrototypeLastIndexOf(entry, input, cursor - 1);
561585
} else {
562-
cursor = entry.indexOf(input, cursor + 1);
586+
cursor = StringPrototypeIndexOf(entry, input, cursor + 1);
563587
}
564588
// Match not found.
565589
if (cursor === -1) {
566590
goToNextHistoryIndex();
567591
// Match found.
568592
} else {
569593
if (repl.useColors) {
570-
const start = entry.slice(0, cursor);
571-
const end = entry.slice(cursor + input.length);
594+
const start = StringPrototypeSlice(entry, 0, cursor);
595+
const end = StringPrototypeSlice(entry, cursor + input.length);
572596
entry = `${start}\x1B[4m${input}\x1B[24m${end}`;
573597
}
574598
print(entry, `${labels[dir]}${input}_`, cursor);
@@ -611,7 +635,7 @@ function setupReverseSearch(repl) {
611635
// tick end instead of after each operation.
612636
let rows = 0;
613637
if (lastMatch !== -1) {
614-
const line = repl.history[lastMatch].slice(0, lastCursor);
638+
const line = StringPrototypeSlice(repl.history[lastMatch], 0, lastCursor);
615639
rows = repl._getDisplayPos(`${repl.getPrompt()}${line}`).rows;
616640
cursorTo(repl.output, promptPos.cols);
617641
} else if (isInReverseSearch && repl.line !== '') {
@@ -633,7 +657,7 @@ function setupReverseSearch(repl) {
633657
// To know exactly how many rows we have to move the cursor back we need the
634658
// cursor rows, the output rows and the input rows.
635659
const prompt = repl.getPrompt();
636-
const cursorLine = `${prompt}${outputLine.slice(0, cursor)}`;
660+
const cursorLine = prompt + StringPrototypeSlice(outputLine, 0, cursor);
637661
const cursorPos = repl._getDisplayPos(cursorLine);
638662
const outputPos = repl._getDisplayPos(`${prompt}${outputLine}`);
639663
const inputPos = repl._getDisplayPos(inputLine);
@@ -691,7 +715,7 @@ function setupReverseSearch(repl) {
691715
search();
692716
} else if (key.name === 'backspace' ||
693717
(key.ctrl && (key.name === 'h' || key.name === 'w'))) {
694-
reset(input.slice(0, input.length - 1));
718+
reset(StringPrototypeSlice(input, 0, input.length - 1));
695719
search();
696720
// Special handle <ctrl> + c and escape. Those should only cancel the
697721
// reverse search. The original line is visible afterwards again.

0 commit comments

Comments
 (0)