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::MetadataUsage(n) => {
131            PackageBodyElement::MetadataUsage(dummy_node(n, n.value.clone()))
132        }
133        PackageBodyElement::EnumDef(n) => {
134            PackageBodyElement::EnumDef(dummy_node(n, normalize_enum_def(&n.value)))
135        }
136        PackageBodyElement::OccurrenceDef(n) => {
137            PackageBodyElement::OccurrenceDef(dummy_node(n, normalize_occurrence_def(&n.value)))
138        }
139        PackageBodyElement::OccurrenceUsage(n) => {
140            PackageBodyElement::OccurrenceUsage(dummy_node(n, n.value.clone()))
141        }
142        PackageBodyElement::AliasDef(n) => {
143            PackageBodyElement::AliasDef(dummy_node(n, n.value.clone()))
144        }
145        PackageBodyElement::AttributeDef(n) => {
146            PackageBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
147        }
148        PackageBodyElement::ActionDef(n) => {
149            PackageBodyElement::ActionDef(dummy_node(n, normalize_action_def(&n.value)))
150        }
151        PackageBodyElement::ActionUsage(n) => {
152            PackageBodyElement::ActionUsage(dummy_node(n, normalize_action_usage(&n.value)))
153        }
154        PackageBodyElement::RequirementDef(n) => {
155            PackageBodyElement::RequirementDef(dummy_node(n, n.value.clone()))
156        }
157        PackageBodyElement::RequirementUsage(n) => {
158            PackageBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
159        }
160        PackageBodyElement::Satisfy(n) => {
161            PackageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
162        }
163        PackageBodyElement::UseCaseDef(n) => {
164            PackageBodyElement::UseCaseDef(dummy_node(n, n.value.clone()))
165        }
166        PackageBodyElement::Actor(n) => PackageBodyElement::Actor(dummy_node(n, n.value.clone())),
167        PackageBodyElement::StateDef(n) => {
168            PackageBodyElement::StateDef(dummy_node(n, n.value.clone()))
169        }
170        PackageBodyElement::StateUsage(n) => {
171            PackageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
172        }
173        PackageBodyElement::ItemDef(n) => {
174            PackageBodyElement::ItemDef(dummy_node(n, n.value.clone()))
175        }
176        PackageBodyElement::IndividualDef(n) => {
177            PackageBodyElement::IndividualDef(dummy_node(n, n.value.clone()))
178        }
179        PackageBodyElement::ConstraintDef(n) => {
180            PackageBodyElement::ConstraintDef(dummy_node(n, n.value.clone()))
181        }
182        PackageBodyElement::CalcDef(n) => {
183            PackageBodyElement::CalcDef(dummy_node(n, n.value.clone()))
184        }
185        PackageBodyElement::ViewDef(n) => {
186            PackageBodyElement::ViewDef(dummy_node(n, n.value.clone()))
187        }
188        PackageBodyElement::ViewpointDef(n) => {
189            PackageBodyElement::ViewpointDef(dummy_node(n, n.value.clone()))
190        }
191        PackageBodyElement::RenderingDef(n) => {
192            PackageBodyElement::RenderingDef(dummy_node(n, n.value.clone()))
193        }
194        PackageBodyElement::ViewUsage(n) => {
195            PackageBodyElement::ViewUsage(dummy_node(n, n.value.clone()))
196        }
197        PackageBodyElement::ViewpointUsage(n) => {
198            PackageBodyElement::ViewpointUsage(dummy_node(n, n.value.clone()))
199        }
200        PackageBodyElement::RenderingUsage(n) => {
201            PackageBodyElement::RenderingUsage(dummy_node(n, n.value.clone()))
202        }
203        PackageBodyElement::Dependency(n) => {
204            PackageBodyElement::Dependency(dummy_node(n, n.value.clone()))
205        }
206        PackageBodyElement::AllocationDef(n) => {
207            PackageBodyElement::AllocationDef(dummy_node(n, n.value.clone()))
208        }
209        PackageBodyElement::AllocationUsage(n) => {
210            PackageBodyElement::AllocationUsage(dummy_node(n, n.value.clone()))
211        }
212        PackageBodyElement::FlowDef(n) => {
213            PackageBodyElement::FlowDef(dummy_node(n, n.value.clone()))
214        }
215        PackageBodyElement::FlowUsage(n) => {
216            PackageBodyElement::FlowUsage(dummy_node(n, n.value.clone()))
217        }
218        PackageBodyElement::ConcernUsage(n) => {
219            PackageBodyElement::ConcernUsage(dummy_node(n, n.value.clone()))
220        }
221        PackageBodyElement::CaseDef(n) => {
222            PackageBodyElement::CaseDef(dummy_node(n, n.value.clone()))
223        }
224        PackageBodyElement::CaseUsage(n) => {
225            PackageBodyElement::CaseUsage(dummy_node(n, n.value.clone()))
226        }
227        PackageBodyElement::AnalysisCaseDef(n) => {
228            PackageBodyElement::AnalysisCaseDef(dummy_node(n, n.value.clone()))
229        }
230        PackageBodyElement::AnalysisCaseUsage(n) => {
231            PackageBodyElement::AnalysisCaseUsage(dummy_node(n, n.value.clone()))
232        }
233        PackageBodyElement::VerificationCaseDef(n) => {
234            PackageBodyElement::VerificationCaseDef(dummy_node(n, n.value.clone()))
235        }
236        PackageBodyElement::VerificationCaseUsage(n) => {
237            PackageBodyElement::VerificationCaseUsage(dummy_node(n, n.value.clone()))
238        }
239        PackageBodyElement::UseCaseUsage(n) => {
240            PackageBodyElement::UseCaseUsage(dummy_node(n, n.value.clone()))
241        }
242        PackageBodyElement::FeatureDecl(n) => {
243            PackageBodyElement::FeatureDecl(dummy_node(n, n.value.clone()))
244        }
245        PackageBodyElement::ClassifierDecl(n) => {
246            PackageBodyElement::ClassifierDecl(dummy_node(n, n.value.clone()))
247        }
248        PackageBodyElement::KermlSemanticDecl(n) => {
249            PackageBodyElement::KermlSemanticDecl(dummy_node(n, n.value.clone()))
250        }
251        PackageBodyElement::KermlFeatureDecl(n) => {
252            PackageBodyElement::KermlFeatureDecl(dummy_node(n, n.value.clone()))
253        }
254        PackageBodyElement::ExtendedLibraryDecl(n) => {
255            PackageBodyElement::ExtendedLibraryDecl(dummy_node(n, n.value.clone()))
256        }
257    };
258    dummy_node(el, value)
259}
260
261fn normalize_attribute_def(a: &AttributeDef) -> AttributeDef {
262    AttributeDef {
263        name: a.name.clone(),
264        typing: a.typing.clone(),
265        value: a.value.clone(),
266        body: a.body.clone(),
267        name_span: None,
268        typing_span: None,
269        value_span: None,
270    }
271}
272
273fn normalize_part_def(p: &PartDef) -> PartDef {
274    PartDef {
275        definition_prefix: p.definition_prefix.clone(),
276        is_individual: p.is_individual,
277        identification: p.identification.clone(),
278        specializes: p.specializes.clone(),
279        specializes_span: None,
280        body: normalize_part_def_body(&p.body),
281    }
282}
283
284fn normalize_part_def_body(b: &PartDefBody) -> PartDefBody {
285    match b {
286        PartDefBody::Semicolon => PartDefBody::Semicolon,
287        PartDefBody::Brace { elements } => PartDefBody::Brace {
288            elements: elements
289                .iter()
290                .map(normalize_part_def_body_element_node)
291                .collect(),
292        },
293    }
294}
295
296fn normalize_part_def_body_element_node(el: &Node<PartDefBodyElement>) -> Node<PartDefBodyElement> {
297    let value = match &el.value {
298        PartDefBodyElement::Error(n) => PartDefBodyElement::Error(dummy_node(n, n.value.clone())),
299        PartDefBodyElement::Doc(n) => PartDefBodyElement::Doc(dummy_node(n, n.value.clone())),
300        PartDefBodyElement::Comment(n) => {
301            PartDefBodyElement::Comment(dummy_node(n, n.value.clone()))
302        }
303        PartDefBodyElement::Annotation(n) => {
304            PartDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
305        }
306        PartDefBodyElement::MetadataAnnotation(n) => {
307            PartDefBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
308        }
309        PartDefBodyElement::MetadataKeywordUsage(n) => {
310            PartDefBodyElement::MetadataKeywordUsage(dummy_node(n, n.value.clone()))
311        }
312        PartDefBodyElement::Other(text) => PartDefBodyElement::Other(text.clone()),
313        PartDefBodyElement::AttributeDef(n) => {
314            PartDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
315        }
316        PartDefBodyElement::AttributeUsage(n) => {
317            PartDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
318        }
319        PartDefBodyElement::RequirementUsage(n) => {
320            PartDefBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
321        }
322        PartDefBodyElement::ItemDef(n) => {
323            PartDefBodyElement::ItemDef(dummy_node(n, n.value.clone()))
324        }
325        PartDefBodyElement::ItemUsage(n) => {
326            PartDefBodyElement::ItemUsage(dummy_node(n, n.value.clone()))
327        }
328        PartDefBodyElement::Ref(n) => {
329            PartDefBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
330        }
331        PartDefBodyElement::PortUsage(n) => {
332            PartDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
333        }
334        PartDefBodyElement::PartUsage(n) => {
335            PartDefBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
336        }
337        PartDefBodyElement::PartDef(n) => {
338            PartDefBodyElement::PartDef(dummy_node(n, normalize_part_def(&n.value)))
339        }
340        PartDefBodyElement::OccurrenceUsage(n) => {
341            PartDefBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
342        }
343        PartDefBodyElement::InterfaceDef(n) => {
344            PartDefBodyElement::InterfaceDef(dummy_node(n, normalize_interface_def(&n.value)))
345        }
346        PartDefBodyElement::InterfaceUsage(n) => {
347            PartDefBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
348        }
349        PartDefBodyElement::Connect(n) => {
350            PartDefBodyElement::Connect(dummy_node(n, n.value.clone()))
351        }
352        PartDefBodyElement::Connection(n) => {
353            PartDefBodyElement::Connection(dummy_node(n, n.value.clone()))
354        }
355        PartDefBodyElement::Perform(n) => {
356            PartDefBodyElement::Perform(dummy_node(n, n.value.clone()))
357        }
358        PartDefBodyElement::Allocate(n) => {
359            PartDefBodyElement::Allocate(dummy_node(n, n.value.clone()))
360        }
361        PartDefBodyElement::OpaqueMember(n) => {
362            PartDefBodyElement::OpaqueMember(dummy_node(n, n.value.clone()))
363        }
364        PartDefBodyElement::ExhibitState(n) => {
365            PartDefBodyElement::ExhibitState(dummy_node(n, n.value.clone()))
366        }
367        PartDefBodyElement::CalcUsage(n) => {
368            PartDefBodyElement::CalcUsage(dummy_node(n, n.value.clone()))
369        }
370        PartDefBodyElement::EnumerationUsage(n) => PartDefBodyElement::EnumerationUsage(
371            dummy_node(n, normalize_enumeration_usage(&n.value)),
372        ),
373    };
374    dummy_node(el, value)
375}
376
377fn normalize_enumeration_usage(u: &EnumerationUsage) -> EnumerationUsage {
378    EnumerationUsage {
379        name: u.name.clone(),
380        type_name: u.type_name.clone(),
381        multiplicity: u.multiplicity.clone(),
382        body: u.body.clone(),
383    }
384}
385
386fn normalize_attribute_usage(a: &AttributeUsage) -> AttributeUsage {
387    AttributeUsage {
388        name: a.name.clone(),
389        typing: a.typing.clone(),
390        subsets: a.subsets.clone(),
391        redefines: a.redefines.clone(),
392        references: a.references.clone(),
393        crosses: a.crosses.clone(),
394        value: a.value.clone(),
395        body: a.body.clone(),
396        name_span: None,
397        typing_span: None,
398        redefines_span: None,
399        direction: a.direction,
400    }
401}
402
403fn normalize_part_usage(p: &PartUsage) -> PartUsage {
404    PartUsage {
405        is_individual: p.is_individual,
406        name: p.name.clone(),
407        type_name: p.type_name.clone(),
408        multiplicity: p.multiplicity.clone(),
409        ordered: p.ordered,
410        subsets: p.subsets.clone(),
411        redefines: p.redefines.clone(),
412        value: p.value.clone(),
413        body: normalize_part_usage_body(&p.body),
414        name_span: None,
415        type_ref_span: None,
416    }
417}
418
419fn normalize_part_usage_body(b: &PartUsageBody) -> PartUsageBody {
420    match b {
421        PartUsageBody::Semicolon => PartUsageBody::Semicolon,
422        PartUsageBody::Brace { elements } => PartUsageBody::Brace {
423            elements: elements
424                .iter()
425                .map(normalize_part_usage_body_element_node)
426                .collect(),
427        },
428    }
429}
430
431fn normalize_perform(p: &Perform) -> Perform {
432    Perform {
433        action_name: p.action_name.clone(),
434        type_name: p.type_name.clone(),
435        body: normalize_perform_body(&p.body),
436    }
437}
438
439fn normalize_perform_body(b: &PerformBody) -> PerformBody {
440    match b {
441        PerformBody::Semicolon => PerformBody::Semicolon,
442        PerformBody::Brace { elements } => PerformBody::Brace {
443            elements: elements
444                .iter()
445                .map(normalize_perform_body_element_node)
446                .collect(),
447        },
448    }
449}
450
451fn normalize_perform_body_element_node(el: &Node<PerformBodyElement>) -> Node<PerformBodyElement> {
452    let value = match &el.value {
453        PerformBodyElement::Doc(n) => PerformBodyElement::Doc(dummy_node(n, n.value.clone())),
454        PerformBodyElement::InOut(n) => PerformBodyElement::InOut(dummy_node(
455            n,
456            PerformInOutBinding {
457                direction: n.value.direction,
458                name: n.value.name.clone(),
459                value: normalize_expression_node(&n.value.value),
460            },
461        )),
462    };
463    dummy_node(el, value)
464}
465
466fn normalize_expression_node(node: &Node<Expression>) -> Node<Expression> {
467    let value = match &node.value {
468        Expression::LiteralInteger(x) => Expression::LiteralInteger(*x),
469        Expression::LiteralReal(s) => Expression::LiteralReal(s.clone()),
470        Expression::LiteralString(s) => Expression::LiteralString(s.clone()),
471        Expression::LiteralBoolean(b) => Expression::LiteralBoolean(*b),
472        Expression::FeatureRef(s) => Expression::FeatureRef(s.clone()),
473        Expression::MemberAccess(base, member) => {
474            Expression::MemberAccess(Box::new(normalize_expression_node(base)), member.clone())
475        }
476        Expression::Index { base, index } => Expression::Index {
477            base: Box::new(normalize_expression_node(base)),
478            index: Box::new(normalize_expression_node(index)),
479        },
480        Expression::Bracket(inner) => {
481            Expression::Bracket(Box::new(normalize_expression_node(inner)))
482        }
483        Expression::LiteralWithUnit { value: v, unit } => Expression::LiteralWithUnit {
484            value: Box::new(normalize_expression_node(v)),
485            unit: Box::new(normalize_expression_node(unit)),
486        },
487        Expression::BinaryOp { op, left, right } => Expression::BinaryOp {
488            op: op.clone(),
489            left: Box::new(normalize_expression_node(left)),
490            right: Box::new(normalize_expression_node(right)),
491        },
492        Expression::UnaryOp { op, operand } => Expression::UnaryOp {
493            op: op.clone(),
494            operand: Box::new(normalize_expression_node(operand)),
495        },
496        Expression::Invocation { callee, args } => Expression::Invocation {
497            callee: Box::new(normalize_expression_node(callee)),
498            args: args.iter().map(normalize_expression_node).collect(),
499        },
500        Expression::Tuple(items) => {
501            Expression::Tuple(items.iter().map(normalize_expression_node).collect())
502        }
503        Expression::Classification { metaclass } => Expression::Classification {
504            metaclass: metaclass.clone(),
505        },
506        Expression::TypeCheck {
507            kind,
508            operand,
509            type_name,
510        } => Expression::TypeCheck {
511            kind: kind.clone(),
512            operand: operand
513                .as_ref()
514                .map(|node| Box::new(normalize_expression_node(node))),
515            type_name: type_name.clone(),
516        },
517        Expression::Select { base, selector } => Expression::Select {
518            base: Box::new(normalize_expression_node(base)),
519            selector: selector.clone(),
520        },
521        Expression::Collect { base, selector } => Expression::Collect {
522            base: Box::new(normalize_expression_node(base)),
523            selector: selector.clone(),
524        },
525        Expression::Null => Expression::Null,
526    };
527    Node::new(Span::dummy(), value)
528}
529
530fn normalize_part_usage_body_element_node(
531    el: &Node<PartUsageBodyElement>,
532) -> Node<PartUsageBodyElement> {
533    let value = match &el.value {
534        PartUsageBodyElement::Error(n) => {
535            PartUsageBodyElement::Error(dummy_node(n, n.value.clone()))
536        }
537        PartUsageBodyElement::Doc(n) => PartUsageBodyElement::Doc(dummy_node(n, n.value.clone())),
538        PartUsageBodyElement::Annotation(n) => {
539            PartUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
540        }
541        PartUsageBodyElement::AttributeUsage(n) => {
542            PartUsageBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
543        }
544        PartUsageBodyElement::EnumerationUsage(n) => PartUsageBodyElement::EnumerationUsage(
545            dummy_node(n, normalize_enumeration_usage(&n.value)),
546        ),
547        PartUsageBodyElement::PartUsage(n) => {
548            PartUsageBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
549        }
550        PartUsageBodyElement::OccurrenceUsage(n) => {
551            PartUsageBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
552        }
553        PartUsageBodyElement::PortUsage(n) => {
554            PartUsageBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
555        }
556        PartUsageBodyElement::Ref(n) => {
557            PartUsageBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
558        }
559        PartUsageBodyElement::Bind(n) => PartUsageBodyElement::Bind(dummy_node(n, n.value.clone())),
560        PartUsageBodyElement::InterfaceUsage(n) => {
561            PartUsageBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
562        }
563        PartUsageBodyElement::Connect(n) => {
564            PartUsageBodyElement::Connect(dummy_node(n, n.value.clone()))
565        }
566        PartUsageBodyElement::Perform(n) => {
567            PartUsageBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
568        }
569        PartUsageBodyElement::Allocate(n) => {
570            PartUsageBodyElement::Allocate(dummy_node(n, n.value.clone()))
571        }
572        PartUsageBodyElement::Satisfy(n) => {
573            PartUsageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
574        }
575        PartUsageBodyElement::StateUsage(n) => {
576            PartUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
577        }
578        PartUsageBodyElement::MetadataAnnotation(n) => {
579            PartUsageBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
580        }
581        PartUsageBodyElement::MetadataKeywordUsage(n) => {
582            PartUsageBodyElement::MetadataKeywordUsage(dummy_node(n, n.value.clone()))
583        }
584    };
585    dummy_node(el, value)
586}
587
588fn normalize_port_usage(p: &PortUsage) -> PortUsage {
589    PortUsage {
590        name: p.name.clone(),
591        type_name: p.type_name.clone(),
592        multiplicity: p.multiplicity.clone(),
593        subsets: p.subsets.clone(),
594        redefines: p.redefines.clone(),
595        references: p.references.clone(),
596        crosses: p.crosses.clone(),
597        body: normalize_port_body(&p.body),
598        name_span: None,
599        type_ref_span: None,
600    }
601}
602
603fn normalize_port_body(b: &PortBody) -> PortBody {
604    match b {
605        PortBody::Semicolon => PortBody::Semicolon,
606        PortBody::Brace { elements } => PortBody::Brace {
607            elements: elements
608                .iter()
609                .map(normalize_port_body_element_node)
610                .collect(),
611        },
612    }
613}
614
615fn normalize_port_body_element_node(el: &Node<PortBodyElement>) -> Node<PortBodyElement> {
616    let value = match &el.value {
617        PortBodyElement::Error(n) => PortBodyElement::Error(dummy_node(n, n.value.clone())),
618        PortBodyElement::InOutDecl(n) => PortBodyElement::InOutDecl(dummy_node(n, n.value.clone())),
619        PortBodyElement::PortUsage(n) => {
620            PortBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
621        }
622        PortBodyElement::Other(text) => PortBodyElement::Other(text.clone()),
623    };
624    dummy_node(el, value)
625}
626
627fn normalize_port_def(p: &PortDef) -> PortDef {
628    PortDef {
629        identification: p.identification.clone(),
630        specializes: p.specializes.clone(),
631        specializes_span: None,
632        body: normalize_port_def_body(&p.body),
633    }
634}
635
636fn normalize_port_def_body(b: &PortDefBody) -> PortDefBody {
637    match b {
638        PortDefBody::Semicolon => PortDefBody::Semicolon,
639        PortDefBody::Brace { elements } => PortDefBody::Brace {
640            elements: elements
641                .iter()
642                .map(normalize_port_def_body_element_node)
643                .collect(),
644        },
645    }
646}
647
648fn normalize_port_def_body_element_node(el: &Node<PortDefBodyElement>) -> Node<PortDefBodyElement> {
649    let value = match &el.value {
650        PortDefBodyElement::InOutDecl(n) => {
651            PortDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
652        }
653        PortDefBodyElement::Doc(n) => PortDefBodyElement::Doc(dummy_node(n, n.value.clone())),
654        PortDefBodyElement::Error(n) => PortDefBodyElement::Error(dummy_node(n, n.value.clone())),
655        PortDefBodyElement::AttributeDef(n) => {
656            PortDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
657        }
658        PortDefBodyElement::AttributeUsage(n) => {
659            PortDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
660        }
661        PortDefBodyElement::ItemUsage(n) => {
662            PortDefBodyElement::ItemUsage(dummy_node(n, n.value.clone()))
663        }
664        PortDefBodyElement::PortUsage(n) => {
665            PortDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
666        }
667    };
668    dummy_node(el, value)
669}
670
671fn normalize_interface_def(i: &InterfaceDef) -> InterfaceDef {
672    InterfaceDef {
673        identification: i.identification.clone(),
674        specializes: i.specializes.clone(),
675        specializes_span: None,
676        body: normalize_interface_def_body(&i.body),
677    }
678}
679
680fn normalize_connection_def(c: &ConnectionDef) -> ConnectionDef {
681    ConnectionDef {
682        annotation: c.annotation.clone(),
683        identification: c.identification.clone(),
684        specializes: c.specializes.clone(),
685        specializes_span: None,
686        body: normalize_connection_def_body(&c.body),
687    }
688}
689
690fn normalize_connection_def_body(b: &ConnectionDefBody) -> ConnectionDefBody {
691    match b {
692        ConnectionDefBody::Semicolon => ConnectionDefBody::Semicolon,
693        ConnectionDefBody::Brace { elements } => ConnectionDefBody::Brace {
694            elements: elements
695                .iter()
696                .map(normalize_connection_def_body_element_node)
697                .collect(),
698        },
699    }
700}
701
702fn normalize_connection_def_body_element_node(
703    el: &Node<ConnectionDefBodyElement>,
704) -> Node<ConnectionDefBodyElement> {
705    let value = match &el.value {
706        ConnectionDefBodyElement::EndDecl(n) => {
707            ConnectionDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
708        }
709        ConnectionDefBodyElement::RefDecl(n) => {
710            ConnectionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
711        }
712        ConnectionDefBodyElement::ConnectStmt(n) => {
713            ConnectionDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
714        }
715    };
716    dummy_node(el, value)
717}
718
719fn normalize_metadata_def(m: &MetadataDef) -> MetadataDef {
720    MetadataDef {
721        is_abstract: m.is_abstract,
722        identification: m.identification.clone(),
723        specializes: m.specializes.clone(),
724        specializes_span: None,
725        body: m.body.clone(),
726    }
727}
728
729fn normalize_enum_def(e: &EnumDef) -> EnumDef {
730    EnumDef {
731        identification: e.identification.clone(),
732        specializes: e.specializes.clone(),
733        specializes_span: None,
734        body: e.body.clone(),
735    }
736}
737
738fn normalize_occurrence_def(o: &OccurrenceDef) -> OccurrenceDef {
739    OccurrenceDef {
740        is_abstract: o.is_abstract,
741        identification: o.identification.clone(),
742        specializes: o.specializes.clone(),
743        specializes_span: None,
744        body: o.body.clone(),
745    }
746}
747
748fn normalize_interface_def_body(b: &InterfaceDefBody) -> InterfaceDefBody {
749    match b {
750        InterfaceDefBody::Semicolon => InterfaceDefBody::Semicolon,
751        InterfaceDefBody::Brace { elements } => InterfaceDefBody::Brace {
752            elements: elements
753                .iter()
754                .map(normalize_interface_def_body_element_node)
755                .collect(),
756        },
757    }
758}
759
760fn normalize_interface_def_body_element_node(
761    el: &Node<InterfaceDefBodyElement>,
762) -> Node<InterfaceDefBodyElement> {
763    let value = match &el.value {
764        InterfaceDefBodyElement::Doc(n) => {
765            InterfaceDefBodyElement::Doc(dummy_node(n, n.value.clone()))
766        }
767        InterfaceDefBodyElement::EndDecl(n) => {
768            InterfaceDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
769        }
770        InterfaceDefBodyElement::RefDecl(n) => {
771            InterfaceDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
772        }
773        InterfaceDefBodyElement::ConnectStmt(n) => {
774            InterfaceDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
775        }
776    };
777    dummy_node(el, value)
778}
779
780fn normalize_end_decl(e: &EndDecl) -> EndDecl {
781    EndDecl {
782        name: e.name.clone(),
783        type_name: e.type_name.clone(),
784        uses_derived_syntax: e.uses_derived_syntax,
785        name_span: None,
786        type_ref_span: None,
787    }
788}
789
790fn normalize_ref_decl(r: &RefDecl) -> RefDecl {
791    RefDecl {
792        name: r.name.clone(),
793        type_name: r.type_name.clone(),
794        value: r.value.clone(),
795        body: r.body.clone(),
796        name_span: None,
797        type_ref_span: None,
798    }
799}
800
801fn normalize_action_def(a: &ActionDef) -> ActionDef {
802    ActionDef {
803        identification: a.identification.clone(),
804        specializes: a.specializes.clone(),
805        specializes_span: None,
806        body: normalize_action_def_body(&a.body),
807    }
808}
809
810fn normalize_action_def_body(b: &ActionDefBody) -> ActionDefBody {
811    match b {
812        ActionDefBody::Semicolon => ActionDefBody::Semicolon,
813        ActionDefBody::Brace { elements } => ActionDefBody::Brace {
814            elements: elements
815                .iter()
816                .map(normalize_action_def_body_element_node)
817                .collect(),
818        },
819    }
820}
821
822fn normalize_action_def_body_element_node(
823    el: &Node<ActionDefBodyElement>,
824) -> Node<ActionDefBodyElement> {
825    let value = match &el.value {
826        ActionDefBodyElement::Error(n) => {
827            ActionDefBodyElement::Error(dummy_node(n, n.value.clone()))
828        }
829        ActionDefBodyElement::InOutDecl(n) => {
830            ActionDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
831        }
832        ActionDefBodyElement::Doc(n) => ActionDefBodyElement::Doc(dummy_node(n, n.value.clone())),
833        ActionDefBodyElement::Annotation(n) => {
834            ActionDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
835        }
836        ActionDefBodyElement::MetadataAnnotation(n) => {
837            ActionDefBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
838        }
839        ActionDefBodyElement::RefDecl(n) => {
840            ActionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
841        }
842        ActionDefBodyElement::Perform(n) => {
843            ActionDefBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
844        }
845        ActionDefBodyElement::Bind(n) => ActionDefBodyElement::Bind(dummy_node(n, n.value.clone())),
846        ActionDefBodyElement::Flow(n) => ActionDefBodyElement::Flow(dummy_node(n, n.value.clone())),
847        ActionDefBodyElement::FirstStmt(n) => {
848            ActionDefBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
849        }
850        ActionDefBodyElement::MergeStmt(n) => {
851            ActionDefBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
852        }
853        ActionDefBodyElement::StateUsage(n) => {
854            ActionDefBodyElement::StateUsage(dummy_node(n, n.value.clone()))
855        }
856        ActionDefBodyElement::ActionUsage(n) => ActionDefBodyElement::ActionUsage(Box::new(
857            dummy_node(n, normalize_action_usage(&n.value)),
858        )),
859        ActionDefBodyElement::Assign(n) => {
860            ActionDefBodyElement::Assign(dummy_node(n, n.value.clone()))
861        }
862        ActionDefBodyElement::ForLoop(n) => {
863            ActionDefBodyElement::ForLoop(dummy_node(n, n.value.clone()))
864        }
865        ActionDefBodyElement::ThenAction(n) => {
866            ActionDefBodyElement::ThenAction(dummy_node(n, n.value.clone()))
867        }
868        ActionDefBodyElement::Decl(n) => ActionDefBodyElement::Decl(dummy_node(n, n.value.clone())),
869    };
870    dummy_node(el, value)
871}
872
873fn normalize_action_usage(a: &ActionUsage) -> ActionUsage {
874    ActionUsage {
875        name: a.name.clone(),
876        type_name: a.type_name.clone(),
877        accept: a.accept.clone(),
878        send: a.send.clone(),
879        body: normalize_action_usage_body(&a.body),
880        name_span: None,
881        type_ref_span: None,
882    }
883}
884
885fn normalize_action_usage_body(b: &ActionUsageBody) -> ActionUsageBody {
886    match b {
887        ActionUsageBody::Semicolon => ActionUsageBody::Semicolon,
888        ActionUsageBody::Brace { elements } => ActionUsageBody::Brace {
889            elements: elements
890                .iter()
891                .map(normalize_action_usage_body_element_node)
892                .collect(),
893        },
894    }
895}
896
897fn normalize_action_usage_body_element_node(
898    el: &Node<ActionUsageBodyElement>,
899) -> Node<ActionUsageBodyElement> {
900    let value = match &el.value {
901        ActionUsageBodyElement::Error(n) => {
902            ActionUsageBodyElement::Error(dummy_node(n, n.value.clone()))
903        }
904        ActionUsageBodyElement::Doc(n) => {
905            ActionUsageBodyElement::Doc(dummy_node(n, n.value.clone()))
906        }
907        ActionUsageBodyElement::Annotation(n) => {
908            ActionUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
909        }
910        ActionUsageBodyElement::MetadataAnnotation(n) => {
911            ActionUsageBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
912        }
913        ActionUsageBodyElement::InOutDecl(n) => {
914            ActionUsageBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
915        }
916        ActionUsageBodyElement::RefDecl(n) => {
917            ActionUsageBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
918        }
919        ActionUsageBodyElement::Bind(n) => {
920            ActionUsageBodyElement::Bind(dummy_node(n, n.value.clone()))
921        }
922        ActionUsageBodyElement::Flow(n) => {
923            ActionUsageBodyElement::Flow(dummy_node(n, n.value.clone()))
924        }
925        ActionUsageBodyElement::FirstStmt(n) => {
926            ActionUsageBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
927        }
928        ActionUsageBodyElement::MergeStmt(n) => {
929            ActionUsageBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
930        }
931        ActionUsageBodyElement::StateUsage(n) => {
932            ActionUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
933        }
934        ActionUsageBodyElement::ActionUsage(n) => ActionUsageBodyElement::ActionUsage(Box::new(
935            dummy_node(n, normalize_action_usage(&n.value)),
936        )),
937        ActionUsageBodyElement::Assign(n) => {
938            ActionUsageBodyElement::Assign(dummy_node(n, n.value.clone()))
939        }
940        ActionUsageBodyElement::ForLoop(n) => {
941            ActionUsageBodyElement::ForLoop(dummy_node(n, n.value.clone()))
942        }
943        ActionUsageBodyElement::ThenAction(n) => {
944            ActionUsageBodyElement::ThenAction(dummy_node(n, n.value.clone()))
945        }
946        ActionUsageBodyElement::Decl(n) => {
947            ActionUsageBodyElement::Decl(dummy_node(n, n.value.clone()))
948        }
949    };
950    dummy_node(el, value)
951}