@@ -14,7 +14,6 @@ use oxc_cfg::{
1414 ControlFlowGraphBuilder , CtxCursor , CtxFlags , EdgeType , ErrorEdgeKind , InstructionKind ,
1515 IterationInstructionKind , ReturnInstructionKind ,
1616} ;
17- use oxc_data_structures:: stack:: Stack ;
1817use oxc_diagnostics:: OxcDiagnostic ;
1918use oxc_span:: { Atom , SourceType , Span } ;
2019use oxc_syntax:: {
@@ -66,8 +65,9 @@ pub struct SemanticBuilder<'a> {
6665 pub ( crate ) current_node_id : NodeId ,
6766 pub ( crate ) current_node_flags : NodeFlags ,
6867 pub ( crate ) current_scope_id : ScopeId ,
69- /// Stores current `AstKind::Function` and `AstKind::ArrowFunctionExpression` during AST visit
70- pub ( crate ) function_stack : Stack < NodeId > ,
68+ /// `NodeId` of current `Function` (not including arrow functions).
69+ /// When not in a function, is `NodeId` of `Program`.
70+ pub ( crate ) current_function_node_id : NodeId ,
7171 pub ( crate ) module_instance_state_cache : FxHashMap < Address , ModuleInstanceState > ,
7272 current_reference_flags : ReferenceFlags ,
7373 pub ( crate ) hoisting_variables : FxHashMap < ScopeId , FxHashMap < Atom < ' a > , SymbolId > > ,
@@ -121,7 +121,7 @@ impl<'a> SemanticBuilder<'a> {
121121 current_node_flags : NodeFlags :: empty ( ) ,
122122 current_reference_flags : ReferenceFlags :: empty ( ) ,
123123 current_scope_id,
124- function_stack : Stack :: with_capacity ( 16 ) ,
124+ current_function_node_id : NodeId :: ROOT ,
125125 module_instance_state_cache : FxHashMap :: default ( ) ,
126126 nodes : AstNodes :: default ( ) ,
127127 hoisting_variables : FxHashMap :: default ( ) ,
@@ -357,12 +357,6 @@ impl<'a> SemanticBuilder<'a> {
357357 self . current_scope_flags ( ) . is_strict_mode ( )
358358 }
359359
360- pub ( crate ) fn set_function_node_flags ( & mut self , flags : NodeFlags ) {
361- if let Some ( current_function) = self . function_stack . last ( ) {
362- * self . nodes . get_node_mut ( * current_function) . flags_mut ( ) |= flags;
363- }
364- }
365-
366360 /// Declares a `Symbol` for the node, adds it to symbol table, and binds it to the scope.
367361 ///
368362 /// includes: the `SymbolFlags` that node has in addition to its declaration type (eg: export, ambient, etc.)
@@ -654,6 +648,9 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
654648 // as scope depth must remain >= 1.
655649
656650 self . leave_node ( kind) ;
651+
652+ // Check `current_function_node_id` has been reset to as it was at start
653+ debug_assert ! ( self . current_function_node_id == NodeId :: ROOT ) ;
657654 }
658655
659656 fn visit_break_statement ( & mut self , stmt : & BreakStatement < ' a > ) {
@@ -1613,10 +1610,14 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
16131610
16141611 let kind = AstKind :: Function ( self . alloc ( func) ) ;
16151612 self . enter_node ( kind) ;
1616- self . function_stack . push ( self . current_node_id ) ;
1613+
1614+ let parent_function_node_id = self . current_function_node_id ;
1615+ self . current_function_node_id = self . current_node_id ;
1616+
16171617 if func. is_declaration ( ) {
16181618 func. bind ( self ) ;
16191619 }
1620+
16201621 self . enter_scope (
16211622 {
16221623 let mut flags = flags;
@@ -1693,7 +1694,8 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
16931694
16941695 self . leave_scope ( ) ;
16951696 self . leave_node ( kind) ;
1696- self . function_stack . pop ( ) ;
1697+
1698+ self . current_function_node_id = parent_function_node_id;
16971699 }
16981700
16991701 fn visit_arrow_function_expression ( & mut self , expr : & ArrowFunctionExpression < ' a > ) {
@@ -1712,7 +1714,6 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
17121714
17131715 let kind = AstKind :: ArrowFunctionExpression ( self . alloc ( expr) ) ;
17141716 self . enter_node ( kind) ;
1715- self . function_stack . push ( self . current_node_id ) ;
17161717 self . enter_scope (
17171718 {
17181719 let mut flags = ScopeFlags :: Function | ScopeFlags :: Arrow ;
@@ -1775,7 +1776,6 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
17751776 /* cfg */
17761777
17771778 self . leave_node ( kind) ;
1778- self . function_stack . pop ( ) ;
17791779 self . leave_scope ( ) ;
17801780 }
17811781
@@ -2039,7 +2039,10 @@ impl<'a> SemanticBuilder<'a> {
20392039 }
20402040 }
20412041 AstKind :: YieldExpression ( _) => {
2042- self . set_function_node_flags ( NodeFlags :: HasYield ) ;
2042+ // If not in a function, `current_function_node_id` is `NodeId` of `Program`.
2043+ // But it shouldn't be possible for `yield` to at top level - that's a parse error.
2044+ * self . nodes . get_node_mut ( self . current_function_node_id ) . flags_mut ( ) |=
2045+ NodeFlags :: HasYield ;
20432046 }
20442047 AstKind :: CallExpression ( call_expr) => {
20452048 if !call_expr. optional && call_expr. callee . is_specific_id ( "eval" ) {
0 commit comments