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