Skip to main content

oak_rust/builder/
mod.rs

1use crate::RustParser;
2#[doc = include_str!("readme.md")]
3use crate::{ast::*, language::RustLanguage, lexer::RustTokenType, parser::RustElementType};
4use core::range::Range;
5use oak_core::{Builder, BuilderCache, GreenNode, OakDiagnostics, OakError, Parser, RedNode, RedTree, SourceText, TextEdit, builder::BuildOutput, source::Source};
6
7/// AST builder for the Rust language.
8///
9/// `RustBuilder` is responsible for parsing Rust source code and constructing
10/// an Abstract Syntax Tree (AST). It uses a Pratt parser to handle operator
11/// precedence in expressions and supports all Rust syntax features.
12#[derive(Clone, Copy)]
13pub struct RustBuilder<'config> {
14    /// Language configuration
15    config: &'config RustLanguage,
16}
17
18impl<'config> RustBuilder<'config> {
19    /// Creates a new `RustBuilder` with the given configuration.
20    pub const fn new(config: &'config RustLanguage) -> Self {
21        Self { config }
22    }
23}
24
25impl<'config> Builder<RustLanguage> for RustBuilder<'config> {
26    fn build<'a, S: Source + ?Sized>(&self, source: &S, edits: &[TextEdit], _cache: &'a mut impl BuilderCache<RustLanguage>) -> BuildOutput<RustLanguage> {
27        // Parse source code to get syntax tree
28        let parser = RustParser::new(self.config);
29
30        // TODO: True incremental building should utilize the cache
31        let mut cache = oak_core::parser::session::ParseSession::<RustLanguage>::default();
32        let parse_result = parser.parse(source, edits, &mut cache);
33
34        // Check if parsing was successful
35        match parse_result.result {
36            Ok(green_tree) => {
37                // Build AST
38                let source_text = SourceText::new(source.get_text_in((0..source.length()).into()).into_owned());
39                match self.build_root(green_tree.clone(), &source_text) {
40                    Ok(ast_root) => OakDiagnostics { result: Ok(ast_root), diagnostics: parse_result.diagnostics },
41                    Err(build_error) => {
42                        let mut diagnostics = parse_result.diagnostics;
43                        diagnostics.push(build_error.clone());
44                        OakDiagnostics { result: Err(build_error), diagnostics }
45                    }
46                }
47            }
48            Err(parse_error) => OakDiagnostics { result: Err(parse_error), diagnostics: parse_result.diagnostics },
49        }
50    }
51}
52
53impl<'config> RustBuilder<'config> {
54    /// Builds the root node.
55    pub(crate) fn build_root(&self, green_tree: GreenNode<RustLanguage>, source: &SourceText) -> Result<RustRoot, OakError> {
56        let red_root = RedNode::new(&green_tree, 0);
57        let mut items = Vec::new();
58
59        for child in red_root.children() {
60            match child {
61                RedTree::Node(n) => match n.green.kind {
62                    RustElementType::Function => {
63                        let func = self.build_function(n, source)?;
64                        items.push(Item::Function(func));
65                    }
66                    RustElementType::StructItem => {
67                        let struct_def = self.build_struct(n, source)?;
68                        items.push(Item::Struct(struct_def));
69                    }
70                    RustElementType::EnumItem => {
71                        let enum_def = self.build_enum(n, source)?;
72                        items.push(Item::Enum(enum_def));
73                    }
74                    RustElementType::Trait => {
75                        let trait_def = self.build_trait(n, source)?;
76                        items.push(Item::Trait(trait_def));
77                    }
78                    RustElementType::Impl => {
79                        let impl_block = self.build_impl(n, source)?;
80                        items.push(Item::Impl(impl_block));
81                    }
82                    RustElementType::ModuleItem => {
83                        let module = self.build_module(n, source)?;
84                        items.push(Item::Module(module));
85                    }
86                    RustElementType::UseItem => {
87                        let use_decl = self.build_use(n, source)?;
88                        items.push(Item::Use(use_decl));
89                    }
90                    RustElementType::Const => {
91                        let const_def = self.build_const(n, source)?;
92                        items.push(Item::Const(const_def));
93                    }
94                    RustElementType::Static => {
95                        let static_def = self.build_static(n, source)?;
96                        items.push(Item::Static(static_def));
97                    }
98                    RustElementType::TypeAlias => {
99                        let type_alias = self.build_type_alias(n, source)?;
100                        items.push(Item::TypeAlias(type_alias));
101                    }
102                    _ => {
103                        // Ignore other node types
104                    }
105                },
106                RedTree::Leaf(_) => {
107                    // Ignore top-level tokens (whitespace, comments, etc.)
108                }
109            }
110        }
111        Ok(RustRoot { items })
112    }
113
114    /// Builds a function definition.
115    pub(crate) fn build_function(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Function, OakError> {
116        let span = node.span();
117        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
118        let mut params = Vec::new();
119        let mut return_type = None;
120        let mut body = None;
121        let mut is_async = false;
122        let mut is_unsafe = false;
123        let mut is_extern = false;
124
125        for child in node.children() {
126            match child {
127                RedTree::Leaf(t) => match t.kind {
128                    RustTokenType::Async => is_async = true,
129                    RustTokenType::Unsafe => is_unsafe = true,
130                    RustTokenType::Extern => is_extern = true,
131                    RustTokenType::Identifier => {
132                        name.name = text(source, t.span.clone().into());
133                        name.span = t.span.clone().into();
134                    }
135                    _ => {}
136                },
137                RedTree::Node(n) => match n.green.kind {
138                    RustElementType::ParameterList => {
139                        params = self.build_param_list(n, source)?;
140                    }
141                    RustElementType::ReturnType => {
142                        return_type = Some(self.build_type(n, source)?);
143                    }
144                    RustElementType::BlockExpression => {
145                        body = Some(self.build_block(n, source)?);
146                    }
147                    _ => {}
148                },
149            }
150        }
151
152        Ok(Function {
153            name,
154            params,
155            return_type,
156            body: body.unwrap_or_else(|| Block { statements: Vec::new(), block_start: 0, block_end: 0, nested: 0, span: Range { start: 0, end: 0 } }),
157            is_async,
158            is_unsafe,
159            generics: Vec::new(),
160            is_extern,
161            span: span.into(),
162        })
163    }
164
165    /// 构建参数列表
166    fn build_param_list(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<Param>, OakError> {
167        let mut params = Vec::new();
168        for child in node.children() {
169            if let RedTree::Node(n) = child {
170                if n.green.kind == RustElementType::Parameter {
171                    params.push(self.build_param(n, source)?);
172                }
173            }
174        }
175        Ok(params)
176    }
177
178    /// 构建参数
179    fn build_param(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Param, OakError> {
180        let span = node.span();
181        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
182        let mut ty = Type::Path("_".to_string());
183
184        for child in node.children() {
185            match child {
186                RedTree::Leaf(t) => {
187                    if let RustTokenType::Identifier = t.kind {
188                        name.name = text(source, t.span.clone().into());
189                        name.span = t.span.clone().into();
190                    }
191                }
192                RedTree::Node(n) => match n.green.kind {
193                    RustElementType::Type => {
194                        ty = self.build_type(n, source)?;
195                    }
196                    _ => {}
197                },
198            }
199        }
200
201        Ok(Param { name, ty, is_mut: false, span: span.into() })
202    }
203
204    /// Builds a code block.
205    fn build_block(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Block, OakError> {
206        let span = node.span();
207        let mut statements = Vec::new();
208
209        for child in node.children() {
210            match child {
211                RedTree::Node(n) => match n.green.kind {
212                    RustElementType::LetStatement => {
213                        statements.push(self.build_let_statement(n, source)?);
214                    }
215                    RustElementType::ExpressionStatement => {
216                        statements.push(self.build_expr_statement(n, source)?);
217                    }
218                    RustElementType::ItemStatement => {
219                        let item = self.build_item_statement(n, source)?;
220                        statements.push(Statement::Item(item));
221                    }
222                    _ => {
223                        // Could be a block expression, treat it as an expression statement
224                        let span = n.span();
225                        if let Ok(block_expr) = self.build_expr(n, source) {
226                            statements.push(Statement::ExprStmt { expr: block_expr, semi: false, span: span.into() });
227                        }
228                    }
229                },
230                RedTree::Leaf(_) => {
231                    // Ignore separators and whitespace
232                }
233            }
234        }
235
236        Ok(Block { statements, block_start: span.start, block_end: span.end, nested: 0, span: span.into() })
237    }
238
239    /// Builds a let statement.
240    fn build_let_statement(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Statement, OakError> {
241        let span = node.span();
242        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
243        let mut ty = None;
244        let mut init = None;
245        let mut mutable = false;
246
247        for child in node.children() {
248            match child {
249                RedTree::Node(n) => match n.green.kind {
250                    RustElementType::Pattern => {
251                        let pattern = self.build_pattern(n, source)?;
252                        // Extract Identifier from Pattern
253                        match pattern {
254                            Pattern::Ident(ident) => name = ident,
255                            _ => {
256                                return Err(OakError::syntax_error("Expected identifier in let statement".to_string(), span.start, None));
257                            }
258                        }
259                    }
260                    RustElementType::Type => {
261                        ty = Some(self.build_type(n, source)?);
262                    }
263                    RustElementType::Expression => {
264                        init = Some(self.build_expr(n, source)?);
265                    }
266                    _ => {}
267                },
268                RedTree::Leaf(t) => {
269                    // Check for mut keyword
270                    if t.kind == RustTokenType::Mut {
271                        mutable = true;
272                    }
273                }
274            }
275        }
276
277        Ok(Statement::Let { name, ty, expr: init, mutable, span: span.into() })
278    }
279
280    /// Builds an expression statement.
281    fn build_expr_statement(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Statement, OakError> {
282        let span = node.span();
283        let mut expr = Expr::Bool { value: false, span: span.clone().into() };
284        let mut has_semicolon = false;
285
286        for child in node.children() {
287            match child {
288                RedTree::Node(n) => {
289                    if let Ok(expression) = self.build_expr(n, source) {
290                        expr = expression;
291                    }
292                }
293                RedTree::Leaf(t) => {
294                    if t.kind == RustTokenType::Semicolon {
295                        has_semicolon = true;
296                    }
297                }
298            }
299        }
300
301        Ok(Statement::ExprStmt { expr, semi: has_semicolon, span: span.into() })
302    }
303
304    /// Builds an expression.
305    pub(crate) fn build_expr(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Expr, OakError> {
306        let span = node.span();
307
308        match node.green.kind {
309            RustElementType::IdentifierExpression => {
310                for child in node.children() {
311                    if let RedTree::Leaf(t) = child {
312                        if t.kind == RustTokenType::Identifier {
313                            let ident = Identifier { name: text(source, t.span.clone().into()), span: t.span.clone().into() };
314                            return Ok(Expr::Ident(ident));
315                        }
316                    }
317                }
318                Err(OakError::syntax_error("Invalid identifier expression".to_string(), span.start, None))
319            }
320            RustElementType::LiteralExpression => {
321                for child in node.children() {
322                    if let RedTree::Leaf(t) = child {
323                        // Infer literal type directly from token text
324                        let text = source.get_text_in(t.span.clone().into());
325                        if text == "true" {
326                            return Ok(Expr::Bool { value: true, span: span.into() });
327                        }
328                        else if text == "false" {
329                            return Ok(Expr::Bool { value: false, span: span.into() });
330                        }
331                        else {
332                            // Other literal types (numbers, strings, characters, etc.)
333                            return Ok(Expr::Literal { value: text.to_string(), span: span.into() });
334                        }
335                    }
336                }
337                Err(OakError::syntax_error("Invalid literal expression".to_string(), span.start, None))
338            }
339            RustElementType::BinaryExpression => {
340                let mut left = None;
341                let mut op = None;
342                let mut right = None;
343
344                for child in node.children() {
345                    match child {
346                        RedTree::Node(n) => {
347                            if left.is_none() {
348                                left = Some(Box::new(self.build_expr(n, source)?));
349                            }
350                            else if right.is_none() {
351                                right = Some(Box::new(self.build_expr(n, source)?));
352                            }
353                        }
354                        RedTree::Leaf(t) => {
355                            if op.is_none() {
356                                // Infer operator type from token text
357                                let text = source.get_text_in(t.span.clone().into());
358                                op = match text.as_ref() {
359                                    "+" => Some(RustTokenType::Plus),
360                                    "-" => Some(RustTokenType::Minus),
361                                    "*" => Some(RustTokenType::Star),
362                                    "/" => Some(RustTokenType::Slash),
363                                    "%" => Some(RustTokenType::Percent),
364                                    "==" => Some(RustTokenType::EqEq),
365                                    "!=" => Some(RustTokenType::Ne),
366                                    "<" => Some(RustTokenType::Lt),
367                                    "<=" => Some(RustTokenType::Le),
368                                    ">" => Some(RustTokenType::Gt),
369                                    ">=" => Some(RustTokenType::Ge),
370                                    "&&" => Some(RustTokenType::AndAnd),
371                                    "||" => Some(RustTokenType::OrOr),
372                                    "&" => Some(RustTokenType::Ampersand),
373                                    _ => None,
374                                };
375                            }
376                        }
377                    }
378                }
379
380                if let (Some(left), Some(op), Some(right)) = (left, op, right) { Ok(Expr::Binary { left, op, right, span: span.into() }) } else { Err(OakError::syntax_error("Invalid binary expression".to_string(), span.start, None)) }
381            }
382            RustElementType::UnaryExpression => {
383                let mut op = None;
384                let mut operand = None;
385
386                for child in node.children() {
387                    match child {
388                        RedTree::Node(n) => {
389                            operand = Some(Box::new(self.build_expr(n, source)?));
390                        }
391                        RedTree::Leaf(t) => {
392                            if op.is_none() {
393                                // Try to infer from the token text if available
394                                let token_text = source.get_text_in(t.span.clone().into());
395                                match token_text.as_ref() {
396                                    "!" => op = Some(RustTokenType::Bang),
397                                    "-" => op = Some(RustTokenType::Minus),
398                                    "+" => op = Some(RustTokenType::Plus),
399                                    _ => {}
400                                }
401                            }
402                        }
403                    }
404                }
405
406                if let (Some(op), Some(operand)) = (op, operand) { Ok(Expr::Unary { op, expr: operand, span: span.into() }) } else { Err(OakError::syntax_error("Invalid unary expression".to_string(), span.start, None)) }
407            }
408            RustElementType::CallExpression => {
409                let mut func = None;
410                let mut args = Vec::new();
411
412                for child in node.children() {
413                    match child {
414                        RedTree::Node(n) => {
415                            if func.is_none() {
416                                func = Some(Box::new(self.build_expr(n, source)?));
417                            }
418                            else if n.green.kind == RustElementType::ArgumentList {
419                                args = self.build_argument_list(n, source)?;
420                            }
421                        }
422                        _ => {}
423                    }
424                }
425
426                if let Some(func) = func { Ok(Expr::Call { callee: func, args, span: span.into() }) } else { Err(OakError::syntax_error("Invalid call expression".to_string(), span.start, None)) }
427            }
428            RustElementType::FieldExpression => {
429                let mut base = None;
430                let mut field = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
431
432                for child in node.children() {
433                    match child {
434                        RedTree::Node(n) => {
435                            base = Some(Box::new(self.build_expr(n, source)?));
436                        }
437                        RedTree::Leaf(t) => {
438                            if t.kind == RustTokenType::Identifier {
439                                field.name = text(source, t.span.clone().into());
440                                field.span = t.span.clone().into();
441                            }
442                        }
443                    }
444                }
445
446                if let Some(receiver) = base { Ok(Expr::Field { receiver, field, span: span.into() }) } else { Err(OakError::syntax_error("Invalid field expression".to_string(), span.start, None)) }
447            }
448            RustElementType::IndexExpression => {
449                let mut base = None;
450                let mut index = None;
451
452                for child in node.children() {
453                    if let RedTree::Node(n) = child {
454                        if base.is_none() {
455                            base = Some(Box::new(self.build_expr(n, source)?));
456                        }
457                        else if index.is_none() {
458                            index = Some(Box::new(self.build_expr(n, source)?));
459                        }
460                    }
461                }
462
463                if let (Some(receiver), Some(index)) = (base, index) { Ok(Expr::Index { receiver, index, span: span.into() }) } else { Err(OakError::syntax_error("Invalid index expression".to_string(), span.start, None)) }
464            }
465            RustElementType::ParenthesizedExpression => {
466                for child in node.children() {
467                    if let RedTree::Node(n) = child {
468                        let inner_expr = self.build_expr(n, source)?;
469                        return Ok(Expr::Paren { expr: Box::new(inner_expr), span: span.into() });
470                    }
471                }
472                Err(OakError::syntax_error("Invalid parenthesized expression".to_string(), span.start, None))
473            }
474            RustElementType::BlockExpression => {
475                let block = self.build_block(node, source)?;
476                Ok(Expr::Block(block))
477            }
478            _ => Err(OakError::syntax_error(format!("Unsupported expression type: {:?}", node.green.kind), span.start, None)),
479        }
480    }
481
482    // Placeholder methods - these need to be implemented based on specific requirements
483    fn build_struct(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Struct, OakError> {
484        let span = node.span();
485        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
486
487        for child in node.children() {
488            if let RedTree::Leaf(t) = child {
489                if t.kind == RustTokenType::Identifier {
490                    name.name = text(source, t.span.clone().into());
491                    name.span = t.span.clone().into();
492                }
493            }
494        }
495
496        Ok(Struct { name, fields: Vec::new(), span: span.into() })
497    }
498
499    fn build_enum(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Enum, OakError> {
500        let span = node.span();
501        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
502
503        for child in node.children() {
504            if let RedTree::Leaf(t) = child {
505                if t.kind == RustTokenType::Identifier {
506                    name.name = text(source, t.span.clone().into());
507                    name.span = t.span.clone().into();
508                }
509            }
510        }
511
512        Ok(Enum { name, variants: Vec::new(), span: span.into() })
513    }
514
515    fn build_trait(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Trait, OakError> {
516        let span = node.span();
517        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
518
519        for child in node.children() {
520            if let RedTree::Leaf(t) = child {
521                if t.kind == RustTokenType::Identifier {
522                    name.name = text(source, t.span.clone().into());
523                    name.span = t.span.clone().into();
524                }
525            }
526        }
527
528        Ok(Trait { name, items: Vec::new(), span: span.into() })
529    }
530
531    fn build_impl(&self, node: RedNode<RustLanguage>, _source: &SourceText) -> Result<Impl, OakError> {
532        let span = node.span();
533        Ok(Impl { trait_: None, ty: Type::Path("_".to_string()), items: Vec::new(), span: span.into() })
534    }
535
536    fn build_module(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Module, OakError> {
537        let span = node.span();
538        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
539
540        for child in node.children() {
541            if let RedTree::Leaf(t) = child {
542                if t.kind == RustTokenType::Identifier {
543                    name.name = text(source, t.span.clone().into());
544                    name.span = t.span.clone().into();
545                }
546            }
547        }
548
549        Ok(Module { name, items: Vec::new(), span: span.into() })
550    }
551
552    fn build_use(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<UseItem, OakError> {
553        let span = node.span();
554        Ok(UseItem { path: text(source, span.clone().into()), span: span.into() })
555    }
556
557    fn build_const(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Const, OakError> {
558        let span = node.span();
559        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
560
561        for child in node.children() {
562            if let RedTree::Leaf(t) = child {
563                if t.kind == RustTokenType::Identifier {
564                    name.name = text(source, t.span.clone().into());
565                    name.span = t.span.clone().into();
566                }
567            }
568        }
569
570        Ok(Const { name, ty: Type::Path("_".to_string()), expr: Expr::Bool { value: false, span: span.clone().into() }, span: span.into() })
571    }
572
573    fn build_static(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Static, OakError> {
574        let span = node.span();
575        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
576
577        for child in node.children() {
578            if let RedTree::Leaf(t) = child {
579                if t.kind == RustTokenType::Identifier {
580                    name.name = text(source, t.span.clone().into());
581                    name.span = t.span.clone().into();
582                }
583            }
584        }
585
586        Ok(Static { name, ty: Type::Path("_".to_string()), expr: Expr::Bool { value: false, span: span.clone().into() }, mutable: false, span: span.into() })
587    }
588
589    fn build_type_alias(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<TypeAlias, OakError> {
590        let span = node.span();
591        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
592
593        for child in node.children() {
594            if let RedTree::Leaf(t) = child {
595                if t.kind == RustTokenType::Identifier {
596                    name.name = text(source, t.span.clone().into());
597                    name.span = t.span.clone().into();
598                }
599            }
600        }
601
602        Ok(TypeAlias { name, ty: Type::Path("_".to_string()), span: span.into() })
603    }
604
605    fn build_item_statement(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Item, OakError> {
606        for child in node.children() {
607            if let RedTree::Node(n) = child {
608                match n.green.kind {
609                    RustElementType::Function => return Ok(Item::Function(self.build_function(n, source)?)),
610                    RustElementType::StructItem => return Ok(Item::Struct(self.build_struct(n, source)?)),
611                    RustElementType::EnumItem => return Ok(Item::Enum(self.build_enum(n, source)?)),
612                    RustElementType::Trait => return Ok(Item::Trait(self.build_trait(n, source)?)),
613                    RustElementType::Impl => return Ok(Item::Impl(self.build_impl(n, source)?)),
614                    RustElementType::ModuleItem => return Ok(Item::Module(self.build_module(n, source)?)),
615                    RustElementType::UseItem => return Ok(Item::Use(self.build_use(n, source)?)),
616                    RustElementType::Const => return Ok(Item::Const(self.build_const(n, source)?)),
617                    RustElementType::Static => return Ok(Item::Static(self.build_static(n, source)?)),
618                    RustElementType::TypeAlias => return Ok(Item::TypeAlias(self.build_type_alias(n, source)?)),
619                    _ => {}
620                }
621            }
622        }
623        Err(OakError::syntax_error("Invalid item statement".to_string(), node.offset, None))
624    }
625
626    fn build_type(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Type, OakError> {
627        let span = node.span();
628        Ok(Type::Path(text(source, span.into())))
629    }
630
631    fn build_pattern(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Pattern, OakError> {
632        for child in node.children() {
633            if let RedTree::Leaf(t) = child {
634                if t.kind == RustTokenType::Identifier {
635                    return Ok(Pattern::Ident(Identifier { name: text(source, t.span.clone().into()), span: t.span.clone().into() }));
636                }
637            }
638        }
639        Ok(Pattern::Wildcard)
640    }
641
642    fn build_argument_list(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<Expr>, OakError> {
643        let mut args = Vec::new();
644        for child in node.children() {
645            if let RedTree::Node(n) = child {
646                args.push(self.build_expr(n, source)?);
647            }
648        }
649        Ok(args)
650    }
651}
652
653/// 从源代码中提取文本的辅助函数
654#[inline]
655fn text(source: &SourceText, span: Range<usize>) -> String {
656    source.get_text_in(span.into()).to_string()
657}