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