1use super::*;
2use crate::cst::{CommaSeperated, CstNode, CstToken, IdentToken};
3use crate::{cst, SyntaxKind};
4use cstree::interning::{Resolver, TokenKey};
5use itertools::Itertools;
6use skullbrain_lexer::{Lexer, LiteralKind, ModifierKind};
7
8impl ToAst for IdentToken {
9 type Output = Ident;
10 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
11 where
12 I: Resolver<TokenKey> + ?Sized,
13 {
14 let span = self.token().text_range();
15
16 Some(Ident {
17 span,
18 name: self.token().resolve_text(resolver).to_string(),
19 })
20 }
21}
22
23impl ToAst for cst::LiteralToken {
24 type Output = Literal;
25 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
26 where
27 I: Resolver<TokenKey> + ?Sized,
28 {
29 let text = self.token().resolve_text(resolver);
30 let Some(tok) = Lexer::new(text.chars()).next() else {
31 unreachable!()
32 };
33
34 let Some(lit) = tok.into_kind().literial() else {
35 unreachable!()
36 };
37
38 let value = match lit {
39 LiteralKind::Int { is_empty, .. } if is_empty => return None,
40 LiteralKind::Double { empty_exponent, .. } if empty_exponent => return None,
41 LiteralKind::Str { is_terminated } if is_terminated => return None,
42 LiteralKind::Str { .. } => Value::Str(text.to_string()).into(),
43 LiteralKind::Int { .. } => {
44 let Ok(int) = text.parse() else {
45 unreachable!()
46 };
47
48 Value::Int(int).into()
49 }
50 LiteralKind::Double { .. } => {
51 let Ok(int) = text.parse() else {
52 unreachable!()
53 };
54
55 Value::Double(int).into()
56 }
57 LiteralKind::Boolean(value) => Value::Bool(value).into(),
58 };
59
60 let span = self.token().text_range();
61 Some(Literal { span, value })
62 }
63}
64
65impl ToAst for cst::BinaryExpr {
66 type Output = BinaryExpr;
67 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
68 where
69 I: Resolver<TokenKey> + ?Sized,
70 {
71 let lhs = self.lhs()?.to_ast(resolver)?;
72 let rhs = self.rhs()?.to_ast(resolver)?;
73
74 let op = match self.operator().kind() {
75 SyntaxKind::OpEq => BinaryOp::Eq,
76 SyntaxKind::OpNotEq => BinaryOp::NotEq,
77 SyntaxKind::OpLt => BinaryOp::Lt,
78 SyntaxKind::OpGt => BinaryOp::Gt,
79 SyntaxKind::OpLtEq => BinaryOp::LtEq,
80 SyntaxKind::OpGtEq => BinaryOp::GtEq,
81 SyntaxKind::OpMinus => BinaryOp::Sub,
82 SyntaxKind::OpAnd => BinaryOp::And,
83 SyntaxKind::OpOr => BinaryOp::Or,
84 SyntaxKind::OpPlus => BinaryOp::Add,
85 SyntaxKind::OpMul => BinaryOp::Mul,
86 SyntaxKind::OpDivide => BinaryOp::Div,
87 SyntaxKind::OpMod => BinaryOp::Mod,
88 _ => unreachable!(),
89 };
90
91 let operand = Box::new((lhs, rhs));
92 Some(BinaryExpr { op, operand })
93 }
94}
95
96impl ToAst for cst::UnaryExpr {
97 type Output = UnaryExpr;
98 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
99 where
100 I: Resolver<TokenKey> + ?Sized,
101 {
102 let rhs = self.expr()?.to_ast(resolver)?;
103 let expr = Box::new(rhs);
104
105 let op = match self.operator().kind() {
106 SyntaxKind::OpNot => UnaryOp::Not,
107 SyntaxKind::OpMinus => UnaryOp::Minus,
108 _ => unreachable!(),
109 };
110
111 Some(UnaryExpr { op, expr })
112 }
113}
114
115impl ToAst for cst::ChainExpr {
116 type Output = ChainExpr;
117 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
118 where
119 I: Resolver<TokenKey> + ?Sized,
120 {
121 let object = self.object()?.to_ast(resolver)?;
122 let method = self.method()?.to_ast(resolver)?;
123 let data = Box::new((object, method));
124 Some(ChainExpr { data })
125 }
126}
127
128impl ToAst for cst::ParenExpr {
129 type Output = ParenExpr;
130 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
131 where
132 I: Resolver<TokenKey> + ?Sized,
133 {
134 let _ = self.open_token()?;
136 let _ = self.close_token()?;
137
138 let expr = self.exprs().exactly_one().ok()?.to_ast(resolver)?;
139 let expr = Box::new(expr);
140
141 let span = self.syntax().text_range();
142
143 Some(ParenExpr { expr, span })
144 }
145}
146
147impl ToAst for cst::BlockExpr {
148 type Output = BlockExpr;
149 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
150 where
151 I: Resolver<TokenKey> + ?Sized,
152 {
153 let _ = self.open_token()?;
154 let _ = self.close_token()?;
155
156 let statements = self
157 .exprs()
158 .map(|expr| expr.to_ast(resolver))
159 .collect::<Option<Box<[_]>>>()?;
160 let span = self.syntax().text_range();
161
162 Some(BlockExpr { statements, span })
163 }
164}
165
166impl ToAst for cst::Break {
167 type Output = Break;
168 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
169 where
170 I: Resolver<TokenKey> + ?Sized,
171 {
172 let value = self.optional_expr()?.to_ast(resolver)?;
173 let value = Box::new(value);
174 let span = self.syntax().text_range();
175
176 Some(Break {
177 value: Some(value),
178 span,
179 })
180 }
181}
182
183impl ToAst for cst::Continue {
184 type Output = Continue;
185 fn to_ast<I>(self, _resolver: &I) -> Option<Self::Output>
186 where
187 I: Resolver<TokenKey> + ?Sized,
188 {
189 let span = self.syntax().text_range();
190 Some(Continue { span })
191 }
192}
193
194impl ToAst for cst::Return {
195 type Output = Return;
196 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
197 where
198 I: Resolver<TokenKey> + ?Sized,
199 {
200 let value = self.optional_expr()?.to_ast(resolver)?;
201 let span = self.syntax().text_range();
202 Some(Return {
203 span,
204 value: Some(Box::new(value)),
205 })
206 }
207}
208
209impl ToAst for cst::Throw {
210 type Output = Throw;
211 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
212 where
213 I: Resolver<TokenKey> + ?Sized,
214 {
215 let value = self.expr()?.to_ast(resolver)?;
216 let span = self.syntax().text_range();
217 Some(Throw {
218 span,
219
220 value: Box::new(value),
221 })
222 }
223}
224
225impl ToAst for cst::While {
226 type Output = While;
227 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
228 where
229 I: Resolver<TokenKey> + ?Sized,
230 {
231 let condition = self.condition()?.to_ast(resolver)?;
232 let body = self.body()?.to_ast(resolver)?;
233 let span = self.syntax().text_range();
234 Some(While {
235 span,
236 condition,
237 body,
238 })
239 }
240}
241
242impl ToAst for cst::ForLoop {
243 type Output = ForLoop;
244 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
245 where
246 I: Resolver<TokenKey> + ?Sized,
247 {
248 let _ = self.open_token()?;
249 let _ = self.close_token()?;
250
251 let iterator = self.iter()?.to_ast(resolver)?;
252 let body = self.body()?.to_ast(resolver)?;
253 let span = self.syntax().text_range();
254 Some(ForLoop {
255 span,
256 iterator,
257 body,
258 })
259 }
260}
261
262impl ToAst for cst::TryCatch {
263 type Output = TryCatch;
264 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
265 where
266 I: Resolver<TokenKey> + ?Sized,
267 {
268 let try_arm = self.try_arm()?;
269 let _ = try_arm.try_token()?;
270 let try_block = try_arm.block()?.to_ast(resolver)?;
271
272 let mut seen_arm_without_ty = false;
273
274 let catch_arms = self
275 .catch_arms()
276 .map(|arm| match arm.catch_ty() {
277 Some(_) if seen_arm_without_ty => None,
278 Some(_) => {
279 seen_arm_without_ty = true;
280 arm.to_ast(resolver)
281 }
282 None => arm.to_ast(resolver),
283 })
284 .collect::<Option<Box<[_]>>>();
285
286 let span = self.syntax().text_range();
287
288 Some(TryCatch {
289 span,
290 try_block,
291 catch_arms,
292 })
293 }
294}
295
296impl ToAst for cst::CatchArm {
297 type Output = CatchArm;
298 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
299 where
300 I: Resolver<TokenKey> + ?Sized,
301 {
302 let _ = self.catch_token()?;
303
304 let catch_ty = match self.catch_ty() {
305 Some(ty) => {
306 let _ = ty.colon_token()?;
307 let name = ty.name()?.to_ast(resolver)?;
308 let ty = ty.ty()?.to_ast(resolver)?;
309 let span = ty.span();
310 Some(CatchType { span, ty, name })
311 }
312 None => None,
313 };
314
315 let body = self.block()?.to_ast(resolver)?;
316 let span = self.syntax().text_range();
317
318 Some(CatchArm {
319 span,
320 catch_ty,
321 body,
322 })
323 }
324}
325
326impl ToAst for cst::VariableStmt {
327 type Output = VariableStmt;
328 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
329 where
330 I: Resolver<TokenKey> + ?Sized,
331 {
332 let is_mutable = self.var_token().is_mutable();
333 let modifiers = self.modifiers()?.to_ast(resolver)?;
334 let name = self.name()?.to_ast(resolver)?;
335 let ty_annotation = self.ty()?.to_ast(resolver)?.into();
336 let initializer = self.initialiser()?.to_ast(resolver)?;
337
338 let span = self.syntax().text_range();
339
340 Some(VariableStmt {
341 span,
342 is_mutable,
343 modifiers,
344 name,
345 ty_annotation,
346 initializer,
347 })
348 }
349}
350
351impl ToAst for cst::TypeAlias {
352 type Output = TypeAlias;
353 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
354 where
355 I: Resolver<TokenKey> + ?Sized,
356 {
357 let modifiers = self.modifiers()?.to_ast(resolver)?;
358
359 let _ = self.alias_token()?;
360 let _ = self.assignment_token()?;
361
362 let name = self.name()?.to_ast(resolver)?;
363 let aliased_type = self.aliased()?.to_ast(resolver)?;
364
365 let span = self.syntax().text_range();
366
367 Some(TypeAlias {
368 span,
369 modifiers,
370 name,
371 aliased_type,
372 })
373 }
374}
375
376impl ToAst for cst::Modifiers {
377 type Output = Modifiers;
378 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
379 where
380 I: Resolver<TokenKey> + ?Sized,
381 {
382 let mut flags = Modifiers::empty();
383
384 for item in self.iter() {
385 let kind = item.kind(resolver);
386 let flag = match kind {
387 ModifierKind::VisibilityPublic => Modifiers::Public,
388 ModifierKind::InstanceAccess => Modifiers::InstanceAccess,
389 };
390
391 if flags.contains(flag.clone()) {
392 return None;
393 } else {
394 flags |= flag
395 }
396 }
397
398 Some(flags)
399 }
400}
401impl ToAst for cst::Type {
402 type Output = Type;
403 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
404 where
405 I: Resolver<TokenKey> + ?Sized,
406 {
407 if let Some(ident) = self.ident() {
408 let ident = ident.to_ast(resolver)?;
409 return Some(Type::Ident(ident));
410 }
411
412 if let Some(func) = self.signature() {
413 let ty = func.to_ast(resolver)?;
414 return Some(Type::Function(ty));
415 }
416
417 unreachable!()
418 }
419}
420
421impl ToAst for cst::FunctionSignature {
422 type Output = FunctionSignature;
423 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
424 where
425 I: Resolver<TokenKey> + ?Sized,
426 {
427 let _ = self.return_ty_token()?;
428 let _ = self.open_brace_token()?;
429 let _ = self.close_brace_token()?;
430
431 let parameters = self.parameters()?;
432 let is_valid = parameters
433 .iter()
434 .enumerate()
435 .all(|(i, item)| match (i % 2, item) {
436 (0, CommaSeperated::Item(_)) => true,
438 (1, CommaSeperated::Comma(_)) => true,
440 _ => false,
441 });
442
443 if !is_valid {
444 return None;
445 }
446
447 let parameters = parameters
448 .iter()
449 .step_by(2) .filter_map(|item| match item {
451 CommaSeperated::Item(param) => Some(param.to_ast(resolver)),
452 _ => None,
453 })
454 .collect::<Option<Box<_>>>()?;
455
456 let return_type = self
457 .return_ty()
458 .and_then(|ty| ty.to_ast(resolver))
459 .map(|ty| Box::new(ty));
460
461 let span = self.syntax().text_range();
462 Some(FunctionSignature {
463 span,
464 parameters,
465 return_type,
466 })
467 }
468}
469
470impl ToAst for cst::Parameter {
471 type Output = Parameter;
472 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
473 where
474 I: Resolver<TokenKey> + ?Sized,
475 {
476 let _ = self.colon_token()?;
477 let name = self.name()?.to_ast(resolver)?;
478 let ty = self.ty()?.to_ast(resolver)?;
479
480 Some(Parameter { name, ty })
481 }
482}
483
484impl ToAst for cst::IfElse {
485 type Output = IfElse;
486 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
487 where
488 I: Resolver<TokenKey> + ?Sized,
489 {
490 let if_arm = self.if_arm()?;
491 let _ = if_arm.if_token()?;
492 let condition = if_arm.condition()?.to_ast(resolver)?;
493 let then_branch = if_arm.body()?.to_ast(resolver)?;
494
495 let mut seen_else_branch = false;
496 let else_branches = self
497 .else_branches()
498 .map(|arm| match arm {
499 crate::cst::ElseBranch::Else(_) if seen_else_branch => None,
500 crate::cst::ElseBranch::Else(_) => {
501 seen_else_branch = true;
502 arm.to_ast(resolver)
503 }
504 _ => arm.to_ast(resolver),
505 })
506 .collect::<Option<Box<[_]>>>()?;
507 let span = self.syntax().text_range();
508
509 Some(IfElse {
510 span,
511 condition,
512 then_branch,
513 else_branches: Some(else_branches),
514 })
515 }
516}
517
518impl ToAst for cst::ElseBranch {
519 type Output = ElseBranch;
520 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
521 where
522 I: Resolver<TokenKey> + ?Sized,
523 {
524 let span = self.syntax().text_range();
525
526 let (condition, then_branch) = match self {
527 cst::ElseBranch::Else(else_arm) => {
528 let _ = else_arm.else_token()?;
529 let body = else_arm.body()?.to_ast(resolver)?;
530 (None, body)
531 }
532 cst::ElseBranch::ElseIf(else_if_arm) => {
533 let _ = else_if_arm.contains_else_if()?;
534 let condition = else_if_arm.condition()?.to_ast(resolver)?;
535 let body = else_if_arm.body()?.to_ast(resolver)?;
536
537 (Some(condition), body)
538 }
539 };
540
541 Some(ElseBranch {
542 span,
543 condition,
544 then_branch,
545 })
546 }
547}
548impl ToAst for cst::Match {
549 type Output = Match;
550 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
551 where
552 I: Resolver<TokenKey> + ?Sized,
553 {
554 let _ = self.body_open_token();
555 let _ = self.body_close_token();
556 if self.disallowed_exprs()?.next().is_some() {
557 return None;
558 }
559
560 let expr = self.expr()?.to_ast(resolver)?;
561
562 let arms = self
563 .match_arms()?
564 .map(|arm| arm.to_ast(resolver))
565 .collect::<Option<Box<_>>>()?;
566
567 let mut iter = arms.iter();
569
570 if iter.find(|arm| arm.pat.is_none()).is_some()
571 && iter.find(|arm| arm.pat.is_none()).is_some()
572 {
573 return None;
574 }
575
576 let span = self.syntax().text_range();
577 Some(Match { span, expr, arms })
578 }
579}
580
581impl ToAst for cst::MatchArm {
582 type Output = MatchArm;
583 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
584 where
585 I: Resolver<TokenKey> + ?Sized,
586 {
587 let res = match self {
588 cst::MatchArm::WithCondition(arm) => MatchArm {
589 pat: Some(arm.pat()?.to_ast(resolver)?),
590 body: arm.body()?.to_ast(resolver)?,
591 },
592 cst::MatchArm::Default(arm) => MatchArm {
593 pat: None,
594 body: arm.body()?.to_ast(resolver)?,
595 },
596 };
597
598 Some(res)
599 }
600}
601
602impl ToAst for cst::MatchPat {
603 type Output = MatchPat;
604 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
605 where
606 I: Resolver<TokenKey> + ?Sized,
607 {
608 let pat = if let Some(ident) = self.ident() {
609 MatchPat::Ident(ident.to_ast(resolver)?)
610 } else if let Some(lit) = self.lit() {
611 MatchPat::Literal(lit.to_ast(resolver)?)
612 } else {
613 todo!()
614 };
615
616 Some(pat)
617 }
618}
619
620impl ToAst for cst::ImportStmt {
621 type Output = ImportStmt;
622 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
623 where
624 I: Resolver<TokenKey> + ?Sized,
625 {
626 let _ = self.import_token()?;
627 let _ = self.alias_token()?;
628 let _ = self.alias_token()?;
629
630 let source = {
631 let source = self.source()?;
632
633 match source.ident() {
634 Some(ident) => ident.to_ast(resolver)?.name,
635 None => match source.path() {
636 Some(path) => path.token().resolve_text(resolver).to_string(),
637 _ => unreachable!(),
638 },
639 }
640 };
641
642 let item_idents = self.items()?;
643
644 let open = item_idents.open_token();
645 let close = item_idents.close_token();
646
647 let is_both = open.is_some() && close.is_some();
648 let is_neither = open.is_none() && close.is_none();
649
650 let items = item_idents
651 .idents()
652 .map(|i| i.to_ast(resolver))
653 .collect::<Option<Box<_>>>()?;
654
655 match items.len() {
659 0 => return None,
660 1 => {
661 if !(is_both || is_neither) {
662 return None;
663 }
664 }
665 _ => {
666 if !is_both {
667 return None;
668 }
669 }
670 }
671 let span = self.syntax().text_range();
672
673 Some(ImportStmt {
674 span,
675 source,
676 items,
677 })
678 }
679}
680
681impl ToAst for cst::Function {
682 type Output = Function;
683 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
684 where
685 I: Resolver<TokenKey> + ?Sized,
686 {
687 let modifiers = self.modifiers()?.to_ast(resolver)?;
688 let name = self.name()?.to_ast(resolver)?;
689 let signature = self.signature()?.to_ast(resolver)?;
690 let body = self.body()?.to_ast(resolver)?;
691 let span = self.syntax().text_range();
692
693 Some(Function {
694 span,
695 modifiers,
696 name,
697 signature,
698 body,
699 })
700 }
701}
702
703impl ToAst for cst::FunctionItem {
704 type Output = FunctionItem;
705 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
706 where
707 I: Resolver<TokenKey> + ?Sized,
708 {
709 let span = self.syntax().text_range();
710
711 let modifiers = self.modifiers()?.to_ast(resolver)?;
712 let name = self.name()?.to_ast(resolver)?;
713 let signature = self.signature()?.to_ast(resolver)?;
714 let body = match self {
715 cst::FunctionItem::Full(function) => Some(function.body()?.to_ast(resolver)?),
716 cst::FunctionItem::Partial(_) => None,
717 };
718
719 Some(FunctionItem {
720 span,
721 modifiers,
722 name,
723 signature,
724 body,
725 })
726 }
727}
728
729impl ToAst for cst::Enum {
730 type Output = Enum;
731 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
732 where
733 I: Resolver<TokenKey> + ?Sized,
734 {
735 let _ = self.body_open_tok()?;
736 let _ = self.body_close_tok()?;
737
738 let modifiers = self.modifiers()?.to_ast(resolver)?;
739 let name = self.name()?.to_ast(resolver)?;
740 let variants = self
741 .variants()
742 .map(|variant| variant.to_ast(resolver))
743 .collect::<Option<Box<_>>>()?;
744
745 let nested_impls = self
746 .nested_impls()?
747 .map(|_impl| _impl.to_ast(resolver))
748 .collect::<Option<Box<_>>>()?;
749
750 let members = MemberConstructions::from_cst(
751 resolver,
752 self.methods(),
753 self.variables(),
754 self.ty_aliasz(),
755 self.implicit_init_exprs(),
756 )?;
757
758 let span = self.syntax().text_range();
759
760 Some(Enum {
761 span,
762 modifiers,
763 name,
764 variants,
765 members,
766 nested_impls,
767 })
768 }
769}
770
771impl ToAst for cst::EnumVariant {
772 type Output = EnumVariant;
773 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
774 where
775 I: Resolver<TokenKey> + ?Sized,
776 {
777 let name = self.name()?.to_ast(resolver)?;
778 let fields = self.fields()?.map(|field| field.to_ast(resolver)).collect();
779 Some(EnumVariant { name, fields })
780 }
781}
782
783impl ToAst for cst::EnumVariantField {
784 type Output = EnumVariantField;
785 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
786 where
787 I: Resolver<TokenKey> + ?Sized,
788 {
789 let _ = self.colon_token()?;
790 let name = self.name()?.to_ast(resolver)?;
791 let ty = self.ty()?.to_ast(resolver)?;
792
793 Some(EnumVariantField { name, ty })
794 }
795}
796
797impl<T> MemberConstructions<T> {
798 fn from_cst<I, A>(
799 resolver: &I,
800 methods: Option<impl Iterator<Item = A>>,
801 fields: Option<impl Iterator<Item = cst::VariableStmt>>,
802 aliasz: Option<impl Iterator<Item = cst::TypeAlias>>,
803 implicit_inits: Option<impl Iterator<Item = cst::Expr>>,
804 ) -> Option<Self>
805 where
806 I: Resolver<TokenKey> + ?Sized,
807 A: ToAst<Output = T>,
808 {
809 let methods = methods?
810 .map(|func| func.to_ast(resolver))
811 .collect::<Option<Box<_>>>()?;
812
813 let fields = fields?
814 .map(|var| var.to_ast(resolver))
815 .collect::<Option<Box<_>>>()?;
816
817 let aliasz = aliasz?
818 .map(|var| var.to_ast(resolver))
819 .collect::<Option<Box<_>>>()?;
820
821 let implicit_inits = implicit_inits?
822 .map(|expr| expr.to_ast(resolver))
823 .collect::<Option<Box<_>>>()?;
824
825 Some(Self {
826 implicit_inits,
827 methods,
828 fields,
829 aliasz,
830 })
831 }
832}
833
834impl ToAst for cst::Class {
835 type Output = Class;
836 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
837 where
838 I: Resolver<TokenKey> + ?Sized,
839 {
840 let _ = self.body_open_tok()?;
841 let _ = self.body_close_tok()?;
842
843 let modifiers = self.modifiers()?.to_ast(resolver)?;
844 let name = self.name()?.to_ast(resolver)?;
845
846 let nested_impls = self
847 .nested_impls()?
848 .map(|_impl| _impl.to_ast(resolver))
849 .collect::<Option<Box<_>>>()?;
850
851 let members = MemberConstructions::from_cst(
852 resolver,
853 self.methods(),
854 self.variables(),
855 self.ty_aliasz(),
856 self.implicit_init_exprs(),
857 )?;
858 let span = self.syntax().text_range();
859
860 Some(Class {
861 span,
862 modifiers,
863 name,
864 members,
865 nested_impls,
866 })
867 }
868}
869
870impl ToAst for cst::TraitImpl {
871 type Output = TraitImpl;
872 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
873 where
874 I: Resolver<TokenKey> + ?Sized,
875 {
876 let _ = self.body_open_tok()?;
877 let _ = self.body_close_tok()?;
878
879 let members = MemberConstructions::from_cst(
880 resolver,
881 self.methods(),
882 self.var_decls(),
883 self.type_aliases(),
884 self.implicit_init_exprs(),
885 )?;
886
887 let span = self.syntax().text_range();
888
889 Some(TraitImpl { span, members })
890 }
891}
892
893impl ToAst for cst::Trait {
894 type Output = Trait;
895 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
896 where
897 I: Resolver<TokenKey> + ?Sized,
898 {
899 let _ = self.open_brace_token()?;
900 let _ = self.close_brace_token()?;
901
902 let modifiers = self.modifiers()?.to_ast(resolver)?;
903 let name = self.name()?.to_ast(resolver)?;
904 let members = MemberConstructions::from_cst(
905 resolver,
906 self.functions(),
907 self.var_decls(),
908 self.type_aliases(),
909 self.implicit_init_exprs(),
910 )?;
911
912 let span = self.syntax().text_range();
913
914 Some(Trait {
915 span,
916 modifiers,
917 name,
918 members,
919 })
920 }
921}
922
923impl ToAst for cst::Expr {
924 type Output = Expr;
925 fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
926 where
927 I: Resolver<TokenKey> + ?Sized,
928 {
929 let res: Expr = match self {
930 cst::Expr::Literal(literal_token) => literal_token.to_ast(resolver)?.into(),
931 cst::Expr::Ident(ident_token) => ident_token.to_ast(resolver)?.into(),
932 cst::Expr::Paren(parenthesis_expr) => parenthesis_expr.to_ast(resolver)?.into(),
933 cst::Expr::Block(block_expr) => block_expr.to_ast(resolver)?.into(),
934 cst::Expr::Binary(binary_op) => binary_op.to_ast(resolver)?.into(),
935 cst::Expr::Unary(unary_op) => unary_op.to_ast(resolver)?.into(),
936 cst::Expr::Chain(chain) => chain.to_ast(resolver)?.into(),
937 cst::Expr::Break(break_expr) => break_expr.to_ast(resolver)?.into(),
938 cst::Expr::Continue(continue_expr) => continue_expr.to_ast(resolver)?.into(),
939 cst::Expr::Return(return_expr) => return_expr.to_ast(resolver)?.into(),
940 cst::Expr::Throw(throw_expr) => throw_expr.to_ast(resolver)?.into(),
941 cst::Expr::While(while_loop) => while_loop.to_ast(resolver)?.into(),
942 cst::Expr::For(for_loop) => for_loop.to_ast(resolver)?.into(),
943 cst::Expr::TryCatch(try_catch) => try_catch.to_ast(resolver)?.into(),
944 cst::Expr::IfElse(if_else) => if_else.to_ast(resolver)?.into(),
945 cst::Expr::Match(match_expr) => match_expr.to_ast(resolver)?.into(),
946 cst::Expr::Variable(variable_decl) => variable_decl.to_ast(resolver)?.into(),
947 cst::Expr::Import(import_expr) => import_expr.to_ast(resolver)?.into(),
948 cst::Expr::TypeAlias(type_alias_decl) => type_alias_decl.to_ast(resolver)?.into(),
949 cst::Expr::Function(function_decl) => function_decl.to_ast(resolver)?.into(),
950 cst::Expr::Trait(trait_decl) => trait_decl.to_ast(resolver)?.into(),
951 cst::Expr::TraitImpl(trait_impl_decl) => trait_impl_decl.to_ast(resolver)?.into(),
952 cst::Expr::Class(class_decl) => class_decl.to_ast(resolver)?.into(),
953 cst::Expr::Enum(enum_decl) => enum_decl.to_ast(resolver)?.into(),
954 cst::Expr::Fragment(_) => return None,
955 };
956
957 Some(res)
958 }
959}
960
961impl From<Literal> for Expr {
962 fn from(value: Literal) -> Self {
963 Expr::Literal(value)
964 }
965}
966
967impl From<Ident> for Expr {
968 fn from(value: Ident) -> Self {
969 Expr::Ident(value)
970 }
971}
972
973impl From<BinaryExpr> for Expr {
975 fn from(value: BinaryExpr) -> Self {
976 Expr::Binary(value)
977 }
978}
979
980impl From<UnaryExpr> for Expr {
981 fn from(value: UnaryExpr) -> Self {
982 Expr::Unary(value)
983 }
984}
985
986impl From<ChainExpr> for Expr {
988 fn from(value: ChainExpr) -> Self {
989 Expr::Chain(value)
990 }
991}
992
993impl From<ParenExpr> for Expr {
995 fn from(value: ParenExpr) -> Self {
996 Expr::Paren(value)
997 }
998}
999
1000impl From<BlockExpr> for Expr {
1001 fn from(value: BlockExpr) -> Self {
1002 Expr::Block(value)
1003 }
1004}
1005
1006impl From<Break> for Expr {
1008 fn from(value: Break) -> Self {
1009 Expr::Break(value)
1010 }
1011}
1012
1013impl From<Continue> for Expr {
1014 fn from(value: Continue) -> Self {
1015 Expr::Continue(value)
1016 }
1017}
1018
1019impl From<Return> for Expr {
1020 fn from(value: Return) -> Self {
1021 Expr::Return(value)
1022 }
1023}
1024
1025impl From<Throw> for Expr {
1026 fn from(value: Throw) -> Self {
1027 Expr::Throw(value)
1028 }
1029}
1030
1031impl From<While> for Expr {
1033 fn from(value: While) -> Self {
1034 Expr::While(value)
1035 }
1036}
1037
1038impl From<ForLoop> for Expr {
1039 fn from(value: ForLoop) -> Self {
1040 Expr::For(value)
1041 }
1042}
1043
1044impl From<IfElse> for Expr {
1046 fn from(value: IfElse) -> Self {
1047 Expr::If(value)
1048 }
1049}
1050
1051impl From<Match> for Expr {
1052 fn from(value: Match) -> Self {
1053 Expr::Match(value)
1054 }
1055}
1056
1057impl From<TryCatch> for Expr {
1059 fn from(value: TryCatch) -> Self {
1060 Expr::TryCatch(value)
1061 }
1062}
1063
1064impl From<VariableStmt> for Expr {
1066 fn from(value: VariableStmt) -> Self {
1067 Expr::Variable(value)
1068 }
1069}
1070
1071impl From<Function> for Expr {
1072 fn from(value: Function) -> Self {
1073 Expr::Function(value)
1074 }
1075}
1076
1077impl From<Class> for Expr {
1078 fn from(value: Class) -> Self {
1079 Expr::Class(value)
1080 }
1081}
1082
1083impl From<Trait> for Expr {
1084 fn from(value: Trait) -> Self {
1085 Expr::Trait(value)
1086 }
1087}
1088
1089impl From<TraitImpl> for Expr {
1090 fn from(value: TraitImpl) -> Self {
1091 Expr::TraitImpl(value)
1092 }
1093}
1094
1095impl From<Enum> for Expr {
1096 fn from(value: Enum) -> Self {
1097 Expr::Enum(value)
1098 }
1099}
1100
1101impl From<TypeAlias> for Expr {
1102 fn from(value: TypeAlias) -> Self {
1103 Expr::TypeAlias(value)
1104 }
1105}
1106
1107impl From<ImportStmt> for Expr {
1108 fn from(value: ImportStmt) -> Self {
1109 Expr::Import(value)
1110 }
1111}