Skip to main content

veryl_parser/
veryl_grammar_trait.rs

1pub use crate::generated::veryl_grammar_trait::*;
2use crate::resource_table::StrId;
3use crate::veryl_token::{VerylToken, is_anonymous_token};
4use paste::paste;
5use std::fmt;
6
7macro_rules! list_group_to_item {
8    ($x:ident) => {
9        paste! {
10            impl<'a> From<&'a [<$x List>]> for Vec<&'a [<$x Item>]> {
11                fn from(x: &'a [<$x List>]) -> Self {
12                    let mut ret = Vec::new();
13                    {
14                        let mut x: Vec<&'a [<$x Item>]> = x.[<$x:snake _group>].as_ref().into();
15                        ret.append(&mut x);
16                    }
17                    for x in &x.[<$x:snake _list_list>] {
18                        let mut x: Vec<&'a [<$x Item>]> = x.[<$x:snake _group>].as_ref().into();
19                        ret.append(&mut x);
20                    }
21                    ret
22                }
23            }
24
25            impl<'a> From<&'a [<$x Group>]> for Vec<&'a [<$x Item>]> {
26                fn from(x: &'a [<$x Group>]) -> Self {
27                    let mut ret = Vec::new();
28                    match &*x.[<$x:snake _group_group>] {
29                        [<$x GroupGroup>]::[<LBrace $x ListRBrace>](x) => {
30                            let mut x: Vec<&'a [<$x Item>]> = x.[<$x:snake _list>].as_ref().into();
31                            ret.append(&mut x);
32                        }
33                        [<$x GroupGroup>]::[<$x Item>](x) => {
34                            ret.push(x.[<$x:snake _item>].as_ref());
35                        }
36                    }
37                    ret
38                }
39            }
40        }
41    };
42}
43
44macro_rules! list_to_item {
45    ($x:ident) => {
46        paste! {
47            impl<'a> From<&'a [<$x List>]> for Vec<&'a [<$x Item>]> {
48                fn from(x: &'a [<$x List>]) -> Self {
49                    let mut ret = Vec::new();
50                    {
51                        ret.push(x.[<$x:snake _item>].as_ref());
52                    }
53                    for x in &x.[<$x:snake _list_list>] {
54                        ret.push(x.[<$x:snake _item>].as_ref());
55                    }
56                    ret
57                }
58            }
59        }
60    };
61}
62
63macro_rules! group_to_item {
64    ($x:ident) => {
65        paste! {
66            impl<'a> From<&'a [<$x Group>]> for Vec<&'a [<$x Item>]> {
67                fn from(x: &'a [<$x Group>]) -> Self {
68                    let mut ret = Vec::new();
69                    match &*x.[<$x:snake _group_group>] {
70                        [<$x GroupGroup>]::[<LBrace $x GroupGroupListRBrace>](x) => {
71                            for x in &x.[<$x:snake _group_group_list>] {
72                                let mut x: Vec<&'a [<$x Item>]> = x.[<$x:snake _group>].as_ref().into();
73                                ret.append(&mut x);
74                            }
75                        }
76                        [<$x GroupGroup>]::[<$x Item>](x) => {
77                            ret.push(x.[<$x:snake _item>].as_ref());
78                        }
79                    }
80                    ret
81                }
82            }
83        }
84    };
85}
86
87impl<'a> From<&'a ScopedIdentifier> for Vec<Option<&'a WithGenericArgument>> {
88    fn from(value: &'a ScopedIdentifier) -> Self {
89        let mut ret = Vec::new();
90        match value.scoped_identifier_group.as_ref() {
91            ScopedIdentifierGroup::IdentifierScopedIdentifierOpt(x) => {
92                if let Some(ref x) = x.scoped_identifier_opt {
93                    ret.push(Some(x.with_generic_argument.as_ref()));
94                } else {
95                    ret.push(None);
96                }
97            }
98            ScopedIdentifierGroup::DollarIdentifier(_) => {
99                ret.push(None);
100            }
101        }
102        for x in &value.scoped_identifier_list {
103            if let Some(ref x) = x.scoped_identifier_opt0 {
104                ret.push(Some(x.with_generic_argument.as_ref()));
105            } else {
106                ret.push(None);
107            }
108        }
109        ret
110    }
111}
112
113impl<'a> From<&'a CaseCondition> for Vec<&'a RangeItem> {
114    fn from(value: &'a CaseCondition) -> Self {
115        let mut ret = Vec::new();
116        ret.push(value.range_item.as_ref());
117
118        for x in &value.case_condition_list {
119            ret.push(x.range_item.as_ref());
120        }
121
122        ret
123    }
124}
125
126impl<'a> From<&'a SwitchCondition> for Vec<&'a Expression> {
127    fn from(value: &'a SwitchCondition) -> Self {
128        let mut ret = Vec::new();
129        ret.push(value.expression.as_ref());
130
131        for x in &value.switch_condition_list {
132            ret.push(x.expression.as_ref());
133        }
134
135        ret
136    }
137}
138
139impl<'a> From<&'a Width> for Vec<&'a Expression> {
140    fn from(value: &'a Width) -> Self {
141        let mut ret = Vec::new();
142        ret.push(value.expression.as_ref());
143
144        for x in &value.width_list {
145            ret.push(x.expression.as_ref());
146        }
147
148        ret
149    }
150}
151
152impl<'a> From<&'a Array> for Vec<&'a Expression> {
153    fn from(value: &'a Array) -> Self {
154        let mut ret = Vec::new();
155        ret.push(value.expression.as_ref());
156
157        for x in &value.array_list {
158            ret.push(x.expression.as_ref());
159        }
160
161        ret
162    }
163}
164
165impl<'a> From<&'a AssignDestination> for Vec<&'a HierarchicalIdentifier> {
166    fn from(value: &'a AssignDestination) -> Self {
167        match value {
168            AssignDestination::HierarchicalIdentifier(x) => {
169                vec![x.hierarchical_identifier.as_ref()]
170            }
171            AssignDestination::LBraceAssignConcatenationListRBrace(x) => {
172                let list: Vec<_> = x.assign_concatenation_list.as_ref().into();
173                list.iter()
174                    .map(|x| x.hierarchical_identifier.as_ref())
175                    .collect()
176            }
177        }
178    }
179}
180
181impl From<&Identifier> for ScopedIdentifier {
182    fn from(value: &Identifier) -> Self {
183        let scoped_identifier_group =
184            Box::new(ScopedIdentifierGroup::IdentifierScopedIdentifierOpt(
185                ScopedIdentifierGroupIdentifierScopedIdentifierOpt {
186                    identifier: Box::new(value.clone()),
187                    scoped_identifier_opt: None,
188                },
189            ));
190        Self {
191            scoped_identifier_group,
192            scoped_identifier_list: vec![],
193        }
194    }
195}
196
197impl From<&Identifier> for ExpressionIdentifier {
198    fn from(value: &Identifier) -> Self {
199        let scoped_identifier: ScopedIdentifier = value.into();
200        (&scoped_identifier).into()
201    }
202}
203
204impl From<&ScopedIdentifier> for ExpressionIdentifier {
205    fn from(value: &ScopedIdentifier) -> Self {
206        Self {
207            scoped_identifier: Box::new(value.clone()),
208            expression_identifier_opt: None,
209            expression_identifier_list: vec![],
210            expression_identifier_list0: vec![],
211        }
212    }
213}
214
215impl From<&GenericArgIdentifier> for ExpressionIdentifier {
216    fn from(value: &GenericArgIdentifier) -> Self {
217        let exp_identifier_list: Vec<_> = value
218            .generic_arg_identifier_list
219            .iter()
220            .map(|x| ExpressionIdentifierList0 {
221                dot: x.dot.clone(),
222                identifier: x.identifier.clone(),
223                expression_identifier_list0_list: vec![],
224            })
225            .collect();
226        Self {
227            scoped_identifier: value.scoped_identifier.clone(),
228            expression_identifier_opt: None,
229            expression_identifier_list: vec![],
230            expression_identifier_list0: exp_identifier_list,
231        }
232    }
233}
234
235impl From<&Number> for Factor {
236    fn from(value: &Number) -> Self {
237        Factor::Number(FactorNumber {
238            number: Box::new(value.clone()),
239        })
240    }
241}
242
243impl From<&BooleanLiteral> for Factor {
244    fn from(value: &BooleanLiteral) -> Self {
245        Factor::BooleanLiteral(FactorBooleanLiteral {
246            boolean_literal: Box::new(value.clone()),
247        })
248    }
249}
250
251impl From<&Identifier> for Factor {
252    fn from(value: &Identifier) -> Self {
253        let identifier_factor = IdentifierFactor {
254            expression_identifier: Box::new(value.into()),
255            identifier_factor_opt: None,
256        };
257        Factor::IdentifierFactor(FactorIdentifierFactor {
258            identifier_factor: Box::new(identifier_factor),
259        })
260    }
261}
262
263impl From<&ExpressionIdentifier> for Factor {
264    fn from(value: &ExpressionIdentifier) -> Self {
265        let identifier_factor = IdentifierFactor {
266            expression_identifier: Box::new(value.clone()),
267            identifier_factor_opt: None,
268        };
269        Factor::IdentifierFactor(FactorIdentifierFactor {
270            identifier_factor: Box::new(identifier_factor),
271        })
272    }
273}
274
275impl From<&GenericArgIdentifier> for Factor {
276    fn from(value: &GenericArgIdentifier) -> Self {
277        let identifier_factor = IdentifierFactor {
278            expression_identifier: Box::new(value.into()),
279            identifier_factor_opt: None,
280        };
281        Factor::IdentifierFactor(FactorIdentifierFactor {
282            identifier_factor: Box::new(identifier_factor),
283        })
284    }
285}
286
287impl From<(&ExpressionIdentifier, &FunctionCall)> for Factor {
288    fn from(value: (&ExpressionIdentifier, &FunctionCall)) -> Self {
289        let function_call = IdentifierFactorOptGroupFunctionCall {
290            function_call: Box::new(value.1.clone()),
291        };
292        let identifier_factor_opt_group = IdentifierFactorOptGroup::FunctionCall(function_call);
293        let identifier_factor_opt = IdentifierFactorOpt {
294            identifier_factor_opt_group: Box::new(identifier_factor_opt_group),
295        };
296        let identifier_factor = IdentifierFactor {
297            expression_identifier: Box::new(value.0.clone()),
298            identifier_factor_opt: Some(identifier_factor_opt),
299        };
300        Factor::IdentifierFactor(FactorIdentifierFactor {
301            identifier_factor: Box::new(identifier_factor),
302        })
303    }
304}
305
306impl From<&FixedType> for Factor {
307    fn from(value: &FixedType) -> Self {
308        let fixed_type = FactorTypeGroupFixedType {
309            fixed_type: Box::new(value.clone()),
310        };
311        let factor_type_group = FactorTypeGroup::FixedType(fixed_type);
312        let factor_type = FactorType {
313            factor_type_group: Box::new(factor_type_group),
314        };
315        let factor_type_factor = FactorTypeFactor {
316            factor_type_factor_list: vec![],
317            factor_type: Box::new(factor_type),
318        };
319        Factor::FactorTypeFactor(FactorFactorTypeFactor {
320            factor_type_factor: Box::new(factor_type_factor),
321        })
322    }
323}
324
325impl From<Factor> for Expression {
326    fn from(value: Factor) -> Self {
327        let expression02 = Box::new(Expression02 {
328            expression02_list: vec![],
329            factor: Box::new(value),
330            expression02_opt: None,
331        });
332        let expression01 = Box::new(Expression01 {
333            expression02,
334            expression01_list: vec![],
335        });
336        let if_expression = Box::new(IfExpression {
337            if_expression_list: vec![],
338            expression01,
339        });
340        Expression { if_expression }
341    }
342}
343
344impl From<&Number> for Expression {
345    fn from(value: &Number) -> Self {
346        let factor: Factor = value.into();
347        factor.into()
348    }
349}
350
351impl From<&BooleanLiteral> for Expression {
352    fn from(value: &BooleanLiteral) -> Self {
353        let factor: Factor = value.into();
354        factor.into()
355    }
356}
357
358impl From<&Identifier> for Expression {
359    fn from(value: &Identifier) -> Self {
360        let factor: Factor = value.into();
361        factor.into()
362    }
363}
364
365impl From<&ExpressionIdentifier> for Expression {
366    fn from(value: &ExpressionIdentifier) -> Self {
367        let factor: Factor = value.into();
368        factor.into()
369    }
370}
371
372impl From<(&ExpressionIdentifier, &FunctionCall)> for Expression {
373    fn from(value: (&ExpressionIdentifier, &FunctionCall)) -> Self {
374        let factor: Factor = value.into();
375        factor.into()
376    }
377}
378
379impl From<&GenericArgIdentifier> for Expression {
380    fn from(value: &GenericArgIdentifier) -> Self {
381        let factor: Factor = value.into();
382        factor.into()
383    }
384}
385
386impl From<&FixedType> for Expression {
387    fn from(value: &FixedType) -> Self {
388        let factor: Factor = value.into();
389        factor.into()
390    }
391}
392
393impl<'a> From<&'a StatementBlock> for Vec<&'a StatementBlockItem> {
394    fn from(value: &'a StatementBlock) -> Self {
395        let mut ret = vec![];
396        for x in &value.statement_block_list {
397            let mut x: Vec<_> = x.statement_block_group.as_ref().into();
398            ret.append(&mut x);
399        }
400        ret
401    }
402}
403
404impl<'a> From<&'a StatementBlockGroup> for Vec<&'a StatementBlockItem> {
405    fn from(x: &'a StatementBlockGroup) -> Self {
406        let mut ret = Vec::new();
407        match &*x.statement_block_group_group {
408            StatementBlockGroupGroup::BlockLBraceStatementBlockGroupGroupListRBrace(x) => {
409                for x in &x.statement_block_group_group_list {
410                    let mut x: Vec<&'a StatementBlockItem> =
411                        x.statement_block_group.as_ref().into();
412                    ret.append(&mut x);
413                }
414            }
415            StatementBlockGroupGroup::StatementBlockItem(x) => {
416                ret.push(x.statement_block_item.as_ref());
417            }
418        }
419        ret
420    }
421}
422
423impl<'a> From<&'a ModportDefaultList> for Vec<&'a Identifier> {
424    fn from(x: &'a ModportDefaultList) -> Self {
425        let mut ret = Vec::new();
426
427        ret.push(x.identifier.as_ref());
428        for x in &x.modport_default_list_list {
429            ret.push(x.identifier.as_ref());
430        }
431
432        ret
433    }
434}
435
436list_group_to_item!(Modport);
437list_group_to_item!(Enum);
438list_group_to_item!(StructUnion);
439list_group_to_item!(InstParameter);
440list_group_to_item!(InstPort);
441list_group_to_item!(WithParameter);
442list_group_to_item!(PortDeclaration);
443list_to_item!(WithGenericParameter);
444list_to_item!(WithGenericArgument);
445list_to_item!(Attribute);
446list_to_item!(Argument);
447list_to_item!(Concatenation);
448list_to_item!(AssignConcatenation);
449list_to_item!(ArrayLiteral);
450list_to_item!(StructConstructor);
451group_to_item!(Module);
452group_to_item!(Interface);
453group_to_item!(Generate);
454group_to_item!(Package);
455group_to_item!(Description);
456
457impl Expression {
458    pub fn unwrap_factor(&self) -> Option<&Factor> {
459        let exp = &*self.if_expression;
460        if !exp.if_expression_list.is_empty() {
461            return None;
462        }
463
464        let exp = &*exp.expression01;
465        if !exp.expression01_list.is_empty() {
466            return None;
467        }
468
469        let exp = &*exp.expression02;
470        if !exp.expression02_list.is_empty() {
471            return None;
472        }
473        if exp.expression02_opt.is_some() {
474            return None;
475        }
476
477        Some(exp.factor.as_ref())
478    }
479
480    pub fn unwrap_identifier(&self) -> Option<&ExpressionIdentifier> {
481        if let Some(Factor::IdentifierFactor(x)) = self.unwrap_factor()
482            && x.identifier_factor.identifier_factor_opt.is_none()
483        {
484            return Some(x.identifier_factor.expression_identifier.as_ref());
485        }
486
487        None
488    }
489
490    pub fn is_assignable(&self) -> bool {
491        let Some(factor) = self.unwrap_factor() else {
492            return false;
493        };
494
495        match factor {
496            Factor::IdentifierFactor(x) => {
497                // Function call
498                if x.identifier_factor.identifier_factor_opt.is_some() {
499                    return false;
500                }
501                true
502            }
503            Factor::LBraceConcatenationListRBrace(x) => {
504                let items: Vec<_> = x.concatenation_list.as_ref().into();
505                items
506                    .iter()
507                    .all(|x| x.concatenation_item_opt.is_none() && x.expression.is_assignable())
508            }
509            _ => false,
510        }
511    }
512
513    pub fn is_anonymous_expression(&self) -> bool {
514        let Some(factor) = self.unwrap_factor() else {
515            return false;
516        };
517
518        match factor {
519            Factor::IdentifierFactor(x) => {
520                let factor = &x.identifier_factor;
521
522                if factor.identifier_factor_opt.is_some() {
523                    return false;
524                }
525
526                let exp_identifier = &*factor.expression_identifier;
527                if exp_identifier.expression_identifier_opt.is_some() {
528                    return false;
529                }
530                if !exp_identifier.expression_identifier_list.is_empty() {
531                    return false;
532                }
533                if !exp_identifier.expression_identifier_list0.is_empty() {
534                    return false;
535                }
536
537                let scoped_identifier = &*exp_identifier.scoped_identifier;
538                if !scoped_identifier.scoped_identifier_list.is_empty() {
539                    return false;
540                }
541
542                let token = scoped_identifier.identifier().token;
543                is_anonymous_token(&token)
544            }
545            _ => false,
546        }
547    }
548}
549
550impl ModuleDeclaration {
551    pub fn collect_import_declarations(&self) -> Vec<ImportDeclaration> {
552        let mut ret = Vec::new();
553        for x in &self.module_declaration_list {
554            ret.append(&mut x.module_group.collect_import_declarations());
555        }
556        ret
557    }
558}
559
560impl ModuleGroup {
561    pub fn collect_import_declarations(&self) -> Vec<ImportDeclaration> {
562        let mut ret = Vec::new();
563        match &*self.module_group_group {
564            ModuleGroupGroup::LBraceModuleGroupGroupListRBrace(x) => {
565                for x in &x.module_group_group_list {
566                    ret.append(&mut x.module_group.collect_import_declarations());
567                }
568            }
569            ModuleGroupGroup::ModuleItem(x) => {
570                if let GenerateItem::ImportDeclaration(x) = &*x.module_item.generate_item {
571                    ret.push(x.import_declaration.as_ref().clone());
572                }
573            }
574        }
575
576        ret
577    }
578}
579
580impl InterfaceDeclaration {
581    pub fn collect_import_declarations(&self) -> Vec<ImportDeclaration> {
582        let mut ret = Vec::new();
583        for x in &self.interface_declaration_list {
584            ret.append(&mut x.interface_group.collect_import_declarations());
585        }
586        ret
587    }
588}
589
590impl InterfaceGroup {
591    pub fn collect_import_declarations(&self) -> Vec<ImportDeclaration> {
592        let mut ret = Vec::new();
593        match &*self.interface_group_group {
594            InterfaceGroupGroup::LBraceInterfaceGroupGroupListRBrace(x) => {
595                for x in &x.interface_group_group_list {
596                    ret.append(&mut x.interface_group.collect_import_declarations());
597                }
598            }
599            InterfaceGroupGroup::InterfaceItem(x) => {
600                if let InterfaceItem::GenerateItem(x) = &*x.interface_item
601                    && let GenerateItem::ImportDeclaration(x) = &*x.generate_item
602                {
603                    ret.push(x.import_declaration.as_ref().clone());
604                }
605            }
606        }
607        ret
608    }
609}
610
611impl PackageDeclaration {
612    pub fn collect_import_declarations(&self) -> Vec<ImportDeclaration> {
613        let mut ret = Vec::new();
614        for x in &self.package_declaration_list {
615            ret.append(&mut x.package_group.collect_import_declarations());
616        }
617        ret
618    }
619}
620
621impl PackageGroup {
622    pub fn collect_import_declarations(&self) -> Vec<ImportDeclaration> {
623        let mut ret = Vec::new();
624        match &*self.package_group_group {
625            PackageGroupGroup::LBracePackageGroupGroupListRBrace(x) => {
626                for x in &x.package_group_group_list {
627                    ret.append(&mut x.package_group.collect_import_declarations());
628                }
629            }
630            PackageGroupGroup::PackageItem(x) => {
631                if let PackageItem::ImportDeclaration(x) = &*x.package_item {
632                    ret.push(x.import_declaration.as_ref().clone());
633                }
634            }
635        }
636        ret
637    }
638}
639
640impl fmt::Display for Direction {
641    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
642        let token = match self {
643            Direction::Input(x) => &x.input.input_token,
644            Direction::Output(x) => &x.output.output_token,
645            Direction::Inout(x) => &x.inout.inout_token,
646            Direction::Modport(x) => &x.modport.modport_token,
647            Direction::Import(x) => &x.import.import_token,
648        };
649        token.fmt(f)
650    }
651}
652
653impl Identifier {
654    pub fn text(&self) -> StrId {
655        self.identifier_token.token.text
656    }
657}
658
659impl ScopedIdentifier {
660    pub fn get_scope_depth(&self) -> usize {
661        self.scoped_identifier_list.len() + 1
662    }
663}
664
665impl ExpressionIdentifier {
666    pub fn last_select(&self) -> Vec<Select> {
667        if self.expression_identifier_list0.is_empty() {
668            self.expression_identifier_list
669                .iter()
670                .map(|x| x.select.as_ref().clone())
671                .collect()
672        } else {
673            self.expression_identifier_list0
674                .last()
675                .unwrap()
676                .expression_identifier_list0_list
677                .iter()
678                .map(|x| x.select.as_ref().clone())
679                .collect()
680        }
681    }
682}
683
684impl HierarchicalIdentifier {
685    pub fn last_select(&self) -> Vec<Select> {
686        if self.hierarchical_identifier_list0.is_empty() {
687            self.hierarchical_identifier_list
688                .iter()
689                .map(|x| x.select.as_ref().clone())
690                .collect()
691        } else {
692            self.hierarchical_identifier_list0
693                .last()
694                .unwrap()
695                .hierarchical_identifier_list0_list
696                .iter()
697                .map(|x| x.select.as_ref().clone())
698                .collect()
699        }
700    }
701}
702
703impl AlwaysFfDeclaration {
704    pub fn has_if_reset(&self) -> bool {
705        let x = self.statement_block.statement_block_list.first();
706        if x.is_none() {
707            return false;
708        }
709
710        let x: Vec<_> = x.unwrap().statement_block_group.as_ref().into();
711        if let Some(StatementBlockItem::Statement(x)) = x.first() {
712            return matches!(*x.statement, Statement::IfResetStatement(_));
713        }
714
715        false
716    }
717
718    pub fn has_explicit_clock(&self) -> bool {
719        self.always_ff_declaration_opt.is_some()
720    }
721
722    pub fn get_explicit_clock(&self) -> Option<HierarchicalIdentifier> {
723        self.always_ff_declaration_opt.as_ref().map(|x| {
724            x.always_ff_event_list
725                .always_ff_clock
726                .hierarchical_identifier
727                .as_ref()
728                .clone()
729        })
730    }
731
732    pub fn has_explicit_reset(&self) -> bool {
733        if let Some(x) = &self.always_ff_declaration_opt {
734            return x.always_ff_event_list.always_ff_event_list_opt.is_some();
735        }
736
737        false
738    }
739
740    pub fn get_explicit_reset(&self) -> Option<HierarchicalIdentifier> {
741        if let Some(x) = &self.always_ff_declaration_opt
742            && let Some(x) = &x.always_ff_event_list.always_ff_event_list_opt
743        {
744            return Some(x.always_ff_reset.hierarchical_identifier.as_ref().clone());
745        }
746
747        None
748    }
749}
750
751impl ProtoDeclaration {
752    pub fn identifier_token(&self) -> VerylToken {
753        match &*self.proto_declaration_group {
754            ProtoDeclarationGroup::ProtoModuleDeclaration(x) => x
755                .proto_module_declaration
756                .identifier
757                .identifier_token
758                .clone(),
759            ProtoDeclarationGroup::ProtoInterfaceDeclaration(x) => x
760                .proto_interface_declaration
761                .identifier
762                .identifier_token
763                .clone(),
764            ProtoDeclarationGroup::ProtoPackageDeclaration(x) => x
765                .proto_package_declaration
766                .identifier
767                .identifier_token
768                .clone(),
769        }
770    }
771}
772
773impl PublicDescriptionItem {
774    pub fn identifier_token(&self) -> VerylToken {
775        match self {
776            PublicDescriptionItem::ModuleDeclaration(x) => {
777                x.module_declaration.identifier.identifier_token.clone()
778            }
779            PublicDescriptionItem::InterfaceDeclaration(x) => {
780                x.interface_declaration.identifier.identifier_token.clone()
781            }
782            PublicDescriptionItem::PackageDeclaration(x) => {
783                x.package_declaration.identifier.identifier_token.clone()
784            }
785            PublicDescriptionItem::AliasDeclaration(x) => {
786                x.alias_declaration.identifier.identifier_token.clone()
787            }
788            PublicDescriptionItem::ProtoDeclaration(x) => x.proto_declaration.identifier_token(),
789            PublicDescriptionItem::FunctionDeclaration(x) => {
790                x.function_declaration.identifier.identifier_token.clone()
791            }
792        }
793    }
794}
795
796impl DescriptionItem {
797    pub fn is_generic(&self) -> bool {
798        match self {
799            DescriptionItem::DescriptionItemOptPublicDescriptionItem(x) => {
800                match x.public_description_item.as_ref() {
801                    PublicDescriptionItem::ModuleDeclaration(x) => {
802                        x.module_declaration.module_declaration_opt.is_some()
803                    }
804                    PublicDescriptionItem::InterfaceDeclaration(x) => {
805                        x.interface_declaration.interface_declaration_opt.is_some()
806                    }
807                    PublicDescriptionItem::PackageDeclaration(x) => {
808                        x.package_declaration.package_declaration_opt.is_some()
809                    }
810                    _ => false,
811                }
812            }
813            _ => false,
814        }
815    }
816
817    pub fn identifier_token(&self) -> Option<VerylToken> {
818        match self {
819            DescriptionItem::DescriptionItemOptPublicDescriptionItem(x) => {
820                Some(x.public_description_item.identifier_token())
821            }
822            DescriptionItem::ImportDeclaration(_) => None,
823            DescriptionItem::BindDeclaration(x) => Some(
824                x.bind_declaration
825                    .component_instantiation
826                    .identifier
827                    .identifier_token
828                    .clone(),
829            ),
830            DescriptionItem::EmbedDeclaration(x) => {
831                Some(x.embed_declaration.identifier.identifier_token.clone())
832            }
833            DescriptionItem::IncludeDeclaration(x) => {
834                Some(x.include_declaration.identifier.identifier_token.clone())
835            }
836        }
837    }
838}