1use crate::ast;
5use crate::ast::Span;
6
7#[derive(Debug, PartialEq)]
9#[allow(missing_docs)]
10pub struct InnerDocComment {
11 pub span: Span,
12 pub line: String,
13}
14
15#[derive(Debug, PartialEq)]
17pub enum Statement {
18 Workbench(WorkbenchDefinition),
20 InlineModule(InlineModule),
22 FileModule(FileModule),
24 Function(FunctionDefinition),
26 Use(UseStatement),
28 Const(ConstAssignment),
30 Init(InitDefinition),
32 Return(Return),
34 InnerAttribute(Attribute),
36 InnerDocComment(InnerDocComment),
38 LocalAssignment(LocalAssignment),
40 Property(PropertyAssignment),
42 Expression(ExpressionStatement),
44 Error(Span),
46}
47
48impl Statement {
49 pub fn span(&self) -> Span {
51 use Statement::*;
52
53 match self {
54 Workbench(st) => st.span.clone(),
55 InlineModule(st) => st.span.clone(),
56 FileModule(st) => st.span.clone(),
57 Function(st) => st.span.clone(),
58 Use(st) => st.span.clone(),
59 Const(st) => st.span.clone(),
60 Init(st) => st.span.clone(),
61 Return(st) => st.span.clone(),
62 InnerAttribute(st) => st.span.clone(),
63 LocalAssignment(st) => st.span.clone(),
64 Property(st) => st.span.clone(),
65 Expression(st) => st.span.clone(),
66 InnerDocComment(st) => st.span.clone(),
67 Error(span) => span.clone(),
68 }
69 }
70
71 pub fn ends_with_semicolon(&self) -> bool {
73 match self {
74 Statement::Workbench(_) => false,
75 Statement::InlineModule(_) => false,
76 Statement::Function(_) => false,
77 Statement::InnerAttribute(_) => false,
78 Statement::InnerDocComment(_) => false,
79 Statement::Init(_) => false,
80 Statement::Error(_) => false,
81
82 Statement::Use(_) => true,
83 Statement::Const(_) => true,
84 Statement::Return(_) => true,
85 Statement::FileModule(_) => true,
86 Statement::LocalAssignment(_) => true,
87 Statement::Property(_) => true,
88 Statement::Expression(e) => !matches!(
89 &e.expression,
90 ast::Expression::Body(_) | ast::Expression::If(_)
91 ),
92 }
93 }
94}
95
96#[derive(Debug, PartialEq, Copy, Clone)]
98pub enum WorkbenchKind {
99 Sketch,
101 Part,
103 Op,
105}
106
107impl std::fmt::Display for WorkbenchKind {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 write!(
110 f,
111 "{}",
112 match &self {
113 WorkbenchKind::Sketch => "sketch",
114 WorkbenchKind::Part => "part",
115 WorkbenchKind::Op => "op",
116 }
117 )
118 }
119}
120
121#[derive(Debug, PartialEq)]
123#[allow(missing_docs)]
124pub struct WorkbenchDefinition {
125 pub span: Span,
126 pub keyword_span: Span,
127 pub extras: ast::ItemExtras,
128 pub doc: DocBlock,
129 pub kind: WorkbenchKind,
130 pub attributes: Vec<Attribute>,
131 pub visibility: Option<Visibility>,
132 pub name: ast::Identifier,
133 pub plan: ParameterList,
134 pub body: ast::Body,
135}
136
137#[derive(Debug, PartialEq)]
139#[allow(missing_docs)]
140pub struct InlineModule {
141 pub span: Span,
142 pub keyword_span: Span,
143 pub extras: ast::ItemExtras,
144 pub doc: DocBlock,
145 pub attributes: Vec<Attribute>,
146 pub visibility: Option<Visibility>,
147 pub name: ast::Identifier,
148 pub body: ast::Body,
149}
150
151#[derive(Debug, PartialEq)]
153#[allow(missing_docs)]
154pub struct FileModule {
155 pub span: Span,
156 pub keyword_span: Span,
157 pub extras: ast::ItemExtras,
158 pub doc: DocBlock,
159 pub attributes: Vec<Attribute>,
160 pub visibility: Option<Visibility>,
161 pub name: ast::Identifier,
162}
163
164#[derive(Debug, PartialEq)]
166#[allow(missing_docs)]
167pub struct FunctionDefinition {
168 pub span: Span,
169 pub keyword_span: Span,
170 pub extras: ast::ItemExtras,
171 pub doc: DocBlock,
172 pub attributes: Vec<Attribute>,
173 pub visibility: Option<Visibility>,
174 pub name: ast::Identifier,
175 pub parameters: ParameterList,
176 pub return_type: Option<ast::Type>,
177 pub body: ast::Body,
178}
179
180#[derive(Debug, PartialEq)]
182#[allow(missing_docs)]
183pub struct InitDefinition {
184 pub span: Span,
185 pub keyword_span: Span,
186 pub extras: ast::ItemExtras,
187 pub doc: DocBlock,
188 pub attributes: Vec<Attribute>,
189 pub parameters: ParameterList,
190 pub body: ast::Body,
191}
192
193#[derive(Debug, PartialEq)]
195#[allow(missing_docs)]
196pub struct UseStatement {
197 pub span: Span,
198 pub attributes: Vec<Attribute>,
199 pub keyword_span: Span,
200 pub extras: ast::ItemExtras,
201 pub visibility: Option<Visibility>,
202 pub name: UseName,
203 pub use_as: Option<ast::Identifier>,
204}
205
206#[derive(Debug, PartialEq)]
208#[allow(missing_docs)]
209pub struct UseName {
210 pub span: Span,
211 pub extras: ast::ItemExtras,
212 pub parts: Vec<UseStatementPart>,
213}
214
215#[derive(Debug, PartialEq)]
217#[allow(missing_docs)]
218pub enum UseStatementPart {
219 Identifier(ast::Identifier),
220 Glob(Span),
221 Error(Span),
222}
223
224#[derive(Debug, PartialEq)]
226#[allow(missing_docs)]
227pub struct Return {
228 pub span: Span,
229 pub keyword_span: Span,
230 pub extras: ast::ItemExtras,
231 pub value: Option<ast::Expression>,
232}
233
234#[derive(Debug, PartialEq)]
236#[allow(missing_docs)]
237pub struct ParameterList {
238 pub span: Span,
239 pub extras: ast::ItemExtras,
240 pub parameters: Vec<Parameter>,
241}
242
243impl ast::Dummy for ParameterList {
244 fn dummy(span: Span) -> Self {
245 Self {
246 span,
247 extras: ast::ItemExtras::default(),
248 parameters: Vec::default(),
249 }
250 }
251}
252
253#[derive(Debug, PartialEq)]
255#[allow(missing_docs)]
256pub struct Parameter {
257 pub span: Span,
258 pub extras: ast::ItemExtras,
259 pub name: ast::Identifier,
260 pub ty: Option<ast::Type>,
261 pub default: Option<ast::Expression>,
262}
263
264#[derive(Debug, PartialEq)]
266#[allow(missing_docs)]
267pub struct Attribute {
268 pub span: Span,
269 pub is_inner: bool,
270 pub extras: ast::ItemExtras,
271 pub commands: Vec<AttributeCommand>,
272}
273
274#[derive(Debug, PartialEq)]
276pub enum AttributeCommand {
277 Ident(ast::Identifier),
279 Assignment(LocalAssignment),
281 Call(ast::Call),
283}
284
285#[derive(Debug, PartialEq)]
287#[allow(missing_docs)]
288pub struct LocalAssignment {
289 pub span: Span,
290 pub extras: ast::ItemExtras,
291 pub attributes: Vec<Attribute>,
292 pub name: ast::Identifier,
293 pub ty: Option<ast::Type>,
294 pub value: Box<ast::Expression>,
295}
296
297#[derive(Debug, PartialEq)]
299#[allow(missing_docs)]
300pub struct ConstAssignment {
301 pub span: Span,
302 pub keyword_span: Span,
303 pub extras: ast::ItemExtras,
304 pub doc: DocBlock,
305 pub attributes: Vec<Attribute>,
306 pub visibility: Option<Visibility>,
307 pub name: ast::Identifier,
308 pub ty: Option<ast::Type>,
309 pub value: Box<ast::Expression>,
310}
311
312#[derive(Debug, PartialEq)]
314#[allow(missing_docs)]
315pub struct PropertyAssignment {
316 pub span: Span,
317 pub keyword_span: Span,
318 pub extras: ast::ItemExtras,
319 pub doc: DocBlock,
320 pub attributes: Vec<Attribute>,
321 pub name: ast::Identifier,
322 pub ty: Option<ast::Type>,
323 pub value: Box<ast::Expression>,
324}
325
326#[derive(Debug, Clone, PartialEq)]
327#[allow(missing_docs)]
328pub enum CommentInner {
329 SingleLine(String),
331 MultiLine(String),
333}
334
335#[derive(Debug, Clone, PartialEq)]
337#[allow(missing_docs)]
338pub struct Comment {
339 pub span: Span,
340 pub inner: CommentInner,
341}
342
343#[derive(Debug, PartialEq)]
345#[allow(missing_docs)]
346pub struct DocBlock {
347 pub span: Span,
348 pub lines: Vec<String>,
349}
350
351#[derive(Debug, PartialEq)]
355pub enum Visibility {
356 Public,
358}
359
360#[derive(Debug, PartialEq)]
362#[allow(missing_docs)]
363pub struct ExpressionStatement {
364 pub span: Span,
365 pub extras: ast::ItemExtras,
366 pub attributes: Vec<Attribute>,
367 pub expression: ast::Expression,
368}
369
370#[derive(Debug, PartialEq)]
372#[allow(missing_docs)]
373pub struct StatementList {
374 pub span: Span,
375 pub extras: ast::ItemExtras,
376 pub statements: Vec<(Statement, ast::TrailingExtras)>,
377 pub tail: Option<Box<ExpressionStatement>>,
378}
379
380impl ast::Dummy for StatementList {
381 fn dummy(span: Span) -> Self {
382 Self {
383 span,
384 extras: ast::ItemExtras::default(),
385 statements: Vec::default(),
386 tail: None,
387 }
388 }
389}