Skip to content

Commit d729bec

Browse files
authored
repl: tab completion targets <class> instead of new <class>
Signed-off-by: hainenber <dotronghai96@gmail.com> PR-URL: #60319 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
1 parent 5e6ac7e commit d729bec

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

lib/internal/repl/completion.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,16 @@ function findExpressionCompleteTarget(code) {
613613
return findExpressionCompleteTarget(argumentCode);
614614
}
615615

616+
// If the last statement is an expression statement with "new" syntax
617+
// we want to extract the callee for completion (e.g. for `new Sample` we want `Sample`)
618+
if (lastBodyStatement.type === 'ExpressionStatement' &&
619+
lastBodyStatement.expression.type === 'NewExpression' &&
620+
lastBodyStatement.expression.callee) {
621+
const callee = lastBodyStatement.expression.callee;
622+
const calleeCode = code.slice(callee.start, callee.end);
623+
return findExpressionCompleteTarget(calleeCode);
624+
}
625+
616626
// Walk the AST for the current block of code, and check whether it contains any
617627
// statement or expression type that would potentially have side effects if evaluated.
618628
let isAllowed = true;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const { startNewREPLServer } = require('../common/repl');
6+
const { describe, it } = require('node:test');
7+
8+
// This test verifies that tab completion works correctly with `new` operator
9+
// for a class. Property access has higher precedence than `new` so the properties
10+
// should be displayed as autocompletion result.
11+
12+
describe('REPL tab completion with new expressions', () => {
13+
it('should output completion of class properties', () => {
14+
const { replServer, input } = startNewREPLServer({ terminal: false });
15+
16+
input.run([
17+
`
18+
class X { x = 1 };
19+
X.Y = class Y { y = 2 };
20+
`,
21+
]);
22+
23+
// Handle completion for property of root class.
24+
replServer.complete(
25+
'new X.',
26+
common.mustSucceed((completions) => {
27+
assert.strictEqual(completions[1], 'X.');
28+
})
29+
);
30+
31+
// Handle completion for property with another class as value.
32+
replServer.complete(
33+
'new X.Y.',
34+
common.mustSucceed((completions) => {
35+
assert.strictEqual(completions[1], 'X.Y.');
36+
})
37+
);
38+
39+
replServer.close();
40+
});
41+
});

0 commit comments

Comments
 (0)