File tree Expand file tree Collapse file tree 3 files changed +68
-3
lines changed
Expand file tree Collapse file tree 3 files changed +68
-3
lines changed Original file line number Diff line number Diff line change @@ -184,7 +184,10 @@ function processTopLevelAwait(src){
184184'^\n\n' + RegExpPrototypeSymbolReplace ( / \( [ ^ ) ] + \) / , e . message , '' ) ;
185185// V8 unexpected token errors include the token string.
186186if ( StringPrototypeEndsWith ( message , 'Unexpected token' ) )
187- message += " '" + src [ e . pos - wrapPrefix . length ] + "'" ;
187+ message += " '" +
188+ // Wrapper end may cause acorn to report error position after the source
189+ ( src [ e . pos - wrapPrefix . length ] ?? src [ src . length - 1 ] ) +
190+ "'" ;
188191// eslint-disable-next-line no-restricted-syntax
189192throw new SyntaxError ( message ) ;
190193}
Original file line number Diff line number Diff line change 7878 ReflectApply,
7979 RegExp,
8080 RegExpPrototypeExec,
81+ RegExpPrototypeSymbolReplace,
8182 RegExpPrototypeTest,
8283 SafeSet,
8384 SafeWeakSet,
@@ -434,8 +435,39 @@ function REPLServer(prompt,
434435awaitPromise = true ;
435436}
436437} catch ( e ) {
437- decorateErrorStack ( e ) ;
438- err = e ;
438+ let recoverableError = false ;
439+ if ( e . name === 'SyntaxError' ) {
440+ let parentURL ;
441+ try {
442+ const { pathToFileURL } = require ( 'url' ) ;
443+ // Adding `/repl` prevents dynamic imports from loading relative
444+ // to the parent of `process.cwd()`.
445+ parentURL = pathToFileURL ( path . join ( process . cwd ( ) , 'repl' ) ) . href ;
446+ } catch {
447+ }
448+
449+ // Remove all "await"s and attempt running the script
450+ // in order to detect if error is truly non recoverable
451+ const fallbackCode = RegExpPrototypeSymbolReplace ( / \b a w a i t \b / g, code , '' ) ;
452+ try {
453+ vm . createScript ( fallbackCode , {
454+ filename : file ,
455+ displayErrors : true ,
456+ importModuleDynamically : async ( specifier ) => {
457+ return asyncESM . ESMLoader . import ( specifier , parentURL ) ;
458+ }
459+ } ) ;
460+ } catch ( fallbackError ) {
461+ if ( isRecoverableError ( fallbackError , fallbackCode ) ) {
462+ recoverableError = true ;
463+ err = new Recoverable ( e ) ;
464+ }
465+ }
466+ }
467+ if ( ! recoverableError ) {
468+ decorateErrorStack ( e ) ;
469+ err = e ;
470+ }
439471}
440472}
441473
Original file line number Diff line number Diff line change @@ -152,6 +152,36 @@ async function ordinaryTests(){
152152'Unexpected token \'.\'' ,
153153] ,
154154] ,
155+ [ 'for (const x of [1,2,3]){\nawait x\n}' , [
156+ 'for (const x of [1,2,3]){\r' ,
157+ '... await x\r' ,
158+ '... }\r' ,
159+ 'undefined' ,
160+ ] ] ,
161+ [ 'for (const x of [1,2,3]){\nawait x;\n}' , [
162+ 'for (const x of [1,2,3]){\r' ,
163+ '... await x;\r' ,
164+ '... }\r' ,
165+ 'undefined' ,
166+ ] ] ,
167+ [ 'for await (const x of [1,2,3]){\nconsole.log(x)\n}' , [
168+ 'for await (const x of [1,2,3]){\r' ,
169+ '... console.log(x)\r' ,
170+ '... }\r' ,
171+ '1' ,
172+ '2' ,
173+ '3' ,
174+ 'undefined' ,
175+ ] ] ,
176+ [ 'for await (const x of [1,2,3]){\nconsole.log(x);\n}' , [
177+ 'for await (const x of [1,2,3]){\r' ,
178+ '... console.log(x);\r' ,
179+ '... }\r' ,
180+ '1' ,
181+ '2' ,
182+ '3' ,
183+ 'undefined' ,
184+ ] ] ,
155185] ;
156186
157187for ( const [ input , expected = [ `${ input } \r` ] , options = { } ] of testCases ) {
You can’t perform that action at this time.
0 commit comments