@@ -73,6 +73,7 @@ const {
73
73
} = require ( 'internal/errors' ) . codes ;
74
74
const { sendInspectorCommand } = require ( 'internal/util/inspector' ) ;
75
75
const { experimentalREPLAwait } = process . binding ( 'config' ) ;
76
+ const { isRecoverableError } = require ( 'internal/repl/recoverable' ) ;
76
77
77
78
// Lazy-loaded.
78
79
let processTopLevelAwait ;
@@ -227,7 +228,8 @@ function REPLServer(prompt,
227
228
// It's confusing for `{ a : 1 }` to be interpreted as a block
228
229
// statement rather than an object literal. So, we first try
229
230
// to wrap it in parentheses, so that it will be interpreted as
230
- // an expression.
231
+ // an expression. Note that if the above condition changes,
232
+ // lib/internal/repl/recoverable.js needs to be changed to match.
231
233
code = `(${ code . trim ( ) } )\n` ;
232
234
wrappedCmd = true ;
233
235
}
@@ -1505,76 +1507,6 @@ function regexpEscape(s) {
1505
1507
return s . replace ( / [ - [ \] { } ( ) * + ? . , \\ ^ $ | # \s ] / g, '\\$&' ) ;
1506
1508
}
1507
1509
1508
- // If the error is that we've unexpectedly ended the input,
1509
- // then let the user try to recover by adding more input.
1510
- function isRecoverableError ( e , code ) {
1511
- if ( e && e . name === 'SyntaxError' ) {
1512
- var message = e . message ;
1513
- if ( message === 'Unterminated template literal' ||
1514
- message === 'Unexpected end of input' ) {
1515
- return true ;
1516
- }
1517
-
1518
- if ( message === 'missing ) after argument list' ) {
1519
- const frames = e . stack . split ( / \r ? \n / ) ;
1520
- const pos = frames . findIndex ( ( f ) => f . match ( / ^ \s * \^ + $ / ) ) ;
1521
- return pos > 0 && frames [ pos - 1 ] . length === frames [ pos ] . length ;
1522
- }
1523
-
1524
- if ( message === 'Invalid or unexpected token' )
1525
- return isCodeRecoverable ( code ) ;
1526
- }
1527
- return false ;
1528
- }
1529
-
1530
- // Check whether a code snippet should be forced to fail in the REPL.
1531
- function isCodeRecoverable ( code ) {
1532
- var current , previous , stringLiteral ;
1533
- var isBlockComment = false ;
1534
- var isSingleComment = false ;
1535
- var isRegExpLiteral = false ;
1536
- var lastChar = code . charAt ( code . length - 2 ) ;
1537
- var prevTokenChar = null ;
1538
-
1539
- for ( var i = 0 ; i < code . length ; i ++ ) {
1540
- previous = current ;
1541
- current = code [ i ] ;
1542
-
1543
- if ( previous === '\\' && ( stringLiteral || isRegExpLiteral ) ) {
1544
- current = null ;
1545
- } else if ( stringLiteral ) {
1546
- if ( stringLiteral === current ) {
1547
- stringLiteral = null ;
1548
- }
1549
- } else if ( isRegExpLiteral && current === '/' ) {
1550
- isRegExpLiteral = false ;
1551
- } else if ( isBlockComment && previous === '*' && current === '/' ) {
1552
- isBlockComment = false ;
1553
- } else if ( isSingleComment && current === '\n' ) {
1554
- isSingleComment = false ;
1555
- } else if ( ! isBlockComment && ! isRegExpLiteral && ! isSingleComment ) {
1556
- if ( current === '/' && previous === '/' ) {
1557
- isSingleComment = true ;
1558
- } else if ( previous === '/' ) {
1559
- if ( current === '*' ) {
1560
- isBlockComment = true ;
1561
- // Distinguish between a division operator and the start of a regex
1562
- // by examining the non-whitespace character that precedes the /
1563
- } else if ( [ null , '(' , '[' , '{' , '}' , ';' ] . includes ( prevTokenChar ) ) {
1564
- isRegExpLiteral = true ;
1565
- }
1566
- } else {
1567
- if ( current . trim ( ) ) prevTokenChar = current ;
1568
- if ( current === '\'' || current === '"' ) {
1569
- stringLiteral = current ;
1570
- }
1571
- }
1572
- }
1573
- }
1574
-
1575
- return stringLiteral ? lastChar === '\\' : isBlockComment ;
1576
- }
1577
-
1578
1510
function Recoverable ( err ) {
1579
1511
this . err = err ;
1580
1512
}
0 commit comments