Skip to content

Commit 377aed3

Browse files
hainenberRafaelGSS
authored andcommitted
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 08fb6c9 commit 377aed3

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

‎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
returnfindExpressionCompleteTarget(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+
constcallee=lastBodyStatement.expression.callee;
622+
constcalleeCode=code.slice(callee.start,callee.end);
623+
returnfindExpressionCompleteTarget(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
letisAllowed=true;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constassert=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)