Skip to main content

sysml_v2_parser/ast/
structure.rs

1use super::behavior::{Allocate, InOut, InOutDecl, StateDefBody, StateUsage};
2use super::common::{CommentAnnotation, ConnectBody, DocComment, Identification, ParseErrorNode};
3use super::requirement::{EnumerationUsage, ItemUsage, RequirementUsage, Satisfy};
4use super::view::{CalcUsage, ConstraintDefBody};
5use crate::ast::core::{Expression, Node, Span};
6
7/// Part definition: `part def` Identification (`:>` specializes)? Body.
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct PartDef {
10    /// Optional `abstract` or `variation` prefix (BNF BasicDefinitionPrefix).
11    pub definition_prefix: Option<DefinitionPrefix>,
12    /// Whether this is an `individual part def`.
13    pub is_individual: bool,
14    pub identification: Identification,
15    /// Supertype after `:>`, e.g. Some("Axle") for `part def FrontAxle :> Axle`.
16    pub specializes: Option<String>,
17    /// Span of the `:> <type>` fragment (for semantic tokens), when present.
18    pub specializes_span: Option<Span>,
19    pub body: PartDefBody,
20}
21
22/// BNF BasicDefinitionPrefix: `abstract` | `variation`.
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum DefinitionPrefix {
25    Abstract,
26    Variation,
27}
28
29/// Body of a part definition: `;` or `{` PartDefBodyElement* `}`.
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum PartDefBody {
32    Semicolon,
33    Brace {
34        elements: Vec<Node<PartDefBodyElement>>,
35    },
36}
37
38/// Element inside a part definition body.
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum PartDefBodyElement {
41    Error(Node<ParseErrorNode>),
42    Doc(Node<DocComment>),
43    Comment(Node<CommentAnnotation>),
44    Annotation(Node<Annotation>),
45    Other(String),
46    AttributeDef(Node<AttributeDef>),
47    AttributeUsage(Node<AttributeUsage>),
48    RequirementUsage(Node<RequirementUsage>),
49    ItemUsage(Node<ItemUsage>),
50    Ref(Node<RefDecl>),
51    PortUsage(Node<PortUsage>),
52    PartUsage(Box<Node<PartUsage>>),
53    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
54    InterfaceDef(Node<InterfaceDef>),
55    InterfaceUsage(Node<InterfaceUsage>),
56    Connect(Node<Connect>),
57    /// `connection` usage member inside a part definition body.
58    Connection(Node<ConnectionUsageMember>),
59    Perform(Node<Perform>),
60    Allocate(Node<Allocate>),
61    OpaqueMember(Node<OpaqueMemberDecl>),
62    /// `exhibit state` name `:` type (`;` or body).
63    ExhibitState(Node<ExhibitState>),
64    /// Calculation usage (`calc` keyword) inside a part definition body.
65    CalcUsage(Node<CalcUsage>),
66    /// Enumeration usage (`enum` keyword) inside a part definition body.
67    EnumerationUsage(Node<EnumerationUsage>),
68}
69
70/// Library-tolerant part member preserved without forcing it into an unrelated node shape.
71#[derive(Debug, Clone, PartialEq, Eq)]
72pub struct OpaqueMemberDecl {
73    pub keyword: String,
74    pub name: String,
75    pub text: String,
76    pub body: AttributeBody,
77}
78
79/// Connection usage member inside part definitions.
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub struct ConnectionUsageMember {
82    pub name: Option<String>,
83    pub type_name: Option<String>,
84    pub body: ConnectionDefBody,
85    pub subsets: Option<String>,
86    pub redefines: Option<String>,
87}
88
89/// Exhibit state usage: `exhibit state` name `:` type (`;` or body).
90#[derive(Debug, Clone, PartialEq, Eq)]
91pub struct ExhibitState {
92    pub name: String,
93    pub type_name: Option<String>,
94    pub redefines: Option<String>,
95    pub body: StateDefBody,
96}
97
98/// Attribute definition: `attribute` [`def`] name (`:>` | `:` type)? (`=` value)? body.
99#[derive(Debug, Clone, PartialEq, Eq)]
100pub struct AttributeDef {
101    pub name: String,
102    /// Type after `:>`, e.g. Some("ISQ::mass").
103    pub typing: Option<String>,
104    /// Default or binding after `=` / `:=` / `default =` before the body terminator.
105    pub value: Option<Node<Expression>>,
106    pub body: AttributeBody,
107    /// Span of the defined name (for semantic tokens).
108    pub name_span: Option<Span>,
109    /// Span of the type after `:>`, if present (for semantic tokens).
110    pub typing_span: Option<Span>,
111}
112
113/// Body of an attribute (def or usage): `;` or `{` AttributeBodyElement* `}`.
114#[derive(Debug, Clone, PartialEq, Eq)]
115pub enum AttributeBody {
116    Semicolon,
117    Brace {
118        elements: Vec<Node<AttributeBodyElement>>,
119    },
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
123pub enum AttributeBodyElement {
124    Error(Node<ParseErrorNode>),
125    Doc(Node<DocComment>),
126    AttributeDef(Node<AttributeDef>),
127    AttributeUsage(Node<AttributeUsage>),
128    Other(String),
129}
130
131/// Item definition: `item def` Identification body (for events, etc.).
132#[derive(Debug, Clone, PartialEq, Eq)]
133pub struct ItemDef {
134    pub identification: Identification,
135    pub specializes: Option<String>,
136    pub specializes_span: Option<Span>,
137    pub body: AttributeBody,
138}
139
140/// Individual definition: `individual def` Identification `:>` type body.
141#[derive(Debug, Clone, PartialEq, Eq)]
142pub struct IndividualDef {
143    pub identification: Identification,
144    pub specializes: Option<String>,
145    pub specializes_span: Option<Span>,
146    pub body: AttributeBody,
147}
148
149/// Part usage: `part` name `:` type multiplicity? `ordered`? (`redefines`|`:>>`)? value? body.
150#[derive(Debug, Clone, PartialEq, Eq)]
151pub struct PartUsage {
152    pub is_individual: bool,
153    pub name: String,
154    /// Type after `:`, e.g. "Vehicle", "AxleAssembly".
155    pub type_name: String,
156    /// Multiplicity, e.g. Some("[2]").
157    pub multiplicity: Option<String>,
158    pub ordered: bool,
159    /// Optional `subsets` feature and value expression.
160    pub subsets: Option<(String, Option<Node<Expression>>)>,
161    /// Redefines target, e.g. Some("frontAxleAssembly") or Some("vehicle1::mass").
162    pub redefines: Option<String>,
163    /// Value expression (= expr, default = expr, := expr).
164    pub value: Option<Node<Expression>>,
165    pub body: PartUsageBody,
166    /// Span of the usage name (for semantic tokens).
167    pub name_span: Option<Span>,
168    /// Span of the type reference after `:` (for semantic tokens).
169    pub type_ref_span: Option<Span>,
170}
171
172/// Body of a part usage: `;` or `{` PartUsageBodyElement* `}`.
173#[derive(Debug, Clone, PartialEq, Eq)]
174pub enum PartUsageBody {
175    Semicolon,
176    Brace {
177        elements: Vec<Node<PartUsageBodyElement>>,
178    },
179}
180
181/// Metadata annotation on usage: `@` Name (`:` Type)? MetadataBody (e.g. `@Security;` or `@Safety{isMandatory = true;}`).
182#[derive(Debug, Clone, PartialEq, Eq)]
183pub struct MetadataAnnotation {
184    pub name: String,
185    pub type_name: Option<String>,
186    pub body: ConnectBody,
187}
188
189/// Generic annotation or metadata usage captured in body scopes.
190#[derive(Debug, Clone, PartialEq, Eq)]
191pub struct Annotation {
192    pub sigil: String,
193    pub head: String,
194    pub type_name: Option<String>,
195    pub body: ConnectBody,
196}
197
198/// Element inside a part usage body.
199#[derive(Debug, Clone, PartialEq, Eq)]
200pub enum PartUsageBodyElement {
201    Error(Node<ParseErrorNode>),
202    Doc(Node<DocComment>),
203    Annotation(Node<Annotation>),
204    AttributeUsage(Node<AttributeUsage>),
205    EnumerationUsage(Node<EnumerationUsage>),
206    PartUsage(Box<Node<PartUsage>>),
207    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
208    PortUsage(Node<PortUsage>),
209    Bind(Node<Bind>),
210    /// `ref` name `:` type body (reference binding in part usage).
211    Ref(Node<RefDecl>),
212    InterfaceUsage(Node<InterfaceUsage>),
213    Connect(Node<Connect>),
214    Perform(Node<Perform>),
215    Allocate(Node<Allocate>),
216    Satisfy(Node<Satisfy>),
217    StateUsage(Node<StateUsage>),
218    MetadataAnnotation(Node<MetadataAnnotation>),
219}
220
221/// Enacted performance: `perform` action_path `{` body `}` inside a part usage.
222#[derive(Debug, Clone, PartialEq, Eq)]
223pub struct Perform {
224    /// Qualified action name (e.g. "provide power" or "provide power.generate torque").
225    pub action_name: String,
226    /// Type after `:` in "perform action name : Type" form.
227    pub type_name: Option<String>,
228    pub body: PerformBody,
229}
230
231/// Body of a perform: `;` or `{` PerformBodyElement* `}`.
232#[derive(Debug, Clone, PartialEq, Eq)]
233pub enum PerformBody {
234    Semicolon,
235    Brace {
236        elements: Vec<Node<PerformBodyElement>>,
237    },
238}
239
240/// Element inside a perform body: doc comment or in/out binding.
241#[derive(Debug, Clone, PartialEq, Eq)]
242pub enum PerformBodyElement {
243    Doc(Node<DocComment>),
244    InOut(Node<PerformInOutBinding>),
245}
246
247/// In/out binding inside a perform body: `in` name `=` expr `;` or `out` name `=` expr `;`.
248#[derive(Debug, Clone, PartialEq, Eq)]
249pub struct PerformInOutBinding {
250    pub direction: InOut,
251    pub name: String,
252    pub value: Node<Expression>,
253}
254
255/// Attribute usage: `attribute` name (`:>` | `:` type)? `redefines`? value? body.
256#[derive(Debug, Clone, PartialEq, Eq)]
257pub struct AttributeUsage {
258    pub name: String,
259    /// Type after `:` or `:>`, e.g. Some("MassValue").
260    pub typing: Option<String>,
261    /// Subsets target after `:>` / `subsets`.
262    pub subsets: Option<String>,
263    /// Redefines target, e.g. Some("Vehicle::mass").
264    pub redefines: Option<String>,
265    /// References target after `::>` / `references`.
266    pub references: Option<String>,
267    /// Crosses target after `=>` / `crosses`.
268    pub crosses: Option<String>,
269    /// Value expression.
270    pub value: Option<Node<Expression>>,
271    pub body: AttributeBody,
272    /// Span of the usage name (for semantic tokens).
273    pub name_span: Option<Span>,
274    /// Span of the type after `:` / `:>`, if present (for semantic tokens).
275    pub typing_span: Option<Span>,
276    /// Span of the redefines target after `redefines`, if present (for semantic tokens).
277    pub redefines_span: Option<Span>,
278}
279
280// ---------------------------------------------------------------------------
281// Port
282// ---------------------------------------------------------------------------
283
284/// Port definition: `port def` Identification body.
285#[derive(Debug, Clone, PartialEq, Eq)]
286pub struct PortDef {
287    pub identification: Identification,
288    /// Supertype after `:>`, e.g. Some("ClutchPort") for `port def ManualClutchPort :> ClutchPort`.
289    pub specializes: Option<String>,
290    pub specializes_span: Option<Span>,
291    pub body: PortDefBody,
292}
293
294/// Body of a port definition: `;` or `{` PortDefBodyElement* `}`.
295#[derive(Debug, Clone, PartialEq, Eq)]
296pub enum PortDefBody {
297    Semicolon,
298    Brace {
299        elements: Vec<Node<PortDefBodyElement>>,
300    },
301}
302
303/// Element inside a port definition body (in/out declarations or nested port usages).
304#[derive(Debug, Clone, PartialEq, Eq)]
305pub enum PortDefBodyElement {
306    InOutDecl(Node<InOutDecl>),
307    Doc(Node<DocComment>),
308    Error(Node<ParseErrorNode>),
309    AttributeDef(Node<AttributeDef>),
310    AttributeUsage(Node<AttributeUsage>),
311    PortUsage(Node<PortUsage>),
312}
313
314/// Port usage: `port` name `:` type multiplicity? `:>` subsets? `redefines`? body.
315#[derive(Debug, Clone, PartialEq, Eq)]
316pub struct PortUsage {
317    pub name: String,
318    pub type_name: Option<String>,
319    pub multiplicity: Option<String>,
320    /// Subsets feature and optional value expression.
321    pub subsets: Option<(String, Option<Node<Expression>>)>,
322    pub redefines: Option<String>,
323    /// References target after `::>` / `references`.
324    pub references: Option<String>,
325    /// Crosses target after `=>` / `crosses`.
326    pub crosses: Option<String>,
327    pub body: PortBody,
328    /// Span of the usage name (for semantic tokens).
329    pub name_span: Option<Span>,
330    /// Span of the type reference after `:`, if present (for semantic tokens).
331    pub type_ref_span: Option<Span>,
332}
333
334/// Body of a port usage: `;` or `{` PortBodyElement* `}`.
335#[derive(Debug, Clone, PartialEq, Eq)]
336pub enum PortBody {
337    Semicolon,
338    Brace {
339        elements: Vec<Node<PortBodyElement>>,
340    },
341}
342
343/// Element inside a port usage body.
344#[derive(Debug, Clone, PartialEq, Eq)]
345#[allow(clippy::large_enum_variant)]
346pub enum PortBodyElement {
347    Error(Node<ParseErrorNode>),
348    InOutDecl(Node<InOutDecl>),
349    PortUsage(Node<PortUsage>),
350    Other(String),
351}
352
353/// Connect statement in interface def or usage: `connect` from `to` to body.
354#[derive(Debug, Clone, PartialEq, Eq)]
355pub struct ConnectStmt {
356    pub from: Node<Expression>,
357    pub to: Node<Expression>,
358    pub body: ConnectBody,
359}
360
361// ---------------------------------------------------------------------------
362// Interface
363// ---------------------------------------------------------------------------
364
365/// Interface definition: `interface def` Identification body.
366#[derive(Debug, Clone, PartialEq, Eq)]
367pub struct InterfaceDef {
368    pub identification: Identification,
369    pub specializes: Option<String>,
370    pub specializes_span: Option<Span>,
371    pub body: InterfaceDefBody,
372}
373
374/// Body of an interface definition: `;` or `{` InterfaceDefBodyElement* `}`.
375#[derive(Debug, Clone, PartialEq, Eq)]
376pub enum InterfaceDefBody {
377    Semicolon,
378    Brace {
379        elements: Vec<Node<InterfaceDefBodyElement>>,
380    },
381}
382
383/// Element inside an interface definition body.
384#[derive(Debug, Clone, PartialEq, Eq)]
385pub enum InterfaceDefBodyElement {
386    Doc(Node<DocComment>),
387    EndDecl(Node<EndDecl>),
388    RefDecl(Node<RefDecl>),
389    ConnectStmt(Node<ConnectStmt>),
390}
391
392/// End declaration in interface def: `end` name `:` type `;`.
393#[derive(Debug, Clone, PartialEq, Eq)]
394pub struct EndDecl {
395    pub name: String,
396    pub type_name: String,
397    pub uses_derived_syntax: bool,
398    /// Span of the name (for semantic tokens).
399    pub name_span: Option<Span>,
400    /// Span of the type after `:` (for semantic tokens).
401    pub type_ref_span: Option<Span>,
402}
403
404/// Ref declaration in interface def: `ref` name `:` type body.
405#[derive(Debug, Clone, PartialEq, Eq)]
406pub struct RefDecl {
407    pub name: String,
408    pub type_name: String,
409    /// Optional binding value: `= expr` (SysML shorthand binding for references).
410    pub value: Option<Node<Expression>>,
411    pub body: RefBody,
412    /// Span of the name (for semantic tokens).
413    pub name_span: Option<Span>,
414    /// Span of the type after `:` (for semantic tokens).
415    pub type_ref_span: Option<Span>,
416}
417
418/// Body of a ref declaration: `;` or `{` ... `}`.
419#[derive(Debug, Clone, PartialEq, Eq)]
420pub enum RefBody {
421    Semicolon,
422    Brace,
423}
424
425// ---------------------------------------------------------------------------
426// Connection (Phase 2)
427// ---------------------------------------------------------------------------
428
429/// Connection definition: `connection def` Identification body (BNF ConnectionDefinition).
430#[derive(Debug, Clone, PartialEq, Eq)]
431pub struct ConnectionDef {
432    pub annotation: Option<String>,
433    pub identification: Identification,
434    pub specializes: Option<String>,
435    pub specializes_span: Option<Span>,
436    pub body: ConnectionDefBody,
437}
438
439/// Body of a connection definition: `;` or `{` end/ref/connect* `}`.
440#[derive(Debug, Clone, PartialEq, Eq)]
441pub enum ConnectionDefBody {
442    Semicolon,
443    Brace {
444        elements: Vec<Node<ConnectionDefBodyElement>>,
445    },
446}
447
448#[derive(Debug, Clone, PartialEq, Eq)]
449pub enum ConnectionDefBodyElement {
450    EndDecl(Node<EndDecl>),
451    RefDecl(Node<RefDecl>),
452    ConnectStmt(Node<ConnectStmt>),
453}
454
455// ---------------------------------------------------------------------------
456// Metadata (Phase 2)
457// ---------------------------------------------------------------------------
458
459/// Metadata definition: `metadata def` Identification body (BNF MetadataDefinition).
460#[derive(Debug, Clone, PartialEq, Eq)]
461pub struct MetadataDef {
462    pub is_abstract: bool,
463    pub identification: Identification,
464    pub specializes: Option<String>,
465    pub specializes_span: Option<Span>,
466    pub body: DefinitionBody,
467}
468
469// ---------------------------------------------------------------------------
470// Enumeration (Phase 2)
471// ---------------------------------------------------------------------------
472
473/// Enumeration definition: `enum def` Identification EnumerationBody (BNF EnumerationDefinition).
474#[derive(Debug, Clone, PartialEq, Eq)]
475pub struct EnumDef {
476    pub identification: Identification,
477    pub specializes: Option<String>,
478    pub specializes_span: Option<Span>,
479    pub body: EnumerationBody,
480}
481
482#[derive(Debug, Clone, PartialEq, Eq)]
483pub enum EnumerationBody {
484    Semicolon,
485    Brace { values: Vec<String> },
486}
487
488// ---------------------------------------------------------------------------
489// Occurrence (Phase 2)
490// ---------------------------------------------------------------------------
491
492/// Occurrence definition: `occurrence def` Identification body (BNF OccurrenceDefinition).
493#[derive(Debug, Clone, PartialEq, Eq)]
494pub struct OccurrenceDef {
495    pub is_abstract: bool,
496    pub identification: Identification,
497    pub specializes: Option<String>,
498    pub specializes_span: Option<Span>,
499    pub body: DefinitionBody,
500}
501
502/// Occurrence usage: `occurrence` name (`:` type)? body, with optional individual/portion modifiers.
503#[derive(Debug, Clone, PartialEq, Eq)]
504pub struct OccurrenceUsage {
505    pub is_individual: bool,
506    pub is_then: bool,
507    pub portion_kind: Option<String>,
508    pub name: String,
509    pub type_name: Option<String>,
510    pub subsets: Option<String>,
511    pub redefines: Option<String>,
512    pub references: Option<String>,
513    pub crosses: Option<String>,
514    pub body: OccurrenceUsageBody,
515}
516
517#[derive(Debug, Clone, PartialEq, Eq)]
518pub enum OccurrenceUsageBody {
519    Semicolon,
520    Brace {
521        elements: Vec<Node<OccurrenceBodyElement>>,
522    },
523}
524
525/// Occurrence-level assert member: `assert constraint` body.
526#[derive(Debug, Clone, PartialEq, Eq)]
527pub struct AssertConstraintMember {
528    pub body: ConstraintDefBody,
529}
530
531#[derive(Debug, Clone, PartialEq, Eq)]
532#[allow(clippy::large_enum_variant)]
533pub enum OccurrenceBodyElement {
534    Error(Node<ParseErrorNode>),
535    Doc(Node<DocComment>),
536    Annotation(Node<Annotation>),
537    AssertConstraint(Node<AssertConstraintMember>),
538    Other(String),
539    AttributeUsage(Node<AttributeUsage>),
540    PartUsage(Box<Node<PartUsage>>),
541    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
542}
543
544// ---------------------------------------------------------------------------
545// Library Package (Phase 2)
546// ---------------------------------------------------------------------------
547
548/// Generic definition body: `;` or `{` DefinitionBodyElement* `}`.
549#[derive(Debug, Clone, PartialEq, Eq)]
550pub enum DefinitionBody {
551    Semicolon,
552    Brace {
553        elements: Vec<Node<DefinitionBodyElement>>,
554    },
555}
556
557#[derive(Debug, Clone, PartialEq, Eq)]
558#[allow(clippy::large_enum_variant)]
559pub enum DefinitionBodyElement {
560    Error(Node<ParseErrorNode>),
561    Doc(Node<DocComment>),
562    OccurrenceMember(Node<OccurrenceBodyElement>),
563    Other(String),
564}
565// ---------------------------------------------------------------------------
566// Part usage body: bind, interface usage, connect
567// ---------------------------------------------------------------------------
568
569/// Bind: `bind` left `=` right (`;` or `{ }`).
570#[derive(Debug, Clone, PartialEq, Eq)]
571pub struct Bind {
572    pub left: Node<Expression>,
573    pub right: Node<Expression>,
574    /// Optional body after the bind (semicolon or brace); 3a fixture uses `bind x = y { }`.
575    pub body: Option<ConnectBody>,
576}
577
578/// Interface usage: typed+connect or connection form.
579#[derive(Debug, Clone, PartialEq, Eq)]
580pub enum InterfaceUsage {
581    /// `interface` `:Type`? `connect` from `to` to body; optional body with ref redefs.
582    TypedConnect {
583        interface_type: Option<String>,
584        from: Node<Expression>,
585        to: Node<Expression>,
586        body: ConnectBody,
587        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
588    },
589    /// `interface` from `to` to body.
590    Connection {
591        from: Node<Expression>,
592        to: Node<Expression>,
593        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
594    },
595}
596
597/// Element in interface usage body (e.g. ref redefinition).
598#[derive(Debug, Clone, PartialEq, Eq)]
599pub enum InterfaceUsageBodyElement {
600    /// `ref` `:>>` name `=` value body.
601    RefRedef {
602        name: String,
603        value: Node<Expression>,
604        body: RefBody,
605    },
606}
607
608/// Connect at part usage level: `connect` from `to` to body.
609#[derive(Debug, Clone, PartialEq, Eq)]
610pub struct Connect {
611    pub from: Node<Expression>,
612    pub to: Node<Expression>,
613    pub body: ConnectBody,
614}
615
616// ---------------------------------------------------------------------------
617// Alias
618// ---------------------------------------------------------------------------
619
620/// Alias definition: `alias` Identification `for` qualified_name body.
621#[derive(Debug, Clone, PartialEq, Eq)]
622pub struct AliasDef {
623    pub identification: Identification,
624    pub target: String,
625    pub body: AliasBody,
626}
627
628/// Body of an alias definition: `;` or `{` ... `}`.
629#[derive(Debug, Clone, PartialEq, Eq)]
630pub enum AliasBody {
631    Semicolon,
632    Brace,
633}