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#[derive(Clone, Copy)]
18pub struct RustBuilder<'config> {
19 config: &'config RustLanguage,
21}
22
23impl<'config> RustBuilder<'config> {
24 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 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 }
105 },
106 RedTree::Leaf(_) => {
107 }
109 }
110 }
111 let root = RustRoot { items };
112 Ok(root)
113 }
114
115 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 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 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 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 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 }
237 }
238 }
239
240 Ok(Block { statements, block_start: span.start, block_end: span.end, nested: 0, span: span.into() })
241 }
242
243 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 if trait_.is_none() {
664 ty = self.build_type(n, source)?;
665 }
666 else {
667 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 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 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 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 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 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 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 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 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#[inline]
899pub(crate) fn text(source: &SourceText, span: Range<usize>) -> String {
900 source.get_text_in(span.into()).to_string()
901}