Skip to main content

sysml_v2_parser/
ast.rs

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