1use petr_ast::{Commented, Expression, ExpressionWithBindings, FunctionDeclaration, ImportStatement, TypeDeclaration};
2use petr_utils::{Identifier, SpannedItem};
3
4use crate::{binder::ScopeKind, Bind, Binder, Item};
5
6impl Bind for SpannedItem<&TypeDeclaration> {
7 type Output = Option<(Identifier, Item)>;
8
9 fn bind(
10 &self,
11 binder: &mut Binder,
12 ) -> Self::Output {
13 binder.insert_type(self)
14 }
15}
16
17impl Bind for SpannedItem<TypeDeclaration> {
18 type Output = Option<(Identifier, Item)>;
19
20 fn bind(
21 &self,
22 binder: &mut Binder,
23 ) -> Self::Output {
24 binder.insert_type(&self.span().with_item(self.item()))
25 }
26}
27
28impl Bind for Expression {
29 type Output = ();
31
32 fn bind(
33 &self,
34 binder: &mut Binder,
35 ) -> Self::Output {
36 match self {
38 Expression::List(list) => {
39 list.bind(binder);
40 },
41 Expression::Binding(ExpressionWithBindings {
42 bindings,
43 expression,
44 expr_id,
45 }) => binder.with_scope(ScopeKind::ExpressionWithBindings, |binder, scope_id| {
46 for binding in bindings.iter() {
47 let binding_id = binder.insert_binding(binding.clone());
48 binder.insert_into_current_scope(binding.name.id, binding.name.span().with_item(Item::Binding(binding_id)));
49 }
50 expression.bind(binder);
51 binder.insert_expression(*expr_id, scope_id);
52 }),
53 _ => (),
54 }
55 }
56}
57
58impl Bind for petr_ast::List {
59 type Output = ();
60
61 fn bind(
62 &self,
63 binder: &mut Binder,
64 ) -> Self::Output {
65 for item in self.elements.iter() {
66 item.bind(binder);
67 }
68 }
69}
70
71impl<T: Bind> Bind for Commented<T> {
72 type Output = T::Output;
73
74 fn bind(
75 &self,
76 binder: &mut Binder,
77 ) -> Self::Output {
78 self.item().bind(binder)
79 }
80}
81
82impl<T: Bind> Bind for SpannedItem<T> {
83 type Output = T::Output;
84
85 fn bind(
86 &self,
87 binder: &mut Binder,
88 ) -> Self::Output {
89 self.item().bind(binder)
90 }
91}
92
93impl Bind for SpannedItem<FunctionDeclaration> {
94 type Output = Option<(Identifier, Item)>;
95
96 fn bind(
97 &self,
98 binder: &mut Binder,
99 ) -> Self::Output {
100 binder.insert_function(&self.span().with_item(self.item()))
101 }
102}
103
104impl Bind for SpannedItem<&FunctionDeclaration> {
105 type Output = Option<(Identifier, Item)>;
106
107 fn bind(
108 &self,
109 binder: &mut Binder,
110 ) -> Self::Output {
111 binder.insert_function(self)
112 }
113}
114
115impl Bind for ImportStatement {
116 type Output = Option<(Identifier, Item)>;
117
118 fn bind(
119 &self,
120 binder: &mut Binder,
121 ) -> Self::Output {
122 let item = Item::Import {
123 path: self.path.clone(),
124 alias: self.alias,
125 };
126
127 let name = self.alias.unwrap_or_else(|| *self.path.iter().last().expect("should never be empty"));
129
130 binder.insert_into_current_scope(name.id, name.span.with_item(item.clone()));
131
132 if self.is_exported() {
133 Some((name, item))
134 } else {
135 None
136 }
137 }
138}