2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2021-05-29 12:38:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020 ,  Stephan  Unverwerth  < s . unverwerth @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 11:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020 - 2021 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-03 14:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  David  Tuin  < davidot @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Ali  Mohammad  Pur  < mpfard @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Idan  Horowitz  < idan . horowitz @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "Parser.h" 
  
						 
					
						
							
								
									
										
										
										
											2021-06-17 01:57:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/Array.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-06-13 10:47:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/CharacterTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-05-10 12:01:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/HashTable.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ScopeGuard.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <AK/StdLibExtras.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-10-15 20:46:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/TemporaryChange.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-29 10:34:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/RegExpObject.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibRegex/Regex.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  JS  {  
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ScopePusher  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher ( Parser &  parser ,  ScopeNode *  node ,  bool  is_top_level ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        :  m_parser ( parser ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ,  m_is_top_level ( is_top_level ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_parent_scope  =  exchange ( m_parser . m_state . current_scope_pusher ,  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( node  | |  ( m_parent_scope  & &  ! is_top_level ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_node  =  m_parent_scope - > m_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_node  =  node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is_top_level ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_top_level_scope  =  m_parent_scope - > m_top_level_scope ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_top_level_scope  =  this ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  ScopePusher  function_scope ( Parser &  parser ,  FunctionBody &  function_body ,  Vector < FunctionDeclaration : : Parameter >  const &  parameters ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ScopePusher  scope_pusher ( parser ,  & function_body ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        scope_pusher . m_function_parameters  =  parameters ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parameter . binding . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( FlyString  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    scope_pusher . m_forbidden_lexical_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( NonnullRefPtr < BindingPattern >  const &  binding_pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    binding_pattern - > for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        scope_pusher . m_forbidden_lexical_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  scope_pusher ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  ScopePusher  program_scope ( Parser &  parser ,  Program &  program ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ScopePusher ( parser ,  & program ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 21:45:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  ScopePusher  block_scope ( Parser &  parser ,  ScopeNode &  node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ScopePusher ( parser ,  & node ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  ScopePusher  for_loop_scope ( Parser &  parser ,  RefPtr < ASTNode >  const &  init ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ScopePusher  scope_pusher ( parser ,  nullptr ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( init  & &  is < VariableDeclaration > ( * init ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  variable_declaration  =  static_cast < VariableDeclaration  const & > ( * init ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( variable_declaration . declaration_kind ( )  ! =  DeclarationKind : : Var )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                variable_declaration . for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    scope_pusher . m_forbidden_var_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  scope_pusher ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 21:45:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 13:34:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  ScopePusher  catch_scope ( Parser &  parser ,  RefPtr < BindingPattern >  const &  pattern ,  FlyString  const &  parameter ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ScopePusher  scope_pusher ( parser ,  nullptr ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            pattern - > for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                scope_pusher . m_forbidden_var_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 13:34:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( ! parameter . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            scope_pusher . m_var_names . set ( parameter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 21:45:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  scope_pusher ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 21:45:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  ScopePusher  static_init_block_scope ( Parser &  parser ,  ScopeNode &  node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ScopePusher ( parser ,  & node ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  ScopePusher  class_field_scope ( Parser &  parser ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ScopePusher ( parser ,  nullptr ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    void  add_declaration ( NonnullRefPtr < Declaration >  declaration ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 21:45:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( declaration - > is_lexical_declaration ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            declaration - > for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_var_names . contains ( name )  | |  m_forbidden_lexical_names . contains ( name )  | |  m_function_names . contains ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    throw_identifier_declared ( name ,  declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_lexical_names . set ( name )  ! =  AK : : HashSetResult : : InsertedNewEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    throw_identifier_declared ( name ,  declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_node - > add_lexical_declaration ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ! declaration - > is_function_declaration ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            declaration - > for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ScopePusher *  pusher  =  this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( pusher - > m_lexical_names . contains ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        | |  pusher - > m_function_names . contains ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        | |  pusher - > m_forbidden_var_names . contains ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        throw_identifier_declared ( name ,  declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    pusher - > m_var_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( pusher - > m_is_top_level ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    VERIFY ( pusher - > m_parent_scope  ! =  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    pusher  =  pusher - > m_parent_scope ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( pusher - > m_is_top_level  & &  pusher - > m_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                pusher - > m_node - > add_var_scoped_declaration ( declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( m_top_level_scope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_top_level_scope - > m_node - > add_var_scoped_declaration ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_is_top_level  & &  m_parser . m_program_type  = =  Program : : Type : : Script )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                declaration - > for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_var_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_node - > add_var_scoped_declaration ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( is < FunctionDeclaration > ( * declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  function_declaration  =  static_cast < FunctionDeclaration  const & > ( * declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  function_name  =  function_declaration . name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_var_names . contains ( function_name )  | |  m_lexical_names . contains ( function_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    throw_identifier_declared ( function_name ,  declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( function_declaration . kind ( )  ! =  FunctionKind : : Regular  | |  m_parser . m_state . strict_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( m_function_names . contains ( function_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        throw_identifier_declared ( function_name ,  declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_lexical_names . set ( function_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_node - > add_lexical_declaration ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_function_names . set ( function_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! m_lexical_names . contains ( function_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_functions_to_hoist . append ( static_ptr_cast < FunctionDeclaration > ( declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_node - > add_lexical_declaration ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 21:45:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopePusher  const *  last_function_scope ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  scope_ptr  =  this ;  scope_ptr ;  scope_ptr  =  scope_ptr - > m_parent_scope )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( scope_ptr - > m_function_parameters . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  scope_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < FunctionDeclaration : : Parameter >  const &  function_parameters ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  * m_function_parameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher *  parent_scope ( )  {  return  m_parent_scope ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher  const *  parent_scope ( )  const  {  return  m_parent_scope ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [[nodiscard]]  bool  has_declaration ( StringView  name )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  m_lexical_names . contains ( name )  | |  m_var_names . contains ( name )  | |  ! m_functions_to_hoist . find_if ( [ & name ] ( auto &  function )  {  return  function - > name ( )  = =  name ;  } ) . is_end ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  contains_direct_call_to_eval ( )  const  {  return  m_contains_direct_call_to_eval ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  contains_access_to_arguments_object ( )  const  {  return  m_contains_access_to_arguments_object ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    void  set_contains_direct_call_to_eval ( )  {  m_contains_direct_call_to_eval  =  true ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    void  set_contains_access_to_arguments_object ( )  {  m_contains_access_to_arguments_object  =  true ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ~ ScopePusher ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( m_is_top_level  | |  m_parent_scope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_contains_access_to_arguments_object )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  it  :  m_identifier_and_argument_index_associations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( auto &  identifier  :  it . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! has_declaration ( identifier . string ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        identifier . set_lexically_bound_function_argument_index ( it . key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  m_functions_to_hoist . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  const &  function_declaration  =  m_functions_to_hoist [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_lexical_names . contains ( function_declaration . name ( ) )  | |  m_forbidden_var_names . contains ( function_declaration . name ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_is_top_level ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_node - > add_hoisted_function ( move ( m_functions_to_hoist [ i ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_parent_scope - > m_functions_to_hoist . append ( move ( m_functions_to_hoist [ i ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_parent_scope  & &  ! m_function_parameters . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_parent_scope - > m_contains_access_to_arguments_object  | =  m_contains_access_to_arguments_object ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_parent_scope - > m_contains_direct_call_to_eval  | =  m_contains_direct_call_to_eval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( m_parser . m_state . current_scope_pusher  = =  this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_parser . m_state . current_scope_pusher  =  m_parent_scope ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    void  associate_identifier_with_argument_index ( NonnullRefPtr < Identifier >  identifier ,  size_t  index ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_identifier_and_argument_index_associations . ensure ( index ) . append ( move ( identifier ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    void  throw_identifier_declared ( FlyString  const &  name ,  NonnullRefPtr < Declaration >  const &  declaration ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_parser . syntax_error ( String : : formatted ( " Identifier '{}' already declared " ,  name ) ,  declaration - > source_range ( ) . start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Parser &  m_parser ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopeNode *  m_node  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  m_is_top_level  {  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher *  m_parent_scope  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher *  m_top_level_scope  {  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < FlyString >  m_lexical_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < FlyString >  m_var_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < FlyString >  m_function_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < FlyString >  m_forbidden_lexical_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < FlyString >  m_forbidden_var_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < FunctionDeclaration >  m_functions_to_hoist ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < Vector < FunctionDeclaration : : Parameter > >  m_function_parameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashMap < size_t ,  NonnullRefPtrVector < Identifier > >  m_identifier_and_argument_index_associations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  m_contains_access_to_arguments_object  {  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  m_contains_direct_call_to_eval  {  false  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  OperatorPrecedenceTable  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    constexpr  OperatorPrecedenceTable ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  m_token_precedence ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  array_size ( m_operator_precedence ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  op  =  m_operator_precedence [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_token_precedence [ static_cast < size_t > ( op . token ) ]  =  op . precedence ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:24:43 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    constexpr  int  get ( TokenType  token )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        int  p  =  m_token_precedence [ static_cast < size_t > ( token ) ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 16:55:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            warnln ( " Internal Error: No precedence for operator {} " ,  Token : : name ( token ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  m_token_precedence [ cs_num_of_js_tokens ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    struct  OperatorPrecedence  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TokenType  token ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        int  precedence ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  constexpr  const  OperatorPrecedence  m_operator_precedence [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Period ,  20  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : BracketOpen ,  20  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : ParenOpen ,  20  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : QuestionMarkPeriod ,  20  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : New ,  19  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : PlusPlus ,  18  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : MinusMinus ,  18  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : ExclamationMark ,  17  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Tilde ,  17  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Typeof ,  17  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Void ,  17  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Delete ,  17  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Await ,  17  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : DoubleAsterisk ,  16  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : Asterisk ,  15  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Slash ,  15  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Percent ,  15  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : Plus ,  14  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Minus ,  14  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : ShiftLeft ,  13  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : ShiftRight ,  13  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : UnsignedShiftRight ,  13  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : LessThan ,  12  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : LessThanEquals ,  12  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : GreaterThan ,  12  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : GreaterThanEquals ,  12  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : In ,  12  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Instanceof ,  12  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : EqualsEquals ,  11  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : ExclamationMarkEquals ,  11  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : EqualsEqualsEquals ,  11  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : ExclamationMarkEqualsEquals ,  11  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : Ampersand ,  10  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : Caret ,  9  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : Pipe ,  8  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : DoubleQuestionMark ,  7  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : DoubleAmpersand ,  6  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : DoublePipe ,  5  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : QuestionMark ,  4  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Equals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : PlusEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : MinusEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : DoubleAsteriskEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : AsteriskEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : SlashEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : PercentEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : ShiftLeftEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : ShiftRightEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : UnsignedShiftRightEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : AmpersandEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : CaretEquals ,  3  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  TokenType : : PipeEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : DoubleAmpersandEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : DoublePipeEquals ,  3  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : DoubleQuestionMarkEquals ,  3  } , 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Yield ,  2  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  TokenType : : Comma ,  1  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								constexpr  OperatorPrecedenceTable  g_operator_precedence ;  
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:30:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Parser : : ParserState : : ParserState ( Lexer  l ,  Program : : Type  program_type )  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :  lexer ( move ( l ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:30:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( program_type  = =  Program : : Type : : Module ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lexer . disallow_html_comments ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    current_token  =  lexer . next ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:30:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Parser : : Parser ( Lexer  lexer ,  Program : : Type  program_type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  m_state ( move ( lexer ) ,  program_type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_program_type ( program_type ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 19:46:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Associativity  Parser : : operator_associativity ( TokenType  type )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Period : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : BracketOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : ParenOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : QuestionMarkPeriod : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Asterisk : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Slash : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Percent : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Plus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Minus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : ShiftLeft : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : ShiftRight : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : UnsignedShiftRight : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : LessThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : LessThanEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : GreaterThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : GreaterThanEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : In : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Instanceof : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : EqualsEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : ExclamationMarkEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : EqualsEqualsEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : ExclamationMarkEqualsEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 11:48:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Typeof : 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 17:55:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Void : 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Delete : 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Await : 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Ampersand : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Caret : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Pipe : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : DoubleQuestionMark : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : DoubleAmpersand : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : DoublePipe : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Comma : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Associativity : : Left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Associativity : : Right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : parse_directive ( ScopeNode &  body )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  found_use_strict  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( ! done ( )  & &  match ( TokenType : : StringLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // It cannot be a labelled function since we hit a string literal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  statement  =  parse_statement ( AllowLabelledFunction : : No ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        body . append ( statement ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( is < ExpressionStatement > ( * statement ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  expression  =  static_cast < ExpressionStatement  const & > ( * statement ) . expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! is < StringLiteral > ( expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  string_literal  =  static_cast < StringLiteral  const & > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( string_literal . is_use_strict_directive ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            found_use_strict  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_state . string_legacy_octal_escape_sequence_in_scope ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Octal escape sequence in string literal not allowed in strict mode " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . string_legacy_octal_escape_sequence_in_scope  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  found_use_strict ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 20:13:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Program >  Parser : : parse_program ( bool  starts_in_strict_mode )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:30:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  program  =  adopt_ref ( * new  Program ( {  m_filename ,  rule_start . position ( ) ,  position ( )  } ,  m_program_type ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopePusher  program_scope  =  ScopePusher : : program_scope ( * this ,  * program ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_program_type  = =  Program : : Type : : Script ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parse_script ( program ,  starts_in_strict_mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parse_module ( program ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    program - > source_range ( ) . end  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  program ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Parser : : parse_script ( Program &  program ,  bool  starts_in_strict_mode )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  strict_before  =  m_state . strict_mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( starts_in_strict_mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . strict_mode  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  has_use_strict  =  parse_directive ( program ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . strict_mode  | |  has_use_strict )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        program . set_strict_mode ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 20:13:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . strict_mode  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 22:22:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parse_statement_list ( program ,  AllowLabelledFunction : : Yes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! done ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        expected ( " statement or declaration " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . strict_mode  =  strict_before ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Parser : : parse_module ( Program &  program )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryChange  strict_mode_rollback ( m_state . strict_mode ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryChange  await_expression_valid_rollback ( m_state . await_expression_is_valid ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Since strict mode is already enabled we skip any directive parsing.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    while  ( ! done ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        parse_statement_list ( program ,  AllowLabelledFunction : : Yes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( done ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_export_or_import ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( m_state . current_token . type ( )  = =  TokenType : : Export  | |  m_state . current_token . type ( )  = =  TokenType : : Import ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_state . current_token . type ( )  = =  TokenType : : Export ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                program . append_export ( parse_export_statement ( program ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                program . append_import ( parse_import_statement ( program ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expected ( " statement or declaration " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  export_statement  :  program . exports ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( export_statement . has_statement ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  entry  :  export_statement . entries ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( entry . kind  = =  ExportStatement : : ExportEntry : : Kind : : ModuleRequest ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  const &  exported_name  =  entry . local_or_import_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  found  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            program . for_each_lexically_declared_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( name  = =  exported_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    found  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( found ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            program . for_each_var_declared_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( name  = =  exported_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    found  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  IterationDecision : : Break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  IterationDecision : : Continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! found ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " '{}' is not declared " ,  exported_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Declaration >  Parser : : parse_declaration ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . type ( )  = =  TokenType : : Async  & &  next_token ( ) . type ( )  = =  TokenType : : Function ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_function_node < FunctionDeclaration > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_state . current_token . type ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Class : 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-29 13:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_class_declaration ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Function : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_function_node < FunctionDeclaration > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Let : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Const : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_variable_declaration ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        expected ( " declaration " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < ErrorDeclaration > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Statement >  Parser : : parse_statement ( AllowLabelledFunction  allow_labelled_function )  
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : CurlyOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_block_statement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Return : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_return_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Var :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  declaration  =  parse_variable_declaration ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . current_scope_pusher - > add_declaration ( declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  declaration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : For : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_for_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : If : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_if_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Throw : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_throw_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_try_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Break : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_break_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Continue : 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-29 13:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_continue_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Switch : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_switch_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Do : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_do_while_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : While : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_while_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : With : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 19:17:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " 'with' statement not allowed in strict mode " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_with_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-30 17:26:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Debugger : 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-29 13:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_debugger_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-03 10:59:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Semicolon : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < EmptyStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 23:28:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Slash : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : SlashEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . current_token  =  m_state . lexer . force_slash_as_regex ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [[fallthrough]] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_invalid_escaped_keyword ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " Keyword must not contain escaped characters " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  result  =  try_parse_labelled_statement ( allow_labelled_function ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 13:36:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! result . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  result . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_expression ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 15:52:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : Async ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( lookahead_token . type ( )  = =  TokenType : : Function  & &  ! lookahead_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Async function declaration not allowed in single-statement context " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( match ( TokenType : : Function )  | |  match ( TokenType : : Class ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " {} declaration not allowed in single-statement context " ,  m_state . current_token . name ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 15:52:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( match ( TokenType : : Let )  & &  next_token ( ) . type ( )  = =  TokenType : : BracketOpen )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " let followed by [ is not allowed in single-statement context " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 15:52:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  expr  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  create_ast_node < ExpressionStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expr ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expected ( " statement " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < ErrorStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-29 13:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_invalid_escaped_keyword ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . current_token . type ( )  ! =  TokenType : : EscapedKeyword ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  token_value  =  m_state . current_token . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:25:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( token_value  = =  " await " sv ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  m_program_type  = =  Program : : Type : : Module  | |  m_state . await_expression_is_valid ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:25:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( token_value  = =  " async " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( token_value  = =  " yield " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  m_state . in_generator_function_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:25:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  token_value  ! =  " let " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  constexpr  AK : : Array < StringView ,  9 >  strict_reserved_words  =  {  " implements " ,  " interface " ,  " let " ,  " package " ,  " private " ,  " protected " ,  " public " ,  " static " ,  " yield "  } ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  is_strict_reserved_word ( StringView  str )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:55:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  any_of ( strict_reserved_words ,  [ & str ] ( StringView  word )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  word  = =  str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_simple_parameter_list ( Vector < FunctionNode : : Parameter >  const &  parameters )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  all_of ( parameters ,  [ ] ( FunctionNode : : Parameter  const &  parameter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ! parameter . is_rest  & &  parameter . default_value . is_null ( )  & &  parameter . binding . has < FlyString > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								RefPtr < FunctionExpression >  Parser : : try_parse_arrow_function_expression ( bool  expect_parens ,  bool  is_async )  
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_async ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( match ( TokenType : : Async ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! expect_parens  & &  ! is_async )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 02:51:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // NOTE: This is a fast path where we try to fail early in case this can't possibly
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       be a match. The idea is to avoid the expensive parser state save/load mechanism.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       The logic is duplicated below in the "real" !expect_parens branch.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! match_identifier ( )  & &  ! match ( TokenType : : Yield )  & &  ! match ( TokenType : : Await ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  token  =  next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 02:51:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( token . type ( )  ! =  TokenType : : Arrow ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    save_state ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-29 08:42:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ArmedScopeGuard  state_rollback_guard  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        load_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  function_kind  =  FunctionKind : : Regular ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( is_async )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Async ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_kind  =  FunctionKind : : Async ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . current_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Since we have async it can be followed by paren open in the expect_parens case
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // so we also consume that token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( expect_parens )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( match ( TokenType : : ParenOpen ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 11:46:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < FunctionNode : : Parameter >  parameters ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 20:02:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i32  function_length  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( expect_parens )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We have parens around the function parameters and can re-use the same parsing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // logic used for regular functions: multiple parameters, default values, rest
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // parameter, maybe a trailing comma. If we have a new syntax error afterwards we
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // check if it's about a wrong token (something like duplicate parameter name must
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // not abort), know parsing failed and rollback the parser state.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  previous_syntax_errors  =  m_state . errors . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TemporaryChange  in_async_context ( m_state . await_expression_is_valid ,  is_async  | |  m_state . await_expression_is_valid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parameters  =  parse_formal_parameters ( function_length ,  FunctionNodeParseOptions : : IsArrowFunction  |  ( is_async  ?  FunctionNodeParseOptions : : IsAsyncFunction  :  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_state . errors . size ( )  >  previous_syntax_errors  & &  m_state . errors [ previous_syntax_errors ] . message . starts_with ( " Unexpected token " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! match ( TokenType : : ParenClose ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // No parens - this must be an identifier followed by arrow. That's it.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! match_identifier ( )  & &  ! match ( TokenType : : Yield )  & &  ! match ( TokenType : : Await ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  token  =  consume_identifier_reference ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  token . value ( ) . is_one_of ( " arguments " sv ,  " eval " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " BindingIdentifier may not be 'arguments' or 'eval' in strict mode " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is_async  & &  token . value ( )  = =  " await " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'await' is a reserved identifier in async functions " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        parameters . append ( {  FlyString  {  token . value ( )  } ,  { }  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:29:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // If there's a newline between the closing paren and arrow it's not a valid arrow function,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // ASI should kick in instead (it'll then fail with "Unexpected token Arrow")
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:29:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : Arrow ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( function_length  = =  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 20:02:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        function_length  =  parameters . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  old_labels_in_scope  =  move ( m_state . labels_in_scope ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 10:49:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopeGuard  guard ( [ & ] ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . labels_in_scope  =  move ( old_labels_in_scope ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 10:49:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  contains_direct_call_to_eval  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  function_body_result  =  [ & ] ( )  - >  RefPtr < FunctionBody >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TemporaryChange  change ( m_state . in_arrow_function_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TemporaryChange  async_context_change ( m_state . await_expression_is_valid ,  is_async ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:29:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TemporaryChange  in_class_static_init_block_change ( m_state . in_class_static_init_block ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : CurlyOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Parse a function body with statements
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  parse_function_body ( parameters ,  function_kind ,  contains_direct_call_to_eval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match_expression ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Parse a function body which returns a single expression
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: We synthesize a block with a return statement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // for arrow function bodies which are a single expression.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Esprima generates a single "ArrowFunctionExpression"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // with a "body" property.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  return_block  =  create_ast_node < FunctionBody > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ScopePusher  function_scope  =  ScopePusher : : function_scope ( * this ,  return_block ,  parameters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  return_expression  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-28 10:42:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return_block - > append < ReturnStatement > ( {  m_filename ,  rule_start . position ( ) ,  position ( )  } ,  move ( return_expression ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return_block - > set_strict_mode ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            contains_direct_call_to_eval  =  function_scope . contains_direct_call_to_eval ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  return_block ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Invalid arrow function body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( function_body_result . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state_rollback_guard . disarm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    discard_saved_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  body  =  function_body_result . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( body - > in_strict_mode ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parameter . binding . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( FlyString  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    check_identifier_name_for_assignment_validity ( name ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( auto  const & )  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < FunctionExpression > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  " " ,  move ( body ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        move ( parameters ) ,  function_length ,  function_kind ,  body - > in_strict_mode ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        /* might_need_arguments_object */  false ,  contains_direct_call_to_eval ,  /* is_arrow_function */  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Replace the custom unwind mechanism with completions :^)
This includes:
- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
											 
										 
										
											2022-01-05 19:11:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								RefPtr < LabelledStatement >  Parser : : try_parse_labelled_statement ( AllowLabelledFunction  allow_function )  
						 
					
						
							
								
									
										
										
										
											2020-05-28 11:09:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-18 19:39:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: This is a fast path where we try to fail early to avoid the expensive save_state+load_state.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( next_token ( ) . type ( )  ! =  TokenType : : Colon ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 19:39:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 11:09:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    save_state ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-29 08:42:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 11:09:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ArmedScopeGuard  state_rollback_guard  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        load_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . value ( )  = =  " yield " sv  & &  ( m_state . strict_mode  | |  m_state . in_generator_function_context ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . value ( )  = =  " await " sv  & &  ( m_program_type  = =  Program : : Type : : Module  | |  m_state . await_expression_is_valid  | |  m_state . in_class_static_init_block ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  identifier  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . current_token . value ( )  = =  " await " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume_identifier_reference ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 11:09:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : Colon ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Colon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! match_statement ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    state_rollback_guard . disarm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    discard_saved_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . strict_mode  & &  identifier  = =  " let " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Strict mode reserved word 'let' is not allowed in label " ,  rule_start . position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Function )  & &  ( allow_function  = =  AllowLabelledFunction : : No  | |  m_state . strict_mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Not allowed to declare a function here " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . labels_in_scope . contains ( identifier ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( String : : formatted ( " Label '{}' has already been declared " ,  identifier ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Replace the custom unwind mechanism with completions :^)
This includes:
- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
											 
										 
										
											2022-01-05 19:11:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < Statement >  labelled_item ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  is_iteration_statement  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Function ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . labels_in_scope . set ( identifier ,  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  function_declaration  =  parse_function_node < FunctionDeclaration > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( m_state . current_scope_pusher ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . current_scope_pusher - > add_declaration ( function_declaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( function_declaration - > kind ( )  = =  FunctionKind : : Generator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Generator functions cannot be defined in labelled statements " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( function_declaration - > kind ( )  = =  FunctionKind : : Async ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Async functions cannot be defined in labelled statements " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Replace the custom unwind mechanism with completions :^)
This includes:
- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
											 
										 
										
											2022-01-05 19:11:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        labelled_item  =  move ( function_declaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . labels_in_scope . set ( identifier ,  { } ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Replace the custom unwind mechanism with completions :^)
This includes:
- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
											 
										 
										
											2022-01-05 19:11:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        labelled_item  =  parse_statement ( allow_function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Extract the innermost statement from a potentially nested chain of LabelledStatements.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  statement  =  labelled_item ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( is < LabelledStatement > ( * statement ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            statement  =  static_cast < LabelledStatement & > ( * statement ) . labelled_item ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < IterationStatement > ( * statement ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            is_iteration_statement  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! is_iteration_statement )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  entry  =  m_state . labels_in_scope . find ( identifier ) ;  entry  ! =  m_state . labels_in_scope . end ( )  & &  entry - > value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " labelled continue statement cannot use non iterating statement " ,  m_state . labels_in_scope . get ( identifier ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 01:01:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . labels_in_scope . remove ( identifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 11:09:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Replace the custom unwind mechanism with completions :^)
This includes:
- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
											 
										 
										
											2022-01-05 19:11:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < LabelledStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  identifier ,  labelled_item . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 11:09:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								RefPtr < MetaProperty >  Parser : : try_parse_new_target_expression ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:41:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Optimization which skips the save/load state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( next_token ( ) . type ( )  ! =  TokenType : : Period ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    save_state ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-29 08:42:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ArmedScopeGuard  state_rollback_guard  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        load_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : New ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:41:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Period ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : Identifier ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // The string 'target' cannot have escapes so we check original value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( consume ( ) . original_value ( )  ! =  " target " sv ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state_rollback_guard . disarm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-29 16:47:39 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    discard_saved_state ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < MetaProperty > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  MetaProperty : : Type : : NewTarget ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								RefPtr < MetaProperty >  Parser : : try_parse_import_meta_expression ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Optimization which skips the save/load state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( next_token ( ) . type ( )  ! =  TokenType : : Period ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    save_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ArmedScopeGuard  state_rollback_guard  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        load_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Import ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Period ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : Identifier ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The string 'meta' cannot have escapes so we check original value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( consume ( ) . original_value ( )  ! =  " meta " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state_rollback_guard . disarm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    discard_saved_state ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < MetaProperty > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  MetaProperty : : Type : : ImportMeta ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullRefPtr < ImportCall >  Parser : : parse_import_call ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // We use the extended definition:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //  ImportCall[Yield, Await]:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //      import(AssignmentExpression[+In, ?Yield, ?Await] ,opt)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //      import(AssignmentExpression[+In, ?Yield, ?Await] ,AssignmentExpression[+In, ?Yield, ?Await] ,opt)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // From https://tc39.es/proposal-import-assertions/#sec-evaluate-import-call
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Import ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  argument  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < Expression >  options ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! match ( TokenType : : ParenClose ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            options  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Second optional comma
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < ImportCall > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( argument ) ,  move ( options ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ClassDeclaration >  Parser : : parse_class_declaration ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ClassDeclaration > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  parse_class_expression ( true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullRefPtr < ClassExpression >  Parser : : parse_class_expression ( bool  expect_class_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Classes are always in strict mode.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  strict_mode_rollback ( m_state . strict_mode ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Class ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    NonnullRefPtrVector < ClassElement >  elements ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < Expression >  super_class ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < FunctionExpression >  constructor ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    HashTable < FlyString >  found_private_names ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    String  class_name  =  expect_class_name  | |  match_identifier ( )  | |  match ( TokenType : : Yield )  | |  match ( TokenType : : Await ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ?  consume_identifier_reference ( ) . value ( ) . to_string ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    check_identifier_name_for_assignment_validity ( class_name ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:29:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . in_class_static_init_block  & &  class_name  = =  " await " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Identifier must not be a reserved word in modules ('await') " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Extends ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  [ expression ,  should_continue_parsing ]  =  parse_primary_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-17 23:19:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Basically a (much) simplified parse_secondary_expression().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : TemplateLiteralStart ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  template_literal  =  parse_template_literal ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expression  =  create_ast_node < TaggedTemplateLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expression ) ,  move ( template_literal ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : BracketOpen )  | |  match ( TokenType : : Period )  | |  match ( TokenType : : ParenOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  precedence  =  g_operator_precedence . get ( m_state . current_token . type ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expression  =  parse_secondary_expression ( move ( expression ) ,  precedence ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        super_class  =  move ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ( void ) should_continue_parsing ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    HashTable < StringView >  referenced_private_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < StringView > *  outer_referenced_private_names  =  m_state . referenced_private_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . referenced_private_names  =  & referenced_private_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopeGuard  restore_private_name_table  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . referenced_private_names  =  outer_referenced_private_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( ! done ( )  & &  ! match ( TokenType : : CurlyClose ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        RefPtr < Expression >  property_key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  is_static  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  is_constructor  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:37:00 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  is_generator  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  is_async  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  method_kind  =  ClassMethod : : Kind : : Method ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Semicolon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Async ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:30:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( lookahead_token . type ( )  ! =  TokenType : : Semicolon  & &  lookahead_token . type ( )  ! =  TokenType : : CurlyClose 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & &  ! lookahead_token . trivia_contains_line_terminator ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                is_async  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:37:00 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Asterisk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            is_generator  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        StringView  name ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_property_key ( )  | |  match ( TokenType : : PrivateIdentifier ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! is_generator  & &  ! is_async  & &  m_state . current_token . original_value ( )  = =  " static " sv )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:37:00 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( match ( TokenType : : Identifier ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    is_static  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( match ( TokenType : : Async ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        is_async  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:37:00 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( match ( TokenType : : Asterisk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        is_generator  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : Identifier ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  identifier_name  =  m_state . current_token . original_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( identifier_name  = =  " get " sv )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    method_kind  =  ClassMethod : : Kind : : Getter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  if  ( identifier_name  = =  " set " sv )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    method_kind  =  ClassMethod : : Kind : : Setter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( match_property_key ( )  | |  match ( TokenType : : PrivateIdentifier ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                switch  ( m_state . current_token . type ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                case  TokenType : : Identifier : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    property_key  =  create_ast_node < StringLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                case  TokenType : : PrivateIdentifier : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( name  = =  " #constructor " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( " Private property with name '#constructor' is not allowed " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( method_kind  ! =  ClassMethod : : Kind : : Method )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // It is a Syntax Error if PrivateBoundIdentifiers of ClassElementList contains any duplicate entries,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        //   unless the name is used once for a getter and once for a setter and in no other entries,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        //   and the getter and setter are either both static or both non-static.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        for  ( auto &  element  :  elements )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            auto  private_name  =  element . private_bound_identifier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( ! private_name . has_value ( )  | |  private_name . value ( )  ! =  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( element . class_element_kind ( )  ! =  ClassElement : : ElementKind : : Method 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                | |  element . is_static ( )  ! =  is_static )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                syntax_error ( String : : formatted ( " Duplicate private field or method named '{}' " ,  name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            VERIFY ( is < ClassMethod > ( element ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            auto &  class_method_element  =  static_cast < ClassMethod  const & > ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( class_method_element . kind ( )  = =  ClassMethod : : Kind : : Method  | |  class_method_element . kind ( )  = =  method_kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                syntax_error ( String : : formatted ( " Duplicate private field or method named '{}' " ,  name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        found_private_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  if  ( found_private_names . set ( name )  ! =  AK : : HashSetResult : : InsertedNewEntry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( String : : formatted ( " Duplicate private field or method named '{}' " ,  name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    property_key  =  create_ast_node < PrivateIdentifier > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                case  TokenType : : StringLiteral :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  string_literal  =  parse_string_literal ( consume ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  string_literal - > value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    property_key  =  move ( string_literal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    property_key  =  parse_property_key ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.
Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.
To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:
Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455
After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37
This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).
The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:
    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();
test262 reports no changes in either direction, apart from a speedup :^)
											 
										 
										
											2021-10-05 08:44:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // https://tc39.es/ecma262/#sec-class-definitions-static-semantics-early-errors
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:30:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // ClassElement : static MethodDefinition
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                //   It is a Syntax Error if PropName of MethodDefinition is "prototype".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( is_static  & &  name  = =  " prototype " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Classes may not have a static property named 'prototype' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:30:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( ( match ( TokenType : : ParenOpen )  | |  match ( TokenType : : Equals )  | |  match ( TokenType : : Semicolon )  | |  match ( TokenType : : CurlyClose ) )  & &  ( is_static  | |  is_async  | |  method_kind  ! =  ClassMethod : : Kind : : Method ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 11:50:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                switch  ( method_kind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  ClassMethod : : Kind : : Method : 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( is_async )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        name  =  " async " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        is_async  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        VERIFY ( is_static ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        name  =  " static " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        is_static  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 11:50:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  ClassMethod : : Kind : : Getter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  " get " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    method_kind  =  ClassMethod : : Kind : : Method ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                case  ClassMethod : : Kind : : Setter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  " set " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    method_kind  =  ClassMethod : : Kind : : Method ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                property_key  =  create_ast_node < StringLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( match ( TokenType : : CurlyOpen )  & &  is_static )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  static_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  static_init_block  =  create_ast_node < FunctionBody > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TemporaryChange  break_context_rollback ( m_state . in_break_context ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TemporaryChange  continue_context_rollback ( m_state . in_continue_context ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TemporaryChange  function_context_rollback ( m_state . in_function_context ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TemporaryChange  generator_function_context_rollback ( m_state . in_generator_function_context ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TemporaryChange  async_function_context_rollback ( m_state . await_expression_is_valid ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TemporaryChange  class_field_initializer_rollback ( m_state . in_class_field_initializer ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TemporaryChange  class_static_init_block_rollback ( m_state . in_class_static_init_block ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-19 02:06:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                TemporaryChange  super_property_access_rollback ( m_state . allow_super_property_lookup ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-20 21:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ScopePusher  static_init_scope  =  ScopePusher : : static_init_block_scope ( * this ,  * static_init_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parse_statement_list ( static_init_block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                elements . append ( create_ast_node < StaticInitializer > ( {  m_state . current_token . filename ( ) ,  static_start . position ( ) ,  position ( )  } ,  move ( static_init_block ) ,  static_init_scope . contains_direct_call_to_eval ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expected ( " property key " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Constructor may be a StringLiteral or an Identifier.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! is_static  & &  name  = =  " constructor " sv )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( method_kind  ! =  ClassMethod : : Kind : : Method ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Class constructor may not be an accessor " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! constructor . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Classes may not have more than one constructor " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:37:00 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( is_generator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Class constructor may not be a generator " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( is_async ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Class constructor may not be async " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                is_constructor  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : ParenOpen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            u8  parse_options  =  FunctionNodeParseOptions : : AllowSuperPropertyLookup ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 11:50:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! super_class . is_null ( )  & &  ! is_static  & &  is_constructor ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : AllowSuperConstructorCall ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( method_kind  = =  ClassMethod : : Kind : : Getter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsGetterFunction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( method_kind  = =  ClassMethod : : Kind : : Setter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsSetterFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:37:00 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_generator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsGeneratorFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_async ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsAsyncFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  function  =  parse_function_node < FunctionExpression > ( parse_options ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_constructor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                constructor  =  move ( function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( ! property_key . is_null ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                elements . append ( create_ast_node < ClassMethod > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  property_key . release_nonnull ( ) ,  move ( function ) ,  method_kind ,  is_static ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " No key for class method " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( is_generator  | |  is_async )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expected ( " ParenOpen " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( property_key . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expected ( " property key " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( name  = =  " constructor " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Class cannot have field named 'constructor' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            RefPtr < Expression >  initializer ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bool  contains_direct_call_to_eval  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : Equals ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TemporaryChange  super_property_access_rollback ( m_state . allow_super_property_lookup ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                TemporaryChange  field_initializer_rollback ( m_state . in_class_field_initializer ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  class_field_scope  =  ScopePusher : : class_field_scope ( * this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                initializer  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                contains_direct_call_to_eval  =  class_field_scope . contains_direct_call_to_eval ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-13 19:59:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            elements . append ( create_ast_node < ClassField > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  property_key . release_nonnull ( ) ,  move ( initializer ) ,  contains_direct_call_to_eval ,  is_static ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( constructor . is_null ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  constructor_body  =  create_ast_node < BlockStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! super_class . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Set constructor to the result of parsing the source text
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // constructor(... args){ super (...args);}
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  super_call  =  create_ast_node < SuperCall > ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                Vector  {  CallExpression : : Argument  {  create_ast_node < Identifier > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  " args " ) ,  true  }  } ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Replace the custom unwind mechanism with completions :^)
This includes:
- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
  each IterationStatement subclass; and IterationStatement evaluation
  via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
  return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
  the spec, using completions
- Honoring result completion types in AsyncBlockStart and
  OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
  VM::throw_exception() now exclusively sets an exception and no longer
  triggers any unwinding mechanism.
  However, we already did a good job updating all of LibWeb and userland
  applications to not use it, and the few remaining uses elsewhere don't
  rely on unwinding AFAICT.
											 
										 
										
											2022-01-05 19:11:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // NOTE: While the JS approximation above doesn't do `return super(...args)`, the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // abstract closure is expected to capture and return the result, so we do need a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // return statement here to create the correct completion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            constructor_body - > append ( create_ast_node < ReturnStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( super_call ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 03:38:05 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            constructor  =  create_ast_node < FunctionExpression > ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  class_name ,  move ( constructor_body ) , 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.
Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.
To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:
Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455
After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37
This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).
The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:
    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();
test262 reports no changes in either direction, apart from a speedup :^)
											 
										 
										
											2021-10-05 08:44:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                Vector  {  FunctionNode : : Parameter  {  FlyString  {  " args "  } ,  nullptr ,  true  }  } ,  0 ,  FunctionKind : : Regular , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                /* is_strict_mode */  true ,  /* might_need_arguments_object */  false ,  /* contains_direct_call_to_eval */  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 03:38:05 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            constructor  =  create_ast_node < FunctionExpression > ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  class_name ,  move ( constructor_body ) , 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.
Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.
To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:
Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455
After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37
This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).
The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:
    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();
test262 reports no changes in either direction, apart from a speedup :^)
											 
										 
										
											2021-10-05 08:44:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                Vector < FunctionNode : : Parameter >  { } ,  0 ,  FunctionKind : : Regular , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                /* is_strict_mode */  true ,  /* might_need_arguments_object */  false ,  /* contains_direct_call_to_eval */  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // We could be in a subclass defined within the main class so must move all non declared private names to outer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  private_name  :  referenced_private_names )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( found_private_names . contains ( private_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( outer_referenced_private_names ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            outer_referenced_private_names - > set ( private_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  // FIXME: Make these error appear in the appropriate places.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Reference to undeclared private field or method '{}' " ,  private_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:09:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ClassExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( class_name ) ,  move ( constructor ) ,  move ( super_class ) ,  move ( elements ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Parser : : PrimaryExpressionParseResult  Parser : : parse_primary_expression ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 09:51:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match_unary_prefixed_expression ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_unary_prefixed_expression ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 09:51:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  try_arrow_function_parse_or_fail  =  [ this ] ( Position  const &  position ,  bool  expect_paren ,  bool  is_async  =  false )  - >  RefPtr < FunctionExpression >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( try_parse_arrow_function_expression_failed_at_position ( position ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  arrow_function  =  try_parse_arrow_function_expression ( expect_paren ,  is_async ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( arrow_function ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  arrow_function ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_try_parse_arrow_function_expression_failed_at_position ( position ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_state . current_token . type ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : ParenOpen :  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-11 22:41:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  paren_position  =  position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ( match ( TokenType : : ParenClose )  | |  match_identifier ( )  | |  match ( TokenType : : TripleDot )  | |  match ( TokenType : : CurlyOpen )  | |  match ( TokenType : : BracketOpen ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  arrow_function_result  =  try_arrow_function_parse_or_fail ( paren_position ,  true ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 17:11:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  {  arrow_function_result . release_nonnull ( ) ,  false  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  expression  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 12:44:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is < FunctionExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto &  function  =  static_cast < FunctionExpression & > ( * expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( function . kind ( )  = =  FunctionKind : : Generator  & &  function . name ( )  = =  " yield " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " function is not allowed to be called 'yield' in this context " ,  function . source_range ( ) . start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( function . kind ( )  = =  FunctionKind : : Async  & &  function . name ( )  = =  " await " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " function is not allowed to be called 'await' in this context " ,  function . source_range ( ) . start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 12:44:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  move ( expression )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 00:42:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : This : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  create_ast_node < ThisExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Class : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_class_expression ( false )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Super : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_state . allow_super_property_lookup ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " 'super' keyword unexpected here " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  create_ast_node < SuperExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : EscapedKeyword : 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:25:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_invalid_escaped_keyword ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " Keyword must not contain escaped characters " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        [[fallthrough]] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Identifier :  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    read_as_identifier : ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto  arrow_function_result  =  try_arrow_function_parse_or_fail ( position ( ) ,  false ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  {  arrow_function_result . release_nonnull ( ) ,  false  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-11 22:41:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  string  =  m_state . current_token . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // This could be 'eval' or 'arguments' and thus needs a custom check (`eval[1] = true`)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  ( string  = =  " let "  | |  is_strict_reserved_word ( string ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Identifier must not be a reserved word in strict mode ('{}') " ,  string ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_identifier ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:26:09 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : NumericLiteral : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  create_ast_node < NumericLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume_and_validate_numeric_literal ( ) . double_value ( ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : BigIntLiteral : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  create_ast_node < BigIntLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . value ( ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : BoolLiteral : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  create_ast_node < BooleanLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . bool_value ( ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:05:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : StringLiteral : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_string_literal ( consume ( ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 23:32:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : NullLiteral : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  create_ast_node < NullLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : CurlyOpen : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_object_expression ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Async :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // No valid async function (arrow or not) can have a line terminator after the async since asi would kick in.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( lookahead_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            goto  read_as_identifier ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( lookahead_token . type ( )  = =  TokenType : : Function ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  {  parse_function_node < FunctionExpression > ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( lookahead_token . type ( )  = =  TokenType : : ParenOpen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  arrow_function_result  =  try_arrow_function_parse_or_fail ( position ( ) ,  true ,  true ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  {  arrow_function_result . release_nonnull ( ) ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( lookahead_token . is_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  arrow_function_result  =  try_arrow_function_parse_or_fail ( position ( ) ,  false ,  true ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  {  arrow_function_result . release_nonnull ( ) ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        goto  read_as_identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:52:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Function : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_function_node < FunctionExpression > ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : BracketOpen : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_array_expression ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : RegexLiteral : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_regexp_literal ( )  } ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : TemplateLiteralStart : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_template_literal ( false )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : New :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  new_start  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  new_target_result  =  try_parse_new_target_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! new_target_result . is_null ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-19 02:06:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! m_state . in_function_context  & &  ! m_state . in_class_static_init_block ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                syntax_error ( " 'new.target' not allowed outside of a function " ,  new_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  {  new_target_result . release_nonnull ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_new_expression ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Import :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( lookahead_token . type ( )  = =  TokenType : : ParenOpen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  {  parse_import_call ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 12:15:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( lookahead_token . type ( )  = =  TokenType : : Period )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  import_meta  =  try_parse_import_meta_expression ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_program_type  ! =  Program : : Type : : Module ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " import.meta is only allowed in modules " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  {  import_meta . release_nonnull ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expected ( " import.meta or import call " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Yield : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_state . in_generator_function_context ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            goto  read_as_identifier ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  {  parse_yield_expression ( ) ,  false  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Await : 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_state . await_expression_is_valid ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            goto  read_as_identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  {  parse_await_expression ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 02:05:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : PrivateIdentifier : 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:16:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( next_token ( ) . type ( )  ! =  TokenType : : In ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Cannot have a private identifier in expression if not followed by 'in' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 02:05:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is_private_identifier_valid ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Reference to undeclared private field or method '{}' " ,  m_state . current_token . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  {  create_ast_node < PrivateIdentifier > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . value ( ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_identifier_name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            goto  read_as_identifier ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    expected ( " primary expression " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  {  create_ast_node < ErrorExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < RegExpLiteral >  Parser : : parse_regexp_literal ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 11:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  pattern  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Remove leading and trailing slash.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pattern  =  pattern . substring_view ( 1 ,  pattern . length ( )  -  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 10:34:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 12:01:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  flags  =  String : : empty ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 10:34:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  parsed_flags  =  RegExpObject : : default_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 12:01:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : RegexFlags ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  flags_start  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        flags  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 10:34:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  parsed_flags_or_error  =  regex_flags_from_string ( flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( parsed_flags_or_error . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( parsed_flags_or_error . release_error ( ) ,  flags_start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parsed_flags  =  parsed_flags_or_error . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 12:01:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 10:34:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  parsed_pattern  =  parse_regex_pattern ( pattern ,  parsed_flags . has_flag_set ( ECMAScriptFlags : : Unicode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  parsed_regex  =  Regex < ECMA262 > : : parse_pattern ( parsed_pattern ,  parsed_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( parsed_regex . error  ! =  regex : : Error : : NoError ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( String : : formatted ( " RegExp compile error: {} " ,  Regex < ECMA262 > ( parsed_regex ,  parsed_pattern ,  parsed_flags ) . error_string ( ) ) ,  rule_start . position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SourceRange  range  {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < RegExpLiteral > ( move ( range ) ,  move ( parsed_regex ) ,  move ( parsed_pattern ) ,  move ( parsed_flags ) ,  pattern . to_string ( ) ,  move ( flags ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 11:23:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Expression >  Parser : : parse_unary_prefixed_expression ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  precedence  =  g_operator_precedence . get ( m_state . current_token . type ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  associativity  =  operator_associativity ( m_state . current_token . type ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( m_state . current_token . type ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:39:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : PlusPlus :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  rhs_start  =  position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:39:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  rhs  =  parse_expression ( precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 20:03:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: Apparently for functions this should also not be enforced on a parser level,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // other engines throw ReferenceError for ++foo()
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is < Identifier > ( * rhs )  & &  ! is < MemberExpression > ( * rhs ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Right-hand side of prefix increment operator must be identifier or member expression, got {} " ,  rhs - > class_name ( ) ) ,  rhs_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  is < Identifier > ( * rhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier  =  static_cast < Identifier & > ( * rhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  name  =  identifier . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UpdateExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UpdateOp : : Increment ,  move ( rhs ) ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:39:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : MinusMinus :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  rhs_start  =  position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:39:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  rhs  =  parse_expression ( precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 20:03:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: Apparently for functions this should also not be enforced on a parser level,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // other engines throw ReferenceError for --foo()
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is < Identifier > ( * rhs )  & &  ! is < MemberExpression > ( * rhs ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Right-hand side of prefix decrement operator must be identifier or member expression, got {} " ,  rhs - > class_name ( ) ) ,  rhs_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  is < Identifier > ( * rhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier  =  static_cast < Identifier & > ( * rhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  name  =  identifier . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UpdateExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UpdateOp : : Decrement ,  move ( rhs ) ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:39:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : ExclamationMark : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UnaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UnaryOp : : Not ,  parse_expression ( precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Tilde : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UnaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UnaryOp : : BitwiseNot ,  parse_expression ( precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 17:58:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Plus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UnaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UnaryOp : : Plus ,  parse_expression ( precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 17:58:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Minus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UnaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UnaryOp : : Minus ,  parse_expression ( precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 06:33:32 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Typeof : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UnaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UnaryOp : : Typeof ,  parse_expression ( precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 17:55:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Void : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-19 02:28:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: This check is really hiding the fact that we don't deal with different expressions correctly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Yield )  & &  m_state . in_generator_function_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'yield' is not an identifier in generator function context " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UnaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UnaryOp : : Void ,  parse_expression ( precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Delete :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  rhs_start  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  rhs  =  parse_expression ( precedence ,  associativity ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < Identifier > ( * rhs )  & &  m_state . strict_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Delete of an unqualified identifier in strict mode. " ,  rhs_start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is < MemberExpression > ( * rhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  member_expression  =  static_cast < MemberExpression  const & > ( * rhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( member_expression . ends_in_private_name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Private fields cannot be deleted " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UnaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UnaryOp : : Delete ,  move ( rhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expected ( " primary expression " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < ErrorExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Expression >  Parser : : parse_property_key ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : StringLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_string_literal ( consume ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( match ( TokenType : : NumericLiteral ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < NumericLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . double_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( match ( TokenType : : BigIntLiteral ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BigIntLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( match ( TokenType : : BracketOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : BracketOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 18:43:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  result  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( TokenType : : BracketClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! match_identifier_name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expected ( " IdentifierName " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < StringLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 11:23:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ObjectExpression >  Parser : : parse_object_expression ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 02:29:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    NonnullRefPtrVector < ObjectProperty >  properties ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ObjectProperty : : Type  property_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:48:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Optional < SourceRange >  invalid_object_literal_property_range ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  skip_to_next_property  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( ! done ( )  & &  ! match ( TokenType : : Comma )  & &  ! match ( TokenType : : CurlyOpen ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // It is a Syntax Error if PropertyNameList of PropertyDefinitionList contains any duplicate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // entries for "__proto__" and at least two of those entries were obtained from productions  of
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 16:01:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // the form PropertyDefinition : PropertyKey : AssignmentExpression .
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  has_direct_proto_property  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 18:29:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( ! done ( )  & &  ! match ( TokenType : : CurlyClose ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        property_type  =  ObjectProperty : : Type : : KeyValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        RefPtr < Expression >  property_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 19:37:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        RefPtr < Expression >  property_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 14:52:59 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        FunctionKind  function_kind  {  FunctionKind : : Regular  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 21:52:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_name  =  parse_expression ( 4 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            properties . append ( create_ast_node < ObjectProperty > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  * property_name ,  nullptr ,  ObjectProperty : : Type : : Spread ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Async ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 16:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( lookahead_token . type ( )  ! =  TokenType : : ParenOpen  & &  lookahead_token . type ( )  ! =  TokenType : : Colon 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:36:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                & &  lookahead_token . type ( )  ! =  TokenType : : Comma  & &  lookahead_token . type ( )  ! =  TokenType : : CurlyClose 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & &  lookahead_token . type ( )  ! =  TokenType : : Async 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 16:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                & &  ! lookahead_token . trivia_contains_line_terminator ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                consume ( TokenType : : Async ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                function_kind  =  FunctionKind : : Async ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 14:52:59 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Asterisk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_type  =  ObjectProperty : : Type : : KeyValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_name  =  parse_property_key ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( function_kind  = =  FunctionKind : : Regular  | |  function_kind  = =  FunctionKind : : Async ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            function_kind  =  function_kind  = =  FunctionKind : : Regular  ?  FunctionKind : : Generator  :  FunctionKind : : AsyncGenerator ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( match_identifier ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  identifier  =  consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( identifier . original_value ( )  = =  " get " sv  & &  match_property_key ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                property_type  =  ObjectProperty : : Type : : Getter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                property_name  =  parse_property_key ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( identifier . original_value ( )  = =  " set " sv  & &  match_property_key ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                property_type  =  ObjectProperty : : Type : : Setter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                property_name  =  parse_property_key ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                property_name  =  create_ast_node < StringLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  identifier . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                property_value  =  create_ast_node < Identifier > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  identifier . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-06 22:17:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            property_name  =  parse_property_key ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  is_proto  =  ( type  = =  TokenType : : StringLiteral  | |  type  = =  TokenType : : Identifier )  & &  is < StringLiteral > ( * property_name )  & &  static_cast < StringLiteral  const & > ( * property_name ) . value ( )  = =  " __proto__ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( property_type  = =  ObjectProperty : : Type : : Getter  | |  property_type  = =  ObjectProperty : : Type : : Setter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! match ( TokenType : : ParenOpen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                expected ( " '(' for object getter or setter property " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                skip_to_next_property ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 17:28:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-06 22:17:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:48:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Equals ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Not a valid object literal, but a valid assignment target
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Parse the expression and throw it away
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  expression  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! invalid_object_literal_property_range . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                invalid_object_literal_property_range  =  expression - > source_range ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : ParenOpen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( property_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            u8  parse_options  =  FunctionNodeParseOptions : : AllowSuperPropertyLookup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( property_type  = =  ObjectProperty : : Type : : Getter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsGetterFunction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( property_type  = =  ObjectProperty : : Type : : Setter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsSetterFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( function_kind  = =  FunctionKind : : Generator  | |  function_kind  = =  FunctionKind : : AsyncGenerator ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 14:52:59 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsGeneratorFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( function_kind  = =  FunctionKind : : Async  | |  function_kind  = =  FunctionKind : : AsyncGenerator ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                parse_options  | =  FunctionNodeParseOptions : : IsAsyncFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  function  =  parse_function_node < FunctionExpression > ( parse_options ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            properties . append ( create_ast_node < ObjectProperty > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  * property_name ,  function ,  property_type ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : Colon ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 17:08:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! property_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                expected ( " a property name " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 17:08:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                skip_to_next_property ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 22:50:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:32:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_proto )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( has_direct_proto_property ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Property name '__proto__' must not appear more than once in object literal " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                has_direct_proto_property  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            properties . append ( create_ast_node < ObjectProperty > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  * property_name ,  parse_expression ( 2 ) ,  property_type ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 17:08:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( property_name  & &  property_value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:36:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_state . strict_mode  & &  is < StringLiteral > ( * property_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  string_literal  =  static_cast < StringLiteral  const & > ( * property_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( is_strict_reserved_word ( string_literal . value ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( String : : formatted ( " '{}' is a reserved keyword " ,  string_literal . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            properties . append ( create_ast_node < ObjectProperty > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  * property_name ,  * property_value ,  property_type ,  false ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 17:08:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expected ( " a property " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 17:08:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            skip_to_next_property ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 02:29:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:48:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ObjectExpression > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move ( properties ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move ( invalid_object_literal_property_range ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ArrayExpression >  Parser : : parse_array_expression ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : BracketOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < RefPtr < Expression > >  elements ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( match_expression ( )  | |  match ( TokenType : : TripleDot )  | |  match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        RefPtr < Expression >  expression ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : TripleDot ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expression  =  create_ast_node < SpreadExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  parse_expression ( 2 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( match_expression ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expression  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 23:05:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 20:09:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elements . append ( expression ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : BracketClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ArrayExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( elements ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:29:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-24 09:58:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < StringLiteral >  Parser : : parse_string_literal ( const  Token &  token ,  bool  in_template_literal )  
						 
					
						
							
								
									
										
										
										
											2020-05-16 23:27:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 23:27:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  status  =  Token : : StringValueStatus : : Ok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  string  =  token . string_value ( status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( status  ! =  Token : : StringValueStatus : : Ok )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        String  message ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 13:30:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( status  = =  Token : : StringValueStatus : : LegacyOctalEscapeSequence )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_state . string_legacy_octal_escape_sequence_in_scope  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 13:30:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( in_template_literal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                message  =  " Octal escape sequence not allowed in template literal " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else  if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 13:30:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                message  =  " Octal escape sequence in string literal not allowed in strict mode " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( status  = =  Token : : StringValueStatus : : MalformedHexEscape  | |  status  = =  Token : : StringValueStatus : : MalformedUnicodeEscape )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 23:27:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  type  =  status  = =  Token : : StringValueStatus : : MalformedUnicodeEscape  ?  " unicode "  :  " hexadecimal " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 14:53:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            message  =  String : : formatted ( " Malformed {} escape sequence " ,  type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 23:27:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( status  = =  Token : : StringValueStatus : : UnicodeEscapeOverflow )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:31:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            message  =  " Unicode code_point must not be greater than 0x10ffff in escape sequence " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 13:30:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 23:27:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 12:48:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! message . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( message ,  Position  {  token . line_number ( ) ,  token . line_column ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 23:27:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 22:22:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-01 21:49:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  is_use_strict_directive  =  ! in_template_literal  & &  ( token . value ( )  = =  " 'use strict' "  | |  token . value ( )  = =  " \" use strict \" " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 13:30:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < StringLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  string ,  is_use_strict_directive ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-16 23:27:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < TemplateLiteral >  Parser : : parse_template_literal ( bool  is_tagged )  
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : TemplateLiteralStart ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Expression >  expressions ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Expression >  raw_strings ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  append_empty_string  =  [ this ,  & rule_start ,  & expressions ,  & raw_strings ,  is_tagged ] ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  string_literal  =  create_ast_node < StringLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expressions . append ( string_literal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_tagged ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raw_strings . append ( string_literal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : TemplateLiteralString ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        append_empty_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 15:36:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( ! done ( )  & &  ! match ( TokenType : : TemplateLiteralEnd )  & &  ! match ( TokenType : : UnterminatedTemplateLiteral ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : TemplateLiteralString ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  token  =  consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 13:30:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expressions . append ( parse_string_literal ( token ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_tagged ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-01 18:34:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                raw_strings . append ( create_ast_node < StringLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  token . raw_template_value ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : TemplateLiteralExprStart ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : TemplateLiteralExprStart ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : TemplateLiteralExprEnd ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Empty template literal expression block " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  create_ast_node < TemplateLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  expressions ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expressions . append ( parse_expression ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : UnterminatedTemplateLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Unterminated template literal " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  create_ast_node < TemplateLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  expressions ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : TemplateLiteralExprEnd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! match ( TokenType : : TemplateLiteralString ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                append_empty_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 15:36:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expected ( " Template literal string or expression " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : UnterminatedTemplateLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Unterminated template literal " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : TemplateLiteralEnd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_tagged ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < TemplateLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  expressions ,  raw_strings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < TemplateLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  expressions ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-24 09:58:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Expression >  Parser : : parse_expression ( int  min_precedence ,  Associativity  associativity ,  const  Vector < TokenType > &  forbidden )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  [ expression ,  should_continue_parsing ]  =  parse_primary_expression ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:48:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  check_for_invalid_object_property  =  [ & ] ( auto &  expression )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < ObjectExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  range  =  static_cast < ObjectExpression & > ( * expression ) . invalid_property_range ( ) ;  range . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Invalid property in object literal " ,  range - > start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < Identifier > ( * expression )  & &  m_state . current_scope_pusher )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  identifier_instance  =  static_ptr_cast < Identifier > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  function_scope  =  m_state . current_scope_pusher - > last_function_scope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  function_parent_scope  =  function_scope  ?  function_scope - > parent_scope ( )  :  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  has_not_been_declared_as_variable  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  scope  =  m_state . current_scope_pusher ;  scope  ! =  function_parent_scope ;  scope  =  scope - > parent_scope ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( scope - > has_declaration ( identifier_instance - > string ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                has_not_been_declared_as_variable  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( has_not_been_declared_as_variable )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( identifier_instance - > string ( )  = =  " arguments " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . current_scope_pusher - > set_contains_access_to_arguments_object ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( match ( TokenType : : TemplateLiteralStart ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 16:34:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  template_literal  =  parse_template_literal ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expression  =  create_ast_node < TaggedTemplateLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expression ) ,  move ( template_literal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( should_continue_parsing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( match_secondary_expression ( forbidden ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            int  new_precedence  =  g_operator_precedence . get ( m_state . current_token . type ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( new_precedence  <  min_precedence ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( new_precedence  = =  min_precedence  & &  associativity  = =  Associativity : : Left ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:48:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            check_for_invalid_object_property ( expression ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Associativity  new_associativity  =  operator_associativity ( m_state . current_token . type ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expression  =  parse_secondary_expression ( move ( expression ) ,  new_precedence ,  new_associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:02:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            while  ( match ( TokenType : : TemplateLiteralStart )  & &  ! is < UpdateExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  template_literal  =  parse_template_literal ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                expression  =  create_ast_node < TaggedTemplateLiteral > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expression ) ,  move ( template_literal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 10:17:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:48:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:08:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < SuperExpression > ( * expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " 'super' keyword unexpected here " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:48:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    check_for_invalid_object_property ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 20:13:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < CallExpression > ( * expression )  & &  m_state . current_scope_pusher )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  callee  =  static_ptr_cast < CallExpression > ( expression ) - > callee ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < Identifier > ( callee ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier_instance  =  static_cast < Identifier  const & > ( callee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( identifier_instance . string ( )  = =  " eval " sv )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bool  has_not_been_declared_as_variable  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( auto  scope  =  m_state . current_scope_pusher ;  scope ;  scope  =  scope - > parent_scope ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( scope - > has_declaration ( identifier_instance . string ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        has_not_been_declared_as_variable  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( has_not_been_declared_as_variable ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_state . current_scope_pusher - > set_contains_direct_call_to_eval ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Comma )  & &  min_precedence  < =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        NonnullRefPtrVector < Expression >  expressions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        expressions . append ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expressions . append ( parse_expression ( 2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expression  =  create_ast_node < SequenceExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expressions ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 11:23:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Expression >  Parser : : parse_secondary_expression ( NonnullRefPtr < Expression >  lhs ,  int  min_precedence ,  Associativity  associativity )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_state . current_token . type ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Plus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : Addition ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : PlusEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : AdditionAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Minus : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : Subtraction ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : MinusEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : SubtractionAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:04:52 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Asterisk : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : Multiplication ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : AsteriskEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : MultiplicationAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:04:52 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Slash : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : Division ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : SlashEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : DivisionAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:17:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Percent : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : Modulo ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:07:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : PercentEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : ModuloAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 00:42:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoubleAsterisk : 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 13:40:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : Exponentiation ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:03:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoubleAsteriskEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : ExponentiationAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:10:27 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : GreaterThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : GreaterThan ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : GreaterThanEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : GreaterThanEquals ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:10:27 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : LessThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : LessThan ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : LessThanEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : LessThanEquals ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:11:33 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : EqualsEqualsEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : StrictlyEquals ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:11:33 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : ExclamationMarkEqualsEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : StrictlyInequals ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-16 00:23:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : EqualsEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : LooselyEquals ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-16 00:23:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : ExclamationMarkEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-24 00:06:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : LooselyInequals ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 16:06:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : In : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : In ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:56:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Instanceof : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : InstanceOf ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 13:02:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Ampersand : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : BitwiseAnd ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : AmpersandEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : BitwiseAndAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 13:02:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Pipe : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : BitwiseOr ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : PipeEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : BitwiseOrAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 13:02:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Caret : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : BitwiseXor ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : CaretEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : BitwiseXorAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : ShiftLeft : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : LeftShift ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : ShiftLeftEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : LeftShiftAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:45:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : ShiftRight : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : RightShift ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:45:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : ShiftRightEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : RightShiftAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : UnsignedShiftRight : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < BinaryExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  BinaryOp : : UnsignedRightShift ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : UnsignedShiftRightEquals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : UnsignedRightShiftAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : ParenOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_call_expression ( move ( lhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Equals : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : Assignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Period : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : PrivateIdentifier ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! is_private_identifier_valid ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " Reference to undeclared private field or method '{}' " ,  m_state . current_token . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  if  ( is < SuperExpression > ( * lhs ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " Cannot access private field or method '{}' on super " ,  m_state . current_token . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  create_ast_node < MemberExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( lhs ) ,  create_ast_node < PrivateIdentifier > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ! match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 20:31:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expected ( " IdentifierName " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < MemberExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( lhs ) ,  create_ast_node < Identifier > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  consume ( ) . value ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:51:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : BracketOpen :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : BracketOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  expression  =  create_ast_node < MemberExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( lhs ) ,  parse_expression ( 0 ) ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:51:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( TokenType : : BracketClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  expression ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : PlusPlus : 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 20:03:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: Apparently for functions this should also not be enforced on a parser level,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // other engines throw ReferenceError for foo()++
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is < Identifier > ( * lhs )  & &  ! is < MemberExpression > ( * lhs ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 14:53:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Left-hand side of postfix increment operator must be identifier or member expression, got {} " ,  lhs - > class_name ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  is < Identifier > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier  =  static_cast < Identifier & > ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  name  =  identifier . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UpdateExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UpdateOp : : Increment ,  move ( lhs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : MinusMinus : 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 20:03:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: Apparently for functions this should also not be enforced on a parser level,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // other engines throw ReferenceError for foo()--
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is < Identifier > ( * lhs )  & &  ! is < MemberExpression > ( * lhs ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 14:53:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Left-hand side of postfix increment operator must be identifier or member expression, got {} " ,  lhs - > class_name ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  is < Identifier > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  identifier  =  static_cast < Identifier & > ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  name  =  identifier . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < UpdateExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  UpdateOp : : Decrement ,  move ( lhs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 23:35:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoubleAmpersand : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < LogicalExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  LogicalOp : : And ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoubleAmpersandEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : AndAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-15 23:35:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoublePipe : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < LogicalExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  LogicalOp : : Or ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoublePipeEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : OrAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoubleQuestionMark : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < LogicalExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  LogicalOp : : NullishCoalescing ,  move ( lhs ) ,  parse_expression ( min_precedence ,  associativity ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : DoubleQuestionMarkEquals : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_assignment_expression ( AssignmentOp : : NullishAssignment ,  move ( lhs ) ,  min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : QuestionMark : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_conditional_expression ( move ( lhs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : QuestionMarkPeriod : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: This should allow `(new Foo)?.bar', but as our parser strips parenthesis,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //        we can't really tell if `lhs' was parenthesized at this point.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < NewExpression > ( lhs . ptr ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'new' cannot be used with optional chaining " ,  position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  lhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  parse_optional_chain ( move ( lhs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expected ( " secondary expression " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < ErrorExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 22:45:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : is_private_identifier_valid ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( match ( TokenType : : PrivateIdentifier ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_state . referenced_private_names ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // We might not have hit the declaration yet so class will check this in the end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . referenced_private_names - > set ( m_state . current_token . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								RefPtr < BindingPattern >  Parser : : synthesize_binding_pattern ( Expression  const &  expression )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( is < ArrayExpression > ( expression )  | |  is < ObjectExpression > ( expression ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Clear any syntax error that has occurred in the range that 'expression' spans.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . errors . remove_all_matching ( [ range  =  expression . source_range ( ) ] ( auto  const &  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  error . position . has_value ( )  & &  range . contains ( * error . position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Make a parser and parse the source for this expression as a binding pattern.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  source  =  m_state . lexer . source ( ) . substring_view ( expression . source_range ( ) . start . offset  -  2 ,  expression . source_range ( ) . end . offset  -  expression . source_range ( ) . start . offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Lexer  lexer  {  source ,  m_state . lexer . filename ( ) ,  expression . source_range ( ) . start . line ,  expression . source_range ( ) . start . column  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Parser  parser  {  lexer  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . strict_mode  =  m_state . strict_mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . allow_super_property_lookup  =  m_state . allow_super_property_lookup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . allow_super_constructor_call  =  m_state . allow_super_constructor_call ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . in_function_context  =  m_state . in_function_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . in_formal_parameter_context  =  m_state . in_formal_parameter_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . in_generator_function_context  =  m_state . in_generator_function_context ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser . m_state . await_expression_is_valid  =  m_state . await_expression_is_valid ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser . m_state . in_arrow_function_context  =  m_state . in_arrow_function_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . in_break_context  =  m_state . in_break_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . in_continue_context  =  m_state . in_continue_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . string_legacy_octal_escape_sequence_in_scope  =  m_state . string_legacy_octal_escape_sequence_in_scope ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parser . m_state . in_class_field_initializer  =  m_state . in_class_field_initializer ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser . m_state . in_class_static_init_block  =  m_state . in_class_static_init_block ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 21:10:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parser . m_state . referenced_private_names  =  m_state . referenced_private_names ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  result  =  parser . parse_binding_pattern ( AllowDuplicates : : Yes ,  AllowMemberExpressions : : Yes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( parser . has_errors ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . errors . extend ( parser . errors ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < AssignmentExpression >  Parser : : parse_assignment_expression ( AssignmentOp  assignment_op ,  NonnullRefPtr < Expression >  lhs ,  int  min_precedence ,  Associativity  associativity )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( match ( TokenType : : Equals ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  match ( TokenType : : PlusEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : MinusEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : AsteriskEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : SlashEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : PercentEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : DoubleAsteriskEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : AmpersandEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : PipeEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : CaretEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : ShiftLeftEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : ShiftRightEquals ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  match ( TokenType : : UnsignedShiftRightEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : DoubleAmpersandEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : DoublePipeEquals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  match ( TokenType : : DoubleQuestionMarkEquals ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 01:16:17 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( assignment_op  = =  AssignmentOp : : Assignment )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < ArrayExpression > ( * lhs )  | |  is < ObjectExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  binding_pattern  =  synthesize_binding_pattern ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( binding_pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  rhs  =  parse_expression ( min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  create_ast_node < AssignmentExpression > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    assignment_op , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    binding_pattern . release_nonnull ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    move ( rhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! is < Identifier > ( * lhs )  & &  ! is < MemberExpression > ( * lhs )  & &  ! is < CallExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " Invalid left-hand side in assignment " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( m_state . strict_mode  & &  is < Identifier > ( * lhs ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  name  =  static_cast < const  Identifier & > ( * lhs ) . string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( m_state . strict_mode  & &  is < CallExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 00:00:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " Cannot assign to function call " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 12:44:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rhs  =  parse_expression ( min_precedence ,  associativity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < AssignmentExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  assignment_op ,  move ( lhs ) ,  move ( rhs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-04 23:58:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Identifier >  Parser : : parse_identifier ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  identifier_start  =  position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  token  =  consume_identifier ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . in_class_field_initializer  & &  token . value ( )  = =  " arguments " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " 'arguments' is not allowed in class field initializer " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  m_state . current_token . filename ( ) ,  identifier_start ,  position ( )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        token . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Vector < CallExpression : : Argument >  Parser : : parse_arguments ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < CallExpression : : Argument >  arguments ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 19:35:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( match_expression ( )  | |  match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            arguments . append ( {  parse_expression ( 2 ) ,  true  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            arguments . append ( {  parse_expression ( 2 ) ,  false  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 20:03:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 19:35:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  arguments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullRefPtr < Expression >  Parser : : parse_call_expression ( NonnullRefPtr < Expression >  lhs )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_state . allow_super_constructor_call  & &  is < SuperExpression > ( * lhs ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " 'super' keyword unexpected here " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  arguments  =  parse_arguments ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:30:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < SuperExpression > ( * lhs ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  create_ast_node < SuperCall > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( arguments ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < CallExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( lhs ) ,  move ( arguments ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < NewExpression >  Parser : : parse_new_expression ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : New ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  callee  =  parse_expression ( g_operator_precedence . get ( TokenType : : New ) ,  Associativity : : Right ,  {  TokenType : : ParenOpen ,  TokenType : : QuestionMarkPeriod  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < ImportCall > ( * callee ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Cannot call new on dynamic import " ,  callee - > source_range ( ) . start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < CallExpression : : Argument >  arguments ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : ParenOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        while  ( match_expression ( )  | |  match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                arguments . append ( {  parse_expression ( 2 ) ,  true  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                arguments . append ( {  parse_expression ( 2 ) ,  false  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 22:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < NewExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( callee ) ,  move ( arguments ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 16:33:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < YieldExpression >  Parser : : parse_yield_expression ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:31:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . in_formal_parameter_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " 'Yield' expression is not allowed in formal parameters of generator function " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Yield ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < Expression >  argument ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  yield_from  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_state . current_token . trivia_contains_line_terminator ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Asterisk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            yield_from  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( yield_from  | |  match_expression ( )  | |  match ( TokenType : : Class ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            argument  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 15:46:41 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < YieldExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( argument ) ,  yield_from ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 22:52:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < AwaitExpression >  Parser : : parse_await_expression ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . in_formal_parameter_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " 'Await' expression is not allowed in formal parameters of an async function " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Await ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  precedence  =  g_operator_precedence . get ( TokenType : : Await ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  associativity  =  operator_associativity ( TokenType : : Await ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  argument  =  parse_expression ( precedence ,  associativity ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < AwaitExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( argument ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 11:23:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ReturnStatement >  Parser : : parse_return_statement ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_state . in_function_context  & &  ! m_state . in_arrow_function_context ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 11:33:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " 'return' not allowed outside of a function " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Return ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Automatic semicolon insertion: terminate statement when return is followed by newline
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  create_ast_node < ReturnStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( match_expression ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 14:00:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  expression  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < ReturnStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expression ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 14:00:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ReturnStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Parser : : parse_statement_list ( ScopeNode &  output_node ,  AllowLabelledFunction  allow_labelled_functions )  
						 
					
						
							
								
									
										
										
										
											2020-10-03 17:02:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( ! done ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match_declaration ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  declaration  =  parse_declaration ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY ( m_state . current_scope_pusher ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state . current_scope_pusher - > add_declaration ( declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            output_node . append ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match_statement ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            output_node . append ( parse_statement ( allow_labelled_functions ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-03 17:02:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// FunctionBody, https://tc39.es/ecma262/#prod-FunctionBody
  
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < FunctionBody >  Parser : : parse_function_body ( Vector < FunctionDeclaration : : Parameter >  const &  parameters ,  FunctionKind  function_kind ,  bool &  contains_direct_call_to_eval )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  function_body  =  create_ast_node < FunctionBody > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher  function_scope  =  ScopePusher : : function_scope ( * this ,  function_body ,  parameters ) ;  // FIXME <-
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  has_use_strict  =  parse_directive ( function_body ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  previous_strict_mode  =  m_state . strict_mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_use_strict )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . strict_mode  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_body - > set_strict_mode ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! is_simple_parameter_list ( parameters ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Illegal 'use strict' directive in function with non-simple parameter list " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( previous_strict_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_body - > set_strict_mode ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 22:22:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    parse_statement_list ( function_body ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 22:22:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // If the function contains 'use strict' we need to check the parameters (again).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( function_body - > in_strict_mode ( )  | |  function_kind  ! =  FunctionKind : : Regular )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Vector < StringView >  parameter_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parameter . binding . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( FlyString  const &  parameter_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    check_identifier_name_for_assignment_validity ( parameter_name ,  function_body - > in_strict_mode ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( function_kind  = =  FunctionKind : : Generator  & &  parameter_name  = =  " yield " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( " Parameter name 'yield' not allowed in this context " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( function_kind  = =  FunctionKind : : Async  & &  parameter_name  = =  " await " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( " Parameter name 'await' not allowed in this context " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    for  ( auto &  previous_name  :  parameter_names )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( previous_name  = =  parameter_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            syntax_error ( String : : formatted ( " Duplicate parameter '{}' not allowed in strict mode " ,  parameter_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    parameter_names . append ( parameter_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( NonnullRefPtr < BindingPattern >  const &  binding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    binding - > for_each_bound_name ( [ & ] ( auto &  bound_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( function_kind  = =  FunctionKind : : Generator  & &  bound_name  = =  " yield " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            syntax_error ( " Parameter name 'yield' not allowed in this context " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        if  ( function_kind  = =  FunctionKind : : Async  & &  bound_name  = =  " await " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            syntax_error ( " Parameter name 'await' not allowed in this context " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        for  ( auto &  previous_name  :  parameter_names )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( previous_name  = =  bound_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                syntax_error ( String : : formatted ( " Duplicate parameter '{}' not allowed in strict mode " ,  bound_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        parameter_names . append ( bound_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . strict_mode  =  previous_strict_mode ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    contains_direct_call_to_eval  =  function_scope . contains_direct_call_to_eval ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  function_body ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullRefPtr < BlockStatement >  Parser : : parse_block_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  block  =  create_ast_node < BlockStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher  block_scope  =  ScopePusher : : block_scope ( * this ,  block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parse_statement_list ( block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  block ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:52:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								template < typename  FunctionNodeType >  
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < FunctionNodeType >  Parser : : parse_function_node ( u8  parse_options )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( ! ( parse_options  &  FunctionNodeParseOptions : : IsGetterFunction  & &  parse_options  &  FunctionNodeParseOptions : : IsSetterFunction ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  super_property_access_rollback ( m_state . allow_super_property_lookup ,  ! ! ( parse_options  &  FunctionNodeParseOptions : : AllowSuperPropertyLookup ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryChange  super_constructor_call_rollback ( m_state . allow_super_constructor_call ,  ! ! ( parse_options  &  FunctionNodeParseOptions : : AllowSuperConstructorCall ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 11:51:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  break_context_rollback ( m_state . in_break_context ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryChange  continue_context_rollback ( m_state . in_continue_context ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:11:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  class_field_initializer_rollback ( m_state . in_class_field_initializer ,  false ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.
Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.
To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:
Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455
After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37
This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).
The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:
    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();
test262 reports no changes in either direction, apart from a speedup :^)
											 
										 
										
											2021-10-05 08:44:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  might_need_arguments_object_rollback ( m_state . function_might_need_arguments_object ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 15:11:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    constexpr  auto  is_function_expression  =  IsSame < FunctionNodeType ,  FunctionExpression > ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    FunctionKind  function_kind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( parse_options  &  FunctionNodeParseOptions : : IsGeneratorFunction )  ! =  0  & &  ( parse_options  &  FunctionNodeParseOptions : : IsAsyncFunction )  ! =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        function_kind  =  FunctionKind : : AsyncGenerator ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( ( parse_options  &  FunctionNodeParseOptions : : IsGeneratorFunction )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_kind  =  FunctionKind : : Generator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( ( parse_options  &  FunctionNodeParseOptions : : IsAsyncFunction )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_kind  =  FunctionKind : : Async ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_kind  =  FunctionKind : : Regular ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:52:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    String  name ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( parse_options  &  FunctionNodeParseOptions : : CheckForFunctionAndName )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( function_kind  = =  FunctionKind : : Regular  & &  match ( TokenType : : Async )  & &  ! next_token ( ) . trivia_contains_line_terminator ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            function_kind  =  FunctionKind : : Async ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Async ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parse_options  =  parse_options  |  FunctionNodeParseOptions : : IsAsyncFunction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( TokenType : : Function ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Asterisk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            function_kind  =  function_kind  = =  FunctionKind : : Regular  ?  FunctionKind : : Generator  :  FunctionKind : : AsyncGenerator ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            consume ( TokenType : : Asterisk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parse_options  =  parse_options  |  FunctionNodeParseOptions : : IsGeneratorFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-14 14:52:59 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( FunctionNodeType : : must_have_name ( )  | |  match_identifier ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            name  =  consume_identifier ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 15:11:11 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( is_function_expression  & &  ( match ( TokenType : : Yield )  | |  match ( TokenType : : Await ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:29:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-19 20:19:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( function_kind  = =  FunctionKind : : AsyncGenerator  & &  ( name  = =  " await " sv  | |  name  = =  " yield " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " async generator function is not allowed to be called '{}' " ,  name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:29:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_state . in_class_static_init_block  & &  name  = =  " await " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'await' is a reserved word " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:52:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:29:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  class_static_initializer_rollback ( m_state . in_class_static_init_block ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:53:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  generator_change ( m_state . in_generator_function_context ,  function_kind  = =  FunctionKind : : Generator  | |  function_kind  = =  FunctionKind : : AsyncGenerator ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  async_change ( m_state . await_expression_is_valid ,  function_kind  = =  FunctionKind : : Async  | |  function_kind  = =  FunctionKind : : AsyncGenerator ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 20:02:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i32  function_length  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  parameters  =  parse_formal_parameters ( function_length ,  parse_options ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( function_length  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function_length  =  parameters . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.
Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.
To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:
Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455
After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37
This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).
The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:
    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();
test262 reports no changes in either direction, apart from a speedup :^)
											 
										 
										
											2021-10-05 08:44:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  function_context_rollback ( m_state . in_function_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  old_labels_in_scope  =  move ( m_state . labels_in_scope ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopeGuard  guard ( [ & ] ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . labels_in_scope  =  move ( old_labels_in_scope ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  contains_direct_call_to_eval  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  body  =  parse_function_body ( parameters ,  function_kind ,  contains_direct_call_to_eval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  has_strict_directive  =  body - > in_strict_mode ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( has_strict_directive ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        check_identifier_name_for_assignment_validity ( name ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:15:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 03:38:05 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < FunctionNodeType > ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-04 03:12:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        name ,  move ( body ) ,  move ( parameters ) ,  function_length , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 12:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        function_kind ,  has_strict_directive ,  m_state . function_might_need_arguments_object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        contains_direct_call_to_eval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Vector < FunctionNode : : Parameter >  Parser : : parse_formal_parameters ( int &  function_length ,  u8  parse_options )  
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  has_default_parameter  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  has_rest_parameter  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:31:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  formal_parameter_context_change  {  m_state . in_formal_parameter_context ,  true  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < FunctionNode : : Parameter >  parameters ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  consume_identifier_or_binding_pattern  =  [ & ] ( )  - >  Variant < FlyString ,  NonnullRefPtr < BindingPattern > >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:37:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( auto  pattern  =  parse_binding_pattern ( AllowDuplicates : : No ,  AllowMemberExpressions : : No ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  pattern . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  token  =  consume_identifier ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  parameter_name  =  token . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        check_identifier_name_for_assignment_validity ( parameter_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bool  has_same_name  =  parameter . binding . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( FlyString  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  name  = =  parameter_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( NonnullRefPtr < BindingPattern >  const &  bindings )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    bool  found_duplicate  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    bindings - > for_each_bound_name ( [ & ] ( auto &  bound_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( bound_name  = =  parameter_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            found_duplicate  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  found_duplicate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! has_same_name ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:29:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            String  message ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( parse_options  &  FunctionNodeParseOptions : : IsArrowFunction ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                message  =  String : : formatted ( " Duplicate parameter '{}' not allowed in arrow function " ,  parameter_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else  if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                message  =  String : : formatted ( " Duplicate parameter '{}' not allowed in strict mode " ,  parameter_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  if  ( has_default_parameter  | |  match ( TokenType : : Equals ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                message  =  String : : formatted ( " Duplicate parameter '{}' not allowed in function with default parameter " ,  parameter_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  if  ( has_rest_parameter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                message  =  String : : formatted ( " Duplicate parameter '{}' not allowed in function with rest parameter " ,  parameter_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! message . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                syntax_error ( message ,  Position  {  token . line_number ( ) ,  token . line_column ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  FlyString  {  token . value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( match ( TokenType : : CurlyOpen )  | |  match ( TokenType : : BracketOpen )  | |  match_identifier ( )  | |  match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( parse_options  &  FunctionNodeParseOptions : : IsGetterFunction ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Getter function must have no arguments " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:43:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( parse_options  &  FunctionNodeParseOptions : : IsSetterFunction  & &  ( parameters . size ( )  > =  1  | |  match ( TokenType : : TripleDot ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " Setter function must have one argument " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  is_rest  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 16:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            has_rest_parameter  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 20:02:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            function_length  =  parameters . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            is_rest  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 16:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  parameter  =  consume_identifier_or_binding_pattern ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 11:46:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        RefPtr < Expression >  default_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Equals ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:47:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( is_rest ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Rest parameter may not have a default initializer " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 22:48:25 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            TemporaryChange  change ( m_state . in_function_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-25 11:14:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            has_default_parameter  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-05 20:02:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            function_length  =  parameters . size ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 17:27:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            default_value  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 10:14:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  is_generator  =  parse_options  &  FunctionNodeParseOptions : : IsGeneratorFunction ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ( is_generator  | |  m_state . strict_mode )  & &  default_value  & &  default_value - > fast_is < Identifier > ( )  & &  static_cast < Identifier & > ( * default_value ) . string ( )  = =  " yield " sv ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 10:14:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                syntax_error ( " Generator function parameter initializer cannot contain a reference to an identifier named  \" yield \" " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 11:46:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        parameters . append ( {  move ( parameter ) ,  default_value ,  is_rest  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-27 22:29:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : ParenClose )  | |  is_rest ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 18:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( parse_options  &  FunctionNodeParseOptions : : IsSetterFunction  & &  parameters . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Setter function must have one argument " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 00:26:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  parameters ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  constexpr  AK : : Array < StringView ,  36 >  s_reserved_words  =  {  " break " ,  " case " ,  " catch " ,  " class " ,  " const " ,  " continue " ,  " debugger " ,  " default " ,  " delete " ,  " do " ,  " else " ,  " enum " ,  " export " ,  " extends " ,  " false " ,  " finally " ,  " for " ,  " function " ,  " if " ,  " import " ,  " in " ,  " instanceof " ,  " new " ,  " null " ,  " return " ,  " super " ,  " switch " ,  " this " ,  " throw " ,  " true " ,  " try " ,  " typeof " ,  " var " ,  " void " ,  " while " ,  " with "  } ;  
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:49:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								RefPtr < BindingPattern >  Parser : : parse_binding_pattern ( Parser : : AllowDuplicates  allow_duplicates ,  Parser : : AllowMemberExpressions  allow_member_expressions )  
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TokenType  closing_token ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  is_object  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : BracketOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        closing_token  =  TokenType : : BracketClose ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        is_object  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( match ( TokenType : : CurlyOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        closing_token  =  TokenType : : CurlyClose ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Vector < BindingPattern : : BindingEntry >  entries ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( ! match ( closing_token ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is_object  & &  match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            entries . append ( BindingPattern : : BindingEntry  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  is_rest  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : TripleDot ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            is_rest  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        decltype ( BindingPattern : : BindingEntry : : name )  name  =  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        decltype ( BindingPattern : : BindingEntry : : alias )  alias  =  Empty  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        RefPtr < Expression >  initializer  =  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is_object )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bool  needs_alias  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( allow_member_expressions  = =  AllowMemberExpressions : : Yes  & &  is_rest )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  expression_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  expression  =  parse_expression ( 2 ,  Associativity : : Right ,  {  TokenType : : Equals  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( is < MemberExpression > ( * expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    alias  =  static_ptr_cast < MemberExpression > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  if  ( is < Identifier > ( * expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  static_ptr_cast < Identifier > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Invalid destructuring assignment target " ,  expression_position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( match_identifier_name ( )  | |  match ( TokenType : : StringLiteral )  | |  match ( TokenType : : NumericLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( match ( TokenType : : StringLiteral )  | |  match ( TokenType : : NumericLiteral ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    needs_alias  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( match ( TokenType : : StringLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  token  =  consume ( TokenType : : StringLiteral ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  string_literal  =  parse_string_literal ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        string_literal - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name  =  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        consume ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( match ( TokenType : : BracketOpen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:49:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  expression  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                name  =  move ( expression ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 14:49:42 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                consume ( TokenType : : BracketClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                expected ( " identifier or computed property name " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! is_rest  & &  match ( TokenType : : Colon ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( allow_member_expressions  = =  AllowMemberExpressions : : Yes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  expression_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  expression  =  parse_expression ( 2 ,  Associativity : : Right ,  {  TokenType : : Equals  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( is < ArrayExpression > ( * expression )  | |  is < ObjectExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( auto  synthesized_binding_pattern  =  synthesize_binding_pattern ( * expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            alias  =  synthesized_binding_pattern . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            syntax_error ( " Invalid destructuring assignment target " ,  expression_position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  if  ( is < MemberExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        alias  =  static_ptr_cast < MemberExpression > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  if  ( is < Identifier > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        alias  =  static_ptr_cast < Identifier > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( " Invalid destructuring assignment target " ,  expression_position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( match ( TokenType : : CurlyOpen )  | |  match ( TokenType : : BracketOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  binding_pattern  =  parse_binding_pattern ( allow_duplicates ,  allow_member_expressions ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( ! binding_pattern ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    alias  =  binding_pattern . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    alias  =  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        consume ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    expected ( " identifier or binding pattern " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( needs_alias )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expected ( " alias for string or numeric literal name " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( allow_member_expressions  = =  AllowMemberExpressions : : Yes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  expression_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  expression  =  parse_expression ( 2 ,  Associativity : : Right ,  {  TokenType : : Equals  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( is < ArrayExpression > ( * expression )  | |  is < ObjectExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( auto  synthesized_binding_pattern  =  synthesize_binding_pattern ( * expression ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        alias  =  synthesized_binding_pattern . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( " Invalid destructuring assignment target " ,  expression_position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( is < MemberExpression > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    alias  =  static_ptr_cast < MemberExpression > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( is < Identifier > ( * expression ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    alias  =  static_ptr_cast < Identifier > ( expression ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Invalid destructuring assignment target " ,  expression_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:49:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( match ( TokenType : : BracketOpen )  | |  match ( TokenType : : CurlyOpen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  pattern  =  parse_binding_pattern ( allow_duplicates ,  allow_member_expressions ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! pattern )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    expected ( " binding pattern " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                alias  =  pattern . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // BindingElement must always have an Empty name field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  identifier_name  =  consume_identifier ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                alias  =  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    identifier_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                expected ( " identifier or binding pattern " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Equals ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( is_rest )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Unexpected initializer after rest element " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            initializer  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! initializer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                expected ( " initialization expression " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        entries . append ( BindingPattern : : BindingEntry  {  move ( name ) ,  move ( alias ) ,  move ( initializer ) ,  is_rest  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( is_rest )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Rest element may not be followed by a comma " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:37:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( is_object  & &  ! match ( TokenType : : CurlyClose ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( ! is_object  & &  match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( closing_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 18:04:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  kind  =  is_object  ?  BindingPattern : : Kind : : Object  :  BindingPattern : : Kind : : Array ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  pattern  =  adopt_ref ( * new  BindingPattern ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pattern - > entries  =  move ( entries ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pattern - > kind  =  kind ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:49:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < StringView >  bound_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pattern - > for_each_bound_name ( [ & ] ( auto &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( allow_duplicates  = =  AllowDuplicates : : No )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:49:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( bound_names . contains_slow ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Duplicate parameter names in bindings " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bound_names . append ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  pattern ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-30 19:08:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < VariableDeclaration >  Parser : : parse_variable_declaration ( bool  for_loop_variable_declaration )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DeclarationKind  declaration_kind ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:16:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( m_state . current_token . type ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:16:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Var : 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        declaration_kind  =  DeclarationKind : : Var ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:16:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  TokenType : : Let : 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        declaration_kind  =  DeclarationKind : : Let ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:16:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 14:24:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  TokenType : : Const : 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 11:59:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        declaration_kind  =  DeclarationKind : : Const ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 14:24:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:16:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:16:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-30 19:08:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < VariableDeclarator >  declarations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 23:00:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Variant < NonnullRefPtr < Identifier > ,  NonnullRefPtr < BindingPattern > ,  Empty >  target  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_identifier ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:29:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  identifier_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  name  =  consume_identifier ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            target  =  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ( declaration_kind  = =  DeclarationKind : : Let  | |  declaration_kind  = =  DeclarationKind : : Const )  & &  name  = =  " let " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Lexical binding may not be called 'let' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( auto  pattern  =  parse_binding_pattern ( declaration_kind  ! =  DeclarationKind : : Var  ?  AllowDuplicates : : No  :  AllowDuplicates : : Yes ,  AllowMemberExpressions : : No ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            target  =  pattern . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ( declaration_kind  = =  DeclarationKind : : Let  | |  declaration_kind  = =  DeclarationKind : : Const ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                target . get < NonnullRefPtr < BindingPattern > > ( ) - > for_each_bound_name ( [ this ] ( auto &  name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( name  = =  " let " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( " Lexical binding may not be called 'let' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:55:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( ! m_state . in_generator_function_context  & &  match ( TokenType : : Yield ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Identifier must not be a reserved word in strict mode ('yield') " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            target  =  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( ! m_state . await_expression_is_valid  & &  match ( TokenType : : Async ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_program_type  = =  Program : : Type : : Module ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Identifier must not be a reserved word in modules ('async') " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:55:34 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            target  =  create_ast_node < Identifier > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( target . has < Empty > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            expected ( " identifier or a binding pattern " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        RefPtr < Expression >  init ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Equals ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // In a for loop 'in' can be ambiguous so we do not allow it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 14.7.4 The for Statement, https://tc39.es/ecma262/#prod-ForStatement and 14.7.5 The for-in, for-of, and for-await-of Statements, https://tc39.es/ecma262/#prod-ForInOfStatement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( for_loop_variable_declaration ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                init  =  parse_expression ( 2 ,  Associativity : : Right ,  {  TokenType : : In  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                init  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-30 19:08:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( ! for_loop_variable_declaration  & &  declaration_kind  = =  DeclarationKind : : Const )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Missing initializer in 'const' variable declaration " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 14:55:53 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( ! for_loop_variable_declaration  & &  target . has < NonnullRefPtr < BindingPattern > > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " Missing initializer in destructuring assignment " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        declarations . append ( create_ast_node < VariableDeclarator > ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-26 21:22:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            move ( target ) . downcast < NonnullRefPtr < Identifier > ,  NonnullRefPtr < BindingPattern > > ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 16:03:19 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            move ( init ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:46:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-30 19:08:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! for_loop_variable_declaration ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  declaration  =  create_ast_node < VariableDeclaration > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  declaration_kind ,  move ( declarations ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 16:42:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  declaration ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ThrowStatement >  Parser : : parse_throw_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Throw ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Automatic semicolon insertion: terminate statement when throw is followed by newline
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . trivia_contains_line_terminator ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:37:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " No line break is allowed between 'throw' and its expression " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < ThrowStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  create_ast_node < ErrorExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  expression  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ThrowStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expression ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < BreakStatement >  Parser : : parse_break_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Break ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 12:02:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    FlyString  target_label ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Semicolon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_state . current_token . trivia_contains_line_terminator ( )  & &  match_identifier ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            target_label  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  label  =  m_state . labels_in_scope . find ( target_label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( label  = =  m_state . labels_in_scope . end ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 10:49:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " Label '{}' not found " ,  target_label ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 12:02:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( target_label . is_null ( )  & &  ! m_state . in_break_context ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " Unlabeled 'break' not allowed outside of a loop or switch statement " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < BreakStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ContinueStatement >  Parser : : parse_continue_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_state . in_continue_context ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " 'continue' not allow outside of a loop " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Continue ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 12:02:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    FlyString  target_label ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Semicolon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  create_ast_node < ContinueStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 12:02:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_state . current_token . trivia_contains_line_terminator ( )  & &  match_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  label_position  =  position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 12:02:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        target_label  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  label  =  m_state . labels_in_scope . find ( target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( label  = =  m_state . labels_in_scope . end ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Label '{}' not found or invalid " ,  target_label ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:01:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            label - > value  =  label_position ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-08 10:49:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ContinueStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  target_label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ConditionalExpression >  Parser : : parse_conditional_expression ( NonnullRefPtr < Expression >  test )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : QuestionMark ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 14:42:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  consequent  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Colon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 14:42:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  alternate  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ConditionalExpression > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( test ) ,  move ( consequent ) ,  move ( alternate ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < OptionalChain >  Parser : : parse_optional_chain ( NonnullRefPtr < Expression >  base )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < OptionalChain : : Reference >  chain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : QuestionMarkPeriod ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : QuestionMarkPeriod ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            switch  ( m_state . current_token . type ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  TokenType : : ParenOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                chain . append ( OptionalChain : : Call  {  parse_arguments ( ) ,  OptionalChain : : Mode : : Optional  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  TokenType : : BracketOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                chain . append ( OptionalChain : : ComputedReference  {  parse_expression ( 0 ) ,  OptionalChain : : Mode : : Optional  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( TokenType : : BracketClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 23:32:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  TokenType : : PrivateIdentifier :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! is_private_identifier_valid ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( String : : formatted ( " Reference to undeclared private field or method '{}' " ,  m_state . current_token . value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  start  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  private_identifier  =  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                chain . append ( OptionalChain : : PrivateMemberReference  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    create_ast_node < PrivateIdentifier > ( {  m_state . current_token . filename ( ) ,  start ,  position ( )  } ,  private_identifier . value ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    OptionalChain : : Mode : : Optional  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            case  TokenType : : TemplateLiteralStart : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // 13.3.1.1 - Static Semantics: Early Errors
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // OptionalChain :
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                //        ?. TemplateLiteral
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                //        OptionalChain TemplateLiteral
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // This is a hard error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Invalid tagged template literal after ?. " ,  position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  start  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  identifier  =  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    chain . append ( OptionalChain : : MemberReference  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        create_ast_node < Identifier > ( {  m_state . current_token . filename ( ) ,  start ,  position ( )  } ,  identifier . value ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        OptionalChain : : Mode : : Optional , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Invalid optional chain reference after ?. " ,  position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : ParenOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            chain . append ( OptionalChain : : Call  {  parse_arguments ( ) ,  OptionalChain : : Mode : : NotOptional  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : Period ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 23:32:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : PrivateIdentifier ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  start  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  private_identifier  =  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                chain . append ( OptionalChain : : PrivateMemberReference  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    create_ast_node < PrivateIdentifier > ( {  m_state . current_token . filename ( ) ,  start ,  position ( )  } ,  private_identifier . value ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    OptionalChain : : Mode : : NotOptional , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  start  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  identifier  =  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                chain . append ( OptionalChain : : MemberReference  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    create_ast_node < Identifier > ( {  m_state . current_token . filename ( ) ,  start ,  position ( )  } ,  identifier . value ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    OptionalChain : : Mode : : NotOptional , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expected ( " an identifier " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : TemplateLiteralStart ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // 13.3.1.1 - Static Semantics: Early Errors
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // OptionalChain :
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //        ?. TemplateLiteral
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //        OptionalChain TemplateLiteral
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Invalid tagged template literal after optional chain " ,  position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : BracketOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            chain . append ( OptionalChain : : ComputedReference  {  parse_expression ( 2 ) ,  OptionalChain : : Mode : : NotOptional  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : BracketClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  while  ( ! done ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < OptionalChain > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move ( base ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move ( chain ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < TryStatement >  Parser : : parse_try_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Try ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  block  =  parse_block_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 20:54:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < CatchClause >  handler ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Catch ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handler  =  parse_catch_clause ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < BlockStatement >  finalizer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Finally ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        finalizer  =  parse_block_statement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 20:54:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! handler  & &  ! finalizer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " try statement must have a 'catch' or 'finally' clause " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < TryStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( block ) ,  move ( handler ) ,  move ( finalizer ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < DoWhileStatement >  Parser : : parse_do_while_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Do ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 16:57:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  body  =  [ & ] ( )  - >  NonnullRefPtr < Statement >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        TemporaryChange  break_change ( m_state . in_break_context ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TemporaryChange  continue_change ( m_state . in_continue_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  parse_statement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 16:57:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : While ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 16:57:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  test  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 16:57:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-27 19:16:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Since ES 2015 a missing semicolon is inserted here, despite the regular ASI rules not applying
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Semicolon ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 16:57:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < DoWhileStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( test ) ,  move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:29:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < WhileStatement >  Parser : : parse_while_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : While ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  test  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  break_change ( m_state . in_break_context ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryChange  continue_change ( m_state . in_continue_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  body  =  parse_statement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < WhileStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( test ) ,  move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < SwitchStatement >  Parser : : parse_switch_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Switch ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  determinant  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < SwitchCase >  cases ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  switch_statement  =  create_ast_node < SwitchStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( determinant ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopePusher  switch_scope  =  ScopePusher : : block_scope ( * this ,  switch_statement ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-18 23:12:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  has_default  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( match ( TokenType : : Case )  | |  match ( TokenType : : Default ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Default ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( has_default ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " Multiple 'default' clauses in switch statement " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            has_default  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch_statement - > add_case ( parse_switch_case ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-18 23:12:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  switch_statement ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < WithStatement >  Parser : : parse_with_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : With ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  object  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  body  =  parse_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < WithStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( object ) ,  move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < SwitchCase >  Parser : : parse_switch_case ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < Expression >  test ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( consume ( ) . type ( )  = =  TokenType : : Case )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        test  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Colon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtrVector < Statement >  consequent ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  break_change ( m_state . in_break_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  switch_case  =  create_ast_node < SwitchCase > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( test ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parse_statement_list ( switch_case ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  switch_case ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < CatchClause >  Parser : : parse_catch_clause ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Catch ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    FlyString  parameter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < BindingPattern >  pattern_parameter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  should_expect_parameter  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : ParenOpen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        should_expect_parameter  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:29:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_identifier_name ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            & &  ( ! match ( TokenType : : Yield )  | |  ! m_state . in_generator_function_context ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            & &  ( ! match ( TokenType : : Async )  | |  ! m_state . await_expression_is_valid ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:29:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            & &  ( ! match ( TokenType : : Await )  | |  ! m_state . in_class_static_init_block ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            parameter  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 01:11:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            pattern_parameter  =  parse_binding_pattern ( AllowDuplicates : : No ,  AllowMemberExpressions : : No ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( should_expect_parameter  & &  parameter . is_empty ( )  & &  ! pattern_parameter ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 23:30:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expected ( " an identifier or a binding pattern " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    HashTable < FlyString >  bound_names ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( pattern_parameter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pattern_parameter - > for_each_bound_name ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( auto &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bound_names . set ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! parameter . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        check_identifier_name_for_assignment_validity ( parameter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bound_names . set ( parameter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 13:34:13 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopePusher  catch_scope  =  ScopePusher : : catch_scope ( * this ,  pattern_parameter ,  parameter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  body  =  parse_block_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    body - > for_each_lexically_declared_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( bound_names . contains ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Identifier '{}' already declared as catch parameter " ,  name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:15:38 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( pattern_parameter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  create_ast_node < CatchClause > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            pattern_parameter . release_nonnull ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            move ( body ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < CatchClause > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move ( parameter ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:03:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < IfStatement >  Parser : : parse_if_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Function declarations in if statement clauses
https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses
B.3.4 FunctionDeclarations in IfStatement Statement Clauses
The following augments the IfStatement production in 13.6:
    IfStatement[Yield, Await, Return] :
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return]
        if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default]
This production only applies when parsing non-strict code. Code matching
this production is processed as if each matching occurrence of
FunctionDeclaration[?Yield, ?Await, ~Default] was the sole
StatementListItem of a BlockStatement occupying that position in the
source code. The semantics of such a synthetic BlockStatement includes
the web legacy compatibility semantics specified in B.3.3.
											 
										 
										
											2020-10-31 13:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  parse_function_declaration_as_block_statement  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Code matching this production is processed as if each matching occurrence of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FunctionDeclaration[?Yield, ?Await, ~Default] was the sole StatementListItem
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // of a BlockStatement occupying that position in the source code.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( match ( TokenType : : Function ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  block  =  create_ast_node < BlockStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ScopePusher  block_scope  =  ScopePusher : : block_scope ( * this ,  * block ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  declaration  =  parse_declaration ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( m_state . current_scope_pusher ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        block_scope . add_declaration ( declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( is < FunctionDeclaration > ( * declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  function_declaration  =  static_cast < FunctionDeclaration  const & > ( * declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( function_declaration . kind ( )  = =  FunctionKind : : Generator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Generator functions can only be declared in top-level or within a block " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( function_declaration . kind ( )  = =  FunctionKind : : Async ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Async functions can only be declared in top-level or within a block " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        block - > append ( move ( declaration ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Function declarations in if statement clauses
https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses
B.3.4 FunctionDeclarations in IfStatement Statement Clauses
The following augments the IfStatement production in 13.6:
    IfStatement[Yield, Await, Return] :
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return]
        if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default]
This production only applies when parsing non-strict code. Code matching
this production is processed as if each matching occurrence of
FunctionDeclaration[?Yield, ?Await, ~Default] was the sole
StatementListItem of a BlockStatement occupying that position in the
source code. The semantics of such a synthetic BlockStatement includes
the web legacy compatibility semantics specified in B.3.3.
											 
										 
										
											2020-10-31 13:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  block ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : If ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  predicate  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Function declarations in if statement clauses
https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses
B.3.4 FunctionDeclarations in IfStatement Statement Clauses
The following augments the IfStatement production in 13.6:
    IfStatement[Yield, Await, Return] :
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return]
        if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default]
This production only applies when parsing non-strict code. Code matching
this production is processed as if each matching occurrence of
FunctionDeclaration[?Yield, ?Await, ~Default] was the sole
StatementListItem of a BlockStatement occupying that position in the
source code. The semantics of such a synthetic BlockStatement includes
the web legacy compatibility semantics specified in B.3.3.
											 
										 
										
											2020-10-31 13:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < Statement >  consequent ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_state . strict_mode  & &  match ( TokenType : : Function ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Function declarations in if statement clauses
https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses
B.3.4 FunctionDeclarations in IfStatement Statement Clauses
The following augments the IfStatement production in 13.6:
    IfStatement[Yield, Await, Return] :
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return]
        if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default]
This production only applies when parsing non-strict code. Code matching
this production is processed as if each matching occurrence of
FunctionDeclaration[?Yield, ?Await, ~Default] was the sole
StatementListItem of a BlockStatement occupying that position in the
source code. The semantics of such a synthetic BlockStatement includes
the web legacy compatibility semantics specified in B.3.3.
											 
										 
										
											2020-10-31 13:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consequent  =  parse_function_declaration_as_block_statement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consequent  =  parse_statement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 16:46:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < Statement >  alternate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Else ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Function declarations in if statement clauses
https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses
B.3.4 FunctionDeclarations in IfStatement Statement Clauses
The following augments the IfStatement production in 13.6:
    IfStatement[Yield, Await, Return] :
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return]
        if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default]
This production only applies when parsing non-strict code. Code matching
this production is processed as if each matching occurrence of
FunctionDeclaration[?Yield, ?Await, ~Default] was the sole
StatementListItem of a BlockStatement occupying that position in the
source code. The semantics of such a synthetic BlockStatement includes
the web legacy compatibility semantics specified in B.3.3.
											 
										 
										
											2020-10-31 13:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_state . strict_mode  & &  match ( TokenType : : Function ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Function declarations in if statement clauses
https://tc39.es/ecma262/#sec-functiondeclarations-in-ifstatement-statement-clauses
B.3.4 FunctionDeclarations in IfStatement Statement Clauses
The following augments the IfStatement production in 13.6:
    IfStatement[Yield, Await, Return] :
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return]
        if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default]
        if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default]
This production only applies when parsing non-strict code. Code matching
this production is processed as if each matching occurrence of
FunctionDeclaration[?Yield, ?Await, ~Default] was the sole
StatementListItem of a BlockStatement occupying that position in the
source code. The semantics of such a synthetic BlockStatement includes
the web legacy compatibility semantics specified in B.3.3.
											 
										 
										
											2020-10-31 13:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            alternate  =  parse_function_declaration_as_block_statement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            alternate  =  parse_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 16:46:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < IfStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( predicate ) ,  move ( * consequent ) ,  move ( alternate ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 18:40:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Statement >  Parser : : parse_for_statement ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  is_await_loop  =  IsForAwaitLoop : : No ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  match_of  =  [ & ] ( Token  const &  token )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  token . type ( )  = =  TokenType : : Identifier  & &  token . original_value ( )  = =  " of " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  match_for_in_of  =  [ & ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  is_of  =  match_of ( m_state . current_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_await_loop  = =  IsForAwaitLoop : : Yes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! is_of ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " for await loop is only valid with 'of' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else  if  ( ! m_state . await_expression_is_valid ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                syntax_error ( " for await loop is only valid in async function or generator " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  match ( TokenType : : In )  | |  is_of ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : For ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Await ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! m_state . await_expression_is_valid ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " for-await-of is only allowed in async function context " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        is_await_loop  =  IsForAwaitLoop : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 22:09:28 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Optional < ScopePusher >  scope_pusher ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-05 21:31:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-23 19:08:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < ASTNode >  init ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : Semicolon ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( match_variable_declaration ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  declaration  =  parse_variable_declaration ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( declaration - > declaration_kind ( )  = =  DeclarationKind : : Var )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . current_scope_pusher - > add_declaration ( declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // This does not follow the normal declaration structure so we need additional checks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                HashTable < FlyString >  bound_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                declaration - > for_each_bound_name ( [ & ] ( auto  const &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( bound_names . set ( name )  ! =  AK : : HashSetResult : : InsertedNewEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        syntax_error ( String : : formatted ( " Identifier '{}' already declared in for loop initializer " ,  name ) ,  declaration - > source_range ( ) . start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            init  =  move ( declaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( match_for_in_of ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  parse_for_in_of_statement ( * init ,  is_await_loop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-30 19:08:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( static_cast < VariableDeclaration & > ( * init ) . declaration_kind ( )  = =  DeclarationKind : : Const )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                for  ( auto &  variable  :  static_cast < VariableDeclaration & > ( * init ) . declarations ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! variable . init ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-30 19:08:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        syntax_error ( " Missing initializer in 'const' variable declaration " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( match_expression ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  starts_with_async_of  =  match ( TokenType : : Async )  & &  match_of ( lookahead_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            init  =  parse_expression ( 0 ,  Associativity : : Right ,  {  TokenType : : In  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( match_for_in_of ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( is_await_loop  ! =  IsForAwaitLoop : : Yes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    & &  starts_with_async_of  & &  match_of ( m_state . current_token ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    syntax_error ( " for-of loop may not start with async of " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  parse_for_in_of_statement ( * init ,  is_await_loop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 00:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 17:08:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " Unexpected token in for loop " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Semicolon ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 11:23:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < Expression >  test ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : Semicolon ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        test  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Semicolon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 11:23:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    RefPtr < Expression >  update ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( TokenType : : ParenClose ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        update  =  parse_expression ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  break_change ( m_state . in_break_context ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryChange  continue_change ( m_state . in_continue_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopePusher  for_loop_scope  =  ScopePusher : : for_loop_scope ( * this ,  init ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:09:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  body  =  parse_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ForStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( init ) ,  move ( test ) ,  move ( update ) ,  move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < Statement >  Parser : : parse_for_in_of_statement ( NonnullRefPtr < ASTNode >  lhs ,  IsForAwaitLoop  is_for_await_loop )  
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Variant < NonnullRefPtr < ASTNode > ,  NonnullRefPtr < BindingPattern > >  for_declaration  =  lhs ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  has_annexB_for_in_init_extension  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-01 19:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is < VariableDeclaration > ( * lhs ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  declaration  =  static_cast < VariableDeclaration & > ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . declarations ( ) . size ( )  >  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Multiple declarations not allowed in for..in/of " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( declaration . declarations ( ) . size ( )  <  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Need exactly one variable declaration in for..in/of " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // AnnexB extension B.3.5 Initializers in ForIn Statement Heads, https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  variable  =  declaration . declarations ( ) . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( variable . init ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_state . strict_mode  | |  declaration . declaration_kind ( )  ! =  DeclarationKind : : Var  | |  ! variable . target ( ) . has < NonnullRefPtr < Identifier > > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( " Variable initializer not allowed in for..in/of " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    has_annexB_for_in_init_extension  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( ! lhs - > is_identifier ( )  & &  ! is < MemberExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  valid  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is < ObjectExpression > ( * lhs )  | |  is < ArrayExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  synthesized_binding_pattern  =  synthesize_binding_pattern ( static_cast < Expression  const & > ( * lhs ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( synthesized_binding_pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for_declaration  =  synthesized_binding_pattern . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                valid  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! valid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Invalid left-hand side in for-loop ('{}') " ,  lhs - > class_name ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  in_or_of  =  consume ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  is_in  =  in_or_of . type ( )  = =  TokenType : : In ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 23:09:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! is_in )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 23:09:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( is < MemberExpression > ( * lhs ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  member  =  static_cast < MemberExpression  const & > ( * lhs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( member . object ( ) . is_identifier ( )  & &  static_cast < Identifier  const & > ( member . object ( ) ) . string ( )  = =  " let " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( " For of statement may not start with let. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( has_annexB_for_in_init_extension ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Variable initializer not allowed in for..of " ,  rule_start . position ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 23:09:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rhs  =  parse_expression ( is_in  ?  0  :  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : ParenClose ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-07 12:21:15 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TemporaryChange  break_change ( m_state . in_break_context ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TemporaryChange  continue_change ( m_state . in_continue_context ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopePusher  for_loop_scope  =  ScopePusher : : for_loop_scope ( * this ,  lhs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  body  =  parse_statement ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_in ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  create_ast_node < ForInStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( for_declaration ) ,  move ( rhs ) ,  move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-23 16:09:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( is_for_await_loop  = =  IsForAwaitLoop : : Yes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  create_ast_node < ForAwaitOfStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( for_declaration ) ,  move ( rhs ) ,  move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:44:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ForOfStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( for_declaration ) ,  move ( rhs ) ,  move ( body ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-30 17:26:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < DebuggerStatement >  Parser : : parse_debugger_statement ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-30 17:26:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    consume ( TokenType : : Debugger ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < DebuggerStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-30 17:26:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								bool  Parser : : match ( TokenType  type )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_state . current_token . type ( )  = =  type ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  Parser : : match_expression ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:45:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( type  = =  TokenType : : Import )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  lookahead_token . type ( )  = =  TokenType : : Period  | |  lookahead_token . type ( )  = =  TokenType : : ParenOpen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  type  = =  TokenType : : BoolLiteral 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : NumericLiteral 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-06 01:14:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : BigIntLiteral 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : StringLiteral 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
    > `foo
    > bar`
    'foo
    bar'
											 
										 
										
											2020-05-03 15:41:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : TemplateLiteralStart 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : NullLiteral 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  match_identifier ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:16:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : PrivateIdentifier 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Await 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : New 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Class 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : CurlyOpen 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : BracketOpen 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ParenOpen 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-19 11:52:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Function 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Async 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 00:42:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : This 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Super 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 16:05:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : RegexLiteral 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 23:28:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Slash        // Wrongly recognized regex by lexer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : SlashEquals  // Wrongly recognized regex by lexer (/=a/ is a valid regex)
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Yield 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  match_unary_prefixed_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  Parser : : match_unary_prefixed_expression ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-14 20:45:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  type  = =  TokenType : : PlusPlus 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : MinusMinus 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ExclamationMark 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 06:33:32 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Tilde 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 17:58:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Plus 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Minus 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 17:55:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Typeof 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-26 13:53:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Void 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Delete ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-24 09:58:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_secondary_expression ( const  Vector < TokenType > &  forbidden )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( forbidden . contains_slow ( type ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  type  = =  TokenType : : Plus 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : PlusEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Minus 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : MinusEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Asterisk 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : AsteriskEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Slash 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:09:15 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : SlashEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 21:17:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Percent 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:07:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : PercentEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 13:40:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoubleAsterisk 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 23:03:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoubleAsteriskEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Equals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:11:33 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : EqualsEqualsEquals 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ExclamationMarkEqualsEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-16 00:23:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : EqualsEquals 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ExclamationMarkEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:10:27 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : GreaterThan 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : GreaterThanEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:10:27 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : LessThan 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:07:08 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : LessThanEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ParenOpen 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 13:45:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Period 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 20:51:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : BracketOpen 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:02:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  ( type  = =  TokenType : : PlusPlus  & &  ! m_state . current_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  ( type  = =  TokenType : : MinusMinus  & &  ! m_state . current_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 16:06:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : In 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 12:14:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Instanceof 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 13:02:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : QuestionMark 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Ampersand 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : AmpersandEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 13:02:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Pipe 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : PipeEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 14:33:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Caret 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 22:34:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : CaretEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ShiftLeft 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ShiftLeftEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 13:45:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ShiftRight 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : ShiftRightEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-23 15:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : UnsignedShiftRight 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : UnsignedShiftRightEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 14:33:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoubleAmpersand 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoubleAmpersandEquals 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 00:49:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoublePipe 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-05 16:49:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoublePipeEquals 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoubleQuestionMark 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-14 06:56:31 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : DoubleQuestionMarkEquals 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : QuestionMarkPeriod ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  Parser : : match_statement ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  match_expression ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Return 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 01:38:30 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Yield 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : If 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 22:03:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Throw 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Try 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : While 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-28 15:05:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : With 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:12:12 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : For 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : CurlyOpen 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-29 13:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Switch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Break 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 00:22:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Continue 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-30 17:26:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Var 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-03 10:59:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Debugger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Semicolon ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_export_or_import ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  type  = =  TokenType : : Export 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Import ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_declaration ( )  const  
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( type  = =  TokenType : : Let  & &  ! m_state . strict_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  try_match_let_declaration ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 15:52:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( type  = =  TokenType : : Async )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  lookahead_token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  lookahead_token . type ( )  = =  TokenType : : Function  & &  ! lookahead_token . trivia_contains_line_terminator ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  type  = =  TokenType : : Function 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Class 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Const 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-30 15:52:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Let ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Token  Parser : : next_token ( )  const  
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Lexer  lookahead_lexer  =  m_state . lexer ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  token_after  =  lookahead_lexer . next ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  token_after ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : try_match_let_declaration ( )  const  
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_state . current_token . type ( )  = =  TokenType : : Let ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  token_after  =  next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( token_after . is_identifier_name ( )  & &  token_after . value ( )  ! =  " in " sv ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 17:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( token_after . type ( )  = =  TokenType : : CurlyOpen  | |  token_after . type ( )  = =  TokenType : : BracketOpen ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 00:38:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_variable_declaration ( )  const  
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 02:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( type  = =  TokenType : : Let  & &  ! m_state . strict_mode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  try_match_let_declaration ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 23:30:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  type  = =  TokenType : : Var 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Let 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : Const ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_identifier ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . type ( )  = =  TokenType : : EscapedKeyword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . current_token . value ( )  = =  " let " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ! m_state . strict_mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . current_token . value ( )  = =  " yield " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ! m_state . strict_mode  & &  ! m_state . in_generator_function_context ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_state . current_token . value ( )  = =  " await " sv ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  m_program_type  ! =  Program : : Type : : Module  & &  ! m_state . await_expression_is_valid  & &  ! m_state . in_class_static_init_block ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_state . current_token . type ( )  = =  TokenType : : Identifier 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  m_state . current_token . type ( )  = =  TokenType : : Async 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  ( m_state . current_token . type ( )  = =  TokenType : : Let  & &  ! m_state . strict_mode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  ( m_state . current_token . type ( )  = =  TokenType : : Await  & &  m_program_type  ! =  Program : : Type : : Module  & &  ! m_state . await_expression_is_valid  & &  ! m_state . in_class_static_init_block ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        | |  ( m_state . current_token . type ( )  = =  TokenType : : Yield  & &  ! m_state . in_generator_function_context  & &  ! m_state . strict_mode ) ;  // See note in Parser::parse_identifier().
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 20:31:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_identifier_name ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_state . current_token . is_identifier_name ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 20:31:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_property_key ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  type  =  m_state . current_token . type ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 13:31:21 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  match_identifier_name ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : BracketOpen 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : StringLiteral 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : NumericLiteral 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  type  = =  TokenType : : BigIntLiteral ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								bool  Parser : : done ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  match ( TokenType : : Eof ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Token  Parser : : consume ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  old_token  =  m_state . current_token ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . current_token  =  m_state . lexer . next ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.
Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.
To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:
Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455
After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37
This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).
The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:
    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();
test262 reports no changes in either direction, apart from a speedup :^)
											 
										 
										
											2021-10-05 08:44:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: This is the bare minimum needed to decide whether we might need an arguments object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // in a function expression or declaration. ("might" because the AST implements some further
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // conditions from the spec that rule out the need for allocating one)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( old_token . type ( )  = =  TokenType : : Identifier  & &  old_token . value ( ) . is_one_of ( " arguments " sv ,  " eval " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . function_might_need_arguments_object  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 23:02:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  old_token ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Parser : : consume_or_insert_semicolon ( )  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Semicolon was found and will be consumed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Semicolon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Insert semicolon if...
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-02 09:59:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ...token is preceded by one or more newlines
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . current_token . trivia_contains_line_terminator ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:27:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ...token is a closing curly brace
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : CurlyClose ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // ...token is eof
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Eof ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // No rule for semicolon insertion applies -> syntax error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    expected ( " Semicolon " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Token  Parser : : consume_identifier ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Identifier ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : EscapedKeyword ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( TokenType : : EscapedKeyword ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Note that 'let' is not a reserved keyword, but our lexer considers it such
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // As it's pretty nice to have that (for syntax highlighting and such), we'll
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // special-case it here instead.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Let ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'let' is not allowed as an identifier in strict mode " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Yield ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  | |  m_state . in_generator_function_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Identifier must not be a reserved word in strict mode ('yield') " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Await ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 23:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_program_type  = =  Program : : Type : : Module  | |  m_state . await_expression_is_valid  | |  m_state . in_class_static_init_block ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( " Identifier must not be a reserved word in modules ('await') " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Async ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    expected ( " Identifier " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://tc39.es/ecma262/#prod-IdentifierReference
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Token  Parser : : consume_identifier_reference ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Identifier ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : EscapedKeyword ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  name  =  m_state . current_token . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  ( name  = =  " let " sv  | |  name  = =  " yield " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " '{}' is not allowed as an identifier in strict mode " ,  name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_program_type  = =  Program : : Type : : Module  & &  name  = =  " await " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'await' is not allowed as an identifier in module " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-21 11:27:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // See note in Parser::parse_identifier().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Let ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'let' is not allowed as an identifier in strict mode " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Yield ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Identifier reference may not be 'yield' in strict mode " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Await ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_program_type  = =  Program : : Type : : Module ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " 'await' is not allowed as an identifier in module " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : Async ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    expected ( Token : : name ( TokenType : : Identifier ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Token  Parser : : consume ( TokenType  expected_type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-21 19:21:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! match ( expected_type ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 15:05:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        expected ( Token : : name ( expected_type ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 01:57:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  token  =  consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( expected_type  = =  TokenType : : Identifier )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_state . strict_mode  & &  is_strict_reserved_word ( token . value ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Identifier must not be a reserved word in strict mode ('{}') " ,  token . value ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 01:57:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  token ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 18:01:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Token  Parser : : consume_and_validate_numeric_literal ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:55:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  is_unprefixed_octal_number  =  [ ] ( StringView  value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 10:47:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  value . length ( )  >  1  & &  value [ 0 ]  = =  ' 0 '  & &  is_ascii_digit ( value [ 1 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 18:01:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  literal_start  =  position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 18:01:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  token  =  consume ( TokenType : : NumericLiteral ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . strict_mode  & &  is_unprefixed_octal_number ( token . value ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " Unprefixed octal number not allowed in strict mode " ,  literal_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match_identifier_name ( )  & &  m_state . current_token . trivia ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 22:18:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " Numeric literal must not be immediately followed by identifier " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 18:01:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  token ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  Parser : : expected ( const  char *  what )  
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:37:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  message  =  m_state . current_token . message ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-26 20:19:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( message . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        message  =  String : : formatted ( " Unexpected token {}. Expected {} " ,  m_state . current_token . name ( ) ,  what ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-26 20:19:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    syntax_error ( message ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:37:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-28 20:45:22 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Position  Parser : : position ( )  const  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . current_token . line_number ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 01:16:17 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_state . current_token . line_column ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . current_token . offset ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-11 22:41:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : try_parse_arrow_function_expression_failed_at_position ( const  Position &  position )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  it  =  m_token_memoizations . find ( position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( it  = =  m_token_memoizations . end ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( * it ) . value . try_parse_arrow_function_expression_failed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Parser : : set_try_parse_arrow_function_expression_failed_at_position ( const  Position &  position ,  bool  failed )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_token_memoizations . set ( position ,  {  failed  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 21:03:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Parser : : syntax_error ( const  String &  message ,  Optional < Position >  position )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! position . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        position  =  this - > position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . errors . append ( {  message ,  position  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:24:43 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Parser : : save_state ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_saved_state . append ( m_state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:24:43 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Parser : : load_state ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( ! m_saved_state . is_empty ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 14:43:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state  =  m_saved_state . take_last ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 08:24:43 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-29 21:37:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-29 16:47:39 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Parser : : discard_saved_state ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_saved_state . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Parser : : check_identifier_name_for_assignment_validity ( StringView  name ,  bool  force_strict )  
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // FIXME: this is now called from multiple places maybe the error message should be dynamic?
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-25 14:21:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( any_of ( s_reserved_words ,  [ & ] ( auto &  value )  {  return  name  = =  value ;  } ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        syntax_error ( " Binding pattern target may not be a reserved word " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( m_state . strict_mode  | |  force_strict )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( name . is_one_of ( " arguments " sv ,  " eval " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Binding pattern target may not be called 'arguments' or 'eval' in strict mode " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-12 01:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( is_strict_reserved_word ( name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 01:45:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Binding pattern target may not be called '{}' in strict mode " ,  name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-11 15:34:55 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Parser : : match_assert_clause ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ! m_state . current_token . trivia_contains_line_terminator ( )  & &  m_state . current_token . original_value ( )  = =  " assert " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// AssertClause, https://tc39.es/proposal-import-assertions/#prod-AssertClause
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Parser : : parse_assert_clause ( ModuleRequest &  request )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VERIFY ( m_state . current_token . original_value ( )  = =  " assert " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( ! done ( )  & &  ! match ( TokenType : : CurlyClose ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        String  key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : StringLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            key  =  parse_string_literal ( m_state . current_token ) - > value ( ) . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            key  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expected ( " IdentifierName or StringValue as AssertionKey " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Colon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : StringLiteral ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  entries  :  request . assertions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( entries . key  = =  key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( String : : formatted ( " Duplicate assertion clauses with name: {} " ,  key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            request . add_assertion ( move ( key ) ,  parse_string_literal ( m_state . current_token ) - > value ( ) . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : StringLiteral ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < ImportStatement >  Parser : : parse_import_statement ( Program &  program )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // We use the extended syntax which adds:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //  ImportDeclaration:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //      import ImportClause FromClause [no LineTerminator here] AssertClause;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //      import ModuleSpecifier [no LineTerminator here] AssertClause;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // From:  https://tc39.es/proposal-import-assertions/#prod-ImportDeclaration
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( program . type ( )  ! =  Program : : Type : : Module ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Cannot use import statement outside a module " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Import ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match ( TokenType : : StringLiteral ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  module_request  =  ModuleRequest ( consume ( TokenType : : StringLiteral ) . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match_assert_clause ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parse_assert_clause ( module_request ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  create_ast_node < ImportStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( module_request ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  match_imported_binding  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  match_identifier ( )  | |  match ( TokenType : : Yield )  | |  match ( TokenType : : Await ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  match_as  =  [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-18 16:34:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  match ( TokenType : : Identifier )  & &  m_state . current_token . original_value ( )  = =  " as " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  continue_parsing  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  ImportWithLocation  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ImportStatement : : ImportEntry  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Position  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < ImportWithLocation >  entries_with_location ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match_imported_binding ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  id_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  bound_name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        entries_with_location . append ( {  {  " default " ,  bound_name  } ,  id_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            continue_parsing  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! continue_parsing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // skip the rest
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( match ( TokenType : : Asterisk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Asterisk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! match_as ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Unexpected token: {} " ,  m_state . current_token . name ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match_imported_binding ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  namespace_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  namespace_name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entries_with_location . append ( {  {  " * " ,  namespace_name  } ,  namespace_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( String : : formatted ( " Unexpected token: {} " ,  m_state . current_token . name ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( match ( TokenType : : CurlyOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( ! done ( )  & &  ! match ( TokenType : : CurlyClose ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  require_as  =  ! match_imported_binding ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  name_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( match_as ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  alias_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  alias  =  consume_identifier ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    check_identifier_name_for_assignment_validity ( alias ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    entries_with_location . append ( {  {  name ,  alias  } ,  alias_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( require_as )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_error ( String : : formatted ( " Unexpected reserved word '{}' " ,  name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    check_identifier_name_for_assignment_validity ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    entries_with_location . append ( {  {  name ,  name  } ,  name_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expected ( " identifier " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        expected ( " import clauses " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 23:02:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  from_statement  =  consume ( TokenType : : Identifier ) . original_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( from_statement  ! =  " from " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( String : : formatted ( " Expected 'from' got {} " ,  from_statement ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  module_request  =  ModuleRequest ( consume ( TokenType : : StringLiteral ) . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( match_assert_clause ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parse_assert_clause ( module_request ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < ImportStatement : : ImportEntry >  entries ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    entries . ensure_capacity ( entries_with_location . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  entries_with_location )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  import_statement  :  program . imports ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( import_statement . has_bound_name ( entry . entry . local_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " Identifier '{}' already declared " ,  entry . entry . local_name ) ,  entry . position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  new_entry  :  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( new_entry . local_name  = =  entry . entry . local_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " Identifier '{}' already declared " ,  entry . entry . local_name ) ,  entry . position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        entries . append ( move ( entry . entry ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  create_ast_node < ImportStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( module_request ) ,  move ( entries ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullRefPtr < ExportStatement >  Parser : : parse_export_statement ( Program &  program )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // We use the extended syntax which adds:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //  ExportDeclaration:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //      export ExportFromClause FromClause [no LineTerminator here] AssertClause ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // From:  https://tc39.es/proposal-import-assertions/#prod-ExportDeclaration
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  rule_start  =  push_start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( program . type ( )  ! =  Program : : Type : : Module ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        syntax_error ( " Cannot use export statement outside a module " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  match_as  =  [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-18 16:34:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  match ( TokenType : : Identifier )  & &  m_state . current_token . original_value ( )  = =  " as " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  match_from  =  [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-18 16:34:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  match ( TokenType : : Identifier )  & &  m_state . current_token . original_value ( )  = =  " from " sv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  match_default  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  match ( TokenType : : Default )  & &  m_state . current_token . original_value ( )  = =  " default " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    consume ( TokenType : : Export ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    struct  EntryAndLocation  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ExportStatement : : ExportEntry  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Position  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        void  to_module_request ( ModuleRequest  from_module ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entry . kind  =  ExportStatement : : ExportEntry : : Kind : : ModuleRequest ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            entry . module_request  =  move ( from_module ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < EntryAndLocation >  entries_with_location ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RefPtr < ASTNode >  expression  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-18 16:34:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( match_default ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  default_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        consume ( TokenType : : Default ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        String  local_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Class ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  class_expression  =  parse_class_expression ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            local_name  =  class_expression - > name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expression  =  move ( class_expression ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-09 20:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : Function )  | |  ( match ( TokenType : : Async )  & &  next_token ( ) . type ( )  = =  TokenType : : Function ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  func_expr  =  parse_function_node < FunctionExpression > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            local_name  =  func_expr - > name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expression  =  move ( func_expr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match_expression ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expression  =  parse_expression ( 2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            local_name  =  " *default* " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expected ( " Declaration or assignment expression " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        entries_with_location . append ( {  {  " default " ,  local_name  } ,  default_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        enum  FromSpecifier  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            NotAllowed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Optional , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Required 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  check_for_from  {  NotAllowed  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( match ( TokenType : : Asterisk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  asterisk_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Asterisk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match_as ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  namespace_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  exported_name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    entries_with_location . append ( {  {  exported_name ,  " * "  } ,  namespace_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    expected ( " identifier " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                entries_with_location . append ( {  {  { } ,  " * "  } ,  asterisk_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            check_for_from  =  Required ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match_declaration ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  decl_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  declaration  =  parse_declaration ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_state . current_scope_pusher - > add_declaration ( declaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is < FunctionDeclaration > ( * declaration ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  func  =  static_cast < FunctionDeclaration & > ( * declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                entries_with_location . append ( {  {  func . name ( ) ,  func . name ( )  } ,  func . source_range ( ) . start  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( is < ClassDeclaration > ( * declaration ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  class_declaration  =  static_cast < ClassDeclaration & > ( * declaration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-27 00:01:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                entries_with_location . append ( {  {  class_declaration . name ( ) ,  class_declaration . name ( )  } ,  class_declaration . source_range ( ) . start  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                VERIFY ( is < VariableDeclaration > ( * declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  variables  =  static_cast < VariableDeclaration & > ( * declaration ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( auto &  decl  :  variables . declarations ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    decl . target ( ) . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        [ & ] ( NonnullRefPtr < Identifier >  const &  identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            entries_with_location . append ( {  {  identifier - > string ( ) ,  identifier - > string ( )  } ,  identifier - > source_range ( ) . start  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        [ & ] ( NonnullRefPtr < BindingPattern >  const &  binding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            binding - > for_each_bound_name ( [ & ] ( auto &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                entries_with_location . append ( {  {  name ,  name  } ,  decl_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expression  =  declaration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : Var ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  variable_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  variable_declaration  =  parse_variable_declaration ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto &  decl  :  variable_declaration - > declarations ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                decl . target ( ) . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    [ & ] ( NonnullRefPtr < Identifier >  const &  identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        entries_with_location . append ( {  {  identifier - > string ( ) ,  identifier - > string ( )  } ,  identifier - > source_range ( ) . start  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    [ & ] ( NonnullRefPtr < BindingPattern >  const &  binding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        binding - > for_each_bound_name ( [ & ] ( auto &  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            entries_with_location . append ( {  {  name ,  name  } ,  variable_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expression  =  variable_declaration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( match ( TokenType : : CurlyOpen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : CurlyOpen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            while  ( ! done ( )  & &  ! match ( TokenType : : CurlyClose ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  identifier_position  =  position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  identifier  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( match_as ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( match_identifier_name ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            auto  export_name  =  consume ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            entries_with_location . append ( {  {  export_name ,  identifier  } ,  identifier_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            expected ( " identifier name " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        entries_with_location . append ( {  {  identifier ,  identifier  } ,  identifier_position  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    expected ( " identifier " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! match ( TokenType : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                consume ( TokenType : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : CurlyClose ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            check_for_from  =  Optional ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            syntax_error ( " Unexpected token 'export' " ,  rule_start . position ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( check_for_from  ! =  NotAllowed  & &  match_from ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume ( TokenType : : Identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( match ( TokenType : : StringLiteral ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 15:29:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  from_specifier  =  ModuleRequest ( consume ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( match_assert_clause ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    parse_assert_clause ( from_specifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 17:42:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                for  ( auto &  entry  :  entries_with_location ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    entry . to_module_request ( from_specifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expected ( " ModuleSpecifier " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( check_for_from  = =  Required )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expected ( " from " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( check_for_from  ! =  NotAllowed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            consume_or_insert_semicolon ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < ExportStatement : : ExportEntry >  entries ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    entries . ensure_capacity ( entries_with_location . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  entry  :  entries_with_location )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  export_statement  :  program . exports ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( export_statement . has_export ( entry . entry . export_name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " Duplicate export with name: '{}' " ,  entry . entry . export_name ) ,  entry . position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  new_entry  :  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( new_entry . export_name  = =  entry . entry . export_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                syntax_error ( String : : formatted ( " Duplicate export with name: '{}' " ,  entry . entry . export_name ) ,  entry . position ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        entries . append ( move ( entry . entry ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  create_ast_node < ExportStatement > ( {  m_state . current_token . filename ( ) ,  rule_start . position ( ) ,  position ( )  } ,  move ( expression ) ,  move ( entries ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}