1use erl_tokenize::tokens::{AtomToken, SymbolToken, VariableToken};
2use erl_tokenize::values::Symbol;
3use erl_tokenize::{Position, PositionRange};
4
5use self::parts::{ExceptionClass, StackTrace, WhenGuard};
6use crate::cst::commons::parts::{Args, Clauses, Sequence};
7use crate::cst::exprs::parts::Body;
8use crate::cst::types;
9use crate::cst::{GuardTest, Pattern, Type};
10use crate::traits::{Parse, TokenRead};
11use crate::{Parser, Result};
12
13pub mod parts;
14
15#[derive(Debug, Clone)]
17pub struct CatchClause {
18 pub class: Option<ExceptionClass>,
19 pub pattern: Pattern,
20 pub stacktrace: Option<StackTrace>,
21 pub guard: Option<WhenGuard>,
22 pub _arrow: SymbolToken,
23 pub body: Body,
24}
25impl Parse for CatchClause {
26 fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
27 where
28 T: TokenRead,
29 {
30 Ok(CatchClause {
31 class: track!(parser.parse())?,
32 pattern: track!(parser.parse())?,
33 stacktrace: track!(parser.parse())?,
34 guard: track!(parser.parse())?,
35 _arrow: track!(parser.expect(&Symbol::RightArrow))?,
36 body: track!(parser.parse())?,
37 })
38 }
39}
40impl PositionRange for CatchClause {
41 fn start_position(&self) -> Position {
42 self.class
43 .as_ref()
44 .map(PositionRange::start_position)
45 .unwrap_or_else(|| self.pattern.start_position())
46 }
47 fn end_position(&self) -> Position {
48 self.body.end_position()
49 }
50}
51
52#[derive(Debug, Clone)]
54pub struct SpecClause {
55 pub args: Args<Type>,
56 pub _arrow: SymbolToken,
57 pub return_type: Type,
58 pub constraints: Option<types::Constraints>,
59}
60impl Parse for SpecClause {
61 fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
62 where
63 T: TokenRead,
64 {
65 Ok(SpecClause {
66 args: track!(parser.parse())?,
67 _arrow: track!(parser.expect(&Symbol::RightArrow))?,
68 return_type: track!(parser.parse())?,
69 constraints: track!(parser.parse())?,
70 })
71 }
72}
73impl PositionRange for SpecClause {
74 fn start_position(&self) -> Position {
75 self.args.start_position()
76 }
77 fn end_position(&self) -> Position {
78 self.constraints
79 .as_ref()
80 .map(PositionRange::end_position)
81 .unwrap_or_else(|| self.return_type.end_position())
82 }
83}
84
85#[derive(Debug, Clone)]
87pub struct CaseClause {
88 pub pattern: Pattern,
89 pub guard: Option<WhenGuard>,
90 pub _arrow: SymbolToken,
91 pub body: Body,
92}
93impl Parse for CaseClause {
94 fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
95 where
96 T: TokenRead,
97 {
98 Ok(CaseClause {
99 pattern: track!(parser.parse())?,
100 guard: track!(parser.parse())?,
101 _arrow: track!(parser.expect(&Symbol::RightArrow))?,
102 body: track!(parser.parse())?,
103 })
104 }
105}
106impl PositionRange for CaseClause {
107 fn start_position(&self) -> Position {
108 self.pattern.start_position()
109 }
110 fn end_position(&self) -> Position {
111 self.body.end_position()
112 }
113}
114
115#[derive(Debug, Clone)]
117pub struct IfClause {
118 pub guard: Clauses<Sequence<GuardTest>>,
119 pub _arrow: SymbolToken,
120 pub body: Body,
121}
122impl Parse for IfClause {
123 fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
124 where
125 T: TokenRead,
126 {
127 Ok(IfClause {
128 guard: track!(parser.parse())?,
129 _arrow: track!(parser.expect(&Symbol::RightArrow))?,
130 body: track!(parser.parse())?,
131 })
132 }
133}
134impl PositionRange for IfClause {
135 fn start_position(&self) -> Position {
136 self.guard.start_position()
137 }
138 fn end_position(&self) -> Position {
139 self.body.end_position()
140 }
141}
142
143#[derive(Debug, Clone)]
145pub struct FunClause {
146 pub patterns: Args<Pattern>,
147 pub guard: Option<WhenGuard>,
148 pub _arrow: SymbolToken,
149 pub body: Body,
150}
151impl Parse for FunClause {
152 fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
153 where
154 T: TokenRead,
155 {
156 Ok(FunClause {
157 patterns: track!(parser.parse())?,
158 guard: track!(parser.parse())?,
159 _arrow: track!(parser.expect(&Symbol::RightArrow))?,
160 body: track!(parser.parse())?,
161 })
162 }
163}
164impl PositionRange for FunClause {
165 fn start_position(&self) -> Position {
166 self.patterns.start_position()
167 }
168 fn end_position(&self) -> Position {
169 self.body.end_position()
170 }
171}
172
173#[derive(Debug, Clone)]
175pub struct NamedFunClause {
176 pub name: VariableToken,
177 pub patterns: Args<Pattern>,
178 pub guard: Option<WhenGuard>,
179 pub _arrow: SymbolToken,
180 pub body: Body,
181}
182impl Parse for NamedFunClause {
183 fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
184 where
185 T: TokenRead,
186 {
187 Ok(NamedFunClause {
188 name: track!(parser.parse())?,
189 patterns: track!(parser.parse())?,
190 guard: track!(parser.parse())?,
191 _arrow: track!(parser.expect(&Symbol::RightArrow))?,
192 body: track!(parser.parse())?,
193 })
194 }
195}
196impl PositionRange for NamedFunClause {
197 fn start_position(&self) -> Position {
198 self.name.start_position()
199 }
200 fn end_position(&self) -> Position {
201 self.body.end_position()
202 }
203}
204
205#[derive(Debug, Clone)]
207pub struct FunDeclClause {
208 pub name: AtomToken,
209 pub patterns: Args<Pattern>,
210 pub guard: Option<WhenGuard>,
211 pub _arrow: SymbolToken,
212 pub body: Body,
213}
214impl Parse for FunDeclClause {
215 fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
216 where
217 T: TokenRead,
218 {
219 Ok(FunDeclClause {
221 name: track!(parser.parse())?,
222 patterns: track!(parser.parse())?,
223 guard: track!(parser.parse())?,
224 _arrow: track!(parser.expect(&Symbol::RightArrow))?,
225 body: track!(parser.parse())?,
226 })
227 }
228}
229impl PositionRange for FunDeclClause {
230 fn start_position(&self) -> Position {
231 self.name.start_position()
232 }
233 fn end_position(&self) -> Position {
234 self.body.end_position()
235 }
236}