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