44//! - `impl_ast_node_vec!` - For non-Option types (uses `.map()`)
55//! - `impl_ast_node_vec_for_option!` - For Option types (uses `.and_then()`)
66
7+ use std:: cmp:: min;
8+
79use oxc_allocator:: { Allocator , Vec } ;
810use oxc_ast:: ast:: * ;
911use oxc_span:: { GetSpan , Span } ;
@@ -158,7 +160,6 @@ impl_ast_node_vec!(ObjectPropertyKind<'a>);
158160impl_ast_node_vec ! ( TemplateElement <' a>) ;
159161impl_ast_node_vec ! ( Argument <' a>) ;
160162impl_ast_node_vec ! ( AssignmentTargetProperty <' a>) ;
161- impl_ast_node_vec ! ( Statement <' a>) ;
162163impl_ast_node_vec ! ( Directive <' a>) ;
163164impl_ast_node_vec ! ( VariableDeclarator <' a>) ;
164165impl_ast_node_vec ! ( SwitchCase <' a>) ;
@@ -181,3 +182,97 @@ impl_ast_node_vec!(TSInterfaceHeritage<'a>);
181182impl_ast_node_vec ! ( Decorator <' a>) ;
182183impl_ast_node_vec_for_option ! ( Option <AssignmentTargetMaybeDefault <' a>>) ;
183184impl_ast_node_vec_for_option ! ( Option <BindingPattern <' a>>) ;
185+
186+ // Manual implementation for Vec<Statement> because we have to handle span
187+ // for ExportDefaultDeclaration and ExportNamedDeclaration that may include
188+ // decorators.
189+ // <https://github.com/oxc-project/oxc/issues/10409>
190+ impl < ' a > AstNode < ' a , Vec < ' a , Statement < ' a > > > {
191+ pub fn iter ( & self ) -> AstNodeIterator < ' a , Statement < ' a > > {
192+ AstNodeIterator {
193+ inner : self . inner . iter ( ) . peekable ( ) ,
194+ parent : self . parent ,
195+ allocator : self . allocator ,
196+ }
197+ }
198+ pub fn first ( & self ) -> Option < & ' a AstNode < ' a , Statement < ' a > > > {
199+ let mut inner_iter = self . inner . iter ( ) ;
200+ self . allocator
201+ . alloc ( inner_iter. next ( ) . map ( |inner| AstNode {
202+ inner,
203+ parent : self . parent ,
204+ allocator : self . allocator ,
205+ following_span : inner_iter. next ( ) . map ( GetSpan :: span) ,
206+ } ) )
207+ . as_ref ( )
208+ }
209+ pub fn last ( & self ) -> Option < & ' a AstNode < ' a , Statement < ' a > > > {
210+ self . allocator
211+ . alloc ( self . inner . last ( ) . map ( |inner| AstNode {
212+ inner,
213+ parent : self . parent ,
214+ allocator : self . allocator ,
215+ following_span : None ,
216+ } ) )
217+ . as_ref ( )
218+ }
219+ }
220+ impl < ' a > Iterator for AstNodeIterator < ' a , Statement < ' a > > {
221+ type Item = & ' a AstNode < ' a , Statement < ' a > > ;
222+ fn next ( & mut self ) -> Option < Self :: Item > {
223+ let allocator = self . allocator ;
224+ allocator
225+ . alloc ( self . inner . next ( ) . map ( |inner| AstNode {
226+ parent : self . parent ,
227+ inner,
228+ allocator,
229+ following_span : {
230+ match self . inner . peek ( ) {
231+ // `@decorator export default class A {}`
232+ // Get the span of the decorator.
233+ Some ( Statement :: ExportDefaultDeclaration ( export) ) => {
234+ if let ExportDefaultDeclarationKind :: ClassDeclaration ( class) =
235+ & export. declaration
236+ && let Some ( decorator) = class. decorators . first ( )
237+ {
238+ Some ( Span :: new (
239+ min ( decorator. span . start , export. span . start ) ,
240+ export. span . end ,
241+ ) )
242+ } else {
243+ Some ( export. span )
244+ }
245+ }
246+ // `@decorator export class A {}`
247+ // Get the span of the decorator.
248+ Some ( Statement :: ExportNamedDeclaration ( export) ) => {
249+ if let Some ( Declaration :: ClassDeclaration ( class) ) = & export. declaration
250+ && let Some ( decorator) = class. decorators . first ( )
251+ {
252+ Some ( Span :: new (
253+ min ( decorator. span . start , export. span . start ) ,
254+ export. span . end ,
255+ ) )
256+ } else {
257+ Some ( export. span )
258+ }
259+ }
260+ Some ( next) => Some ( next. span ( ) ) ,
261+ None => None ,
262+ }
263+ } ,
264+ } ) )
265+ . as_ref ( )
266+ }
267+ }
268+ impl < ' a > IntoIterator for & AstNode < ' a , Vec < ' a , Statement < ' a > > > {
269+ type Item = & ' a AstNode < ' a , Statement < ' a > > ;
270+ type IntoIter = AstNodeIterator < ' a , Statement < ' a > > ;
271+ fn into_iter ( self ) -> Self :: IntoIter {
272+ AstNodeIterator :: < Statement < ' a > > {
273+ inner : self . inner . iter ( ) . peekable ( ) ,
274+ parent : self . parent ,
275+ allocator : self . allocator ,
276+ }
277+ }
278+ }
0 commit comments