Skip to main content

sysml_v2_parser/
ast.rs

1//! Abstract syntax tree types for SysML v2 textual notation.
2
3/// Source location: byte offset, line, column, and length in the source file.
4/// Line and column are **1-based**. Use [`Span::to_lsp_range`] for 0-based LSP ranges.
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Span {
7    pub offset: usize,
8    pub line: u32,
9    pub column: usize,
10    pub len: usize,
11}
12
13impl Span {
14    /// Dummy span for tests or synthetic nodes (offset 0, line 1, column 1, len 0).
15    pub fn dummy() -> Self {
16        Self {
17            offset: 0,
18            line: 1,
19            column: 1,
20            len: 0,
21        }
22    }
23
24    /// LSP uses 0-based line and 0-based character. Returns (start_line, start_character, end_line, end_character).
25    pub fn to_lsp_range(&self) -> (u32, u32, u32, u32) {
26        let start_line = self.line.saturating_sub(1);
27        let start_char = self.column.saturating_sub(1);
28        let end_char = start_char.saturating_add(self.len);
29        (start_line, start_char as u32, start_line, end_char as u32)
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::Span;
36
37    #[test]
38    fn span_dummy() {
39        let s = Span::dummy();
40        assert_eq!(s.offset, 0);
41        assert_eq!(s.line, 1);
42        assert_eq!(s.column, 1);
43        assert_eq!(s.len, 0);
44    }
45}
46
47#[derive(Debug, Clone)]
48pub struct Node<T> {
49    pub span: Span,
50    pub value: T,
51}
52
53impl<T: PartialEq> PartialEq for Node<T> {
54    fn eq(&self, other: &Self) -> bool {
55        self.value == other.value
56    }
57}
58
59impl<T: Eq> Eq for Node<T> {}
60
61impl<T> Node<T> {
62    pub fn new(span: Span, value: T) -> Self {
63        Self { span, value }
64    }
65}
66
67impl<T> std::ops::Deref for Node<T> {
68    type Target = T;
69    fn deref(&self) -> &T {
70        &self.value
71    }
72}
73
74/// Trait for generic access to node source span (e.g. visitors).
75pub trait AstNode {
76    fn span(&self) -> Span;
77}
78
79impl<T> AstNode for Node<T> {
80    fn span(&self) -> Span {
81        self.span.clone()
82    }
83}
84
85/// Expression: literals, feature refs, member access, index, bracket/unit, etc.
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub enum Expression {
88    LiteralInteger(i64),
89    LiteralReal(String),
90    LiteralString(String),
91    LiteralBoolean(bool),
92    /// Single name or qualified name.
93    FeatureRef(String),
94    /// base.member (e.g. engine.fuelCmdPort).
95    MemberAccess(Box<Node<Expression>>, String),
96    /// base#(index) e.g. frontWheel#(1).
97    Index {
98        base: Box<Node<Expression>>,
99        index: Box<Node<Expression>>,
100    },
101    /// [unit] e.g. [kg].
102    Bracket(Box<Node<Expression>>),
103    /// value [unit] e.g. 1750 [kg].
104    LiteralWithUnit {
105        value: Box<Node<Expression>>,
106        unit: Box<Node<Expression>>,
107    },
108    /// Binary infix operation e.g. `a >= b * c`, `x / y`.
109    BinaryOp {
110        op: String,
111        left: Box<Node<Expression>>,
112        right: Box<Node<Expression>>,
113    },
114    /// Unary prefix: + - ~ not
115    UnaryOp {
116        op: String,
117        operand: Box<Node<Expression>>,
118    },
119    /// Function-like invocation, e.g. `ComputeMargin(a, b)`.
120    Invocation {
121        callee: Box<Node<Expression>>,
122        args: Vec<Node<Expression>>,
123    },
124    /// Comma-separated sequence in parentheses, e.g. `(engine1, engine2)` for ordered composition values.
125    Tuple(Vec<Node<Expression>>),
126    /// KerML null or empty sequence ().
127    Null,
128}
129
130/// KerML top-level element: package, namespace, import, or library package (BNF RootNamespace = PackageBodyElement*).
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub enum RootElement {
133    Package(Node<Package>),
134    LibraryPackage(Node<LibraryPackage>),
135    Namespace(Node<NamespaceDecl>),
136    Import(Node<Import>),
137}
138
139/// KerML NamespaceDeclaration: `namespace` Identification NamespaceBody (same body structure as Package).
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct NamespaceDecl {
142    pub identification: Identification,
143    pub body: PackageBody,
144}
145
146/// Root of a SysML/KerML document: a sequence of top-level package or namespace elements.
147#[derive(Debug, Clone, PartialEq, Eq)]
148pub struct RootNamespace {
149    pub elements: Vec<Node<RootElement>>,
150}
151
152/// KerML ElementFilterMember: MemberPrefix? 'filter' condition ';'
153#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct FilterMember {
155    pub visibility: Option<Visibility>,
156    pub condition: Node<Expression>,
157}
158
159/// Placeholder node inserted when resilient parsing skips malformed input.
160#[derive(Debug, Clone, PartialEq, Eq)]
161pub struct ParseErrorNode {
162    pub message: String,
163    pub code: String,
164    pub expected: Option<String>,
165    pub found: Option<String>,
166    pub suggestion: Option<String>,
167    pub category: Option<crate::error::DiagnosticCategory>,
168}
169
170/// Modeled KerML semantic declaration captured as package-level syntax.
171#[derive(Debug, Clone, PartialEq, Eq)]
172pub struct KermlSemanticDecl {
173    pub bnf_production: String,
174    pub text: String,
175}
176
177/// Modeled KerML feature declaration family (occurrence/expr/predicate/succession).
178#[derive(Debug, Clone, PartialEq, Eq)]
179pub struct KermlFeatureDecl {
180    pub bnf_production: String,
181    pub text: String,
182}
183
184/// Package-level KerML feature declaration captured as an explicit dedicated node.
185#[derive(Debug, Clone, PartialEq, Eq)]
186pub struct FeatureDecl {
187    pub keyword: String,
188    pub text: String,
189}
190
191/// Package-level KerML classifier declaration captured as an explicit dedicated node.
192#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct ClassifierDecl {
194    pub keyword: String,
195    pub text: String,
196}
197
198/// Modeled extended SysML/KerML declaration family not yet represented by
199/// dedicated concrete nodes (e.g. concern/message style library declarations).
200#[derive(Debug, Clone, PartialEq, Eq)]
201pub struct ExtendedLibraryDecl {
202    pub bnf_production: String,
203    pub text: String,
204}
205
206/// Top-level element inside a namespace or package body.
207#[derive(Debug, Clone, PartialEq, Eq)]
208pub enum PackageBodyElement {
209    Error(Node<ParseErrorNode>),
210    Doc(Node<DocComment>),
211    Comment(Node<CommentAnnotation>),
212    TextualRep(Node<TextualRepresentation>),
213    Filter(Node<FilterMember>),
214    Package(Node<Package>),
215    LibraryPackage(Node<LibraryPackage>),
216    Import(Node<Import>),
217    PartDef(Node<PartDef>),
218    PartUsage(Node<PartUsage>),
219    PortDef(Node<PortDef>),
220    InterfaceDef(Node<InterfaceDef>),
221    AliasDef(Node<AliasDef>),
222    AttributeDef(Node<AttributeDef>),
223    ActionDef(Node<ActionDef>),
224    ActionUsage(Node<ActionUsage>),
225    RequirementDef(Node<RequirementDef>),
226    RequirementUsage(Node<RequirementUsage>),
227    Satisfy(Node<Satisfy>),
228    UseCaseDef(Node<UseCaseDef>),
229    Actor(Node<ActorDecl>),
230    StateDef(Node<StateDef>),
231    StateUsage(Node<StateUsage>),
232    ItemDef(Node<ItemDef>),
233    IndividualDef(Node<IndividualDef>),
234    ConstraintDef(Node<ConstraintDef>),
235    CalcDef(Node<CalcDef>),
236    ViewDef(Node<ViewDef>),
237    ViewpointDef(Node<ViewpointDef>),
238    RenderingDef(Node<RenderingDef>),
239    ViewUsage(Node<ViewUsage>),
240    ViewpointUsage(Node<ViewpointUsage>),
241    RenderingUsage(Node<RenderingUsage>),
242    ConnectionDef(Node<ConnectionDef>),
243    MetadataDef(Node<MetadataDef>),
244    EnumDef(Node<EnumDef>),
245    OccurrenceDef(Node<OccurrenceDef>),
246    OccurrenceUsage(Node<OccurrenceUsage>),
247    Dependency(Node<Dependency>),
248    AllocationDef(Node<AllocationDef>),
249    AllocationUsage(Node<AllocationUsage>),
250    FlowDef(Node<FlowDef>),
251    FlowUsage(Node<FlowUsage>),
252    ConcernUsage(Node<ConcernUsage>),
253    CaseDef(Node<CaseDef>),
254    CaseUsage(Node<CaseUsage>),
255    AnalysisCaseDef(Node<AnalysisCaseDef>),
256    AnalysisCaseUsage(Node<AnalysisCaseUsage>),
257    VerificationCaseDef(Node<VerificationCaseDef>),
258    VerificationCaseUsage(Node<VerificationCaseUsage>),
259    UseCaseUsage(Node<UseCaseUsage>),
260    FeatureDecl(Node<FeatureDecl>),
261    ClassifierDecl(Node<ClassifierDecl>),
262    KermlSemanticDecl(Node<KermlSemanticDecl>),
263    KermlFeatureDecl(Node<KermlFeatureDecl>),
264    ExtendedLibraryDecl(Node<ExtendedLibraryDecl>),
265}
266
267/// A package declaration: `package` Identification PackageBody
268#[derive(Debug, Clone, PartialEq, Eq)]
269pub struct Package {
270    pub identification: Identification,
271    pub body: PackageBody,
272}
273
274/// Identification: optional short name in `< >`, optional name.
275/// BNF: ( '<' declaredShortName = NAME '>' )? ( declaredName = NAME )?
276#[derive(Debug, Clone, PartialEq, Eq)]
277pub struct Identification {
278    /// Short name inside `< ... >`, if present.
279    pub short_name: Option<String>,
280    /// Main declared name (may be quoted, e.g. '1a-Parts Tree').
281    pub name: Option<String>,
282}
283
284/// Package body: either `;` or `{` PackageBodyElement* `}`
285#[derive(Debug, Clone, PartialEq, Eq)]
286pub enum PackageBody {
287    /// Semicolon form: no body elements.
288    Semicolon,
289    /// Brace form: list of body elements (may be empty).
290    Brace {
291        elements: Vec<Node<PackageBodyElement>>,
292    },
293}
294
295/// Visibility for imports and members.
296#[derive(Debug, Clone, Copy, PartialEq, Eq)]
297pub enum Visibility {
298    Public,
299    Private,
300    Protected,
301}
302
303/// KerML FilterPackageMember: `[` OwnedExpression `]`.
304#[derive(Debug, Clone, PartialEq, Eq)]
305pub struct FilterPackageMember {
306    pub expression: Node<Expression>,
307}
308
309/// Import: `private`? `import` `all`? QualifiedName (`::` `*`)? or FilterPackage form.
310#[derive(Debug, Clone, PartialEq, Eq)]
311pub struct Import {
312    pub visibility: Option<Visibility>,
313    /// Whether this is a namespace import (QualifiedName::* or FilterPackage) or membership import (single QualifiedName).
314    pub is_import_all: bool,
315    /// Import target, e.g. "SI::kg" or "Definitions::*".
316    pub target: String,
317    /// KerML: optional recursive import after :: (e.g. QualifiedName::** or QualifiedName::*::**).
318    pub is_recursive: bool,
319    /// KerML FilterPackage form: one or more `[ expr ]` members. When present, this is a namespace import of a filter package.
320    pub filter_members: Option<Vec<Node<FilterPackageMember>>>,
321}
322
323/// Part definition: `part def` Identification (`:>` specializes)? Body.
324#[derive(Debug, Clone, PartialEq, Eq)]
325pub struct PartDef {
326    /// Optional `abstract` or `variation` prefix (BNF BasicDefinitionPrefix).
327    pub definition_prefix: Option<DefinitionPrefix>,
328    /// Whether this is an `individual part def`.
329    pub is_individual: bool,
330    pub identification: Identification,
331    /// Supertype after `:>`, e.g. Some("Axle") for `part def FrontAxle :> Axle`.
332    pub specializes: Option<String>,
333    /// Span of the `:> <type>` fragment (for semantic tokens), when present.
334    pub specializes_span: Option<Span>,
335    pub body: PartDefBody,
336}
337
338/// BNF BasicDefinitionPrefix: `abstract` | `variation`.
339#[derive(Debug, Clone, PartialEq, Eq)]
340pub enum DefinitionPrefix {
341    Abstract,
342    Variation,
343}
344
345/// Body of a part definition: `;` or `{` PartDefBodyElement* `}`.
346#[derive(Debug, Clone, PartialEq, Eq)]
347pub enum PartDefBody {
348    Semicolon,
349    Brace {
350        elements: Vec<Node<PartDefBodyElement>>,
351    },
352}
353
354/// Element inside a part definition body.
355#[derive(Debug, Clone, PartialEq, Eq)]
356pub enum PartDefBodyElement {
357    Error(Node<ParseErrorNode>),
358    Doc(Node<DocComment>),
359    Comment(Node<CommentAnnotation>),
360    Annotation(Node<Annotation>),
361    Other(String),
362    AttributeDef(Node<AttributeDef>),
363    AttributeUsage(Node<AttributeUsage>),
364    RequirementUsage(Node<RequirementUsage>),
365    Ref(Node<RefDecl>),
366    PortUsage(Node<PortUsage>),
367    PartUsage(Box<Node<PartUsage>>),
368    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
369    InterfaceDef(Node<InterfaceDef>),
370    InterfaceUsage(Node<InterfaceUsage>),
371    Connect(Node<Connect>),
372    /// `connection` usage member inside a part definition body.
373    Connection(Node<ConnectionUsageMember>),
374    Perform(Node<Perform>),
375    Allocate(Node<Allocate>),
376    OpaqueMember(Node<OpaqueMemberDecl>),
377    /// `exhibit state` name `:` type (`;` or body).
378    ExhibitState(Node<ExhibitState>),
379}
380
381/// Library-tolerant part member preserved without forcing it into an unrelated node shape.
382#[derive(Debug, Clone, PartialEq, Eq)]
383pub struct OpaqueMemberDecl {
384    pub keyword: String,
385    pub name: String,
386    pub text: String,
387    pub body: AttributeBody,
388}
389
390/// Connection usage member inside part definitions.
391#[derive(Debug, Clone, PartialEq, Eq)]
392pub struct ConnectionUsageMember {
393    pub name: Option<String>,
394    pub type_name: Option<String>,
395    pub body: ConnectionDefBody,
396    pub subsets: Option<String>,
397    pub redefines: Option<String>,
398}
399
400/// Exhibit state usage: `exhibit state` name `:` type (`;` or body).
401#[derive(Debug, Clone, PartialEq, Eq)]
402pub struct ExhibitState {
403    pub name: String,
404    pub type_name: Option<String>,
405    pub redefines: Option<String>,
406    pub body: StateDefBody,
407}
408
409/// Attribute definition: `attribute` [`def`] name (`:>` | `:` type)? (`=` value)? body.
410#[derive(Debug, Clone, PartialEq, Eq)]
411pub struct AttributeDef {
412    pub name: String,
413    /// Type after `:>`, e.g. Some("ISQ::mass").
414    pub typing: Option<String>,
415    /// Default or binding after `=` / `:=` / `default =` before the body terminator.
416    pub value: Option<Node<Expression>>,
417    pub body: AttributeBody,
418    /// Span of the defined name (for semantic tokens).
419    pub name_span: Option<Span>,
420    /// Span of the type after `:>`, if present (for semantic tokens).
421    pub typing_span: Option<Span>,
422}
423
424/// Body of an attribute (def or usage): `;` or `{` AttributeBodyElement* `}`.
425#[derive(Debug, Clone, PartialEq, Eq)]
426pub enum AttributeBody {
427    Semicolon,
428    Brace {
429        elements: Vec<Node<AttributeBodyElement>>,
430    },
431}
432
433#[derive(Debug, Clone, PartialEq, Eq)]
434pub enum AttributeBodyElement {
435    Error(Node<ParseErrorNode>),
436    Doc(Node<DocComment>),
437    AttributeDef(Node<AttributeDef>),
438    AttributeUsage(Node<AttributeUsage>),
439    Other(String),
440}
441
442/// Item definition: `item def` Identification body (for events, etc.).
443#[derive(Debug, Clone, PartialEq, Eq)]
444pub struct ItemDef {
445    pub identification: Identification,
446    pub specializes: Option<String>,
447    pub specializes_span: Option<Span>,
448    pub body: AttributeBody,
449}
450
451/// Individual definition: `individual def` Identification `:>` type body.
452#[derive(Debug, Clone, PartialEq, Eq)]
453pub struct IndividualDef {
454    pub identification: Identification,
455    pub specializes: Option<String>,
456    pub specializes_span: Option<Span>,
457    pub body: AttributeBody,
458}
459
460/// Part usage: `part` name `:` type multiplicity? `ordered`? (`redefines`|`:>>`)? value? body.
461#[derive(Debug, Clone, PartialEq, Eq)]
462pub struct PartUsage {
463    pub is_individual: bool,
464    pub name: String,
465    /// Type after `:`, e.g. "Vehicle", "AxleAssembly".
466    pub type_name: String,
467    /// Multiplicity, e.g. Some("[2]").
468    pub multiplicity: Option<String>,
469    pub ordered: bool,
470    /// Optional `subsets` feature and value expression.
471    pub subsets: Option<(String, Option<Node<Expression>>)>,
472    /// Redefines target, e.g. Some("frontAxleAssembly") or Some("vehicle1::mass").
473    pub redefines: Option<String>,
474    /// Value expression (= expr, default = expr, := expr).
475    pub value: Option<Node<Expression>>,
476    pub body: PartUsageBody,
477    /// Span of the usage name (for semantic tokens).
478    pub name_span: Option<Span>,
479    /// Span of the type reference after `:` (for semantic tokens).
480    pub type_ref_span: Option<Span>,
481}
482
483/// Body of a part usage: `;` or `{` PartUsageBodyElement* `}`.
484#[derive(Debug, Clone, PartialEq, Eq)]
485pub enum PartUsageBody {
486    Semicolon,
487    Brace {
488        elements: Vec<Node<PartUsageBodyElement>>,
489    },
490}
491
492/// Metadata annotation on usage: `@` Name (`:` Type)? MetadataBody (e.g. `@Security;` or `@Safety{isMandatory = true;}`).
493#[derive(Debug, Clone, PartialEq, Eq)]
494pub struct MetadataAnnotation {
495    pub name: String,
496    pub type_name: Option<String>,
497    pub body: ConnectBody,
498}
499
500/// Generic annotation or metadata usage captured in body scopes.
501#[derive(Debug, Clone, PartialEq, Eq)]
502pub struct Annotation {
503    pub sigil: String,
504    pub head: String,
505    pub type_name: Option<String>,
506    pub body: ConnectBody,
507}
508
509/// Element inside a part usage body.
510#[derive(Debug, Clone, PartialEq, Eq)]
511pub enum PartUsageBodyElement {
512    Error(Node<ParseErrorNode>),
513    Doc(Node<DocComment>),
514    Annotation(Node<Annotation>),
515    AttributeUsage(Node<AttributeUsage>),
516    PartUsage(Box<Node<PartUsage>>),
517    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
518    PortUsage(Node<PortUsage>),
519    Bind(Node<Bind>),
520    /// `ref` name `:` type body (reference binding in part usage).
521    Ref(Node<RefDecl>),
522    InterfaceUsage(Node<InterfaceUsage>),
523    Connect(Node<Connect>),
524    Perform(Node<Perform>),
525    Allocate(Node<Allocate>),
526    Satisfy(Node<Satisfy>),
527    StateUsage(Node<StateUsage>),
528    MetadataAnnotation(Node<MetadataAnnotation>),
529}
530
531/// Enacted performance: `perform` action_path `{` body `}` inside a part usage.
532#[derive(Debug, Clone, PartialEq, Eq)]
533pub struct Perform {
534    /// Qualified action name (e.g. "provide power" or "provide power.generate torque").
535    pub action_name: String,
536    /// Type after `:` in "perform action name : Type" form.
537    pub type_name: Option<String>,
538    pub body: PerformBody,
539}
540
541/// Body of a perform: `;` or `{` PerformBodyElement* `}`.
542#[derive(Debug, Clone, PartialEq, Eq)]
543pub enum PerformBody {
544    Semicolon,
545    Brace {
546        elements: Vec<Node<PerformBodyElement>>,
547    },
548}
549
550/// Element inside a perform body: doc comment or in/out binding.
551#[derive(Debug, Clone, PartialEq, Eq)]
552pub enum PerformBodyElement {
553    Doc(Node<DocComment>),
554    InOut(Node<PerformInOutBinding>),
555}
556
557/// In/out binding inside a perform body: `in` name `=` expr `;` or `out` name `=` expr `;`.
558#[derive(Debug, Clone, PartialEq, Eq)]
559pub struct PerformInOutBinding {
560    pub direction: InOut,
561    pub name: String,
562    pub value: Node<Expression>,
563}
564
565/// Attribute usage: `attribute` name (`:>` | `:` type)? `redefines`? value? body.
566#[derive(Debug, Clone, PartialEq, Eq)]
567pub struct AttributeUsage {
568    pub name: String,
569    /// Type after `:` or `:>`, e.g. Some("MassValue").
570    pub typing: Option<String>,
571    /// Redefines target, e.g. Some("Vehicle::mass").
572    pub redefines: Option<String>,
573    /// Value expression.
574    pub value: Option<Node<Expression>>,
575    pub body: AttributeBody,
576    /// Span of the usage name (for semantic tokens).
577    pub name_span: Option<Span>,
578    /// Span of the type after `:` / `:>`, if present (for semantic tokens).
579    pub typing_span: Option<Span>,
580    /// Span of the redefines target after `redefines`, if present (for semantic tokens).
581    pub redefines_span: Option<Span>,
582}
583
584// ---------------------------------------------------------------------------
585// Port
586// ---------------------------------------------------------------------------
587
588/// Port definition: `port def` Identification body.
589#[derive(Debug, Clone, PartialEq, Eq)]
590pub struct PortDef {
591    pub identification: Identification,
592    /// Supertype after `:>`, e.g. Some("ClutchPort") for `port def ManualClutchPort :> ClutchPort`.
593    pub specializes: Option<String>,
594    pub specializes_span: Option<Span>,
595    pub body: PortDefBody,
596}
597
598/// Body of a port definition: `;` or `{` PortDefBodyElement* `}`.
599#[derive(Debug, Clone, PartialEq, Eq)]
600pub enum PortDefBody {
601    Semicolon,
602    Brace {
603        elements: Vec<Node<PortDefBodyElement>>,
604    },
605}
606
607/// Element inside a port definition body (in/out declarations or nested port usages).
608#[derive(Debug, Clone, PartialEq, Eq)]
609pub enum PortDefBodyElement {
610    InOutDecl(Node<InOutDecl>),
611    Doc(Node<DocComment>),
612    Error(Node<ParseErrorNode>),
613    AttributeDef(Node<AttributeDef>),
614    AttributeUsage(Node<AttributeUsage>),
615    PortUsage(Node<PortUsage>),
616}
617
618/// Port usage: `port` name `:` type multiplicity? `:>` subsets? `redefines`? body.
619#[derive(Debug, Clone, PartialEq, Eq)]
620pub struct PortUsage {
621    pub name: String,
622    pub type_name: Option<String>,
623    pub multiplicity: Option<String>,
624    /// Subsets feature and optional value expression.
625    pub subsets: Option<(String, Option<Node<Expression>>)>,
626    pub redefines: Option<String>,
627    pub body: PortBody,
628    /// Span of the usage name (for semantic tokens).
629    pub name_span: Option<Span>,
630    /// Span of the type reference after `:`, if present (for semantic tokens).
631    pub type_ref_span: Option<Span>,
632}
633
634/// Body of a port usage: `;` or `{` PortBodyElement* `}`.
635#[derive(Debug, Clone, PartialEq, Eq)]
636pub enum PortBody {
637    Semicolon,
638    Brace {
639        elements: Vec<Node<PortBodyElement>>,
640    },
641}
642
643/// Element inside a port usage body.
644#[derive(Debug, Clone, PartialEq, Eq)]
645pub enum PortBodyElement {
646    Error(Node<ParseErrorNode>),
647    InOutDecl(Node<InOutDecl>),
648    PortUsage(Node<PortUsage>),
649    Other(String),
650}
651
652// ---------------------------------------------------------------------------
653// Interface
654// ---------------------------------------------------------------------------
655
656/// Interface definition: `interface def` Identification body.
657#[derive(Debug, Clone, PartialEq, Eq)]
658pub struct InterfaceDef {
659    pub identification: Identification,
660    pub specializes: Option<String>,
661    pub specializes_span: Option<Span>,
662    pub body: InterfaceDefBody,
663}
664
665/// Body of an interface definition: `;` or `{` InterfaceDefBodyElement* `}`.
666#[derive(Debug, Clone, PartialEq, Eq)]
667pub enum InterfaceDefBody {
668    Semicolon,
669    Brace {
670        elements: Vec<Node<InterfaceDefBodyElement>>,
671    },
672}
673
674/// Element inside an interface definition body.
675#[derive(Debug, Clone, PartialEq, Eq)]
676pub enum InterfaceDefBodyElement {
677    Doc(Node<DocComment>),
678    EndDecl(Node<EndDecl>),
679    RefDecl(Node<RefDecl>),
680    ConnectStmt(Node<ConnectStmt>),
681}
682
683/// End declaration in interface def: `end` name `:` type `;`.
684#[derive(Debug, Clone, PartialEq, Eq)]
685pub struct EndDecl {
686    pub name: String,
687    pub type_name: String,
688    pub uses_derived_syntax: bool,
689    /// Span of the name (for semantic tokens).
690    pub name_span: Option<Span>,
691    /// Span of the type after `:` (for semantic tokens).
692    pub type_ref_span: Option<Span>,
693}
694
695/// Ref declaration in interface def: `ref` name `:` type body.
696#[derive(Debug, Clone, PartialEq, Eq)]
697pub struct RefDecl {
698    pub name: String,
699    pub type_name: String,
700    /// Optional binding value: `= expr` (SysML shorthand binding for references).
701    pub value: Option<Node<Expression>>,
702    pub body: RefBody,
703    /// Span of the name (for semantic tokens).
704    pub name_span: Option<Span>,
705    /// Span of the type after `:` (for semantic tokens).
706    pub type_ref_span: Option<Span>,
707}
708
709/// Body of a ref declaration: `;` or `{` ... `}`.
710#[derive(Debug, Clone, PartialEq, Eq)]
711pub enum RefBody {
712    Semicolon,
713    Brace,
714}
715
716// ---------------------------------------------------------------------------
717// Connection (Phase 2)
718// ---------------------------------------------------------------------------
719
720/// Connection definition: `connection def` Identification body (BNF ConnectionDefinition).
721#[derive(Debug, Clone, PartialEq, Eq)]
722pub struct ConnectionDef {
723    pub annotation: Option<String>,
724    pub identification: Identification,
725    pub specializes: Option<String>,
726    pub specializes_span: Option<Span>,
727    pub body: ConnectionDefBody,
728}
729
730/// Body of a connection definition: `;` or `{` end/ref/connect* `}`.
731#[derive(Debug, Clone, PartialEq, Eq)]
732pub enum ConnectionDefBody {
733    Semicolon,
734    Brace {
735        elements: Vec<Node<ConnectionDefBodyElement>>,
736    },
737}
738
739#[derive(Debug, Clone, PartialEq, Eq)]
740pub enum ConnectionDefBodyElement {
741    EndDecl(Node<EndDecl>),
742    RefDecl(Node<RefDecl>),
743    ConnectStmt(Node<ConnectStmt>),
744}
745
746// ---------------------------------------------------------------------------
747// Metadata (Phase 2)
748// ---------------------------------------------------------------------------
749
750/// Metadata definition: `metadata def` Identification body (BNF MetadataDefinition).
751#[derive(Debug, Clone, PartialEq, Eq)]
752pub struct MetadataDef {
753    pub is_abstract: bool,
754    pub identification: Identification,
755    pub specializes: Option<String>,
756    pub specializes_span: Option<Span>,
757    pub body: DefinitionBody,
758}
759
760// ---------------------------------------------------------------------------
761// Enumeration (Phase 2)
762// ---------------------------------------------------------------------------
763
764/// Enumeration definition: `enum def` Identification EnumerationBody (BNF EnumerationDefinition).
765#[derive(Debug, Clone, PartialEq, Eq)]
766pub struct EnumDef {
767    pub identification: Identification,
768    pub specializes: Option<String>,
769    pub specializes_span: Option<Span>,
770    pub body: EnumerationBody,
771}
772
773#[derive(Debug, Clone, PartialEq, Eq)]
774pub enum EnumerationBody {
775    Semicolon,
776    Brace { values: Vec<String> },
777}
778
779// ---------------------------------------------------------------------------
780// Occurrence (Phase 2)
781// ---------------------------------------------------------------------------
782
783/// Occurrence definition: `occurrence def` Identification body (BNF OccurrenceDefinition).
784#[derive(Debug, Clone, PartialEq, Eq)]
785pub struct OccurrenceDef {
786    pub is_abstract: bool,
787    pub identification: Identification,
788    pub specializes: Option<String>,
789    pub specializes_span: Option<Span>,
790    pub body: DefinitionBody,
791}
792
793/// Occurrence usage: `occurrence` name (`:` type)? body, with optional individual/portion modifiers.
794#[derive(Debug, Clone, PartialEq, Eq)]
795pub struct OccurrenceUsage {
796    pub is_individual: bool,
797    pub is_then: bool,
798    pub portion_kind: Option<String>,
799    pub name: String,
800    pub type_name: Option<String>,
801    pub subsets: Option<String>,
802    pub redefines: Option<String>,
803    pub body: OccurrenceUsageBody,
804}
805
806#[derive(Debug, Clone, PartialEq, Eq)]
807pub enum OccurrenceUsageBody {
808    Semicolon,
809    Brace {
810        elements: Vec<Node<OccurrenceBodyElement>>,
811    },
812}
813
814/// Occurrence-level assert member: `assert constraint` body.
815#[derive(Debug, Clone, PartialEq, Eq)]
816pub struct AssertConstraintMember {
817    pub body: ConstraintDefBody,
818}
819
820#[derive(Debug, Clone, PartialEq, Eq)]
821pub enum OccurrenceBodyElement {
822    Error(Node<ParseErrorNode>),
823    Doc(Node<DocComment>),
824    Annotation(Node<Annotation>),
825    AssertConstraint(Node<AssertConstraintMember>),
826    Other(String),
827    AttributeUsage(Node<AttributeUsage>),
828    PartUsage(Box<Node<PartUsage>>),
829    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
830}
831
832// ---------------------------------------------------------------------------
833// Library Package (Phase 2)
834// ---------------------------------------------------------------------------
835
836/// Library package: `library` (optional `standard`) `package` Identification PackageBody (BNF LibraryPackage).
837#[derive(Debug, Clone, PartialEq, Eq)]
838pub struct LibraryPackage {
839    pub is_standard: bool,
840    pub identification: Identification,
841    pub body: PackageBody,
842}
843
844/// Generic definition body: `;` or `{` DefinitionBodyElement* `}`.
845#[derive(Debug, Clone, PartialEq, Eq)]
846pub enum DefinitionBody {
847    Semicolon,
848    Brace {
849        elements: Vec<Node<DefinitionBodyElement>>,
850    },
851}
852
853#[derive(Debug, Clone, PartialEq, Eq)]
854pub enum DefinitionBodyElement {
855    Error(Node<ParseErrorNode>),
856    Doc(Node<DocComment>),
857    OccurrenceMember(Node<OccurrenceBodyElement>),
858    Other(String),
859}
860
861/// Connect statement in interface def or usage: `connect` from `to` to body.
862#[derive(Debug, Clone, PartialEq, Eq)]
863pub struct ConnectStmt {
864    pub from: Node<Expression>,
865    pub to: Node<Expression>,
866    pub body: ConnectBody,
867}
868
869/// Body of a connect statement: `;` or `{` ... `}`.
870#[derive(Debug, Clone, PartialEq, Eq)]
871pub enum ConnectBody {
872    Semicolon,
873    Brace,
874}
875
876// ---------------------------------------------------------------------------
877// Part usage body: bind, interface usage, connect
878// ---------------------------------------------------------------------------
879
880/// Bind: `bind` left `=` right (`;` or `{ }`).
881#[derive(Debug, Clone, PartialEq, Eq)]
882pub struct Bind {
883    pub left: Node<Expression>,
884    pub right: Node<Expression>,
885    /// Optional body after the bind (semicolon or brace); 3a fixture uses `bind x = y { }`.
886    pub body: Option<ConnectBody>,
887}
888
889/// Interface usage: typed+connect or connection form.
890#[derive(Debug, Clone, PartialEq, Eq)]
891pub enum InterfaceUsage {
892    /// `interface` `:Type`? `connect` from `to` to body; optional body with ref redefs.
893    TypedConnect {
894        interface_type: Option<String>,
895        from: Node<Expression>,
896        to: Node<Expression>,
897        body: ConnectBody,
898        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
899    },
900    /// `interface` from `to` to body.
901    Connection {
902        from: Node<Expression>,
903        to: Node<Expression>,
904        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
905    },
906}
907
908/// Element in interface usage body (e.g. ref redefinition).
909#[derive(Debug, Clone, PartialEq, Eq)]
910pub enum InterfaceUsageBodyElement {
911    /// `ref` `:>>` name `=` value body.
912    RefRedef {
913        name: String,
914        value: Node<Expression>,
915        body: RefBody,
916    },
917}
918
919/// Connect at part usage level: `connect` from `to` to body.
920#[derive(Debug, Clone, PartialEq, Eq)]
921pub struct Connect {
922    pub from: Node<Expression>,
923    pub to: Node<Expression>,
924    pub body: ConnectBody,
925}
926
927// ---------------------------------------------------------------------------
928// Alias
929// ---------------------------------------------------------------------------
930
931/// Alias definition: `alias` Identification `for` qualified_name body.
932#[derive(Debug, Clone, PartialEq, Eq)]
933pub struct AliasDef {
934    pub identification: Identification,
935    pub target: String,
936    pub body: AliasBody,
937}
938
939/// Body of an alias definition: `;` or `{` ... `}`.
940#[derive(Debug, Clone, PartialEq, Eq)]
941pub enum AliasBody {
942    Semicolon,
943    Brace,
944}
945
946// ---------------------------------------------------------------------------
947// Action (function-based behavior)
948// ---------------------------------------------------------------------------
949
950/// Action definition: `action def` Identification body (in/out params).
951#[derive(Debug, Clone, PartialEq, Eq)]
952pub struct ActionDef {
953    pub identification: Identification,
954    pub specializes: Option<String>,
955    pub specializes_span: Option<Span>,
956    pub body: ActionDefBody,
957}
958
959/// Body of an action definition: `;` or `{` ActionDefBodyElement* `}`.
960#[derive(Debug, Clone, PartialEq, Eq)]
961pub enum ActionDefBody {
962    Semicolon,
963    Brace {
964        elements: Vec<Node<ActionDefBodyElement>>,
965    },
966}
967
968/// Element inside an action definition body.
969#[derive(Debug, Clone, PartialEq, Eq)]
970pub enum ActionDefBodyElement {
971    Error(Node<ParseErrorNode>),
972    InOutDecl(Node<InOutDecl>),
973    Doc(Node<DocComment>),
974    Annotation(Node<Annotation>),
975    RefDecl(Node<RefDecl>),
976    Perform(Node<Perform>),
977    Bind(Node<Bind>),
978    Flow(Node<Flow>),
979    FirstStmt(Node<FirstStmt>),
980    MergeStmt(Node<MergeStmt>),
981    StateUsage(Node<StateUsage>),
982    ActionUsage(Box<Node<ActionUsage>>),
983    Assign(Node<AssignStmt>),
984    ForLoop(Node<ForLoop>),
985    ThenAction(Node<ThenAction>),
986    Decl(Node<ActionBodyDecl>),
987}
988
989/// Assignment statement (SysML v2 AssignmentNode/AssignmentActionUsage).
990///
991/// Examples:
992/// - `assign x := y;`
993/// - `then assign position := dynamics.x_out;`
994#[derive(Debug, Clone, PartialEq, Eq)]
995pub struct AssignStmt {
996    pub is_then: bool,
997    pub lhs: String,
998    pub rhs: String,
999}
1000
1001/// For-loop node (SysML v2 ForLoopNode) - modeled minimally.
1002#[derive(Debug, Clone, PartialEq, Eq)]
1003pub struct ForLoop {
1004    pub var: String,
1005    pub range: String,
1006    pub body: ActionDefBody,
1007}
1008
1009/// Succession to an action usage: `then action ...`.
1010#[derive(Debug, Clone, PartialEq, Eq)]
1011pub struct ThenAction {
1012    pub action: Node<ActionUsage>,
1013}
1014
1015/// In/out parameter in action def: `in` name `:` type `;` or `out` name `:` type `;`.
1016#[derive(Debug, Clone, PartialEq, Eq)]
1017pub struct InOutDecl {
1018    pub direction: InOut,
1019    pub name: String,
1020    pub type_name: String,
1021}
1022
1023#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1024pub enum InOut {
1025    In,
1026    Out,
1027    InOut,
1028}
1029
1030/// Action usage: `action` name `:` type_name (`accept` param_name `:` param_type)? body.
1031#[derive(Debug, Clone, PartialEq, Eq)]
1032pub struct ActionUsage {
1033    pub name: String,
1034    pub type_name: String,
1035    /// For accept form: (param_name, param_type).
1036    pub accept: Option<(String, String)>,
1037    pub body: ActionUsageBody,
1038    /// Span of the usage name (for semantic tokens).
1039    pub name_span: Option<Span>,
1040    /// Span of the type reference after `:` (for semantic tokens).
1041    pub type_ref_span: Option<Span>,
1042}
1043
1044/// Body of an action usage: `;` or `{` ActionUsageBodyElement* `}`.
1045#[derive(Debug, Clone, PartialEq, Eq)]
1046pub enum ActionUsageBody {
1047    Semicolon,
1048    Brace {
1049        elements: Vec<Node<ActionUsageBodyElement>>,
1050    },
1051}
1052
1053/// Element inside an action usage body.
1054#[derive(Debug, Clone, PartialEq, Eq)]
1055pub enum ActionUsageBodyElement {
1056    Error(Node<ParseErrorNode>),
1057    Doc(Node<DocComment>),
1058    Annotation(Node<Annotation>),
1059    InOutDecl(Node<InOutDecl>),
1060    RefDecl(Node<RefDecl>),
1061    Bind(Node<Bind>),
1062    Flow(Node<Flow>),
1063    FirstStmt(Node<FirstStmt>),
1064    MergeStmt(Node<MergeStmt>),
1065    StateUsage(Node<StateUsage>),
1066    ActionUsage(Box<Node<ActionUsage>>),
1067    Assign(Node<AssignStmt>),
1068    ForLoop(Node<ForLoop>),
1069    ThenAction(Node<ThenAction>),
1070    Decl(Node<ActionBodyDecl>),
1071}
1072
1073/// A minimally-modeled declaration inside an action/behavior body (e.g. `attribute ...;`, `calc ...;`).
1074#[derive(Debug, Clone, PartialEq, Eq)]
1075pub struct ActionBodyDecl {
1076    pub keyword: String,
1077    pub text: String,
1078}
1079
1080/// Flow: `flow` from `to` to body.
1081#[derive(Debug, Clone, PartialEq, Eq)]
1082pub struct Flow {
1083    pub from: Node<Expression>,
1084    pub to: Node<Expression>,
1085    pub body: ConnectBody,
1086}
1087
1088/// Flow definition: `flow def` Identification body.
1089#[derive(Debug, Clone, PartialEq, Eq)]
1090pub struct FlowDef {
1091    pub identification: Identification,
1092    pub specializes: Option<String>,
1093    pub specializes_span: Option<Span>,
1094    pub body: DefinitionBody,
1095}
1096
1097/// Flow usage: `flow` name (`:` type)? [`from` expr `to` expr]? body.
1098#[derive(Debug, Clone, PartialEq, Eq)]
1099pub struct FlowUsage {
1100    pub name: String,
1101    pub type_name: Option<String>,
1102    pub from: Option<Node<Expression>>,
1103    pub to: Option<Node<Expression>>,
1104    pub body: DefinitionBody,
1105}
1106
1107/// First/then control flow: `first` expr `then` expr body.
1108#[derive(Debug, Clone, PartialEq, Eq)]
1109pub struct FirstStmt {
1110    pub first: Node<Expression>,
1111    pub then: Node<Expression>,
1112    pub body: FirstMergeBody,
1113}
1114
1115/// Merge: `merge` expr body.
1116#[derive(Debug, Clone, PartialEq, Eq)]
1117pub struct MergeStmt {
1118    pub merge: Node<Expression>,
1119    pub body: FirstMergeBody,
1120}
1121
1122/// Body of first/merge: `;` or `{` ... `}`.
1123#[derive(Debug, Clone, PartialEq, Eq)]
1124pub enum FirstMergeBody {
1125    Semicolon,
1126    Brace,
1127}
1128
1129// ---------------------------------------------------------------------------
1130// Allocation
1131// ---------------------------------------------------------------------------
1132
1133/// Allocate statement at part usage level: `allocate` from `to` to body.
1134#[derive(Debug, Clone, PartialEq, Eq)]
1135pub struct Allocate {
1136    pub source: Node<Expression>,
1137    pub target: Node<Expression>,
1138    pub body: ConnectBody,
1139}
1140
1141/// Allocation definition: `allocation def` Identification body.
1142#[derive(Debug, Clone, PartialEq, Eq)]
1143pub struct AllocationDef {
1144    pub identification: Identification,
1145    pub specializes: Option<String>,
1146    pub specializes_span: Option<Span>,
1147    pub body: DefinitionBody,
1148}
1149
1150/// Allocation usage: `allocation` name (`:` type)? [`allocate` source `to` target]? body.
1151#[derive(Debug, Clone, PartialEq, Eq)]
1152pub struct AllocationUsage {
1153    pub name: String,
1154    pub type_name: Option<String>,
1155    pub source: Option<Node<Expression>>,
1156    pub target: Option<Node<Expression>>,
1157    pub body: DefinitionBody,
1158}
1159
1160// ---------------------------------------------------------------------------
1161// Requirements
1162// ---------------------------------------------------------------------------
1163
1164/// Requirement definition: `requirement def` Identification (`:>` specializes)? body.
1165#[derive(Debug, Clone, PartialEq, Eq)]
1166pub struct RequirementDef {
1167    pub identification: Identification,
1168    /// Supertype after `:>`, e.g. Some("UserRequirement") for `requirement def Need :> UserRequirement`.
1169    pub specializes: Option<String>,
1170    /// Span of the `:> <type>` fragment (for semantic tokens), when present.
1171    pub specializes_span: Option<Span>,
1172    pub body: RequirementDefBody,
1173}
1174
1175/// Body of an requirement definition: `;` or `{` RequirementDefBodyElement* `}`.
1176#[derive(Debug, Clone, PartialEq, Eq)]
1177pub enum RequirementDefBody {
1178    Semicolon,
1179    Brace {
1180        elements: Vec<Node<RequirementDefBodyElement>>,
1181    },
1182}
1183
1184#[derive(Debug, Clone, PartialEq, Eq)]
1185pub enum RequirementDefBodyElement {
1186    Error(Node<ParseErrorNode>),
1187    /// Unmodeled requirement-body element captured as raw text (used for library parsing).
1188    Other(String),
1189    Annotation(Node<Annotation>),
1190    Import(Node<Import>),
1191    SubjectDecl(Node<SubjectDecl>),
1192    AttributeDef(Node<AttributeDef>),
1193    AttributeUsage(Node<AttributeUsage>),
1194    VerifyRequirement(Node<VerifyRequirementMember>),
1195    RequireConstraint(Node<RequireConstraint>),
1196    Frame(Node<FrameMember>),
1197    Doc(Node<DocComment>),
1198}
1199
1200/// Subject declaration: `subject` name `:` type `;`.
1201#[derive(Debug, Clone, PartialEq, Eq)]
1202pub struct SubjectDecl {
1203    pub name: String,
1204    pub type_name: String,
1205}
1206
1207/// Require constraint: `require constraint { ... }`.
1208#[derive(Debug, Clone, PartialEq, Eq)]
1209pub struct RequireConstraint {
1210    pub body: RequireConstraintBody,
1211}
1212
1213/// Requirement verification usage in requirement/objective bodies:
1214/// `verify requirement <...>` or shorthand `verify <qualified_name>;`.
1215#[derive(Debug, Clone, PartialEq, Eq)]
1216pub struct VerifyRequirementMember {
1217    /// True for `verify requirement ...`; false for shorthand `verify ...;`.
1218    pub explicit_requirement_keyword: bool,
1219    /// Parsed requirement usage when explicit form is used.
1220    pub requirement: Option<Node<RequirementUsage>>,
1221    /// Shorthand verified requirement reference (`verify QualifiedName;`).
1222    pub target: Option<String>,
1223}
1224
1225/// Require constraint body: `;` or `{` ConstraintDefBodyElement* `}`.
1226#[derive(Debug, Clone, PartialEq, Eq)]
1227pub enum RequireConstraintBody {
1228    Semicolon,
1229    Brace {
1230        elements: Vec<Node<ConstraintDefBodyElement>>,
1231    },
1232}
1233
1234/// Requirement usage / Satisfy. Example: `satisfy EnduranceReq by droneInstance;`
1235#[derive(Debug, Clone, PartialEq, Eq)]
1236pub struct Satisfy {
1237    pub source: Node<Expression>,
1238    pub target: Node<Expression>,
1239    pub body: ConnectBody,
1240}
1241
1242/// Bare requirement Usage.
1243#[derive(Debug, Clone, PartialEq, Eq)]
1244pub struct RequirementUsage {
1245    pub name: String,
1246    pub type_name: Option<String>,
1247    pub subsets: Option<String>,
1248    pub body: RequirementDefBody,
1249}
1250
1251/// Dependency: `dependency` (Identification `from`)? client(s) `to` supplier(s) RelationshipBody.
1252#[derive(Debug, Clone, PartialEq, Eq)]
1253pub struct Dependency {
1254    pub identification: Option<Identification>,
1255    pub clients: Vec<String>,
1256    pub suppliers: Vec<String>,
1257    pub body: ConnectBody,
1258}
1259
1260/// Framed concern member in requirement body: `frame` name (`;` or body).
1261#[derive(Debug, Clone, PartialEq, Eq)]
1262pub struct FrameMember {
1263    pub name: String,
1264    pub body: RequirementDefBody,
1265}
1266
1267/// Concern usage at package level: `concern` name (`:` type)? RequirementBody.
1268#[derive(Debug, Clone, PartialEq, Eq)]
1269pub struct ConcernUsage {
1270    pub name: String,
1271    pub type_name: Option<String>,
1272    pub body: RequirementDefBody,
1273}
1274
1275/// Case definition: `case def` Identification body.
1276#[derive(Debug, Clone, PartialEq, Eq)]
1277pub struct CaseDef {
1278    pub identification: Identification,
1279    pub specializes: Option<String>,
1280    pub specializes_span: Option<Span>,
1281    pub body: UseCaseDefBody,
1282}
1283
1284/// Case usage: `case` name (`:` type)? body.
1285#[derive(Debug, Clone, PartialEq, Eq)]
1286pub struct CaseUsage {
1287    pub name: String,
1288    pub type_name: Option<String>,
1289    pub body: UseCaseDefBody,
1290}
1291
1292/// Analysis case definition: `analysis def` Identification body.
1293#[derive(Debug, Clone, PartialEq, Eq)]
1294pub struct AnalysisCaseDef {
1295    pub identification: Identification,
1296    pub specializes: Option<String>,
1297    pub specializes_span: Option<Span>,
1298    pub body: UseCaseDefBody,
1299}
1300
1301/// Analysis case usage: `analysis` name (`:` type)? body.
1302#[derive(Debug, Clone, PartialEq, Eq)]
1303pub struct AnalysisCaseUsage {
1304    pub name: String,
1305    pub type_name: Option<String>,
1306    pub body: UseCaseDefBody,
1307}
1308
1309/// Verification case definition: `verification def` Identification body.
1310#[derive(Debug, Clone, PartialEq, Eq)]
1311pub struct VerificationCaseDef {
1312    pub identification: Identification,
1313    pub specializes: Option<String>,
1314    pub specializes_span: Option<Span>,
1315    pub body: UseCaseDefBody,
1316}
1317
1318/// Verification case usage: `verification` name (`:` type)? body.
1319#[derive(Debug, Clone, PartialEq, Eq)]
1320pub struct VerificationCaseUsage {
1321    pub name: String,
1322    pub type_name: Option<String>,
1323    pub body: UseCaseDefBody,
1324}
1325
1326/// Use case usage at package level: `use case` name (`:` type)? CaseBody.
1327#[derive(Debug, Clone, PartialEq, Eq)]
1328pub struct UseCaseUsage {
1329    pub name: String,
1330    pub type_name: Option<String>,
1331    pub body: UseCaseDefBody,
1332}
1333
1334// ---------------------------------------------------------------------------
1335// Use Cases
1336// ---------------------------------------------------------------------------
1337
1338/// Actor declaration: `actor` Identification `;`.
1339#[derive(Debug, Clone, PartialEq, Eq)]
1340pub struct ActorDecl {
1341    pub identification: Identification,
1342}
1343
1344/// Use Case definition: `use case def` Identification body.
1345#[derive(Debug, Clone, PartialEq, Eq)]
1346pub struct UseCaseDef {
1347    pub identification: Identification,
1348    pub specializes: Option<String>,
1349    pub specializes_span: Option<Span>,
1350    pub body: UseCaseDefBody,
1351}
1352
1353#[derive(Debug, Clone, PartialEq, Eq)]
1354pub enum UseCaseDefBody {
1355    Semicolon,
1356    Brace {
1357        elements: Vec<Node<UseCaseDefBodyElement>>,
1358    },
1359}
1360
1361/// `first <name>;` inside a case/use-case body (used in SysML v2 release fixtures).
1362#[derive(Debug, Clone, PartialEq, Eq)]
1363pub struct FirstSuccession {
1364    pub target: String,
1365}
1366
1367/// `then done;` inside a case/use-case body.
1368#[derive(Debug, Clone, PartialEq, Eq)]
1369pub struct ThenDone {}
1370
1371/// `include <usecase> ...` inside a case/use-case body.
1372#[derive(Debug, Clone, PartialEq, Eq)]
1373pub struct IncludeUseCase {
1374    pub name: String,
1375    /// Optional multiplicity suffix like `[0..*]` captured as raw text including brackets.
1376    pub multiplicity: Option<String>,
1377    pub body: UseCaseDefBody,
1378}
1379
1380/// `then include <usecase> ...` inside a case/use-case body.
1381#[derive(Debug, Clone, PartialEq, Eq)]
1382pub struct ThenIncludeUseCase {
1383    pub include: Node<IncludeUseCase>,
1384}
1385
1386/// `then use case <name> ...` inside a case/use-case body.
1387#[derive(Debug, Clone, PartialEq, Eq)]
1388pub struct ThenUseCaseUsage {
1389    pub use_case: Node<UseCaseUsage>,
1390}
1391
1392/// `subject;` shorthand used in SysML v2 release fixtures (subject of an enclosing case/use case).
1393#[derive(Debug, Clone, PartialEq, Eq)]
1394pub struct SubjectRef {}
1395
1396/// `actor :>> <name> = <expr>;` redefinition/assignment used in SysML v2 release fixtures.
1397#[derive(Debug, Clone, PartialEq, Eq)]
1398pub struct ActorRedefinitionAssignment {
1399    pub name: String,
1400    /// Raw RHS expression text up to `;` (we don't model the expression grammar here yet).
1401    pub rhs: String,
1402}
1403
1404/// `ref :>> <name> { ... }` redefinition used in SysML v2 release fixtures.
1405#[derive(Debug, Clone, PartialEq, Eq)]
1406pub struct RefRedefinition {
1407    pub name: String,
1408    /// Raw body text for now (balanced `{ ... }` including nested braces).
1409    pub body: String,
1410}
1411
1412/// `return ref <name><multiplicity?> { ... }` used in SysML v2 release libraries.
1413#[derive(Debug, Clone, PartialEq, Eq)]
1414pub struct ReturnRef {
1415    pub name: String,
1416    pub multiplicity: Option<String>,
1417    /// Raw body text for now (balanced `{ ... }` including nested braces).
1418    pub body: String,
1419}
1420
1421#[derive(Debug, Clone, PartialEq, Eq)]
1422pub enum UseCaseDefBodyElement {
1423    Error(Node<ParseErrorNode>),
1424    /// Unmodeled use-case / analysis-case body element captured as raw text (used for library parsing).
1425    Other(String),
1426    AttributeDef(Node<AttributeDef>),
1427    Doc(Node<DocComment>),
1428    SubjectDecl(Node<SubjectDecl>),
1429    /// `subject;` shorthand.
1430    SubjectRef(Node<SubjectRef>),
1431    ActorUsage(Node<ActorUsage>),
1432    ActorRedefinitionAssignment(Node<ActorRedefinitionAssignment>),
1433    Objective(Node<Objective>),
1434    FirstSuccession(Node<FirstSuccession>),
1435    ThenIncludeUseCase(Node<ThenIncludeUseCase>),
1436    ThenUseCaseUsage(Node<ThenUseCaseUsage>),
1437    ThenDone(Node<ThenDone>),
1438    IncludeUseCase(Node<IncludeUseCase>),
1439    RefRedefinition(Node<RefRedefinition>),
1440    ReturnRef(Node<ReturnRef>),
1441    Assign(Node<AssignStmt>),
1442    ForLoop(Node<ForLoop>),
1443    ThenAction(Node<ThenAction>),
1444}
1445
1446/// actor usage `actor pilot : Operator;`
1447#[derive(Debug, Clone, PartialEq, Eq)]
1448pub struct ActorUsage {
1449    pub name: String,
1450    pub type_name: String,
1451}
1452
1453/// Objective `objective { doc ... }`
1454#[derive(Debug, Clone, PartialEq, Eq)]
1455pub struct Objective {
1456    pub visibility: Option<Visibility>,
1457    pub requirement: Node<RequirementUsage>,
1458}
1459
1460// ---------------------------------------------------------------------------
1461// State Machine
1462// ---------------------------------------------------------------------------
1463
1464/// State definition: `state def` Identification body.
1465#[derive(Debug, Clone, PartialEq, Eq)]
1466pub struct StateDef {
1467    pub identification: Identification,
1468    pub specializes: Option<String>,
1469    pub specializes_span: Option<Span>,
1470    pub body: StateDefBody,
1471}
1472
1473#[derive(Debug, Clone, PartialEq, Eq)]
1474pub enum StateDefBody {
1475    Semicolon,
1476    Brace {
1477        elements: Vec<Node<StateDefBodyElement>>,
1478    },
1479}
1480
1481#[derive(Debug, Clone, PartialEq, Eq)]
1482pub enum StateDefBodyElement {
1483    Error(Node<ParseErrorNode>),
1484    Doc(Node<DocComment>),
1485    Annotation(Node<Annotation>),
1486    Other(String),
1487    /// `entry` (`;` or body) - entry action.
1488    Entry(Node<EntryAction>),
1489    /// `then` name `;` - initial state.
1490    Then(Node<ThenStmt>),
1491    /// `ref` name `:` type body – reference binding in state.
1492    Ref(Node<RefDecl>),
1493    RequirementUsage(Node<RequirementUsage>),
1494    StateUsage(Node<StateUsage>),
1495    Transition(Node<Transition>),
1496}
1497
1498/// Entry action: `entry` (`;` or body).
1499#[derive(Debug, Clone, PartialEq, Eq)]
1500pub struct EntryAction {
1501    /// For `entry action name body` form; None for plain `entry` body.
1502    pub action_name: Option<String>,
1503    pub body: StateDefBody,
1504}
1505
1506/// Then (initial state): `then` name `;`
1507#[derive(Debug, Clone, PartialEq, Eq)]
1508pub struct ThenStmt {
1509    pub state_name: String,
1510}
1511
1512/// State usage: `state` name (`:` type)? body.
1513#[derive(Debug, Clone, PartialEq, Eq)]
1514pub struct StateUsage {
1515    pub name: String,
1516    pub type_name: Option<String>,
1517    pub body: StateDefBody,
1518}
1519
1520/// Transition: `transition` name [`first` source] [`if` guard] [`do` effect] `then` target body.
1521#[derive(Debug, Clone, PartialEq, Eq)]
1522pub struct Transition {
1523    pub name: Option<String>,
1524    /// If omitted, form is `transition name then target;`.
1525    pub source: Option<Node<Expression>>,
1526    pub guard: Option<Node<Expression>>,
1527    pub effect: Option<Node<Expression>>,
1528    pub target: Node<Expression>,
1529    pub body: ConnectBody,
1530}
1531
1532// ---------------------------------------------------------------------------
1533// Constraints & Calculations
1534// ---------------------------------------------------------------------------
1535
1536/// Constraint definition: `constraint def` Identification body.
1537#[derive(Debug, Clone, PartialEq, Eq)]
1538pub struct ConstraintDef {
1539    pub identification: Identification,
1540    pub specializes: Option<String>,
1541    pub specializes_span: Option<Span>,
1542    pub body: ConstraintDefBody,
1543}
1544
1545#[derive(Debug, Clone, PartialEq, Eq)]
1546pub enum ConstraintDefBody {
1547    Semicolon,
1548    Brace {
1549        elements: Vec<Node<ConstraintDefBodyElement>>,
1550    },
1551}
1552
1553#[derive(Debug, Clone, PartialEq, Eq)]
1554pub enum ConstraintDefBodyElement {
1555    Error(Node<ParseErrorNode>),
1556    Doc(Node<DocComment>),
1557    InOutDecl(Node<InOutDecl>),
1558    Expression(Node<Expression>), // e.g. totalThrust >= totalWeight * margin
1559    /// Unmodeled constraint-body element captured as raw text (used for library parsing).
1560    Other(String),
1561}
1562
1563/// constraint body {}
1564#[derive(Debug, Clone, PartialEq, Eq)]
1565pub enum ConstraintBody {
1566    Semicolon,
1567    Brace, // Often contains docs or block of expressions
1568}
1569
1570/// KerML Documentation: 'doc' Identification? ( 'locale' STRING_VALUE )? body = REGULAR_COMMENT.
1571#[derive(Debug, Clone, PartialEq, Eq)]
1572pub struct DocComment {
1573    /// Optional identification after 'doc'.
1574    pub identification: Option<Identification>,
1575    /// Optional locale string (e.g. "en").
1576    pub locale: Option<String>,
1577    /// Body text (content between /* and */).
1578    pub text: String,
1579}
1580
1581/// KerML Comment: ( 'comment' Identification? )? ( 'locale' STRING_VALUE )? body = REGULAR_COMMENT.
1582#[derive(Debug, Clone, PartialEq, Eq)]
1583pub struct CommentAnnotation {
1584    pub identification: Option<Identification>,
1585    pub locale: Option<String>,
1586    pub text: String,
1587}
1588
1589/// KerML TextualRepresentation: ( 'rep' Identification )? 'language' STRING_VALUE body.
1590#[derive(Debug, Clone, PartialEq, Eq)]
1591pub struct TextualRepresentation {
1592    pub rep_identification: Option<Identification>,
1593    pub language: String,
1594    pub text: String,
1595}
1596
1597/// Calc definition: `calc def` Identification body.
1598#[derive(Debug, Clone, PartialEq, Eq)]
1599pub struct CalcDef {
1600    pub identification: Identification,
1601    pub body: CalcDefBody,
1602}
1603
1604#[derive(Debug, Clone, PartialEq, Eq)]
1605pub enum CalcDefBody {
1606    Semicolon,
1607    Brace {
1608        elements: Vec<Node<CalcDefBodyElement>>,
1609    },
1610}
1611
1612#[derive(Debug, Clone, PartialEq, Eq)]
1613pub enum CalcDefBodyElement {
1614    Error(Node<ParseErrorNode>),
1615    Doc(Node<DocComment>),
1616    InOutDecl(Node<InOutDecl>),
1617    ReturnDecl(Node<ReturnDecl>),
1618    Expression(Node<Expression>), // formula
1619    /// Unmodeled calc-body element captured as raw text (used for library parsing).
1620    Other(String),
1621}
1622
1623/// Return declaration: `return` name `:` type `;`.
1624#[derive(Debug, Clone, PartialEq, Eq)]
1625pub struct ReturnDecl {
1626    pub name: String,
1627    pub type_name: String,
1628}
1629
1630// ---------------------------------------------------------------------------
1631// Views and Viewpoints (SysML v2 Clause 8.2.2.26)
1632// ---------------------------------------------------------------------------
1633
1634/// View definition: `view def` Identification ViewDefinitionBody.
1635#[derive(Debug, Clone, PartialEq, Eq)]
1636pub struct ViewDef {
1637    pub identification: Identification,
1638    pub specializes: Option<String>,
1639    pub specializes_span: Option<Span>,
1640    pub body: ViewDefBody,
1641}
1642
1643#[derive(Debug, Clone, PartialEq, Eq)]
1644pub enum ViewDefBody {
1645    Semicolon,
1646    Brace {
1647        elements: Vec<Node<ViewDefBodyElement>>,
1648    },
1649}
1650
1651#[derive(Debug, Clone, PartialEq, Eq)]
1652pub enum ViewDefBodyElement {
1653    Error(Node<ParseErrorNode>),
1654    /// Unmodeled view-definition body element captured as raw text (used for library parsing).
1655    Other(String),
1656    Doc(Node<DocComment>),
1657    Filter(Node<FilterMember>),
1658    ViewRendering(Node<ViewRenderingUsage>),
1659}
1660
1661/// View rendering usage: `render` name `:` type (`;` or body).
1662#[derive(Debug, Clone, PartialEq, Eq)]
1663pub struct ViewRenderingUsage {
1664    pub name: String,
1665    pub type_name: Option<String>,
1666    pub body: ConnectBody,
1667}
1668
1669/// Viewpoint definition: `viewpoint def` Identification RequirementBody.
1670#[derive(Debug, Clone, PartialEq, Eq)]
1671pub struct ViewpointDef {
1672    pub identification: Identification,
1673    pub specializes: Option<String>,
1674    pub specializes_span: Option<Span>,
1675    pub body: RequirementDefBody,
1676}
1677
1678/// Rendering definition: `rendering def` Definition.
1679#[derive(Debug, Clone, PartialEq, Eq)]
1680pub struct RenderingDef {
1681    pub identification: Identification,
1682    pub specializes: Option<String>,
1683    pub specializes_span: Option<Span>,
1684    pub body: RenderingDefBody,
1685}
1686
1687#[derive(Debug, Clone, PartialEq, Eq)]
1688pub enum RenderingDefBody {
1689    Semicolon,
1690    Brace {
1691        elements: Vec<Node<RenderingDefBodyElement>>,
1692    },
1693}
1694
1695#[derive(Debug, Clone, PartialEq, Eq)]
1696pub enum RenderingDefBodyElement {
1697    Error(Node<ParseErrorNode>),
1698    Doc(Node<DocComment>),
1699    Filter(Node<FilterMember>),
1700    ViewRendering(Node<ViewRenderingUsage>),
1701    Other(String),
1702}
1703
1704/// View usage: `view` name `:` type? ViewBody.
1705#[derive(Debug, Clone, PartialEq, Eq)]
1706pub struct ViewUsage {
1707    pub name: String,
1708    pub type_name: Option<String>,
1709    pub body: ViewBody,
1710}
1711
1712#[derive(Debug, Clone, PartialEq, Eq)]
1713pub enum ViewBody {
1714    Semicolon,
1715    Brace {
1716        elements: Vec<Node<ViewBodyElement>>,
1717    },
1718}
1719
1720#[derive(Debug, Clone, PartialEq, Eq)]
1721pub enum ViewBodyElement {
1722    Error(Node<ParseErrorNode>),
1723    /// Unmodeled view body element captured as raw text (used for library parsing).
1724    Other(String),
1725    Doc(Node<DocComment>),
1726    Filter(Node<FilterMember>),
1727    ViewRendering(Node<ViewRenderingUsage>),
1728    Expose(Node<ExposeMember>),
1729    Satisfy(Node<SatisfyViewMember>),
1730}
1731
1732/// Expose in view body: `expose` (MembershipImport | NamespaceImport) RelationshipBody.
1733#[derive(Debug, Clone, PartialEq, Eq)]
1734pub struct ExposeMember {
1735    /// Full target path (e.g. vehicle, vehicle::*, vehicle::*::**, SystemModel::vehicle::**).
1736    pub target: String,
1737    pub body: ConnectBody,
1738}
1739
1740/// Satisfy in view body: `satisfy` QualifiedName RelationshipBody.
1741#[derive(Debug, Clone, PartialEq, Eq)]
1742pub struct SatisfyViewMember {
1743    pub viewpoint_ref: String,
1744    pub body: ConnectBody,
1745}
1746
1747/// Viewpoint usage: `viewpoint` ConstraintUsageDeclaration RequirementBody.
1748#[derive(Debug, Clone, PartialEq, Eq)]
1749pub struct ViewpointUsage {
1750    pub name: String,
1751    pub type_name: String,
1752    pub body: RequirementDefBody,
1753}
1754
1755/// Rendering usage: `rendering` Usage.
1756#[derive(Debug, Clone, PartialEq, Eq)]
1757pub struct RenderingUsage {
1758    pub name: String,
1759    pub type_name: Option<String>,
1760    pub body: ConnectBody,
1761}
1762
1763// ---------------------------------------------------------------------------
1764// Normalization for test comparison (strips optional spans so parsed == expected)
1765// ---------------------------------------------------------------------------
1766
1767impl RootNamespace {
1768    /// Returns a copy with all optional source spans set to `None` and all `Node` spans set to
1769    /// `Span::dummy()`. Use when comparing parser output to hand-built expected AST in tests.
1770    pub fn normalize_for_test_comparison(&self) -> Self {
1771        RootNamespace {
1772            elements: self
1773                .elements
1774                .iter()
1775                .map(normalize_root_element_node)
1776                .collect(),
1777        }
1778    }
1779}
1780
1781fn dummy_node<T: Clone>(_n: &Node<T>, value: T) -> Node<T> {
1782    Node::new(Span::dummy(), value)
1783}
1784
1785fn normalize_root_element_node(el: &Node<RootElement>) -> Node<RootElement> {
1786    let value = match &el.value {
1787        RootElement::Package(p) => RootElement::Package(dummy_node(p, normalize_package(&p.value))),
1788        RootElement::LibraryPackage(lp) => {
1789            RootElement::LibraryPackage(dummy_node(lp, normalize_library_package(&lp.value)))
1790        }
1791        RootElement::Namespace(n) => {
1792            RootElement::Namespace(dummy_node(n, normalize_namespace_decl(&n.value)))
1793        }
1794        RootElement::Import(n) => RootElement::Import(dummy_node(n, n.value.clone())),
1795    };
1796    dummy_node(el, value)
1797}
1798
1799fn normalize_library_package(lp: &LibraryPackage) -> LibraryPackage {
1800    LibraryPackage {
1801        is_standard: lp.is_standard,
1802        identification: lp.identification.clone(),
1803        body: normalize_package_body(&lp.body),
1804    }
1805}
1806
1807fn normalize_namespace_decl(n: &NamespaceDecl) -> NamespaceDecl {
1808    NamespaceDecl {
1809        identification: n.identification.clone(),
1810        body: normalize_package_body(&n.body),
1811    }
1812}
1813
1814fn normalize_package(p: &Package) -> Package {
1815    Package {
1816        identification: p.identification.clone(),
1817        body: normalize_package_body(&p.body),
1818    }
1819}
1820
1821fn normalize_package_body(b: &PackageBody) -> PackageBody {
1822    match b {
1823        PackageBody::Semicolon => PackageBody::Semicolon,
1824        PackageBody::Brace { elements } => PackageBody::Brace {
1825            elements: elements
1826                .iter()
1827                .map(normalize_package_body_element_node)
1828                .collect(),
1829        },
1830    }
1831}
1832
1833fn normalize_package_body_element_node(el: &Node<PackageBodyElement>) -> Node<PackageBodyElement> {
1834    let value = match &el.value {
1835        PackageBodyElement::Error(n) => PackageBodyElement::Error(dummy_node(n, n.value.clone())),
1836        PackageBodyElement::Doc(n) => PackageBodyElement::Doc(dummy_node(n, n.value.clone())),
1837        PackageBodyElement::Comment(n) => {
1838            PackageBodyElement::Comment(dummy_node(n, n.value.clone()))
1839        }
1840        PackageBodyElement::TextualRep(n) => {
1841            PackageBodyElement::TextualRep(dummy_node(n, n.value.clone()))
1842        }
1843        PackageBodyElement::Filter(n) => PackageBodyElement::Filter(dummy_node(n, n.value.clone())),
1844        PackageBodyElement::Package(n) => {
1845            PackageBodyElement::Package(dummy_node(n, normalize_package(&n.value)))
1846        }
1847        PackageBodyElement::LibraryPackage(n) => {
1848            PackageBodyElement::LibraryPackage(dummy_node(n, normalize_library_package(&n.value)))
1849        }
1850        PackageBodyElement::Import(n) => PackageBodyElement::Import(dummy_node(n, n.value.clone())),
1851        PackageBodyElement::PartDef(n) => {
1852            PackageBodyElement::PartDef(dummy_node(n, normalize_part_def(&n.value)))
1853        }
1854        PackageBodyElement::PartUsage(n) => {
1855            PackageBodyElement::PartUsage(dummy_node(n, normalize_part_usage(&n.value)))
1856        }
1857        PackageBodyElement::PortDef(n) => {
1858            PackageBodyElement::PortDef(dummy_node(n, normalize_port_def(&n.value)))
1859        }
1860        PackageBodyElement::InterfaceDef(n) => {
1861            PackageBodyElement::InterfaceDef(dummy_node(n, normalize_interface_def(&n.value)))
1862        }
1863        PackageBodyElement::ConnectionDef(n) => {
1864            PackageBodyElement::ConnectionDef(dummy_node(n, normalize_connection_def(&n.value)))
1865        }
1866        PackageBodyElement::MetadataDef(n) => {
1867            PackageBodyElement::MetadataDef(dummy_node(n, normalize_metadata_def(&n.value)))
1868        }
1869        PackageBodyElement::EnumDef(n) => {
1870            PackageBodyElement::EnumDef(dummy_node(n, normalize_enum_def(&n.value)))
1871        }
1872        PackageBodyElement::OccurrenceDef(n) => {
1873            PackageBodyElement::OccurrenceDef(dummy_node(n, normalize_occurrence_def(&n.value)))
1874        }
1875        PackageBodyElement::OccurrenceUsage(n) => {
1876            PackageBodyElement::OccurrenceUsage(dummy_node(n, n.value.clone()))
1877        }
1878        PackageBodyElement::AliasDef(n) => {
1879            PackageBodyElement::AliasDef(dummy_node(n, n.value.clone()))
1880        }
1881        PackageBodyElement::AttributeDef(n) => {
1882            PackageBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
1883        }
1884        PackageBodyElement::ActionDef(n) => {
1885            PackageBodyElement::ActionDef(dummy_node(n, normalize_action_def(&n.value)))
1886        }
1887        PackageBodyElement::ActionUsage(n) => {
1888            PackageBodyElement::ActionUsage(dummy_node(n, normalize_action_usage(&n.value)))
1889        }
1890        PackageBodyElement::RequirementDef(n) => {
1891            PackageBodyElement::RequirementDef(dummy_node(n, n.value.clone()))
1892        }
1893        PackageBodyElement::RequirementUsage(n) => {
1894            PackageBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
1895        }
1896        PackageBodyElement::Satisfy(n) => {
1897            PackageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
1898        }
1899        PackageBodyElement::UseCaseDef(n) => {
1900            PackageBodyElement::UseCaseDef(dummy_node(n, n.value.clone()))
1901        }
1902        PackageBodyElement::Actor(n) => PackageBodyElement::Actor(dummy_node(n, n.value.clone())),
1903        PackageBodyElement::StateDef(n) => {
1904            PackageBodyElement::StateDef(dummy_node(n, n.value.clone()))
1905        }
1906        PackageBodyElement::StateUsage(n) => {
1907            PackageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
1908        }
1909        PackageBodyElement::ItemDef(n) => {
1910            PackageBodyElement::ItemDef(dummy_node(n, n.value.clone()))
1911        }
1912        PackageBodyElement::IndividualDef(n) => {
1913            PackageBodyElement::IndividualDef(dummy_node(n, n.value.clone()))
1914        }
1915        PackageBodyElement::ConstraintDef(n) => {
1916            PackageBodyElement::ConstraintDef(dummy_node(n, n.value.clone()))
1917        }
1918        PackageBodyElement::CalcDef(n) => {
1919            PackageBodyElement::CalcDef(dummy_node(n, n.value.clone()))
1920        }
1921        PackageBodyElement::ViewDef(n) => {
1922            PackageBodyElement::ViewDef(dummy_node(n, n.value.clone()))
1923        }
1924        PackageBodyElement::ViewpointDef(n) => {
1925            PackageBodyElement::ViewpointDef(dummy_node(n, n.value.clone()))
1926        }
1927        PackageBodyElement::RenderingDef(n) => {
1928            PackageBodyElement::RenderingDef(dummy_node(n, n.value.clone()))
1929        }
1930        PackageBodyElement::ViewUsage(n) => {
1931            PackageBodyElement::ViewUsage(dummy_node(n, n.value.clone()))
1932        }
1933        PackageBodyElement::ViewpointUsage(n) => {
1934            PackageBodyElement::ViewpointUsage(dummy_node(n, n.value.clone()))
1935        }
1936        PackageBodyElement::RenderingUsage(n) => {
1937            PackageBodyElement::RenderingUsage(dummy_node(n, n.value.clone()))
1938        }
1939        PackageBodyElement::Dependency(n) => {
1940            PackageBodyElement::Dependency(dummy_node(n, n.value.clone()))
1941        }
1942        PackageBodyElement::AllocationDef(n) => {
1943            PackageBodyElement::AllocationDef(dummy_node(n, n.value.clone()))
1944        }
1945        PackageBodyElement::AllocationUsage(n) => {
1946            PackageBodyElement::AllocationUsage(dummy_node(n, n.value.clone()))
1947        }
1948        PackageBodyElement::FlowDef(n) => {
1949            PackageBodyElement::FlowDef(dummy_node(n, n.value.clone()))
1950        }
1951        PackageBodyElement::FlowUsage(n) => {
1952            PackageBodyElement::FlowUsage(dummy_node(n, n.value.clone()))
1953        }
1954        PackageBodyElement::ConcernUsage(n) => {
1955            PackageBodyElement::ConcernUsage(dummy_node(n, n.value.clone()))
1956        }
1957        PackageBodyElement::CaseDef(n) => {
1958            PackageBodyElement::CaseDef(dummy_node(n, n.value.clone()))
1959        }
1960        PackageBodyElement::CaseUsage(n) => {
1961            PackageBodyElement::CaseUsage(dummy_node(n, n.value.clone()))
1962        }
1963        PackageBodyElement::AnalysisCaseDef(n) => {
1964            PackageBodyElement::AnalysisCaseDef(dummy_node(n, n.value.clone()))
1965        }
1966        PackageBodyElement::AnalysisCaseUsage(n) => {
1967            PackageBodyElement::AnalysisCaseUsage(dummy_node(n, n.value.clone()))
1968        }
1969        PackageBodyElement::VerificationCaseDef(n) => {
1970            PackageBodyElement::VerificationCaseDef(dummy_node(n, n.value.clone()))
1971        }
1972        PackageBodyElement::VerificationCaseUsage(n) => {
1973            PackageBodyElement::VerificationCaseUsage(dummy_node(n, n.value.clone()))
1974        }
1975        PackageBodyElement::UseCaseUsage(n) => {
1976            PackageBodyElement::UseCaseUsage(dummy_node(n, n.value.clone()))
1977        }
1978        PackageBodyElement::FeatureDecl(n) => {
1979            PackageBodyElement::FeatureDecl(dummy_node(n, n.value.clone()))
1980        }
1981        PackageBodyElement::ClassifierDecl(n) => {
1982            PackageBodyElement::ClassifierDecl(dummy_node(n, n.value.clone()))
1983        }
1984        PackageBodyElement::KermlSemanticDecl(n) => {
1985            PackageBodyElement::KermlSemanticDecl(dummy_node(n, n.value.clone()))
1986        }
1987        PackageBodyElement::KermlFeatureDecl(n) => {
1988            PackageBodyElement::KermlFeatureDecl(dummy_node(n, n.value.clone()))
1989        }
1990        PackageBodyElement::ExtendedLibraryDecl(n) => {
1991            PackageBodyElement::ExtendedLibraryDecl(dummy_node(n, n.value.clone()))
1992        }
1993    };
1994    dummy_node(el, value)
1995}
1996
1997fn normalize_attribute_def(a: &AttributeDef) -> AttributeDef {
1998    AttributeDef {
1999        name: a.name.clone(),
2000        typing: a.typing.clone(),
2001        value: a.value.clone(),
2002        body: a.body.clone(),
2003        name_span: None,
2004        typing_span: None,
2005    }
2006}
2007
2008fn normalize_part_def(p: &PartDef) -> PartDef {
2009    PartDef {
2010        definition_prefix: p.definition_prefix.clone(),
2011        is_individual: p.is_individual,
2012        identification: p.identification.clone(),
2013        specializes: p.specializes.clone(),
2014        specializes_span: None,
2015        body: normalize_part_def_body(&p.body),
2016    }
2017}
2018
2019fn normalize_part_def_body(b: &PartDefBody) -> PartDefBody {
2020    match b {
2021        PartDefBody::Semicolon => PartDefBody::Semicolon,
2022        PartDefBody::Brace { elements } => PartDefBody::Brace {
2023            elements: elements
2024                .iter()
2025                .map(normalize_part_def_body_element_node)
2026                .collect(),
2027        },
2028    }
2029}
2030
2031fn normalize_part_def_body_element_node(el: &Node<PartDefBodyElement>) -> Node<PartDefBodyElement> {
2032    let value = match &el.value {
2033        PartDefBodyElement::Error(n) => PartDefBodyElement::Error(dummy_node(n, n.value.clone())),
2034        PartDefBodyElement::Doc(n) => PartDefBodyElement::Doc(dummy_node(n, n.value.clone())),
2035        PartDefBodyElement::Comment(n) => {
2036            PartDefBodyElement::Comment(dummy_node(n, n.value.clone()))
2037        }
2038        PartDefBodyElement::Annotation(n) => {
2039            PartDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
2040        }
2041        PartDefBodyElement::Other(text) => PartDefBodyElement::Other(text.clone()),
2042        PartDefBodyElement::AttributeDef(n) => {
2043            PartDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
2044        }
2045        PartDefBodyElement::AttributeUsage(n) => {
2046            PartDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
2047        }
2048        PartDefBodyElement::RequirementUsage(n) => {
2049            PartDefBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
2050        }
2051        PartDefBodyElement::Ref(n) => {
2052            PartDefBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
2053        }
2054        PartDefBodyElement::PortUsage(n) => {
2055            PartDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2056        }
2057        PartDefBodyElement::PartUsage(n) => {
2058            PartDefBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
2059        }
2060        PartDefBodyElement::OccurrenceUsage(n) => {
2061            PartDefBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
2062        }
2063        PartDefBodyElement::InterfaceDef(n) => {
2064            PartDefBodyElement::InterfaceDef(dummy_node(n, normalize_interface_def(&n.value)))
2065        }
2066        PartDefBodyElement::InterfaceUsage(n) => {
2067            PartDefBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
2068        }
2069        PartDefBodyElement::Connect(n) => {
2070            PartDefBodyElement::Connect(dummy_node(n, n.value.clone()))
2071        }
2072        PartDefBodyElement::Connection(n) => {
2073            PartDefBodyElement::Connection(dummy_node(n, n.value.clone()))
2074        }
2075        PartDefBodyElement::Perform(n) => {
2076            PartDefBodyElement::Perform(dummy_node(n, n.value.clone()))
2077        }
2078        PartDefBodyElement::Allocate(n) => {
2079            PartDefBodyElement::Allocate(dummy_node(n, n.value.clone()))
2080        }
2081        PartDefBodyElement::OpaqueMember(n) => {
2082            PartDefBodyElement::OpaqueMember(dummy_node(n, n.value.clone()))
2083        }
2084        PartDefBodyElement::ExhibitState(n) => {
2085            PartDefBodyElement::ExhibitState(dummy_node(n, n.value.clone()))
2086        }
2087    };
2088    dummy_node(el, value)
2089}
2090
2091fn normalize_attribute_usage(a: &AttributeUsage) -> AttributeUsage {
2092    AttributeUsage {
2093        name: a.name.clone(),
2094        typing: a.typing.clone(),
2095        redefines: a.redefines.clone(),
2096        value: a.value.clone(),
2097        body: a.body.clone(),
2098        name_span: None,
2099        typing_span: None,
2100        redefines_span: None,
2101    }
2102}
2103
2104fn normalize_part_usage(p: &PartUsage) -> PartUsage {
2105    PartUsage {
2106        is_individual: p.is_individual,
2107        name: p.name.clone(),
2108        type_name: p.type_name.clone(),
2109        multiplicity: p.multiplicity.clone(),
2110        ordered: p.ordered,
2111        subsets: p.subsets.clone(),
2112        redefines: p.redefines.clone(),
2113        value: p.value.clone(),
2114        body: normalize_part_usage_body(&p.body),
2115        name_span: None,
2116        type_ref_span: None,
2117    }
2118}
2119
2120fn normalize_part_usage_body(b: &PartUsageBody) -> PartUsageBody {
2121    match b {
2122        PartUsageBody::Semicolon => PartUsageBody::Semicolon,
2123        PartUsageBody::Brace { elements } => PartUsageBody::Brace {
2124            elements: elements
2125                .iter()
2126                .map(normalize_part_usage_body_element_node)
2127                .collect(),
2128        },
2129    }
2130}
2131
2132fn normalize_perform(p: &Perform) -> Perform {
2133    Perform {
2134        action_name: p.action_name.clone(),
2135        type_name: p.type_name.clone(),
2136        body: normalize_perform_body(&p.body),
2137    }
2138}
2139
2140fn normalize_perform_body(b: &PerformBody) -> PerformBody {
2141    match b {
2142        PerformBody::Semicolon => PerformBody::Semicolon,
2143        PerformBody::Brace { elements } => PerformBody::Brace {
2144            elements: elements
2145                .iter()
2146                .map(normalize_perform_body_element_node)
2147                .collect(),
2148        },
2149    }
2150}
2151
2152fn normalize_perform_body_element_node(el: &Node<PerformBodyElement>) -> Node<PerformBodyElement> {
2153    let value = match &el.value {
2154        PerformBodyElement::Doc(n) => PerformBodyElement::Doc(dummy_node(n, n.value.clone())),
2155        PerformBodyElement::InOut(n) => PerformBodyElement::InOut(dummy_node(
2156            n,
2157            PerformInOutBinding {
2158                direction: n.value.direction,
2159                name: n.value.name.clone(),
2160                value: normalize_expression_node(&n.value.value),
2161            },
2162        )),
2163    };
2164    dummy_node(el, value)
2165}
2166
2167fn normalize_expression_node(node: &Node<Expression>) -> Node<Expression> {
2168    let value = match &node.value {
2169        Expression::LiteralInteger(x) => Expression::LiteralInteger(*x),
2170        Expression::LiteralReal(s) => Expression::LiteralReal(s.clone()),
2171        Expression::LiteralString(s) => Expression::LiteralString(s.clone()),
2172        Expression::LiteralBoolean(b) => Expression::LiteralBoolean(*b),
2173        Expression::FeatureRef(s) => Expression::FeatureRef(s.clone()),
2174        Expression::MemberAccess(base, member) => {
2175            Expression::MemberAccess(Box::new(normalize_expression_node(base)), member.clone())
2176        }
2177        Expression::Index { base, index } => Expression::Index {
2178            base: Box::new(normalize_expression_node(base)),
2179            index: Box::new(normalize_expression_node(index)),
2180        },
2181        Expression::Bracket(inner) => {
2182            Expression::Bracket(Box::new(normalize_expression_node(inner)))
2183        }
2184        Expression::LiteralWithUnit { value: v, unit } => Expression::LiteralWithUnit {
2185            value: Box::new(normalize_expression_node(v)),
2186            unit: Box::new(normalize_expression_node(unit)),
2187        },
2188        Expression::BinaryOp { op, left, right } => Expression::BinaryOp {
2189            op: op.clone(),
2190            left: Box::new(normalize_expression_node(left)),
2191            right: Box::new(normalize_expression_node(right)),
2192        },
2193        Expression::UnaryOp { op, operand } => Expression::UnaryOp {
2194            op: op.clone(),
2195            operand: Box::new(normalize_expression_node(operand)),
2196        },
2197        Expression::Invocation { callee, args } => Expression::Invocation {
2198            callee: Box::new(normalize_expression_node(callee)),
2199            args: args.iter().map(normalize_expression_node).collect(),
2200        },
2201        Expression::Tuple(items) => {
2202            Expression::Tuple(items.iter().map(normalize_expression_node).collect())
2203        }
2204        Expression::Null => Expression::Null,
2205    };
2206    Node::new(Span::dummy(), value)
2207}
2208
2209fn normalize_part_usage_body_element_node(
2210    el: &Node<PartUsageBodyElement>,
2211) -> Node<PartUsageBodyElement> {
2212    let value = match &el.value {
2213        PartUsageBodyElement::Error(n) => {
2214            PartUsageBodyElement::Error(dummy_node(n, n.value.clone()))
2215        }
2216        PartUsageBodyElement::Doc(n) => PartUsageBodyElement::Doc(dummy_node(n, n.value.clone())),
2217        PartUsageBodyElement::Annotation(n) => {
2218            PartUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
2219        }
2220        PartUsageBodyElement::AttributeUsage(n) => {
2221            PartUsageBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
2222        }
2223        PartUsageBodyElement::PartUsage(n) => {
2224            PartUsageBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
2225        }
2226        PartUsageBodyElement::OccurrenceUsage(n) => {
2227            PartUsageBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
2228        }
2229        PartUsageBodyElement::PortUsage(n) => {
2230            PartUsageBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2231        }
2232        PartUsageBodyElement::Ref(n) => {
2233            PartUsageBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
2234        }
2235        PartUsageBodyElement::Bind(n) => PartUsageBodyElement::Bind(dummy_node(n, n.value.clone())),
2236        PartUsageBodyElement::InterfaceUsage(n) => {
2237            PartUsageBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
2238        }
2239        PartUsageBodyElement::Connect(n) => {
2240            PartUsageBodyElement::Connect(dummy_node(n, n.value.clone()))
2241        }
2242        PartUsageBodyElement::Perform(n) => {
2243            PartUsageBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
2244        }
2245        PartUsageBodyElement::Allocate(n) => {
2246            PartUsageBodyElement::Allocate(dummy_node(n, n.value.clone()))
2247        }
2248        PartUsageBodyElement::Satisfy(n) => {
2249            PartUsageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
2250        }
2251        PartUsageBodyElement::StateUsage(n) => {
2252            PartUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2253        }
2254        PartUsageBodyElement::MetadataAnnotation(n) => {
2255            PartUsageBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
2256        }
2257    };
2258    dummy_node(el, value)
2259}
2260
2261fn normalize_port_usage(p: &PortUsage) -> PortUsage {
2262    PortUsage {
2263        name: p.name.clone(),
2264        type_name: p.type_name.clone(),
2265        multiplicity: p.multiplicity.clone(),
2266        subsets: p.subsets.clone(),
2267        redefines: p.redefines.clone(),
2268        body: normalize_port_body(&p.body),
2269        name_span: None,
2270        type_ref_span: None,
2271    }
2272}
2273
2274fn normalize_port_body(b: &PortBody) -> PortBody {
2275    match b {
2276        PortBody::Semicolon => PortBody::Semicolon,
2277        PortBody::Brace { elements } => PortBody::Brace {
2278            elements: elements
2279                .iter()
2280                .map(normalize_port_body_element_node)
2281                .collect(),
2282        },
2283    }
2284}
2285
2286fn normalize_port_body_element_node(el: &Node<PortBodyElement>) -> Node<PortBodyElement> {
2287    let value = match &el.value {
2288        PortBodyElement::Error(n) => PortBodyElement::Error(dummy_node(n, n.value.clone())),
2289        PortBodyElement::InOutDecl(n) => {
2290            PortBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2291        }
2292        PortBodyElement::PortUsage(n) => {
2293            PortBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2294        }
2295        PortBodyElement::Other(text) => PortBodyElement::Other(text.clone()),
2296    };
2297    dummy_node(el, value)
2298}
2299
2300fn normalize_port_def(p: &PortDef) -> PortDef {
2301    PortDef {
2302        identification: p.identification.clone(),
2303        specializes: p.specializes.clone(),
2304        specializes_span: None,
2305        body: normalize_port_def_body(&p.body),
2306    }
2307}
2308
2309fn normalize_port_def_body(b: &PortDefBody) -> PortDefBody {
2310    match b {
2311        PortDefBody::Semicolon => PortDefBody::Semicolon,
2312        PortDefBody::Brace { elements } => PortDefBody::Brace {
2313            elements: elements
2314                .iter()
2315                .map(normalize_port_def_body_element_node)
2316                .collect(),
2317        },
2318    }
2319}
2320
2321fn normalize_port_def_body_element_node(el: &Node<PortDefBodyElement>) -> Node<PortDefBodyElement> {
2322    let value = match &el.value {
2323        PortDefBodyElement::InOutDecl(n) => {
2324            PortDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2325        }
2326        PortDefBodyElement::Doc(n) => PortDefBodyElement::Doc(dummy_node(n, n.value.clone())),
2327        PortDefBodyElement::Error(n) => PortDefBodyElement::Error(dummy_node(n, n.value.clone())),
2328        PortDefBodyElement::AttributeDef(n) => {
2329            PortDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
2330        }
2331        PortDefBodyElement::AttributeUsage(n) => {
2332            PortDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
2333        }
2334        PortDefBodyElement::PortUsage(n) => {
2335            PortDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2336        }
2337    };
2338    dummy_node(el, value)
2339}
2340
2341fn normalize_interface_def(i: &InterfaceDef) -> InterfaceDef {
2342    InterfaceDef {
2343        identification: i.identification.clone(),
2344        specializes: i.specializes.clone(),
2345        specializes_span: None,
2346        body: normalize_interface_def_body(&i.body),
2347    }
2348}
2349
2350fn normalize_connection_def(c: &ConnectionDef) -> ConnectionDef {
2351    ConnectionDef {
2352        annotation: c.annotation.clone(),
2353        identification: c.identification.clone(),
2354        specializes: c.specializes.clone(),
2355        specializes_span: None,
2356        body: normalize_connection_def_body(&c.body),
2357    }
2358}
2359
2360fn normalize_connection_def_body(b: &ConnectionDefBody) -> ConnectionDefBody {
2361    match b {
2362        ConnectionDefBody::Semicolon => ConnectionDefBody::Semicolon,
2363        ConnectionDefBody::Brace { elements } => ConnectionDefBody::Brace {
2364            elements: elements
2365                .iter()
2366                .map(normalize_connection_def_body_element_node)
2367                .collect(),
2368        },
2369    }
2370}
2371
2372fn normalize_connection_def_body_element_node(
2373    el: &Node<ConnectionDefBodyElement>,
2374) -> Node<ConnectionDefBodyElement> {
2375    let value = match &el.value {
2376        ConnectionDefBodyElement::EndDecl(n) => {
2377            ConnectionDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
2378        }
2379        ConnectionDefBodyElement::RefDecl(n) => {
2380            ConnectionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2381        }
2382        ConnectionDefBodyElement::ConnectStmt(n) => {
2383            ConnectionDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
2384        }
2385    };
2386    dummy_node(el, value)
2387}
2388
2389fn normalize_metadata_def(m: &MetadataDef) -> MetadataDef {
2390    MetadataDef {
2391        is_abstract: m.is_abstract,
2392        identification: m.identification.clone(),
2393        specializes: m.specializes.clone(),
2394        specializes_span: None,
2395        body: m.body.clone(),
2396    }
2397}
2398
2399fn normalize_enum_def(e: &EnumDef) -> EnumDef {
2400    EnumDef {
2401        identification: e.identification.clone(),
2402        specializes: e.specializes.clone(),
2403        specializes_span: None,
2404        body: e.body.clone(),
2405    }
2406}
2407
2408fn normalize_occurrence_def(o: &OccurrenceDef) -> OccurrenceDef {
2409    OccurrenceDef {
2410        is_abstract: o.is_abstract,
2411        identification: o.identification.clone(),
2412        specializes: o.specializes.clone(),
2413        specializes_span: None,
2414        body: o.body.clone(),
2415    }
2416}
2417
2418fn normalize_interface_def_body(b: &InterfaceDefBody) -> InterfaceDefBody {
2419    match b {
2420        InterfaceDefBody::Semicolon => InterfaceDefBody::Semicolon,
2421        InterfaceDefBody::Brace { elements } => InterfaceDefBody::Brace {
2422            elements: elements
2423                .iter()
2424                .map(normalize_interface_def_body_element_node)
2425                .collect(),
2426        },
2427    }
2428}
2429
2430fn normalize_interface_def_body_element_node(
2431    el: &Node<InterfaceDefBodyElement>,
2432) -> Node<InterfaceDefBodyElement> {
2433    let value = match &el.value {
2434        InterfaceDefBodyElement::Doc(n) => {
2435            InterfaceDefBodyElement::Doc(dummy_node(n, n.value.clone()))
2436        }
2437        InterfaceDefBodyElement::EndDecl(n) => {
2438            InterfaceDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
2439        }
2440        InterfaceDefBodyElement::RefDecl(n) => {
2441            InterfaceDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2442        }
2443        InterfaceDefBodyElement::ConnectStmt(n) => {
2444            InterfaceDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
2445        }
2446    };
2447    dummy_node(el, value)
2448}
2449
2450fn normalize_end_decl(e: &EndDecl) -> EndDecl {
2451    EndDecl {
2452        name: e.name.clone(),
2453        type_name: e.type_name.clone(),
2454        uses_derived_syntax: e.uses_derived_syntax,
2455        name_span: None,
2456        type_ref_span: None,
2457    }
2458}
2459
2460fn normalize_ref_decl(r: &RefDecl) -> RefDecl {
2461    RefDecl {
2462        name: r.name.clone(),
2463        type_name: r.type_name.clone(),
2464        value: r.value.clone(),
2465        body: r.body.clone(),
2466        name_span: None,
2467        type_ref_span: None,
2468    }
2469}
2470
2471fn normalize_action_def(a: &ActionDef) -> ActionDef {
2472    ActionDef {
2473        identification: a.identification.clone(),
2474        specializes: a.specializes.clone(),
2475        specializes_span: None,
2476        body: normalize_action_def_body(&a.body),
2477    }
2478}
2479
2480fn normalize_action_def_body(b: &ActionDefBody) -> ActionDefBody {
2481    match b {
2482        ActionDefBody::Semicolon => ActionDefBody::Semicolon,
2483        ActionDefBody::Brace { elements } => ActionDefBody::Brace {
2484            elements: elements
2485                .iter()
2486                .map(normalize_action_def_body_element_node)
2487                .collect(),
2488        },
2489    }
2490}
2491
2492fn normalize_action_def_body_element_node(
2493    el: &Node<ActionDefBodyElement>,
2494) -> Node<ActionDefBodyElement> {
2495    let value = match &el.value {
2496        ActionDefBodyElement::Error(n) => {
2497            ActionDefBodyElement::Error(dummy_node(n, n.value.clone()))
2498        }
2499        ActionDefBodyElement::InOutDecl(n) => {
2500            ActionDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2501        }
2502        ActionDefBodyElement::Doc(n) => ActionDefBodyElement::Doc(dummy_node(n, n.value.clone())),
2503        ActionDefBodyElement::Annotation(n) => {
2504            ActionDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
2505        }
2506        ActionDefBodyElement::RefDecl(n) => {
2507            ActionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2508        }
2509        ActionDefBodyElement::Perform(n) => {
2510            ActionDefBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
2511        }
2512        ActionDefBodyElement::Bind(n) => ActionDefBodyElement::Bind(dummy_node(n, n.value.clone())),
2513        ActionDefBodyElement::Flow(n) => ActionDefBodyElement::Flow(dummy_node(n, n.value.clone())),
2514        ActionDefBodyElement::FirstStmt(n) => {
2515            ActionDefBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
2516        }
2517        ActionDefBodyElement::MergeStmt(n) => {
2518            ActionDefBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
2519        }
2520        ActionDefBodyElement::StateUsage(n) => {
2521            ActionDefBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2522        }
2523        ActionDefBodyElement::ActionUsage(n) => ActionDefBodyElement::ActionUsage(Box::new(
2524            dummy_node(n, normalize_action_usage(&n.value)),
2525        )),
2526        ActionDefBodyElement::Assign(n) => {
2527            ActionDefBodyElement::Assign(dummy_node(n, n.value.clone()))
2528        }
2529        ActionDefBodyElement::ForLoop(n) => {
2530            ActionDefBodyElement::ForLoop(dummy_node(n, n.value.clone()))
2531        }
2532        ActionDefBodyElement::ThenAction(n) => {
2533            ActionDefBodyElement::ThenAction(dummy_node(n, n.value.clone()))
2534        }
2535        ActionDefBodyElement::Decl(n) => ActionDefBodyElement::Decl(dummy_node(n, n.value.clone())),
2536    };
2537    dummy_node(el, value)
2538}
2539
2540fn normalize_action_usage(a: &ActionUsage) -> ActionUsage {
2541    ActionUsage {
2542        name: a.name.clone(),
2543        type_name: a.type_name.clone(),
2544        accept: a.accept.clone(),
2545        body: normalize_action_usage_body(&a.body),
2546        name_span: None,
2547        type_ref_span: None,
2548    }
2549}
2550
2551fn normalize_action_usage_body(b: &ActionUsageBody) -> ActionUsageBody {
2552    match b {
2553        ActionUsageBody::Semicolon => ActionUsageBody::Semicolon,
2554        ActionUsageBody::Brace { elements } => ActionUsageBody::Brace {
2555            elements: elements
2556                .iter()
2557                .map(normalize_action_usage_body_element_node)
2558                .collect(),
2559        },
2560    }
2561}
2562
2563fn normalize_action_usage_body_element_node(
2564    el: &Node<ActionUsageBodyElement>,
2565) -> Node<ActionUsageBodyElement> {
2566    let value = match &el.value {
2567        ActionUsageBodyElement::Error(n) => {
2568            ActionUsageBodyElement::Error(dummy_node(n, n.value.clone()))
2569        }
2570        ActionUsageBodyElement::Doc(n) => {
2571            ActionUsageBodyElement::Doc(dummy_node(n, n.value.clone()))
2572        }
2573        ActionUsageBodyElement::Annotation(n) => {
2574            ActionUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
2575        }
2576        ActionUsageBodyElement::InOutDecl(n) => {
2577            ActionUsageBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2578        }
2579        ActionUsageBodyElement::RefDecl(n) => {
2580            ActionUsageBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2581        }
2582        ActionUsageBodyElement::Bind(n) => {
2583            ActionUsageBodyElement::Bind(dummy_node(n, n.value.clone()))
2584        }
2585        ActionUsageBodyElement::Flow(n) => {
2586            ActionUsageBodyElement::Flow(dummy_node(n, n.value.clone()))
2587        }
2588        ActionUsageBodyElement::FirstStmt(n) => {
2589            ActionUsageBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
2590        }
2591        ActionUsageBodyElement::MergeStmt(n) => {
2592            ActionUsageBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
2593        }
2594        ActionUsageBodyElement::StateUsage(n) => {
2595            ActionUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2596        }
2597        ActionUsageBodyElement::ActionUsage(n) => ActionUsageBodyElement::ActionUsage(Box::new(
2598            dummy_node(n, normalize_action_usage(&n.value)),
2599        )),
2600        ActionUsageBodyElement::Assign(n) => {
2601            ActionUsageBodyElement::Assign(dummy_node(n, n.value.clone()))
2602        }
2603        ActionUsageBodyElement::ForLoop(n) => {
2604            ActionUsageBodyElement::ForLoop(dummy_node(n, n.value.clone()))
2605        }
2606        ActionUsageBodyElement::ThenAction(n) => {
2607            ActionUsageBodyElement::ThenAction(dummy_node(n, n.value.clone()))
2608        }
2609        ActionUsageBodyElement::Decl(n) => {
2610            ActionUsageBodyElement::Decl(dummy_node(n, n.value.clone()))
2611        }
2612    };
2613    dummy_node(el, value)
2614}