@ -55,7 +55,6 @@ pub enum ContainsSymbol {
///
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-contains
#[ must_use ]
#[ inline ]
pub fn contains < N > ( node : & N , symbol : ContainsSymbol ) -> bool
where
N : VisitWith ,
@ -67,27 +66,22 @@ where
impl < ' ast > Visitor < ' ast > for ContainsVisitor {
type BreakTy = ( ) ;
#[ inline ]
fn visit_function ( & mut self , _ : & ' ast Function ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_function ( & mut self , _ : & ' ast AsyncFunction ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_generator ( & mut self , _ : & ' ast Generator ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_generator ( & mut self , _ : & ' ast AsyncGenerator ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_class ( & mut self , node : & ' ast Class ) -> ControlFlow < Self ::BreakTy > {
if ! node . elements ( ) . is_empty ( ) & & self . 0 = = ContainsSymbol ::ClassBody {
return ControlFlow ::Break ( ( ) ) ;
@ -101,7 +95,6 @@ where
}
// `ComputedPropertyContains`: https://tc39.es/ecma262/#sec-static-semantics-computedpropertycontains
#[ inline ]
fn visit_class_element ( & mut self , node : & ' ast ClassElement ) -> ControlFlow < Self ::BreakTy > {
match node {
ClassElement ::MethodDefinition ( name , _ )
@ -112,7 +105,6 @@ where
}
}
#[ inline ]
fn visit_property_definition (
& mut self ,
node : & ' ast PropertyDefinition ,
@ -127,7 +119,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_arrow_function (
& mut self ,
node : & ' ast ArrowFunction ,
@ -147,7 +138,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_async_arrow_function (
& mut self ,
node : & ' ast AsyncArrowFunction ,
@ -167,7 +157,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_super_property_access (
& mut self ,
node : & ' ast SuperPropertyAccess ,
@ -178,7 +167,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_super_call ( & mut self , node : & ' ast SuperCall ) -> ControlFlow < Self ::BreakTy > {
if [ ContainsSymbol ::SuperCall , ContainsSymbol ::Super ] . contains ( & self . 0 ) {
return ControlFlow ::Break ( ( ) ) ;
@ -186,7 +174,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_yield ( & mut self , node : & ' ast Yield ) -> ControlFlow < Self ::BreakTy > {
if self . 0 = = ContainsSymbol ::YieldExpression {
return ControlFlow ::Break ( ( ) ) ;
@ -195,7 +182,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_await ( & mut self , node : & ' ast Await ) -> ControlFlow < Self ::BreakTy > {
if self . 0 = = ContainsSymbol ::AwaitExpression {
return ControlFlow ::Break ( ( ) ) ;
@ -204,7 +190,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_expression ( & mut self , node : & ' ast Expression ) -> ControlFlow < Self ::BreakTy > {
if node = = & Expression ::This & & self . 0 = = ContainsSymbol ::This {
return ControlFlow ::Break ( ( ) ) ;
@ -236,7 +221,6 @@ where
impl < ' ast > Visitor < ' ast > for ContainsArgsVisitor {
type BreakTy = ( ) ;
#[ inline ]
fn visit_identifier ( & mut self , node : & ' ast Identifier ) -> ControlFlow < Self ::BreakTy > {
if node . sym ( ) = = Sym ::ARGUMENTS {
ControlFlow ::Break ( ( ) )
@ -245,27 +229,22 @@ where
}
}
#[ inline ]
fn visit_function ( & mut self , _ : & ' ast Function ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_function ( & mut self , _ : & ' ast AsyncFunction ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_generator ( & mut self , _ : & ' ast Generator ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_generator ( & mut self , _ : & ' ast AsyncGenerator ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_class_element ( & mut self , node : & ' ast ClassElement ) -> ControlFlow < Self ::BreakTy > {
match node {
ClassElement ::MethodDefinition ( name , _ )
@ -275,7 +254,6 @@ where
node . visit_with ( self )
}
#[ inline ]
fn visit_property_definition (
& mut self ,
node : & ' ast PropertyDefinition ,
@ -314,21 +292,18 @@ trait IdentList {
}
impl IdentList for Vec < Identifier > {
#[ inline ]
fn add ( & mut self , value : Identifier , _function : bool ) {
self . push ( value ) ;
}
}
impl IdentList for Vec < ( Identifier , bool ) > {
#[ inline ]
fn add ( & mut self , value : Identifier , function : bool ) {
self . push ( ( value , function ) ) ;
}
}
impl IdentList for FxHashSet < Identifier > {
#[ inline ]
fn add ( & mut self , value : Identifier , _function : bool ) {
self . insert ( value ) ;
}
@ -341,45 +316,44 @@ struct BoundNamesVisitor<'a, T: IdentList>(&'a mut T);
impl < ' ast , T : IdentList > Visitor < ' ast > for BoundNamesVisitor < ' _ , T > {
type BreakTy = Infallible ;
#[ inline ]
fn visit_identifier ( & mut self , node : & ' ast Identifier ) -> ControlFlow < Self ::BreakTy > {
self . 0. add ( * node , false ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_expression ( & mut self , _ : & ' ast Expression ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
// TODO: add "*default" for module default functions without name
#[ inline ]
fn visit_function ( & mut self , node : & ' ast Function ) -> ControlFlow < Self ::BreakTy > {
if let Some ( ident ) = node . name ( ) {
self . 0. add ( ident , true ) ;
}
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_generator ( & mut self , node : & ' ast Generator ) -> ControlFlow < Self ::BreakTy > {
if let Some ( ident ) = node . name ( ) {
self . 0. add ( ident , false ) ;
}
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_function ( & mut self , node : & ' ast AsyncFunction ) -> ControlFlow < Self ::BreakTy > {
if let Some ( ident ) = node . name ( ) {
self . 0. add ( ident , false ) ;
}
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_generator ( & mut self , node : & ' ast AsyncGenerator ) -> ControlFlow < Self ::BreakTy > {
if let Some ( ident ) = node . name ( ) {
self . 0. add ( ident , false ) ;
}
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_class ( & mut self , node : & ' ast Class ) -> ControlFlow < Self ::BreakTy > {
if let Some ( ident ) = node . name ( ) {
self . 0. add ( ident , false ) ;
@ -394,7 +368,6 @@ impl<'ast, T: IdentList> Visitor<'ast> for BoundNamesVisitor<'_, T> {
///
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-boundnames
#[ must_use ]
#[ inline ]
pub fn bound_names < ' a , N > ( node : & ' a N ) -> Vec < Identifier >
where
& ' a N : Into < NodeRef < ' a > > ,
@ -411,54 +384,45 @@ struct LexicallyDeclaredNamesVisitor<'a, T: IdentList>(&'a mut T);
impl < ' ast , T : IdentList > Visitor < ' ast > for LexicallyDeclaredNamesVisitor < ' _ , T > {
type BreakTy = Infallible ;
#[ inline ]
fn visit_expression ( & mut self , _ : & ' ast Expression ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_statement ( & mut self , node : & ' ast Statement ) -> ControlFlow < Self ::BreakTy > {
if let Statement ::Labelled ( labelled ) = node {
return self . visit_labelled ( labelled ) ;
}
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_declaration ( & mut self , node : & ' ast Declaration ) -> ControlFlow < Self ::BreakTy > {
BoundNamesVisitor ( self . 0 ) . visit_declaration ( node )
}
#[ inline ]
fn visit_labelled_item ( & mut self , node : & ' ast LabelledItem ) -> ControlFlow < Self ::BreakTy > {
match node {
LabelledItem ::Function ( f ) = > BoundNamesVisitor ( self . 0 ) . visit_function ( f ) ,
LabelledItem ::Statement ( _ ) = > ControlFlow ::Continue ( ( ) ) ,
}
}
#[ inline ]
fn visit_function ( & mut self , node : & ' ast Function ) -> ControlFlow < Self ::BreakTy > {
top_level_lexicals ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_function ( & mut self , node : & ' ast AsyncFunction ) -> ControlFlow < Self ::BreakTy > {
top_level_lexicals ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_generator ( & mut self , node : & ' ast Generator ) -> ControlFlow < Self ::BreakTy > {
top_level_lexicals ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_generator ( & mut self , node : & ' ast AsyncGenerator ) -> ControlFlow < Self ::BreakTy > {
top_level_lexicals ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_arrow_function ( & mut self , node : & ' ast ArrowFunction ) -> ControlFlow < Self ::BreakTy > {
top_level_lexicals ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_arrow_function (
& mut self ,
node : & ' ast AsyncArrowFunction ,
@ -466,7 +430,6 @@ impl<'ast, T: IdentList> Visitor<'ast> for LexicallyDeclaredNamesVisitor<'_, T>
top_level_lexicals ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_class_element ( & mut self , node : & ' ast ClassElement ) -> ControlFlow < Self ::BreakTy > {
if let ClassElement ::StaticBlock ( stmts ) = node {
top_level_lexicals ( stmts , self . 0 ) ;
@ -485,7 +448,6 @@ impl<'ast, T: IdentList> Visitor<'ast> for LexicallyDeclaredNamesVisitor<'_, T>
///
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-lexicallydeclarednames
#[ must_use ]
#[ inline ]
pub fn lexically_declared_names < ' a , N > ( node : & ' a N ) -> Vec < Identifier >
where
& ' a N : Into < NodeRef < ' a > > ,
@ -503,7 +465,6 @@ where
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-lexicallydeclarednames
/// [changes]: https://tc39.es/ecma262/#sec-block-duplicates-allowed-static-semantics
#[ must_use ]
#[ inline ]
pub fn lexically_declared_names_legacy < ' a , N > ( node : & ' a N ) -> Vec < ( Identifier , bool ) >
where
& ' a N : Into < NodeRef < ' a > > ,
@ -519,51 +480,51 @@ struct VarDeclaredNamesVisitor<'a>(&'a mut FxHashSet<Identifier>);
impl < ' ast > Visitor < ' ast > for VarDeclaredNamesVisitor < ' _ > {
type BreakTy = Infallible ;
#[ inline ]
fn visit_expression ( & mut self , _ : & ' ast Expression ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_declaration ( & mut self , _ : & ' ast Declaration ) -> ControlFlow < Self ::BreakTy > {
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_var_declaration ( & mut self , node : & ' ast VarDeclaration ) -> ControlFlow < Self ::BreakTy > {
BoundNamesVisitor ( self . 0 ) . visit_var_declaration ( node )
}
#[ inline ]
fn visit_labelled_item ( & mut self , node : & ' ast LabelledItem ) -> ControlFlow < Self ::BreakTy > {
match node {
LabelledItem ::Function ( _ ) = > ControlFlow ::Continue ( ( ) ) ,
LabelledItem ::Statement ( stmt ) = > stmt . visit_with ( self ) ,
}
}
#[ inline ]
fn visit_function ( & mut self , node : & ' ast Function ) -> ControlFlow < Self ::BreakTy > {
top_level_vars ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_function ( & mut self , node : & ' ast AsyncFunction ) -> ControlFlow < Self ::BreakTy > {
top_level_vars ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_generator ( & mut self , node : & ' ast Generator ) -> ControlFlow < Self ::BreakTy > {
top_level_vars ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_generator ( & mut self , node : & ' ast AsyncGenerator ) -> ControlFlow < Self ::BreakTy > {
top_level_vars ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_arrow_function ( & mut self , node : & ' ast ArrowFunction ) -> ControlFlow < Self ::BreakTy > {
top_level_vars ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_async_arrow_function (
& mut self ,
node : & ' ast AsyncArrowFunction ,
@ -571,7 +532,7 @@ impl<'ast> Visitor<'ast> for VarDeclaredNamesVisitor<'_> {
top_level_vars ( node . body ( ) , self . 0 ) ;
ControlFlow ::Continue ( ( ) )
}
#[ inline ]
fn visit_class_element ( & mut self , node : & ' ast ClassElement ) -> ControlFlow < Self ::BreakTy > {
if let ClassElement ::StaticBlock ( stmts ) = node {
top_level_vars ( stmts , self . 0 ) ;
@ -590,7 +551,6 @@ impl<'ast> Visitor<'ast> for VarDeclaredNamesVisitor<'_> {
///
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-vardeclarednames
#[ must_use ]
#[ inline ]
pub fn var_declared_names < ' a , N > ( node : & ' a N ) -> FxHashSet < Identifier >
where
& ' a N : Into < NodeRef < ' a > > ,
@ -601,7 +561,6 @@ where
}
/// Utility function that collects the top level lexicals of a statement list into `names`.
#[ inline ]
fn top_level_lexicals < T : IdentList > ( stmts : & StatementList , names : & mut T ) {
for stmt in stmts . statements ( ) {
if let StatementListItem ::Declaration ( decl ) = stmt {
@ -638,7 +597,6 @@ pub fn top_level_lexically_declared_names(stmts: &StatementList) -> Vec<Identifi
}
/// Utility function that collects the top level vars of a statement list into `names`.
#[ inline ]
fn top_level_vars ( stmts : & StatementList , names : & mut FxHashSet < Identifier > ) {
for stmt in stmts . statements ( ) {
match stmt {