@@ -1384,53 +1384,61 @@ pub fn parse_stmt_block_body<'a, P: Parser<'a>>(
13841384
13851385pub ( super ) fn parse_block_body < ' a , P : Parser < ' a > , Type : IsDirective + From < Stmt > > (
13861386 p : & mut P ,
1387- mut allow_directives : bool ,
1387+ allow_directives : bool ,
13881388 end : Option < & P :: Token > ,
13891389 handle_import_export : impl Fn ( & mut P , Vec < Decorator > ) -> PResult < Type > ,
13901390) -> PResult < Vec < Type > > {
13911391 trace_cur ! ( p, parse_block_body) ;
13921392
1393- let old_ctx = p. ctx ( ) ;
1394-
13951393 let mut stmts = Vec :: with_capacity ( 8 ) ;
1396- while {
1397- match ( p. input_mut ( ) . cur ( ) , end) {
1398- ( Some ( cur) , Some ( end) ) => cur != end,
1399- ( Some ( _) , None ) => true ,
1400- ( None , None ) => false ,
1401- ( None , Some ( _) ) => {
1402- let eof_text = p. input_mut ( ) . dump_cur ( ) ;
1403- p. emit_err (
1404- p. input ( ) . cur_span ( ) ,
1405- SyntaxError :: Expected ( format ! ( "{:?}" , end. unwrap( ) ) , eof_text) ,
1406- ) ;
1407- false
1408- }
1394+
1395+ let is_stmt_start = |p : & mut P | match ( p. input_mut ( ) . cur ( ) , end) {
1396+ ( Some ( cur) , Some ( end) ) => cur != end,
1397+ ( Some ( _) , None ) => true ,
1398+ ( None , None ) => false ,
1399+ ( None , Some ( _) ) => {
1400+ let eof_text = p. input_mut ( ) . dump_cur ( ) ;
1401+ p. emit_err (
1402+ p. input ( ) . cur_span ( ) ,
1403+ SyntaxError :: Expected ( format ! ( "{:?}" , end. unwrap( ) ) , eof_text) ,
1404+ ) ;
1405+ false
14091406 }
1410- } {
1407+ } ;
1408+
1409+ let mut has_strict_directive = false ;
1410+ if is_stmt_start ( p) {
14111411 let stmt = parse_stmt_like ( p, true , & handle_import_export) ?;
1412- if allow_directives {
1413- allow_directives = false ;
1414- if stmt. is_use_strict ( ) {
1415- p. set_ctx ( old_ctx | Context :: Strict ) ;
1416- if p. input ( ) . knows_cur ( ) && !p. is_general_semi ( ) {
1417- unreachable ! (
1418- "'use strict'; directive requires parser.input.cur to be empty or '}}', \
1419- but current token was: {:?}",
1420- p. input_mut( ) . cur( )
1421- )
1422- }
1412+ if allow_directives && stmt. is_use_strict ( ) {
1413+ has_strict_directive = true ;
1414+ if p. input ( ) . knows_cur ( ) && !p. is_general_semi ( ) {
1415+ unreachable ! (
1416+ "'use strict'; directive requires parser.input.cur to be empty or '}}', but \
1417+ current token was: {:?}",
1418+ p. input_mut( ) . cur( )
1419+ )
14231420 }
14241421 }
1425-
14261422 stmts. push ( stmt) ;
14271423 }
14281424
1425+ let parse_rest_stmts = |p : & mut P , stmts : & mut Vec < Type > | -> PResult < ( ) > {
1426+ while is_stmt_start ( p) {
1427+ let stmt = parse_stmt_like ( p, true , & handle_import_export) ?;
1428+ stmts. push ( stmt) ;
1429+ }
1430+ Ok ( ( ) )
1431+ } ;
1432+
1433+ if has_strict_directive {
1434+ p. do_inside_of_context ( Context :: Strict , |p| parse_rest_stmts ( p, & mut stmts) ) ?;
1435+ } else {
1436+ parse_rest_stmts ( p, & mut stmts) ?;
1437+ } ;
1438+
14291439 if p. input_mut ( ) . cur ( ) . is_some ( ) && end. is_some ( ) {
14301440 p. bump ( ) ;
14311441 }
14321442
1433- p. set_ctx ( old_ctx) ;
1434-
14351443 Ok ( stmts)
14361444}
0 commit comments