Skip to main content

oak_rust/builder/
mod.rs

1use crate::RustParser;
2
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};
6use std::sync::Arc;
7
8mod build_generics;
9
10pub use build_generics::*;
11
12/// AST builder for the Rust language.
13///
14/// `RustBuilder` is responsible for parsing Rust source code and constructing
15/// an Abstract Syntax Tree (AST). It uses a Pratt parser to handle operator
16/// precedence in expressions and supports all Rust syntax features.
17#[derive(Clone, Copy)]
18pub struct RustBuilder<'config> {
19    /// Language configuration
20    config: &'config RustLanguage,
21}
22
23impl<'config> RustBuilder<'config> {
24    /// Creates a new `RustBuilder` with the given configuration.
25    pub const fn new(config: &'config RustLanguage) -> Self {
26        Self { config }
27    }
28}
29
30impl<'config> Builder<RustLanguage> for RustBuilder<'config> {
31    fn build<'a, S: Source + ?Sized>(&self, source: &S, edits: &[TextEdit], _cache: &'a mut impl BuilderCache<RustLanguage>) -> BuildOutput<RustLanguage> {
32        let parser = RustParser::new(self.config);
33        let mut session = oak_core::parser::session::ParseSession::<RustLanguage>::default();
34        let OakDiagnostics { result, diagnostics } = parser.parse(source, edits, &mut session);
35
36        match result {
37            Ok(green) => {
38                let source_text = SourceText::new(source.get_text_in((0..source.length()).into()).into_owned());
39                match self.build_root(green, &source_text) {
40                    Ok(root) => OakDiagnostics { result: Ok(root), diagnostics },
41                    Err(e) => {
42                        let mut diagnostics = diagnostics;
43                        diagnostics.push(e.clone());
44                        OakDiagnostics { result: Err(e), diagnostics }
45                    }
46                }
47            }
48            Err(e) => OakDiagnostics { result: Err(e), diagnostics },
49        }
50    }
51}
52
53impl<'config> RustBuilder<'config> {
54    /// Builds the root of the AST (the entire source file).
55    pub(crate) fn build_root<'a>(&self, green_tree: &'a GreenNode<'a, 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        let root = RustRoot { items };
112        Ok(root)
113    }
114
115    /// Builds a function definition.
116    pub(crate) fn build_function(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Function>, OakError> {
117        let span = node.span();
118        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
119        let mut params = Vec::new();
120        let mut return_type = None;
121        let mut body = None;
122        let generics = self.build_generics_and_where(node.clone(), source)?;
123        let mut is_async = false;
124        let mut is_unsafe = false;
125        let mut is_extern = false;
126
127        for child in node.children() {
128            match child {
129                RedTree::Leaf(t) => match t.kind {
130                    RustTokenType::Async => is_async = true,
131                    RustTokenType::Unsafe => is_unsafe = true,
132                    RustTokenType::Extern => is_extern = true,
133                    RustTokenType::Identifier => {
134                        name.name = text(source, t.span.clone().into());
135                        name.span = t.span.clone().into();
136                    }
137                    _ => {}
138                },
139                RedTree::Node(n) => match n.green.kind {
140                    RustElementType::ParameterList => {
141                        params = self.build_param_list(n, source)?;
142                    }
143                    RustElementType::ReturnType => {
144                        return_type = Some(self.build_type(n, source)?);
145                    }
146                    RustElementType::BlockExpression => {
147                        body = Some(self.build_block(n, source)?);
148                    }
149                    _ => {}
150                },
151            }
152        }
153
154        let function = Arc::new(Function {
155            name,
156            params,
157            return_type,
158            body: body.unwrap_or_else(|| Block { statements: Vec::new(), block_start: 0, block_end: 0, nested: 0, span: Range { start: 0, end: 0 } }),
159            is_async,
160            is_unsafe,
161            generics,
162            is_extern,
163            span: span.into(),
164        });
165
166        Ok(function)
167    }
168
169    /// Builds a parameter list.
170    fn build_param_list(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<Param>, OakError> {
171        let mut params = Vec::new();
172        for child in node.children() {
173            if let RedTree::Node(n) = child {
174                if n.green.kind == RustElementType::Parameter {
175                    params.push(self.build_param(n, source)?);
176                }
177            }
178        }
179        Ok(params)
180    }
181
182    /// Builds a parameter.
183    fn build_param(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Param, OakError> {
184        let span = node.span();
185        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
186        let mut ty = Type::Path("_".to_string());
187
188        for child in node.children() {
189            match child {
190                RedTree::Leaf(t) => {
191                    if let RustTokenType::Identifier = t.kind {
192                        name.name = text(source, t.span.clone().into());
193                        name.span = t.span.clone().into();
194                    }
195                }
196                RedTree::Node(n) => match n.green.kind {
197                    RustElementType::Type => {
198                        ty = self.build_type(n, source)?;
199                    }
200                    _ => {}
201                },
202            }
203        }
204
205        Ok(Param { name, ty, is_mut: false, span: span.into() })
206    }
207
208    /// Builds a code block.
209    fn build_block(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Block, OakError> {
210        let span = node.span();
211        let mut statements = Vec::new();
212
213        for child in node.children() {
214            match child {
215                RedTree::Node(n) => match n.green.kind {
216                    RustElementType::LetStatement => {
217                        statements.push(self.build_let_statement(n, source)?);
218                    }
219                    RustElementType::ExpressionStatement => {
220                        statements.push(self.build_expr_statement(n, source)?);
221                    }
222                    RustElementType::ItemStatement => {
223                        let item = self.build_item_statement(n, source)?;
224                        statements.push(Statement::Item(item));
225                    }
226                    _ => {
227                        // Could be a block expression, treat it as an expression statement
228                        let span = n.span();
229                        if let Ok(block_expr) = self.build_expr(n, source) {
230                            statements.push(Statement::ExprStmt { expr: block_expr, semi: false, span: span.into() });
231                        }
232                    }
233                },
234                RedTree::Leaf(_) => {
235                    // Ignore separators and whitespace
236                }
237            }
238        }
239
240        Ok(Block { statements, block_start: span.start, block_end: span.end, nested: 0, span: span.into() })
241    }
242
243    /// Builds a let statement.
244    fn build_let_statement(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Statement, OakError> {
245        let span = node.span();
246        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
247        let mut ty = None;
248        let mut init = None;
249        let mut mutable = false;
250
251        for child in node.children() {
252            match child {
253                RedTree::Node(n) => match n.green.kind {
254                    RustElementType::Pattern => {
255                        let pattern = self.build_pattern(n, source)?;
256                        // Extract Identifier from Pattern
257                        match pattern {
258                            Pattern::Ident(ident) => name = ident,
259                            _ => {
260                                return Err(OakError::syntax_error("Expected identifier in let statement".to_string(), span.start, None));
261                            }
262                        }
263                    }
264                    RustElementType::Type => {
265                        ty = Some(self.build_type(n, source)?);
266                    }
267                    RustElementType::Expression => {
268                        init = Some(self.build_expr(n, source)?);
269                    }
270                    _ => {}
271                },
272                RedTree::Leaf(t) => {
273                    // Check for mut keyword
274                    if t.kind == RustTokenType::Mut {
275                        mutable = true;
276                    }
277                }
278            }
279        }
280
281        Ok(Statement::Let { name, ty, expr: init, mutable, span: span.into() })
282    }
283
284    /// Builds an expression statement.
285    fn build_expr_statement(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Statement, OakError> {
286        let span = node.span();
287        let mut expr = Expr::Bool { value: false, span: span.clone().into() };
288        let mut has_semicolon = false;
289
290        for child in node.children() {
291            match child {
292                RedTree::Node(n) => {
293                    if let Ok(expression) = self.build_expr(n, source) {
294                        expr = expression;
295                    }
296                }
297                RedTree::Leaf(t) => {
298                    if t.kind == RustTokenType::Semicolon {
299                        has_semicolon = true;
300                    }
301                }
302            }
303        }
304
305        Ok(Statement::ExprStmt { expr, semi: has_semicolon, span: span.into() })
306    }
307
308    /// Builds an expression.
309    pub(crate) fn build_expr(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Expr, OakError> {
310        let span = node.span();
311
312        match node.green.kind {
313            RustElementType::IdentifierExpression => {
314                for child in node.children() {
315                    if let RedTree::Leaf(t) = child {
316                        if t.kind == RustTokenType::Identifier {
317                            let ident = Identifier { name: text(source, t.span.clone().into()), span: t.span.clone().into() };
318                            return Ok(Expr::Ident(ident));
319                        }
320                    }
321                }
322                Err(OakError::syntax_error("Invalid identifier expression".to_string(), span.start, None))
323            }
324            RustElementType::LiteralExpression => {
325                for child in node.children() {
326                    if let RedTree::Leaf(t) = child {
327                        // Infer literal type directly from token text
328                        let text = source.get_text_in(t.span.clone().into());
329                        if text == "true" {
330                            return Ok(Expr::Bool { value: true, span: span.into() });
331                        }
332                        else if text == "false" {
333                            return Ok(Expr::Bool { value: false, span: span.into() });
334                        }
335                        else {
336                            // Other literal types (numbers, strings, characters, etc.)
337                            return Ok(Expr::Literal { value: text.to_string(), span: span.into() });
338                        }
339                    }
340                }
341                Err(OakError::syntax_error("Invalid literal expression".to_string(), span.start, None))
342            }
343            RustElementType::BinaryExpression => {
344                let mut left = None;
345                let mut op = None;
346                let mut right = None;
347
348                for child in node.children() {
349                    match child {
350                        RedTree::Node(n) => {
351                            if left.is_none() {
352                                left = Some(Box::new(self.build_expr(n, source)?));
353                            }
354                            else if right.is_none() {
355                                right = Some(Box::new(self.build_expr(n, source)?));
356                            }
357                        }
358                        RedTree::Leaf(t) => {
359                            if op.is_none() {
360                                // Infer operator type from token text
361                                let text = source.get_text_in(t.span.clone().into());
362                                op = match text.as_ref() {
363                                    "+" => Some(RustTokenType::Plus),
364                                    "-" => Some(RustTokenType::Minus),
365                                    "*" => Some(RustTokenType::Star),
366                                    "/" => Some(RustTokenType::Slash),
367                                    "%" => Some(RustTokenType::Percent),
368                                    "==" => Some(RustTokenType::EqEq),
369                                    "!=" => Some(RustTokenType::Ne),
370                                    "<" => Some(RustTokenType::Lt),
371                                    "<=" => Some(RustTokenType::Le),
372                                    ">" => Some(RustTokenType::Gt),
373                                    ">=" => Some(RustTokenType::Ge),
374                                    "&&" => Some(RustTokenType::AndAnd),
375                                    "||" => Some(RustTokenType::OrOr),
376                                    "&" => Some(RustTokenType::Ampersand),
377                                    _ => None,
378                                };
379                            }
380                        }
381                    }
382                }
383
384                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)) }
385            }
386            RustElementType::UnaryExpression => {
387                let mut op = None;
388                let mut operand = None;
389
390                for child in node.children() {
391                    match child {
392                        RedTree::Node(n) => {
393                            operand = Some(Box::new(self.build_expr(n, source)?));
394                        }
395                        RedTree::Leaf(t) => {
396                            if op.is_none() {
397                                // Try to infer from the token text if available
398                                let token_text = source.get_text_in(t.span.clone().into());
399                                match token_text.as_ref() {
400                                    "!" => op = Some(RustTokenType::Bang),
401                                    "-" => op = Some(RustTokenType::Minus),
402                                    "+" => op = Some(RustTokenType::Plus),
403                                    _ => {}
404                                }
405                            }
406                        }
407                    }
408                }
409
410                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)) }
411            }
412            RustElementType::CallExpression => {
413                let mut func = None;
414                let mut args = Vec::new();
415
416                for child in node.children() {
417                    match child {
418                        RedTree::Node(n) => {
419                            if func.is_none() {
420                                func = Some(Box::new(self.build_expr(n, source)?));
421                            }
422                            else if n.green.kind == RustElementType::ArgumentList {
423                                args = self.build_argument_list(n, source)?;
424                            }
425                        }
426                        _ => {}
427                    }
428                }
429
430                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)) }
431            }
432            RustElementType::FieldExpression => {
433                let mut base = None;
434                let mut field = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
435
436                for child in node.children() {
437                    match child {
438                        RedTree::Node(n) => {
439                            base = Some(Box::new(self.build_expr(n, source)?));
440                        }
441                        RedTree::Leaf(t) => {
442                            if t.kind == RustTokenType::Identifier {
443                                field.name = text(source, t.span.clone().into());
444                                field.span = t.span.clone().into();
445                            }
446                        }
447                    }
448                }
449
450                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)) }
451            }
452            RustElementType::IndexExpression => {
453                let mut base = None;
454                let mut index = None;
455
456                for child in node.children() {
457                    if let RedTree::Node(n) = child {
458                        if base.is_none() {
459                            base = Some(Box::new(self.build_expr(n, source)?));
460                        }
461                        else if index.is_none() {
462                            index = Some(Box::new(self.build_expr(n, source)?));
463                        }
464                    }
465                }
466
467                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)) }
468            }
469            RustElementType::ParenthesizedExpression => {
470                for child in node.children() {
471                    if let RedTree::Node(n) = child {
472                        let inner_expr = self.build_expr(n, source)?;
473                        return Ok(Expr::Paren { expr: Box::new(inner_expr), span: span.into() });
474                    }
475                }
476                Err(OakError::syntax_error("Invalid parenthesized expression".to_string(), span.start, None))
477            }
478            RustElementType::BlockExpression => {
479                let block = self.build_block(node, source)?;
480                Ok(Expr::Block(block))
481            }
482            _ => Err(OakError::syntax_error(format!("Unsupported expression type: {:?}", node.green.kind), span.start, None)),
483        }
484    }
485
486    /// Builds a struct definition.
487    pub(crate) fn build_struct(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Struct>, OakError> {
488        let span = node.span();
489        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
490        let mut fields = Vec::new();
491        let generics = self.build_generics_and_where(node.clone(), source)?;
492
493        for child in node.children() {
494            match child {
495                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
496                    name.name = text(source, t.span.clone().into());
497                    name.span = t.span.clone().into();
498                }
499                RedTree::Node(n) if n.green.kind == RustElementType::StructBody => {
500                    fields = self.build_fields(n, source)?;
501                }
502                _ => {}
503            }
504        }
505
506        let struct_def = Arc::new(Struct { name, generics, fields, span: span.into() });
507        Ok(struct_def)
508    }
509
510    /// Builds a list of fields (for structs or enums).
511    fn build_fields(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<Field>, OakError> {
512        let mut fields = Vec::new();
513        for child in node.children() {
514            if let RedTree::Node(n) = child {
515                if n.green.kind == RustElementType::Field {
516                    fields.push(self.build_field(n, source)?);
517                }
518            }
519        }
520        Ok(fields)
521    }
522
523    /// Builds a single field.
524    fn build_field(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Field, OakError> {
525        let span = node.span();
526        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
527        let mut ty = Type::Path("_".to_string());
528
529        for child in node.children() {
530            match child {
531                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
532                    name.name = text(source, t.span.clone().into());
533                    name.span = t.span.clone().into();
534                }
535                RedTree::Node(n) if n.green.kind == RustElementType::Type => {
536                    ty = self.build_type(n, source)?;
537                }
538                _ => {}
539            }
540        }
541
542        Ok(Field { name, ty, span: span.into() })
543    }
544
545    /// Builds an enum definition.
546    pub(crate) fn build_enum(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Enum>, OakError> {
547        let span = node.span();
548        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
549        let mut variants = Vec::new();
550        let generics = self.build_generics_and_where(node.clone(), source)?;
551
552        for child in node.children() {
553            match child {
554                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
555                    name.name = text(source, t.span.clone().into());
556                    name.span = t.span.clone().into();
557                }
558                RedTree::Node(n) if n.green.kind == RustElementType::EnumBody => {
559                    variants = self.build_variants(n, source)?;
560                }
561                _ => {}
562            }
563        }
564
565        let enum_def = Arc::new(Enum { name, generics, variants, span: span.into() });
566        Ok(enum_def)
567    }
568
569    /// Builds a list of enum variants.
570    fn build_variants(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<Variant>, OakError> {
571        let mut variants = Vec::new();
572        for child in node.children() {
573            if let RedTree::Node(n) = child {
574                if n.green.kind == RustElementType::Variant {
575                    variants.push(self.build_variant(n, source)?);
576                }
577            }
578        }
579        Ok(variants)
580    }
581
582    /// Builds a single enum variant.
583    fn build_variant(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Variant, OakError> {
584        let span = node.span();
585        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
586        let mut fields = None;
587
588        for child in node.children() {
589            match child {
590                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
591                    name.name = text(source, t.span.clone().into());
592                    name.span = t.span.clone().into();
593                }
594                RedTree::Node(n) if n.green.kind == RustElementType::TupleBody || n.green.kind == RustElementType::StructBody => {
595                    fields = Some(self.build_fields(n, source)?);
596                }
597                _ => {}
598            }
599        }
600
601        Ok(Variant { name, fields, span: span.into() })
602    }
603
604    /// Builds a trait definition.
605    pub(crate) fn build_trait(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Trait>, OakError> {
606        let span = node.span();
607        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
608        let mut items = Vec::new();
609        let generics = self.build_generics_and_where(node.clone(), source)?;
610
611        for child in node.children() {
612            match child {
613                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
614                    name.name = text(source, t.span.clone().into());
615                    name.span = t.span.clone().into();
616                }
617                RedTree::Node(n) if n.green.kind == RustElementType::TraitBody => {
618                    items = self.build_trait_items(n, source)?;
619                }
620                _ => {}
621            }
622        }
623
624        let trait_def = Arc::new(Trait { name, generics, items, span: span.into() });
625        Ok(trait_def)
626    }
627
628    /// Builds items within a trait.
629    fn build_trait_items(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<TraitItem>, OakError> {
630        let mut items = Vec::new();
631        for child in node.children() {
632            if let RedTree::Node(n) = child {
633                match n.green.kind {
634                    RustElementType::Function => {
635                        let func = self.build_function(n, source)?;
636                        items.push(TraitItem::Method((*func).clone()));
637                    }
638                    RustElementType::TypeAlias => {
639                        let alias = self.build_type_alias(n, source)?;
640                        items.push(TraitItem::Type((*alias).clone()));
641                    }
642                    _ => {}
643                }
644            }
645        }
646        Ok(items)
647    }
648
649    /// Builds an impl block.
650    pub(crate) fn build_impl(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Impl>, OakError> {
651        let span = node.span();
652        let mut ty = Type::Path("_".to_string());
653        let mut trait_ = None;
654        let mut items = Vec::new();
655        let generics = self.build_generics_and_where(node.clone(), source)?;
656
657        for child in node.children() {
658            if let RedTree::Node(n) = child {
659                match n.green.kind {
660                    RustElementType::Type => {
661                        // In Rust, `impl Trait for Type` or `impl Type`.
662                        // The parser distinguishes these.
663                        if trait_.is_none() {
664                            ty = self.build_type(n, source)?;
665                        }
666                        else {
667                            // This would be the type after 'for'
668                            ty = self.build_type(n, source)?;
669                        }
670                    }
671                    RustElementType::TraitRef => {
672                        trait_ = Some(self.build_type(n, source)?);
673                    }
674                    RustElementType::ImplBody => {
675                        items = self.build_impl_items(n, source)?;
676                    }
677                    _ => {}
678                }
679            }
680        }
681
682        let impl_block = Arc::new(Impl { generics, ty, trait_, items, span: span.into() });
683        Ok(impl_block)
684    }
685
686    /// Builds items within an impl block.
687    fn build_impl_items(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<ImplItem>, OakError> {
688        let mut items = Vec::new();
689        for child in node.children() {
690            if let RedTree::Node(n) = child {
691                match n.green.kind {
692                    RustElementType::Function => {
693                        let func = self.build_function(n, source)?;
694                        items.push(ImplItem::Method((*func).clone()));
695                    }
696                    RustElementType::TypeAlias => {
697                        let alias = self.build_type_alias(n, source)?;
698                        items.push(ImplItem::Type((*alias).clone()));
699                    }
700                    RustElementType::Const => {
701                        let constant = self.build_const(n, source)?;
702                        items.push(ImplItem::Const((*constant).clone()));
703                    }
704                    _ => {}
705                }
706            }
707        }
708        Ok(items)
709    }
710
711    /// Builds a module definition.
712    pub(crate) fn build_module(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Module>, OakError> {
713        let span = node.span();
714        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
715        let mut items = Vec::new();
716
717        for child in node.children() {
718            match child {
719                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
720                    name.name = text(source, t.span.clone().into());
721                    name.span = t.span.clone().into();
722                }
723                RedTree::Node(n) if n.green.kind == RustElementType::Block => {
724                    // Reuse build_root logic for module items
725                    let root = self.build_root(n.green, source)?;
726                    items = root.items;
727                }
728                _ => {}
729            }
730        }
731
732        let module = Arc::new(Module { name, items, span: span.into() });
733        Ok(module)
734    }
735
736    /// Builds a use statement.
737    pub(crate) fn build_use(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<UseItem>, OakError> {
738        let span = node.span();
739        let mut path = String::new();
740
741        for child in node.children() {
742            if let RedTree::Leaf(t) = child {
743                if t.kind == RustTokenType::Identifier {
744                    path = text(source, t.span().into());
745                }
746            }
747        }
748
749        let use_item = Arc::new(UseItem { path, span: span.into() });
750        Ok(use_item)
751    }
752
753    /// Builds a constant definition.
754    pub(crate) fn build_const(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Const>, OakError> {
755        let span = node.span();
756        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
757        let mut ty = Type::Path("_".to_string());
758        let mut expr = Expr::Bool { value: false, span: span.clone().into() };
759
760        for child in node.children() {
761            match child {
762                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
763                    name.name = text(source, t.span.clone().into());
764                    name.span = t.span.clone().into();
765                }
766                RedTree::Node(n) => match n.green.kind {
767                    RustElementType::Type => ty = self.build_type(n, source)?,
768                    RustElementType::Expression => expr = self.build_expr(n, source)?,
769                    _ => {}
770                },
771                _ => {}
772            }
773        }
774
775        let constant = Arc::new(Const { name, ty, expr, span: span.into() });
776        Ok(constant)
777    }
778
779    /// Builds a static definition.
780    pub(crate) fn build_static(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<Static>, OakError> {
781        let span = node.span();
782        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
783        let mut ty = Type::Path("_".to_string());
784        let mut expr = Expr::Bool { value: false, span: span.clone().into() };
785        let mut mutable = false;
786
787        for child in node.children() {
788            match child {
789                RedTree::Leaf(t) => match t.kind {
790                    RustTokenType::Identifier => {
791                        name.name = text(source, t.span.clone().into());
792                        name.span = t.span.clone().into();
793                    }
794                    RustTokenType::Mut => mutable = true,
795                    _ => {}
796                },
797                RedTree::Node(n) => match n.green.kind {
798                    RustElementType::Type => ty = self.build_type(n, source)?,
799                    RustElementType::Expression => expr = self.build_expr(n, source)?,
800                    _ => {}
801                },
802            }
803        }
804
805        let static_def = Arc::new(Static { name, ty, expr, mutable, span: span.into() });
806        Ok(static_def)
807    }
808
809    /// Builds a type alias.
810    pub(crate) fn build_type_alias(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Arc<TypeAlias>, OakError> {
811        let span = node.span();
812        let mut name = Identifier { name: String::new(), span: Range { start: 0, end: 0 } };
813        let mut ty = Type::Path("_".to_string());
814        let generics = self.build_generics_and_where(node.clone(), source)?;
815
816        for child in node.children() {
817            match child {
818                RedTree::Leaf(t) if t.kind == RustTokenType::Identifier => {
819                    name.name = text(source, t.span.clone().into());
820                    name.span = t.span.clone().into();
821                }
822                RedTree::Node(n) if n.green.kind == RustElementType::Type => {
823                    ty = self.build_type(n, source)?;
824                }
825                _ => {}
826            }
827        }
828
829        let type_alias = Arc::new(TypeAlias { name, generics, ty, span: span.into() });
830        Ok(type_alias)
831    }
832
833    fn build_item_statement(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Item, OakError> {
834        for child in node.children() {
835            if let RedTree::Node(n) = child {
836                match n.green.kind {
837                    RustElementType::Function => return Ok(Item::Function(self.build_function(n, source)?)),
838                    RustElementType::StructItem => return Ok(Item::Struct(self.build_struct(n, source)?)),
839                    RustElementType::EnumItem => return Ok(Item::Enum(self.build_enum(n, source)?)),
840                    RustElementType::Trait => return Ok(Item::Trait(self.build_trait(n, source)?)),
841                    RustElementType::Impl => return Ok(Item::Impl(self.build_impl(n, source)?)),
842                    RustElementType::ModuleItem => return Ok(Item::Module(self.build_module(n, source)?)),
843                    RustElementType::UseItem => return Ok(Item::Use(self.build_use(n, source)?)),
844                    RustElementType::Const => return Ok(Item::Const(self.build_const(n, source)?)),
845                    RustElementType::Static => return Ok(Item::Static(self.build_static(n, source)?)),
846                    RustElementType::TypeAlias => return Ok(Item::TypeAlias(self.build_type_alias(n, source)?)),
847                    _ => {}
848                }
849            }
850        }
851        Err(OakError::syntax_error("Invalid item statement".to_string(), node.offset, None))
852    }
853
854    fn build_type(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Type, OakError> {
855        let span = node.span();
856        match node.green.kind {
857            _ => Ok(Type::Path(text(source, span.into()))),
858        }
859    }
860
861    fn build_pattern(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Pattern, OakError> {
862        for child in node.children() {
863            match child {
864                RedTree::Leaf(t) => match t.kind {
865                    RustTokenType::Identifier => {
866                        return Ok(Pattern::Ident(Identifier { name: text(source, t.span.clone().into()), span: t.span.clone().into() }));
867                    }
868                    RustTokenType::Underscore => {
869                        return Ok(Pattern::Wildcard);
870                    }
871                    _ => {}
872                },
873                RedTree::Node(n) => {
874                    // Recurse into nested patterns if necessary
875                    if let Ok(pattern) = self.build_pattern(n, source) {
876                        if !matches!(pattern, Pattern::Wildcard) {
877                            return Ok(pattern);
878                        }
879                    }
880                }
881            }
882        }
883        Ok(Pattern::Wildcard)
884    }
885
886    fn build_argument_list(&self, node: RedNode<RustLanguage>, source: &SourceText) -> Result<Vec<Expr>, OakError> {
887        let mut args = Vec::new();
888        for child in node.children() {
889            if let RedTree::Node(n) = child {
890                args.push(self.build_expr(n, source)?);
891            }
892        }
893        Ok(args)
894    }
895}
896
897/// Helper function to extract text from source code.
898#[inline]
899pub(crate) fn text(source: &SourceText, span: Range<usize>) -> String {
900    source.get_text_in(span.into()).to_string()
901}