Skip to main content

sysml_v2_parser/ast/
mod.rs

1//! Abstract syntax tree types for SysML v2 textual notation.
2
3mod core;
4mod kerml_fallback;
5
6pub use core::*;
7pub use kerml_fallback::*;
8mod behavior;
9mod common;
10mod package;
11mod requirement;
12mod root;
13mod structure;
14mod view;
15
16pub use behavior::*;
17pub use common::*;
18pub use package::*;
19pub use requirement::*;
20pub use root::*;
21pub use structure::*;
22pub use view::*;
23
24// ---------------------------------------------------------------------------
25// Normalization for test comparison (strips optional spans so parsed == expected)
26// ---------------------------------------------------------------------------
27
28impl RootNamespace {
29    /// Returns a copy with all optional source spans set to `None` and all `Node` spans set to
30    /// `Span::dummy()`. Use when comparing parser output to hand-built expected AST in tests.
31    pub fn normalize_for_test_comparison(&self) -> Self {
32        RootNamespace {
33            elements: self
34                .elements
35                .iter()
36                .map(normalize_root_element_node)
37                .collect(),
38        }
39    }
40}
41
42fn dummy_node<T: Clone>(_n: &Node<T>, value: T) -> Node<T> {
43    Node::new(Span::dummy(), value)
44}
45
46fn normalize_root_element_node(el: &Node<RootElement>) -> Node<RootElement> {
47    let value = match &el.value {
48        RootElement::Package(p) => RootElement::Package(dummy_node(p, normalize_package(&p.value))),
49        RootElement::LibraryPackage(lp) => {
50            RootElement::LibraryPackage(dummy_node(lp, normalize_library_package(&lp.value)))
51        }
52        RootElement::Namespace(n) => {
53            RootElement::Namespace(dummy_node(n, normalize_namespace_decl(&n.value)))
54        }
55        RootElement::Import(n) => RootElement::Import(dummy_node(n, n.value.clone())),
56    };
57    dummy_node(el, value)
58}
59
60fn normalize_library_package(lp: &LibraryPackage) -> LibraryPackage {
61    LibraryPackage {
62        is_standard: lp.is_standard,
63        identification: lp.identification.clone(),
64        body: normalize_package_body(&lp.body),
65    }
66}
67
68fn normalize_namespace_decl(n: &NamespaceDecl) -> NamespaceDecl {
69    NamespaceDecl {
70        identification: n.identification.clone(),
71        body: normalize_package_body(&n.body),
72    }
73}
74
75fn normalize_package(p: &Package) -> Package {
76    Package {
77        identification: p.identification.clone(),
78        body: normalize_package_body(&p.body),
79    }
80}
81
82fn normalize_package_body(b: &PackageBody) -> PackageBody {
83    match b {
84        PackageBody::Semicolon => PackageBody::Semicolon,
85        PackageBody::Brace { elements } => PackageBody::Brace {
86            elements: elements
87                .iter()
88                .map(normalize_package_body_element_node)
89                .collect(),
90        },
91    }
92}
93
94fn normalize_package_body_element_node(el: &Node<PackageBodyElement>) -> Node<PackageBodyElement> {
95    let value = match &el.value {
96        PackageBodyElement::Error(n) => PackageBodyElement::Error(dummy_node(n, n.value.clone())),
97        PackageBodyElement::Doc(n) => PackageBodyElement::Doc(dummy_node(n, n.value.clone())),
98        PackageBodyElement::Comment(n) => {
99            PackageBodyElement::Comment(dummy_node(n, n.value.clone()))
100        }
101        PackageBodyElement::TextualRep(n) => {
102            PackageBodyElement::TextualRep(dummy_node(n, n.value.clone()))
103        }
104        PackageBodyElement::Filter(n) => PackageBodyElement::Filter(dummy_node(n, n.value.clone())),
105        PackageBodyElement::Package(n) => {
106            PackageBodyElement::Package(dummy_node(n, normalize_package(&n.value)))
107        }
108        PackageBodyElement::LibraryPackage(n) => {
109            PackageBodyElement::LibraryPackage(dummy_node(n, normalize_library_package(&n.value)))
110        }
111        PackageBodyElement::Import(n) => PackageBodyElement::Import(dummy_node(n, n.value.clone())),
112        PackageBodyElement::PartDef(n) => {
113            PackageBodyElement::PartDef(dummy_node(n, normalize_part_def(&n.value)))
114        }
115        PackageBodyElement::PartUsage(n) => {
116            PackageBodyElement::PartUsage(dummy_node(n, normalize_part_usage(&n.value)))
117        }
118        PackageBodyElement::PortDef(n) => {
119            PackageBodyElement::PortDef(dummy_node(n, normalize_port_def(&n.value)))
120        }
121        PackageBodyElement::InterfaceDef(n) => {
122            PackageBodyElement::InterfaceDef(dummy_node(n, normalize_interface_def(&n.value)))
123        }
124        PackageBodyElement::ConnectionDef(n) => {
125            PackageBodyElement::ConnectionDef(dummy_node(n, normalize_connection_def(&n.value)))
126        }
127        PackageBodyElement::MetadataDef(n) => {
128            PackageBodyElement::MetadataDef(dummy_node(n, normalize_metadata_def(&n.value)))
129        }
130        PackageBodyElement::EnumDef(n) => {
131            PackageBodyElement::EnumDef(dummy_node(n, normalize_enum_def(&n.value)))
132        }
133        PackageBodyElement::OccurrenceDef(n) => {
134            PackageBodyElement::OccurrenceDef(dummy_node(n, normalize_occurrence_def(&n.value)))
135        }
136        PackageBodyElement::OccurrenceUsage(n) => {
137            PackageBodyElement::OccurrenceUsage(dummy_node(n, n.value.clone()))
138        }
139        PackageBodyElement::AliasDef(n) => {
140            PackageBodyElement::AliasDef(dummy_node(n, n.value.clone()))
141        }
142        PackageBodyElement::AttributeDef(n) => {
143            PackageBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
144        }
145        PackageBodyElement::ActionDef(n) => {
146            PackageBodyElement::ActionDef(dummy_node(n, normalize_action_def(&n.value)))
147        }
148        PackageBodyElement::ActionUsage(n) => {
149            PackageBodyElement::ActionUsage(dummy_node(n, normalize_action_usage(&n.value)))
150        }
151        PackageBodyElement::RequirementDef(n) => {
152            PackageBodyElement::RequirementDef(dummy_node(n, n.value.clone()))
153        }
154        PackageBodyElement::RequirementUsage(n) => {
155            PackageBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
156        }
157        PackageBodyElement::Satisfy(n) => {
158            PackageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
159        }
160        PackageBodyElement::UseCaseDef(n) => {
161            PackageBodyElement::UseCaseDef(dummy_node(n, n.value.clone()))
162        }
163        PackageBodyElement::Actor(n) => PackageBodyElement::Actor(dummy_node(n, n.value.clone())),
164        PackageBodyElement::StateDef(n) => {
165            PackageBodyElement::StateDef(dummy_node(n, n.value.clone()))
166        }
167        PackageBodyElement::StateUsage(n) => {
168            PackageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
169        }
170        PackageBodyElement::ItemDef(n) => {
171            PackageBodyElement::ItemDef(dummy_node(n, n.value.clone()))
172        }
173        PackageBodyElement::IndividualDef(n) => {
174            PackageBodyElement::IndividualDef(dummy_node(n, n.value.clone()))
175        }
176        PackageBodyElement::ConstraintDef(n) => {
177            PackageBodyElement::ConstraintDef(dummy_node(n, n.value.clone()))
178        }
179        PackageBodyElement::CalcDef(n) => {
180            PackageBodyElement::CalcDef(dummy_node(n, n.value.clone()))
181        }
182        PackageBodyElement::ViewDef(n) => {
183            PackageBodyElement::ViewDef(dummy_node(n, n.value.clone()))
184        }
185        PackageBodyElement::ViewpointDef(n) => {
186            PackageBodyElement::ViewpointDef(dummy_node(n, n.value.clone()))
187        }
188        PackageBodyElement::RenderingDef(n) => {
189            PackageBodyElement::RenderingDef(dummy_node(n, n.value.clone()))
190        }
191        PackageBodyElement::ViewUsage(n) => {
192            PackageBodyElement::ViewUsage(dummy_node(n, n.value.clone()))
193        }
194        PackageBodyElement::ViewpointUsage(n) => {
195            PackageBodyElement::ViewpointUsage(dummy_node(n, n.value.clone()))
196        }
197        PackageBodyElement::RenderingUsage(n) => {
198            PackageBodyElement::RenderingUsage(dummy_node(n, n.value.clone()))
199        }
200        PackageBodyElement::Dependency(n) => {
201            PackageBodyElement::Dependency(dummy_node(n, n.value.clone()))
202        }
203        PackageBodyElement::AllocationDef(n) => {
204            PackageBodyElement::AllocationDef(dummy_node(n, n.value.clone()))
205        }
206        PackageBodyElement::AllocationUsage(n) => {
207            PackageBodyElement::AllocationUsage(dummy_node(n, n.value.clone()))
208        }
209        PackageBodyElement::FlowDef(n) => {
210            PackageBodyElement::FlowDef(dummy_node(n, n.value.clone()))
211        }
212        PackageBodyElement::FlowUsage(n) => {
213            PackageBodyElement::FlowUsage(dummy_node(n, n.value.clone()))
214        }
215        PackageBodyElement::ConcernUsage(n) => {
216            PackageBodyElement::ConcernUsage(dummy_node(n, n.value.clone()))
217        }
218        PackageBodyElement::CaseDef(n) => {
219            PackageBodyElement::CaseDef(dummy_node(n, n.value.clone()))
220        }
221        PackageBodyElement::CaseUsage(n) => {
222            PackageBodyElement::CaseUsage(dummy_node(n, n.value.clone()))
223        }
224        PackageBodyElement::AnalysisCaseDef(n) => {
225            PackageBodyElement::AnalysisCaseDef(dummy_node(n, n.value.clone()))
226        }
227        PackageBodyElement::AnalysisCaseUsage(n) => {
228            PackageBodyElement::AnalysisCaseUsage(dummy_node(n, n.value.clone()))
229        }
230        PackageBodyElement::VerificationCaseDef(n) => {
231            PackageBodyElement::VerificationCaseDef(dummy_node(n, n.value.clone()))
232        }
233        PackageBodyElement::VerificationCaseUsage(n) => {
234            PackageBodyElement::VerificationCaseUsage(dummy_node(n, n.value.clone()))
235        }
236        PackageBodyElement::UseCaseUsage(n) => {
237            PackageBodyElement::UseCaseUsage(dummy_node(n, n.value.clone()))
238        }
239        PackageBodyElement::FeatureDecl(n) => {
240            PackageBodyElement::FeatureDecl(dummy_node(n, n.value.clone()))
241        }
242        PackageBodyElement::ClassifierDecl(n) => {
243            PackageBodyElement::ClassifierDecl(dummy_node(n, n.value.clone()))
244        }
245        PackageBodyElement::KermlSemanticDecl(n) => {
246            PackageBodyElement::KermlSemanticDecl(dummy_node(n, n.value.clone()))
247        }
248        PackageBodyElement::KermlFeatureDecl(n) => {
249            PackageBodyElement::KermlFeatureDecl(dummy_node(n, n.value.clone()))
250        }
251        PackageBodyElement::ExtendedLibraryDecl(n) => {
252            PackageBodyElement::ExtendedLibraryDecl(dummy_node(n, n.value.clone()))
253        }
254    };
255    dummy_node(el, value)
256}
257
258fn normalize_attribute_def(a: &AttributeDef) -> AttributeDef {
259    AttributeDef {
260        name: a.name.clone(),
261        typing: a.typing.clone(),
262        value: a.value.clone(),
263        body: a.body.clone(),
264        name_span: None,
265        typing_span: None,
266    }
267}
268
269fn normalize_part_def(p: &PartDef) -> PartDef {
270    PartDef {
271        definition_prefix: p.definition_prefix.clone(),
272        is_individual: p.is_individual,
273        identification: p.identification.clone(),
274        specializes: p.specializes.clone(),
275        specializes_span: None,
276        body: normalize_part_def_body(&p.body),
277    }
278}
279
280fn normalize_part_def_body(b: &PartDefBody) -> PartDefBody {
281    match b {
282        PartDefBody::Semicolon => PartDefBody::Semicolon,
283        PartDefBody::Brace { elements } => PartDefBody::Brace {
284            elements: elements
285                .iter()
286                .map(normalize_part_def_body_element_node)
287                .collect(),
288        },
289    }
290}
291
292fn normalize_part_def_body_element_node(el: &Node<PartDefBodyElement>) -> Node<PartDefBodyElement> {
293    let value = match &el.value {
294        PartDefBodyElement::Error(n) => PartDefBodyElement::Error(dummy_node(n, n.value.clone())),
295        PartDefBodyElement::Doc(n) => PartDefBodyElement::Doc(dummy_node(n, n.value.clone())),
296        PartDefBodyElement::Comment(n) => {
297            PartDefBodyElement::Comment(dummy_node(n, n.value.clone()))
298        }
299        PartDefBodyElement::Annotation(n) => {
300            PartDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
301        }
302        PartDefBodyElement::Other(text) => PartDefBodyElement::Other(text.clone()),
303        PartDefBodyElement::AttributeDef(n) => {
304            PartDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
305        }
306        PartDefBodyElement::AttributeUsage(n) => {
307            PartDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
308        }
309        PartDefBodyElement::RequirementUsage(n) => {
310            PartDefBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
311        }
312        PartDefBodyElement::ItemUsage(n) => {
313            PartDefBodyElement::ItemUsage(dummy_node(n, n.value.clone()))
314        }
315        PartDefBodyElement::Ref(n) => {
316            PartDefBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
317        }
318        PartDefBodyElement::PortUsage(n) => {
319            PartDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
320        }
321        PartDefBodyElement::PartUsage(n) => {
322            PartDefBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
323        }
324        PartDefBodyElement::OccurrenceUsage(n) => {
325            PartDefBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
326        }
327        PartDefBodyElement::InterfaceDef(n) => {
328            PartDefBodyElement::InterfaceDef(dummy_node(n, normalize_interface_def(&n.value)))
329        }
330        PartDefBodyElement::InterfaceUsage(n) => {
331            PartDefBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
332        }
333        PartDefBodyElement::Connect(n) => {
334            PartDefBodyElement::Connect(dummy_node(n, n.value.clone()))
335        }
336        PartDefBodyElement::Connection(n) => {
337            PartDefBodyElement::Connection(dummy_node(n, n.value.clone()))
338        }
339        PartDefBodyElement::Perform(n) => {
340            PartDefBodyElement::Perform(dummy_node(n, n.value.clone()))
341        }
342        PartDefBodyElement::Allocate(n) => {
343            PartDefBodyElement::Allocate(dummy_node(n, n.value.clone()))
344        }
345        PartDefBodyElement::OpaqueMember(n) => {
346            PartDefBodyElement::OpaqueMember(dummy_node(n, n.value.clone()))
347        }
348        PartDefBodyElement::ExhibitState(n) => {
349            PartDefBodyElement::ExhibitState(dummy_node(n, n.value.clone()))
350        }
351        PartDefBodyElement::CalcUsage(n) => {
352            PartDefBodyElement::CalcUsage(dummy_node(n, n.value.clone()))
353        }
354        PartDefBodyElement::EnumerationUsage(n) => PartDefBodyElement::EnumerationUsage(
355            dummy_node(n, normalize_enumeration_usage(&n.value)),
356        ),
357    };
358    dummy_node(el, value)
359}
360
361fn normalize_enumeration_usage(u: &EnumerationUsage) -> EnumerationUsage {
362    EnumerationUsage {
363        name: u.name.clone(),
364        type_name: u.type_name.clone(),
365        multiplicity: u.multiplicity.clone(),
366        body: u.body.clone(),
367    }
368}
369
370fn normalize_attribute_usage(a: &AttributeUsage) -> AttributeUsage {
371    AttributeUsage {
372        name: a.name.clone(),
373        typing: a.typing.clone(),
374        subsets: a.subsets.clone(),
375        redefines: a.redefines.clone(),
376        references: a.references.clone(),
377        crosses: a.crosses.clone(),
378        value: a.value.clone(),
379        body: a.body.clone(),
380        name_span: None,
381        typing_span: None,
382        redefines_span: None,
383    }
384}
385
386fn normalize_part_usage(p: &PartUsage) -> PartUsage {
387    PartUsage {
388        is_individual: p.is_individual,
389        name: p.name.clone(),
390        type_name: p.type_name.clone(),
391        multiplicity: p.multiplicity.clone(),
392        ordered: p.ordered,
393        subsets: p.subsets.clone(),
394        redefines: p.redefines.clone(),
395        value: p.value.clone(),
396        body: normalize_part_usage_body(&p.body),
397        name_span: None,
398        type_ref_span: None,
399    }
400}
401
402fn normalize_part_usage_body(b: &PartUsageBody) -> PartUsageBody {
403    match b {
404        PartUsageBody::Semicolon => PartUsageBody::Semicolon,
405        PartUsageBody::Brace { elements } => PartUsageBody::Brace {
406            elements: elements
407                .iter()
408                .map(normalize_part_usage_body_element_node)
409                .collect(),
410        },
411    }
412}
413
414fn normalize_perform(p: &Perform) -> Perform {
415    Perform {
416        action_name: p.action_name.clone(),
417        type_name: p.type_name.clone(),
418        body: normalize_perform_body(&p.body),
419    }
420}
421
422fn normalize_perform_body(b: &PerformBody) -> PerformBody {
423    match b {
424        PerformBody::Semicolon => PerformBody::Semicolon,
425        PerformBody::Brace { elements } => PerformBody::Brace {
426            elements: elements
427                .iter()
428                .map(normalize_perform_body_element_node)
429                .collect(),
430        },
431    }
432}
433
434fn normalize_perform_body_element_node(el: &Node<PerformBodyElement>) -> Node<PerformBodyElement> {
435    let value = match &el.value {
436        PerformBodyElement::Doc(n) => PerformBodyElement::Doc(dummy_node(n, n.value.clone())),
437        PerformBodyElement::InOut(n) => PerformBodyElement::InOut(dummy_node(
438            n,
439            PerformInOutBinding {
440                direction: n.value.direction,
441                name: n.value.name.clone(),
442                value: normalize_expression_node(&n.value.value),
443            },
444        )),
445    };
446    dummy_node(el, value)
447}
448
449fn normalize_expression_node(node: &Node<Expression>) -> Node<Expression> {
450    let value = match &node.value {
451        Expression::LiteralInteger(x) => Expression::LiteralInteger(*x),
452        Expression::LiteralReal(s) => Expression::LiteralReal(s.clone()),
453        Expression::LiteralString(s) => Expression::LiteralString(s.clone()),
454        Expression::LiteralBoolean(b) => Expression::LiteralBoolean(*b),
455        Expression::FeatureRef(s) => Expression::FeatureRef(s.clone()),
456        Expression::MemberAccess(base, member) => {
457            Expression::MemberAccess(Box::new(normalize_expression_node(base)), member.clone())
458        }
459        Expression::Index { base, index } => Expression::Index {
460            base: Box::new(normalize_expression_node(base)),
461            index: Box::new(normalize_expression_node(index)),
462        },
463        Expression::Bracket(inner) => {
464            Expression::Bracket(Box::new(normalize_expression_node(inner)))
465        }
466        Expression::LiteralWithUnit { value: v, unit } => Expression::LiteralWithUnit {
467            value: Box::new(normalize_expression_node(v)),
468            unit: Box::new(normalize_expression_node(unit)),
469        },
470        Expression::BinaryOp { op, left, right } => Expression::BinaryOp {
471            op: op.clone(),
472            left: Box::new(normalize_expression_node(left)),
473            right: Box::new(normalize_expression_node(right)),
474        },
475        Expression::UnaryOp { op, operand } => Expression::UnaryOp {
476            op: op.clone(),
477            operand: Box::new(normalize_expression_node(operand)),
478        },
479        Expression::Invocation { callee, args } => Expression::Invocation {
480            callee: Box::new(normalize_expression_node(callee)),
481            args: args.iter().map(normalize_expression_node).collect(),
482        },
483        Expression::Tuple(items) => {
484            Expression::Tuple(items.iter().map(normalize_expression_node).collect())
485        }
486        Expression::Null => Expression::Null,
487    };
488    Node::new(Span::dummy(), value)
489}
490
491fn normalize_part_usage_body_element_node(
492    el: &Node<PartUsageBodyElement>,
493) -> Node<PartUsageBodyElement> {
494    let value = match &el.value {
495        PartUsageBodyElement::Error(n) => {
496            PartUsageBodyElement::Error(dummy_node(n, n.value.clone()))
497        }
498        PartUsageBodyElement::Doc(n) => PartUsageBodyElement::Doc(dummy_node(n, n.value.clone())),
499        PartUsageBodyElement::Annotation(n) => {
500            PartUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
501        }
502        PartUsageBodyElement::AttributeUsage(n) => {
503            PartUsageBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
504        }
505        PartUsageBodyElement::EnumerationUsage(n) => PartUsageBodyElement::EnumerationUsage(
506            dummy_node(n, normalize_enumeration_usage(&n.value)),
507        ),
508        PartUsageBodyElement::PartUsage(n) => {
509            PartUsageBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
510        }
511        PartUsageBodyElement::OccurrenceUsage(n) => {
512            PartUsageBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
513        }
514        PartUsageBodyElement::PortUsage(n) => {
515            PartUsageBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
516        }
517        PartUsageBodyElement::Ref(n) => {
518            PartUsageBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
519        }
520        PartUsageBodyElement::Bind(n) => PartUsageBodyElement::Bind(dummy_node(n, n.value.clone())),
521        PartUsageBodyElement::InterfaceUsage(n) => {
522            PartUsageBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
523        }
524        PartUsageBodyElement::Connect(n) => {
525            PartUsageBodyElement::Connect(dummy_node(n, n.value.clone()))
526        }
527        PartUsageBodyElement::Perform(n) => {
528            PartUsageBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
529        }
530        PartUsageBodyElement::Allocate(n) => {
531            PartUsageBodyElement::Allocate(dummy_node(n, n.value.clone()))
532        }
533        PartUsageBodyElement::Satisfy(n) => {
534            PartUsageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
535        }
536        PartUsageBodyElement::StateUsage(n) => {
537            PartUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
538        }
539        PartUsageBodyElement::MetadataAnnotation(n) => {
540            PartUsageBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
541        }
542    };
543    dummy_node(el, value)
544}
545
546fn normalize_port_usage(p: &PortUsage) -> PortUsage {
547    PortUsage {
548        name: p.name.clone(),
549        type_name: p.type_name.clone(),
550        multiplicity: p.multiplicity.clone(),
551        subsets: p.subsets.clone(),
552        redefines: p.redefines.clone(),
553        references: p.references.clone(),
554        crosses: p.crosses.clone(),
555        body: normalize_port_body(&p.body),
556        name_span: None,
557        type_ref_span: None,
558    }
559}
560
561fn normalize_port_body(b: &PortBody) -> PortBody {
562    match b {
563        PortBody::Semicolon => PortBody::Semicolon,
564        PortBody::Brace { elements } => PortBody::Brace {
565            elements: elements
566                .iter()
567                .map(normalize_port_body_element_node)
568                .collect(),
569        },
570    }
571}
572
573fn normalize_port_body_element_node(el: &Node<PortBodyElement>) -> Node<PortBodyElement> {
574    let value = match &el.value {
575        PortBodyElement::Error(n) => PortBodyElement::Error(dummy_node(n, n.value.clone())),
576        PortBodyElement::InOutDecl(n) => PortBodyElement::InOutDecl(dummy_node(n, n.value.clone())),
577        PortBodyElement::PortUsage(n) => {
578            PortBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
579        }
580        PortBodyElement::Other(text) => PortBodyElement::Other(text.clone()),
581    };
582    dummy_node(el, value)
583}
584
585fn normalize_port_def(p: &PortDef) -> PortDef {
586    PortDef {
587        identification: p.identification.clone(),
588        specializes: p.specializes.clone(),
589        specializes_span: None,
590        body: normalize_port_def_body(&p.body),
591    }
592}
593
594fn normalize_port_def_body(b: &PortDefBody) -> PortDefBody {
595    match b {
596        PortDefBody::Semicolon => PortDefBody::Semicolon,
597        PortDefBody::Brace { elements } => PortDefBody::Brace {
598            elements: elements
599                .iter()
600                .map(normalize_port_def_body_element_node)
601                .collect(),
602        },
603    }
604}
605
606fn normalize_port_def_body_element_node(el: &Node<PortDefBodyElement>) -> Node<PortDefBodyElement> {
607    let value = match &el.value {
608        PortDefBodyElement::InOutDecl(n) => {
609            PortDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
610        }
611        PortDefBodyElement::Doc(n) => PortDefBodyElement::Doc(dummy_node(n, n.value.clone())),
612        PortDefBodyElement::Error(n) => PortDefBodyElement::Error(dummy_node(n, n.value.clone())),
613        PortDefBodyElement::AttributeDef(n) => {
614            PortDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
615        }
616        PortDefBodyElement::AttributeUsage(n) => {
617            PortDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
618        }
619        PortDefBodyElement::PortUsage(n) => {
620            PortDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
621        }
622    };
623    dummy_node(el, value)
624}
625
626fn normalize_interface_def(i: &InterfaceDef) -> InterfaceDef {
627    InterfaceDef {
628        identification: i.identification.clone(),
629        specializes: i.specializes.clone(),
630        specializes_span: None,
631        body: normalize_interface_def_body(&i.body),
632    }
633}
634
635fn normalize_connection_def(c: &ConnectionDef) -> ConnectionDef {
636    ConnectionDef {
637        annotation: c.annotation.clone(),
638        identification: c.identification.clone(),
639        specializes: c.specializes.clone(),
640        specializes_span: None,
641        body: normalize_connection_def_body(&c.body),
642    }
643}
644
645fn normalize_connection_def_body(b: &ConnectionDefBody) -> ConnectionDefBody {
646    match b {
647        ConnectionDefBody::Semicolon => ConnectionDefBody::Semicolon,
648        ConnectionDefBody::Brace { elements } => ConnectionDefBody::Brace {
649            elements: elements
650                .iter()
651                .map(normalize_connection_def_body_element_node)
652                .collect(),
653        },
654    }
655}
656
657fn normalize_connection_def_body_element_node(
658    el: &Node<ConnectionDefBodyElement>,
659) -> Node<ConnectionDefBodyElement> {
660    let value = match &el.value {
661        ConnectionDefBodyElement::EndDecl(n) => {
662            ConnectionDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
663        }
664        ConnectionDefBodyElement::RefDecl(n) => {
665            ConnectionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
666        }
667        ConnectionDefBodyElement::ConnectStmt(n) => {
668            ConnectionDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
669        }
670    };
671    dummy_node(el, value)
672}
673
674fn normalize_metadata_def(m: &MetadataDef) -> MetadataDef {
675    MetadataDef {
676        is_abstract: m.is_abstract,
677        identification: m.identification.clone(),
678        specializes: m.specializes.clone(),
679        specializes_span: None,
680        body: m.body.clone(),
681    }
682}
683
684fn normalize_enum_def(e: &EnumDef) -> EnumDef {
685    EnumDef {
686        identification: e.identification.clone(),
687        specializes: e.specializes.clone(),
688        specializes_span: None,
689        body: e.body.clone(),
690    }
691}
692
693fn normalize_occurrence_def(o: &OccurrenceDef) -> OccurrenceDef {
694    OccurrenceDef {
695        is_abstract: o.is_abstract,
696        identification: o.identification.clone(),
697        specializes: o.specializes.clone(),
698        specializes_span: None,
699        body: o.body.clone(),
700    }
701}
702
703fn normalize_interface_def_body(b: &InterfaceDefBody) -> InterfaceDefBody {
704    match b {
705        InterfaceDefBody::Semicolon => InterfaceDefBody::Semicolon,
706        InterfaceDefBody::Brace { elements } => InterfaceDefBody::Brace {
707            elements: elements
708                .iter()
709                .map(normalize_interface_def_body_element_node)
710                .collect(),
711        },
712    }
713}
714
715fn normalize_interface_def_body_element_node(
716    el: &Node<InterfaceDefBodyElement>,
717) -> Node<InterfaceDefBodyElement> {
718    let value = match &el.value {
719        InterfaceDefBodyElement::Doc(n) => {
720            InterfaceDefBodyElement::Doc(dummy_node(n, n.value.clone()))
721        }
722        InterfaceDefBodyElement::EndDecl(n) => {
723            InterfaceDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
724        }
725        InterfaceDefBodyElement::RefDecl(n) => {
726            InterfaceDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
727        }
728        InterfaceDefBodyElement::ConnectStmt(n) => {
729            InterfaceDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
730        }
731    };
732    dummy_node(el, value)
733}
734
735fn normalize_end_decl(e: &EndDecl) -> EndDecl {
736    EndDecl {
737        name: e.name.clone(),
738        type_name: e.type_name.clone(),
739        uses_derived_syntax: e.uses_derived_syntax,
740        name_span: None,
741        type_ref_span: None,
742    }
743}
744
745fn normalize_ref_decl(r: &RefDecl) -> RefDecl {
746    RefDecl {
747        name: r.name.clone(),
748        type_name: r.type_name.clone(),
749        value: r.value.clone(),
750        body: r.body.clone(),
751        name_span: None,
752        type_ref_span: None,
753    }
754}
755
756fn normalize_action_def(a: &ActionDef) -> ActionDef {
757    ActionDef {
758        identification: a.identification.clone(),
759        specializes: a.specializes.clone(),
760        specializes_span: None,
761        body: normalize_action_def_body(&a.body),
762    }
763}
764
765fn normalize_action_def_body(b: &ActionDefBody) -> ActionDefBody {
766    match b {
767        ActionDefBody::Semicolon => ActionDefBody::Semicolon,
768        ActionDefBody::Brace { elements } => ActionDefBody::Brace {
769            elements: elements
770                .iter()
771                .map(normalize_action_def_body_element_node)
772                .collect(),
773        },
774    }
775}
776
777fn normalize_action_def_body_element_node(
778    el: &Node<ActionDefBodyElement>,
779) -> Node<ActionDefBodyElement> {
780    let value = match &el.value {
781        ActionDefBodyElement::Error(n) => {
782            ActionDefBodyElement::Error(dummy_node(n, n.value.clone()))
783        }
784        ActionDefBodyElement::InOutDecl(n) => {
785            ActionDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
786        }
787        ActionDefBodyElement::Doc(n) => ActionDefBodyElement::Doc(dummy_node(n, n.value.clone())),
788        ActionDefBodyElement::Annotation(n) => {
789            ActionDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
790        }
791        ActionDefBodyElement::RefDecl(n) => {
792            ActionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
793        }
794        ActionDefBodyElement::Perform(n) => {
795            ActionDefBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
796        }
797        ActionDefBodyElement::Bind(n) => ActionDefBodyElement::Bind(dummy_node(n, n.value.clone())),
798        ActionDefBodyElement::Flow(n) => ActionDefBodyElement::Flow(dummy_node(n, n.value.clone())),
799        ActionDefBodyElement::FirstStmt(n) => {
800            ActionDefBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
801        }
802        ActionDefBodyElement::MergeStmt(n) => {
803            ActionDefBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
804        }
805        ActionDefBodyElement::StateUsage(n) => {
806            ActionDefBodyElement::StateUsage(dummy_node(n, n.value.clone()))
807        }
808        ActionDefBodyElement::ActionUsage(n) => ActionDefBodyElement::ActionUsage(Box::new(
809            dummy_node(n, normalize_action_usage(&n.value)),
810        )),
811        ActionDefBodyElement::Assign(n) => {
812            ActionDefBodyElement::Assign(dummy_node(n, n.value.clone()))
813        }
814        ActionDefBodyElement::ForLoop(n) => {
815            ActionDefBodyElement::ForLoop(dummy_node(n, n.value.clone()))
816        }
817        ActionDefBodyElement::ThenAction(n) => {
818            ActionDefBodyElement::ThenAction(dummy_node(n, n.value.clone()))
819        }
820        ActionDefBodyElement::Decl(n) => ActionDefBodyElement::Decl(dummy_node(n, n.value.clone())),
821    };
822    dummy_node(el, value)
823}
824
825fn normalize_action_usage(a: &ActionUsage) -> ActionUsage {
826    ActionUsage {
827        name: a.name.clone(),
828        type_name: a.type_name.clone(),
829        accept: a.accept.clone(),
830        body: normalize_action_usage_body(&a.body),
831        name_span: None,
832        type_ref_span: None,
833    }
834}
835
836fn normalize_action_usage_body(b: &ActionUsageBody) -> ActionUsageBody {
837    match b {
838        ActionUsageBody::Semicolon => ActionUsageBody::Semicolon,
839        ActionUsageBody::Brace { elements } => ActionUsageBody::Brace {
840            elements: elements
841                .iter()
842                .map(normalize_action_usage_body_element_node)
843                .collect(),
844        },
845    }
846}
847
848fn normalize_action_usage_body_element_node(
849    el: &Node<ActionUsageBodyElement>,
850) -> Node<ActionUsageBodyElement> {
851    let value = match &el.value {
852        ActionUsageBodyElement::Error(n) => {
853            ActionUsageBodyElement::Error(dummy_node(n, n.value.clone()))
854        }
855        ActionUsageBodyElement::Doc(n) => {
856            ActionUsageBodyElement::Doc(dummy_node(n, n.value.clone()))
857        }
858        ActionUsageBodyElement::Annotation(n) => {
859            ActionUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
860        }
861        ActionUsageBodyElement::InOutDecl(n) => {
862            ActionUsageBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
863        }
864        ActionUsageBodyElement::RefDecl(n) => {
865            ActionUsageBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
866        }
867        ActionUsageBodyElement::Bind(n) => {
868            ActionUsageBodyElement::Bind(dummy_node(n, n.value.clone()))
869        }
870        ActionUsageBodyElement::Flow(n) => {
871            ActionUsageBodyElement::Flow(dummy_node(n, n.value.clone()))
872        }
873        ActionUsageBodyElement::FirstStmt(n) => {
874            ActionUsageBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
875        }
876        ActionUsageBodyElement::MergeStmt(n) => {
877            ActionUsageBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
878        }
879        ActionUsageBodyElement::StateUsage(n) => {
880            ActionUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
881        }
882        ActionUsageBodyElement::ActionUsage(n) => ActionUsageBodyElement::ActionUsage(Box::new(
883            dummy_node(n, normalize_action_usage(&n.value)),
884        )),
885        ActionUsageBodyElement::Assign(n) => {
886            ActionUsageBodyElement::Assign(dummy_node(n, n.value.clone()))
887        }
888        ActionUsageBodyElement::ForLoop(n) => {
889            ActionUsageBodyElement::ForLoop(dummy_node(n, n.value.clone()))
890        }
891        ActionUsageBodyElement::ThenAction(n) => {
892            ActionUsageBodyElement::ThenAction(dummy_node(n, n.value.clone()))
893        }
894        ActionUsageBodyElement::Decl(n) => {
895            ActionUsageBodyElement::Decl(dummy_node(n, n.value.clone()))
896        }
897    };
898    dummy_node(el, value)
899}