Skip to main content

veryl_analyzer/
symbol_path.rs

1use crate::ir::VarPath;
2use crate::literal::Literal;
3use crate::literal_table;
4use crate::namespace::Namespace;
5use crate::namespace_table;
6use crate::symbol::{DocComment, GenericInstanceProperty, GenericMap, Symbol, SymbolKind};
7use crate::symbol_table;
8use crate::{SVec, svec};
9use std::cmp::Ordering;
10use std::fmt;
11use veryl_parser::resource_table::{self, PathId, StrId};
12use veryl_parser::token_range::TokenRange;
13use veryl_parser::veryl_grammar_trait as syntax_tree;
14use veryl_parser::veryl_token::{Token, TokenSource, is_anonymous_token};
15
16#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
17pub struct SymbolPath(pub SVec<StrId>);
18
19impl SymbolPath {
20    pub fn new(x: &[StrId]) -> Self {
21        Self(x.into())
22    }
23
24    pub fn push(&mut self, x: StrId) {
25        self.0.push(x)
26    }
27
28    pub fn pop(&mut self) -> Option<StrId> {
29        self.0.pop()
30    }
31
32    pub fn clear(&mut self) {
33        self.0.clear()
34    }
35
36    pub fn as_slice(&self) -> &[StrId] {
37        self.0.as_slice()
38    }
39
40    pub fn to_vec(self) -> SVec<StrId> {
41        self.0
42    }
43
44    pub fn len(&self) -> usize {
45        self.0.len()
46    }
47
48    pub fn is_empty(&self) -> bool {
49        self.0.is_empty()
50    }
51}
52
53impl fmt::Display for SymbolPath {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        let mut text = String::new();
56        for path in self.as_slice() {
57            text.push_str(&format!("{path} "));
58        }
59        text.fmt(f)
60    }
61}
62
63impl From<&[Token]> for SymbolPath {
64    fn from(value: &[Token]) -> Self {
65        let mut path = SVec::new();
66        for x in value {
67            path.push(x.text);
68        }
69        SymbolPath(path)
70    }
71}
72
73impl From<&Token> for SymbolPath {
74    fn from(value: &Token) -> Self {
75        let path = svec![value.text];
76        SymbolPath(path)
77    }
78}
79
80impl From<&syntax_tree::Identifier> for SymbolPath {
81    fn from(value: &syntax_tree::Identifier) -> Self {
82        let path = svec![value.identifier_token.token.text];
83        SymbolPath(path)
84    }
85}
86
87impl From<&[syntax_tree::Identifier]> for SymbolPath {
88    fn from(value: &[syntax_tree::Identifier]) -> Self {
89        let mut path = SVec::new();
90        for x in value {
91            path.push(x.identifier_token.token.text);
92        }
93        SymbolPath(path)
94    }
95}
96
97impl From<&syntax_tree::HierarchicalIdentifier> for SymbolPath {
98    fn from(value: &syntax_tree::HierarchicalIdentifier) -> Self {
99        let mut path = SVec::new();
100        path.push(value.identifier.identifier_token.token.text);
101        for x in &value.hierarchical_identifier_list0 {
102            path.push(x.identifier.identifier_token.token.text);
103        }
104        SymbolPath(path)
105    }
106}
107
108impl From<&syntax_tree::ScopedIdentifier> for SymbolPath {
109    fn from(value: &syntax_tree::ScopedIdentifier) -> Self {
110        let path: GenericSymbolPath = value.into();
111        path.generic_path()
112    }
113}
114
115impl From<&syntax_tree::ExpressionIdentifier> for SymbolPath {
116    fn from(value: &syntax_tree::ExpressionIdentifier) -> Self {
117        let mut path: SymbolPath = value.scoped_identifier.as_ref().into();
118        for x in &value.expression_identifier_list0 {
119            path.push(x.identifier.identifier_token.token.text);
120        }
121        path
122    }
123}
124
125impl From<&str> for SymbolPath {
126    fn from(value: &str) -> Self {
127        let mut path = SVec::new();
128        for x in value.split("::") {
129            path.push(x.into());
130        }
131        SymbolPath(path)
132    }
133}
134
135#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
136pub struct SymbolPathNamespace(pub SymbolPath, pub Namespace);
137
138impl SymbolPathNamespace {
139    pub fn pop_namespace(&mut self) -> Option<StrId> {
140        self.1.pop()
141    }
142}
143
144impl From<&Token> for SymbolPathNamespace {
145    fn from(value: &Token) -> Self {
146        let namespace = namespace_table::get(value.id).unwrap_or_default();
147        SymbolPathNamespace(value.into(), namespace)
148    }
149}
150
151impl From<&Vec<Token>> for SymbolPathNamespace {
152    fn from(value: &Vec<Token>) -> Self {
153        let namespace = namespace_table::get(value[0].id).unwrap_or_default();
154        let path: Vec<_> = value.iter().map(|x| x.text).collect();
155        let path = SymbolPath::new(&path);
156        SymbolPathNamespace(path, namespace)
157    }
158}
159
160impl From<&SymbolPathNamespace> for SymbolPathNamespace {
161    fn from(value: &SymbolPathNamespace) -> Self {
162        value.clone()
163    }
164}
165
166impl From<(&SymbolPath, &Namespace)> for SymbolPathNamespace {
167    fn from(value: (&SymbolPath, &Namespace)) -> Self {
168        SymbolPathNamespace(value.0.clone(), value.1.clone())
169    }
170}
171
172impl From<(&Token, &Namespace)> for SymbolPathNamespace {
173    fn from(value: (&Token, &Namespace)) -> Self {
174        let path = SymbolPath::new(&[value.0.text]);
175        SymbolPathNamespace(path, value.1.clone())
176    }
177}
178
179impl From<(&Vec<Token>, &Namespace)> for SymbolPathNamespace {
180    fn from(value: (&Vec<Token>, &Namespace)) -> Self {
181        let path: Vec<_> = value.0.iter().map(|x| x.text).collect();
182        let path = SymbolPath::new(&path);
183        SymbolPathNamespace(path, value.1.clone())
184    }
185}
186
187impl From<(&Vec<StrId>, &Namespace)> for SymbolPathNamespace {
188    fn from(value: (&Vec<StrId>, &Namespace)) -> Self {
189        let path = SymbolPath::new(value.0);
190        SymbolPathNamespace(path, value.1.clone())
191    }
192}
193
194impl From<(&SVec<StrId>, &Namespace)> for SymbolPathNamespace {
195    fn from(value: (&SVec<StrId>, &Namespace)) -> Self {
196        let path = SymbolPath::new(value.0);
197        SymbolPathNamespace(path, value.1.clone())
198    }
199}
200
201impl From<(StrId, &Namespace)> for SymbolPathNamespace {
202    fn from(value: (StrId, &Namespace)) -> Self {
203        let path = SymbolPath::new(&[value.0]);
204        SymbolPathNamespace(path, value.1.clone())
205    }
206}
207
208impl From<&syntax_tree::Identifier> for SymbolPathNamespace {
209    fn from(value: &syntax_tree::Identifier) -> Self {
210        let namespace = namespace_table::get(value.identifier_token.token.id).unwrap_or_default();
211        SymbolPathNamespace(value.into(), namespace)
212    }
213}
214
215impl From<(&syntax_tree::Identifier, &Namespace)> for SymbolPathNamespace {
216    fn from(value: (&syntax_tree::Identifier, &Namespace)) -> Self {
217        let (identifier, namespace) = value;
218        SymbolPathNamespace(identifier.into(), namespace.clone())
219    }
220}
221
222impl From<(&syntax_tree::Identifier, Option<&Namespace>)> for SymbolPathNamespace {
223    fn from(value: (&syntax_tree::Identifier, Option<&Namespace>)) -> Self {
224        let (identifier, namespace) = value;
225        if let Some(namespace) = namespace {
226            (identifier, namespace).into()
227        } else {
228            identifier.into()
229        }
230    }
231}
232
233impl From<&[syntax_tree::Identifier]> for SymbolPathNamespace {
234    fn from(value: &[syntax_tree::Identifier]) -> Self {
235        let namespace =
236            namespace_table::get(value[0].identifier_token.token.id).unwrap_or_default();
237        SymbolPathNamespace(value.into(), namespace)
238    }
239}
240
241impl From<&syntax_tree::HierarchicalIdentifier> for SymbolPathNamespace {
242    fn from(value: &syntax_tree::HierarchicalIdentifier) -> Self {
243        let namespace =
244            namespace_table::get(value.identifier.identifier_token.token.id).unwrap_or_default();
245        SymbolPathNamespace(value.into(), namespace)
246    }
247}
248
249impl From<&syntax_tree::ScopedIdentifier> for SymbolPathNamespace {
250    fn from(value: &syntax_tree::ScopedIdentifier) -> Self {
251        let namespace = namespace_table::get(value.identifier().token.id).unwrap_or_default();
252        SymbolPathNamespace(value.into(), namespace)
253    }
254}
255
256impl From<&syntax_tree::ExpressionIdentifier> for SymbolPathNamespace {
257    fn from(value: &syntax_tree::ExpressionIdentifier) -> Self {
258        let namespace = namespace_table::get(value.identifier().token.id).unwrap_or_default();
259        SymbolPathNamespace(value.into(), namespace)
260    }
261}
262
263impl From<&GenericSymbolPathNamespace> for SymbolPathNamespace {
264    fn from(value: &GenericSymbolPathNamespace) -> Self {
265        SymbolPathNamespace(value.0.generic_path(), value.1.clone())
266    }
267}
268
269impl From<&GenericSymbolPath> for SymbolPathNamespace {
270    fn from(value: &GenericSymbolPath) -> Self {
271        let namespace = namespace_table::get(value.paths[0].base.id).unwrap_or_default();
272        SymbolPathNamespace(value.generic_path(), namespace)
273    }
274}
275
276#[derive(Clone, Debug, PartialEq, Eq)]
277pub struct GenericSymbolPathNamespace(pub GenericSymbolPath, pub Namespace);
278
279impl From<(&GenericSymbolPath, &Namespace)> for GenericSymbolPathNamespace {
280    fn from(value: (&GenericSymbolPath, &Namespace)) -> Self {
281        let (path, namespace) = value;
282        GenericSymbolPathNamespace(path.clone(), namespace.clone())
283    }
284}
285
286#[derive(Copy, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
287pub enum GenericSymbolPathKind {
288    Identifier,
289    TypeLiteral,
290    ValueLiteral,
291}
292
293impl fmt::Display for GenericSymbolPathKind {
294    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295        let text = match self {
296            GenericSymbolPathKind::Identifier => "identifier".to_string(),
297            GenericSymbolPathKind::TypeLiteral => "type".to_string(),
298            GenericSymbolPathKind::ValueLiteral => "value".to_string(),
299        };
300        text.fmt(f)
301    }
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
305pub struct GenericSymbolPath {
306    pub paths: Vec<GenericSymbol>,
307    pub kind: GenericSymbolPathKind,
308    pub range: TokenRange,
309}
310
311#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
312pub struct GenericSymbol {
313    pub base: Token,
314    pub arguments: Vec<GenericSymbolPath>,
315}
316
317impl GenericSymbol {
318    pub fn base(&self) -> StrId {
319        self.base.text
320    }
321
322    pub fn mangled(&self) -> StrId {
323        if self.arguments.is_empty() {
324            self.base()
325        } else {
326            // If arguments have unresolved generic parameter, return base path
327            for arg in &self.arguments {
328                if !arg.is_resolvable() {
329                    continue;
330                }
331                let head = &arg.paths[0];
332                if let Ok(symbol) = symbol_table::resolve(&head.base)
333                    && matches!(symbol.found.kind, SymbolKind::GenericParameter(_))
334                {
335                    return self.base();
336                }
337            }
338
339            let mut text = format!("__{}", self.base);
340            for a in &self.arguments {
341                text.push('_');
342                for a in a.mangled_path().0.as_slice() {
343                    text.push_str(&format!("_{a}"));
344                }
345            }
346            resource_table::insert_str(&text)
347        }
348    }
349
350    pub fn get_generic_instance(
351        &self,
352        base: &Symbol,
353        affiliation_symbol: Option<&Symbol>,
354    ) -> Option<(Token, Symbol)> {
355        if self.arguments.is_empty() {
356            None
357        } else {
358            let affiliation_id = if let Some(symbol) = affiliation_symbol {
359                Some(symbol.id)
360            } else {
361                base.get_parent().map(|parent| parent.id)
362            };
363            let property = GenericInstanceProperty {
364                base: base.id,
365                arguments: self.arguments.clone(),
366                affiliation_symbol: affiliation_id,
367            };
368            let kind = SymbolKind::GenericInstance(property);
369            let token = &self.base;
370            let token = Token::new(
371                &self.mangled().to_string(),
372                token.line,
373                token.column,
374                token.length,
375                token.pos,
376                token.source,
377            );
378            let symbol = Symbol::new(&token, kind, &base.namespace, false, DocComment::default());
379
380            Some((token, symbol))
381        }
382    }
383}
384
385impl GenericSymbolPath {
386    pub fn len(&self) -> usize {
387        self.paths.len()
388    }
389
390    pub fn is_empty(&self) -> bool {
391        self.paths.is_empty()
392    }
393
394    pub fn base_path(&self, i: usize) -> SymbolPath {
395        let path: Vec<_> = self
396            .paths
397            .iter()
398            .enumerate()
399            .filter_map(|(j, x)| match i.cmp(&j) {
400                Ordering::Greater => Some(x.mangled()),
401                Ordering::Equal => Some(x.base()),
402                Ordering::Less => None,
403            })
404            .collect();
405        SymbolPath::new(&path)
406    }
407
408    pub fn slice(&self, i: usize) -> GenericSymbolPath {
409        let paths: Vec<_> = self.paths.clone().drain(0..=i).collect();
410        let range = TokenRange {
411            beg: paths.first().map(|x| x.base).unwrap(),
412            end: paths.last().map(|x| x.base).unwrap(),
413        };
414        GenericSymbolPath {
415            paths,
416            kind: self.kind,
417            range,
418        }
419    }
420
421    pub fn mangled_path(&self) -> SymbolPath {
422        let path: Vec<_> = self.paths.iter().map(|x| x.mangled()).collect();
423        SymbolPath::new(&path)
424    }
425
426    pub fn generic_path(&self) -> SymbolPath {
427        let path: Vec<_> = self.paths.iter().map(|x| x.base()).collect();
428        SymbolPath::new(&path)
429    }
430
431    pub fn generic_arguments(&self) -> Vec<Vec<GenericSymbolPath>> {
432        let path: Vec<_> = self.paths.iter().map(|x| x.arguments.clone()).collect();
433        path
434    }
435
436    pub fn file_path(&self) -> Option<PathId> {
437        if let TokenSource::File { path, .. } = self.range.beg.source {
438            Some(path)
439        } else {
440            None
441        }
442    }
443
444    pub fn unalias(&mut self) {
445        if !self.is_resolvable() {
446            return;
447        }
448
449        let Some(namespace) = namespace_table::get(self.paths[0].base.id) else {
450            return;
451        };
452        let mut generic_maps: Vec<_> = Vec::new();
453
454        for i in 0..self.len() {
455            let symbol = symbol_table::resolve((&self.slice(i).mangled_path(), &namespace));
456
457            if let Ok(ref symbol) = symbol
458                && let Some(mut alias_target) = symbol.found.alias_target(false)
459            {
460                alias_target.resolve_imported(&namespace, Some(&generic_maps));
461                alias_target.apply_map(&generic_maps);
462                if (i + 1) < self.len() {
463                    for j in (i + 1)..self.len() {
464                        alias_target.paths.push(self.paths[j].clone());
465                    }
466                }
467                alias_target.unalias();
468
469                self.paths = alias_target.paths;
470                self.kind = alias_target.kind;
471                self.range = alias_target.range;
472                return;
473            }
474
475            if let Some(path) = self.paths.get_mut(i) {
476                for arg in path.arguments.iter_mut() {
477                    arg.unalias();
478                }
479
480                if let Ok(ref symbol) = symbol
481                    && matches!(&symbol.found.kind, SymbolKind::GenericInstance(_))
482                {
483                    let map = symbol
484                        .found
485                        .generic_map(Some(symbol.found.id), &path.arguments);
486                    generic_maps.push(map);
487                }
488            }
489        }
490    }
491
492    pub fn to_literal(&self) -> Option<Literal> {
493        literal_table::get(&self.paths[0].base.id)
494    }
495
496    pub fn to_generic_maps(&self) -> Vec<GenericMap> {
497        let mut ret = vec![];
498
499        let mut full_path = vec![];
500        for path in &self.paths {
501            full_path.push(path.base);
502            if let Ok(symbol) = symbol_table::resolve(&full_path) {
503                let params = symbol.found.generic_parameters();
504
505                let mut map = GenericMap::default();
506
507                for (i, (name, value)) in params.into_iter().enumerate() {
508                    if let Some(x) = path.arguments.get(i) {
509                        map.map.insert(name, x.clone());
510                    } else if let Some(x) = value.default_value {
511                        map.map.insert(name, x);
512                    }
513                }
514
515                ret.push(map);
516            }
517        }
518
519        ret
520    }
521
522    pub fn is_anonymous(&self) -> bool {
523        self.paths.len() == 1
524            && self.paths[0].arguments.is_empty()
525            && is_anonymous_token(&self.paths[0].base)
526    }
527
528    pub fn is_resolvable(&self) -> bool {
529        self.kind == GenericSymbolPathKind::Identifier
530    }
531
532    pub fn is_generic(&self) -> bool {
533        for path in &self.paths {
534            if !path.arguments.is_empty() {
535                return true;
536            }
537        }
538        false
539    }
540
541    pub fn is_generic_reference(&self) -> bool {
542        // path starts with generic parameter
543        if !self.is_resolvable() {
544            return false;
545        }
546
547        let head = &self.paths[0];
548        if let Ok(symbol) = symbol_table::resolve(&head.base) {
549            let is_generic = matches!(
550                symbol.found.kind,
551                SymbolKind::GenericParameter(_) | SymbolKind::ProtoPackage(_)
552            ) || (symbol.imported
553                && symbol
554                    .found
555                    .get_parent_package()
556                    .map(|x| matches!(x.kind, SymbolKind::ProtoPackage(_)))
557                    .unwrap_or(false));
558            if is_generic {
559                return true;
560            }
561        }
562        // path contains generic parameter as generic argument
563        for path in &self.paths {
564            for arg in &path.arguments {
565                if arg.is_generic_reference() {
566                    return true;
567                }
568            }
569        }
570
571        false
572    }
573
574    pub fn apply_map(&mut self, maps: &[GenericMap]) {
575        for map in maps.iter().rev() {
576            let head = &self.paths[0];
577            if let Some(x) = map.map.get(&head.base()) {
578                let mut paths: Vec<_> = self.paths.drain(1..).collect();
579                self.paths.clone_from(&x.paths);
580                self.paths.append(&mut paths);
581                self.kind = x.kind;
582                self.range = x.range;
583                break;
584            }
585        }
586
587        for path in &mut self.paths {
588            for arg in &mut path.arguments {
589                arg.apply_map(maps);
590            }
591        }
592    }
593
594    /// Resolve and expand path if the path is imported at declaration
595    pub fn resolve_imported(
596        &mut self,
597        namespace: &Namespace,
598        generic_maps: Option<&Vec<GenericMap>>,
599    ) {
600        if !self.is_resolvable() {
601            return;
602        }
603
604        // Import process is performed against the head symbol of the given path.
605        let head = self.slice(0).generic_path();
606        if let Ok(head_symbol) = symbol_table::resolve((&head, namespace))
607            && head_symbol.imported
608        {
609            let self_namespace = namespace_table::get(self.range.beg.id).unwrap();
610            let Some(self_file_path) = self.file_path() else {
611                return;
612            };
613
614            if let Ok(head_symbol) = symbol_table::resolve((&head, &self_namespace))
615                && head_symbol.found.get_parent_package().is_some()
616                && let Some(import) = head_symbol
617                    .found
618                    .imported
619                    .iter()
620                    .find(|x| namespace.included(&x.namespace))
621            {
622                let mut package_path = import.path.0.clone();
623                if !import.wildcard {
624                    package_path.paths.pop();
625                }
626                if let Some(maps) = generic_maps {
627                    package_path.apply_map(maps);
628                }
629                package_path.unalias();
630
631                for (i, path) in package_path.paths.iter().enumerate() {
632                    let token = Token::generate(path.base.text, self_file_path);
633                    namespace_table::insert(token.id, self_file_path, &self_namespace);
634
635                    let mut path = path.clone();
636                    path.base = token;
637                    self.paths.insert(i, path);
638                }
639            }
640        }
641
642        for path in &mut self.paths {
643            for arg in &mut path.arguments {
644                arg.resolve_imported(namespace, generic_maps);
645            }
646        }
647    }
648
649    pub fn append_namespace_path(&mut self, namespace: &Namespace, target_namespace: &Namespace) {
650        fn is_defined_in_package(path: &GenericSymbolPath, namespace: &Namespace) -> bool {
651            if !namespace
652                .get_symbol()
653                .map(|x| x.is_package(true))
654                .unwrap_or(false)
655            {
656                // The given namespace does not point a package
657                return false;
658            }
659
660            symbol_table::resolve((&path.base_path(0), namespace))
661                .map(|symbol| {
662                    // Generic parameter is not visible from other namespace.
663                    !matches!(symbol.found.kind, SymbolKind::GenericParameter(_))
664                        && symbol.found.namespace.matched(namespace)
665                })
666                .unwrap_or(false)
667        }
668
669        fn is_component_path(path: &GenericSymbolPath, namespace: &Namespace) -> bool {
670            symbol_table::resolve((&path.base_path(0), namespace))
671                .map(|x| x.found.is_component(true))
672                .unwrap_or(false)
673        }
674
675        if let Some(file_path) = self.file_path() {
676            if !namespace.matched(target_namespace) && is_defined_in_package(self, namespace) {
677                // The given path is referened from the `target_namespace`
678                // but it is not visible because it has no package paths.
679                for i in 1..namespace.depth() {
680                    let token = Token::generate(namespace.paths[i], file_path);
681                    namespace_table::insert(token.id, file_path, namespace);
682
683                    let symbol_path = GenericSymbol {
684                        base: token,
685                        arguments: vec![],
686                    };
687                    self.paths.insert(i - 1, symbol_path);
688                }
689            }
690
691            if namespace.paths[0] != target_namespace.paths[0] && is_component_path(self, namespace)
692            {
693                // Append the project prefix to the path.
694                let token = Token::generate(namespace.paths[0], file_path);
695                namespace_table::insert(token.id, file_path, namespace);
696
697                let symbol_path = GenericSymbol {
698                    base: token,
699                    arguments: vec![],
700                };
701                self.paths.insert(0, symbol_path);
702            }
703        }
704
705        for i in 0..self.len() {
706            if !self.paths[i].arguments.is_empty()
707                && let Ok(path_symbol) =
708                    symbol_table::resolve((&self.slice(i).generic_path(), namespace))
709            {
710                for arg in &mut self.paths[i].arguments {
711                    arg.append_namespace_path(namespace, &path_symbol.found.namespace);
712                }
713            }
714        }
715    }
716
717    pub fn to_var_path(&self) -> Option<VarPath> {
718        let mut ret = VarPath::default();
719        for path in &self.paths {
720            if path.arguments.is_empty() {
721                ret.push(path.base());
722            } else {
723                return None;
724            }
725        }
726        Some(ret)
727    }
728}
729
730impl From<&Token> for GenericSymbolPath {
731    fn from(value: &Token) -> Self {
732        let path = GenericSymbol {
733            base: *value,
734            arguments: vec![],
735        };
736        GenericSymbolPath {
737            paths: vec![path],
738            kind: GenericSymbolPathKind::Identifier,
739            range: value.into(),
740        }
741    }
742}
743
744impl From<&syntax_tree::FixedType> for GenericSymbolPath {
745    fn from(value: &syntax_tree::FixedType) -> Self {
746        let token: TokenRange = value.into();
747        GenericSymbolPath {
748            paths: vec![GenericSymbol {
749                base: token.beg,
750                arguments: Vec::new(),
751            }],
752            kind: GenericSymbolPathKind::TypeLiteral,
753            range: token,
754        }
755    }
756}
757
758impl From<&syntax_tree::Number> for GenericSymbolPath {
759    fn from(value: &syntax_tree::Number) -> Self {
760        let token = match value {
761            syntax_tree::Number::IntegralNumber(x) => match x.integral_number.as_ref() {
762                syntax_tree::IntegralNumber::Based(x) => x.based.based_token.token,
763                syntax_tree::IntegralNumber::AllBit(x) => x.all_bit.all_bit_token.token,
764                syntax_tree::IntegralNumber::BaseLess(x) => x.base_less.base_less_token.token,
765            },
766            syntax_tree::Number::RealNumber(x) => match x.real_number.as_ref() {
767                syntax_tree::RealNumber::Exponent(x) => x.exponent.exponent_token.token,
768                syntax_tree::RealNumber::FixedPoint(x) => x.fixed_point.fixed_point_token.token,
769            },
770        };
771
772        GenericSymbolPath {
773            paths: vec![GenericSymbol {
774                base: token,
775                arguments: Vec::new(),
776            }],
777            kind: GenericSymbolPathKind::ValueLiteral,
778            range: token.into(),
779        }
780    }
781}
782
783impl From<&syntax_tree::BooleanLiteral> for GenericSymbolPath {
784    fn from(value: &syntax_tree::BooleanLiteral) -> Self {
785        let token = match value {
786            syntax_tree::BooleanLiteral::True(x) => x.r#true.true_token.token,
787            syntax_tree::BooleanLiteral::False(x) => x.r#false.false_token.token,
788        };
789        GenericSymbolPath {
790            paths: vec![GenericSymbol {
791                base: token,
792                arguments: Vec::new(),
793            }],
794            kind: GenericSymbolPathKind::ValueLiteral,
795            range: token.into(),
796        }
797    }
798}
799
800impl From<&syntax_tree::WithGenericArgumentItem> for GenericSymbolPath {
801    fn from(value: &syntax_tree::WithGenericArgumentItem) -> Self {
802        match value {
803            syntax_tree::WithGenericArgumentItem::GenericArgIdentifier(x) => {
804                x.generic_arg_identifier.as_ref().into()
805            }
806            syntax_tree::WithGenericArgumentItem::FixedType(x) => x.fixed_type.as_ref().into(),
807            syntax_tree::WithGenericArgumentItem::Number(x) => x.number.as_ref().into(),
808            syntax_tree::WithGenericArgumentItem::BooleanLiteral(x) => {
809                x.boolean_literal.as_ref().into()
810            }
811        }
812    }
813}
814
815impl From<&syntax_tree::Identifier> for GenericSymbolPath {
816    fn from(value: &syntax_tree::Identifier) -> Self {
817        GenericSymbolPath {
818            paths: vec![GenericSymbol {
819                base: value.identifier_token.token,
820                arguments: Vec::new(),
821            }],
822            kind: GenericSymbolPathKind::Identifier,
823            range: value.into(),
824        }
825    }
826}
827
828impl From<&syntax_tree::HierarchicalIdentifier> for GenericSymbolPath {
829    fn from(value: &syntax_tree::HierarchicalIdentifier) -> Self {
830        let mut path: Self = value.identifier.as_ref().into();
831
832        for x in &value.hierarchical_identifier_list0 {
833            path.paths.push(GenericSymbol {
834                base: x.identifier.identifier_token.token,
835                arguments: vec![],
836            });
837        }
838
839        path.range = value.into();
840        path
841    }
842}
843
844impl From<&syntax_tree::ScopedIdentifier> for GenericSymbolPath {
845    fn from(value: &syntax_tree::ScopedIdentifier) -> Self {
846        let mut paths = Vec::new();
847        match value.scoped_identifier_group.as_ref() {
848            syntax_tree::ScopedIdentifierGroup::DollarIdentifier(x) => {
849                let base = x.dollar_identifier.dollar_identifier_token.token;
850                paths.push(GenericSymbol {
851                    base,
852                    arguments: Vec::new(),
853                });
854            }
855            syntax_tree::ScopedIdentifierGroup::IdentifierScopedIdentifierOpt(x) => {
856                let base = x.identifier.identifier_token.token;
857                let mut arguments = Vec::new();
858
859                if let Some(ref x) = x.scoped_identifier_opt
860                    && let Some(ref x) = x.with_generic_argument.with_generic_argument_opt
861                {
862                    let list: Vec<_> = x.with_generic_argument_list.as_ref().into();
863                    for x in &list {
864                        let arg: GenericSymbolPath = (*x).into();
865                        arguments.push(arg);
866                    }
867                }
868
869                paths.push(GenericSymbol { base, arguments });
870            }
871        }
872
873        for x in &value.scoped_identifier_list {
874            let base = x.identifier.identifier_token.token;
875            let mut arguments = Vec::new();
876
877            if let Some(ref x) = x.scoped_identifier_opt0
878                && let Some(ref x) = x.with_generic_argument.with_generic_argument_opt
879            {
880                let list: Vec<_> = x.with_generic_argument_list.as_ref().into();
881                for x in &list {
882                    let arg: GenericSymbolPath = (*x).into();
883                    arguments.push(arg);
884                }
885            }
886
887            paths.push(GenericSymbol { base, arguments });
888        }
889
890        GenericSymbolPath {
891            paths,
892            kind: GenericSymbolPathKind::Identifier,
893            range: value.into(),
894        }
895    }
896}
897
898impl From<&syntax_tree::ExpressionIdentifier> for GenericSymbolPath {
899    fn from(value: &syntax_tree::ExpressionIdentifier) -> Self {
900        let mut path: GenericSymbolPath = value.scoped_identifier.as_ref().into();
901
902        for base in value
903            .expression_identifier_list0
904            .iter()
905            .map(|x| x.identifier.identifier_token.token)
906        {
907            path.paths.push(GenericSymbol {
908                base,
909                arguments: vec![],
910            });
911        }
912
913        path.range = value.into();
914        path
915    }
916}
917
918impl From<&syntax_tree::GenericArgIdentifier> for GenericSymbolPath {
919    fn from(value: &syntax_tree::GenericArgIdentifier) -> Self {
920        let mut path: Self = value.scoped_identifier.as_ref().into();
921
922        for x in &value.generic_arg_identifier_list {
923            path.paths.push(GenericSymbol {
924                base: x.identifier.identifier_token.token,
925                arguments: vec![],
926            });
927        }
928
929        path.range = value.into();
930        path
931    }
932}
933
934impl fmt::Display for GenericSymbolPath {
935    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
936        let mut text = String::new();
937        for (i, path) in self.paths.iter().enumerate() {
938            if i == 0 {
939                text.push_str(&format!("{}", path.mangled()));
940            } else {
941                text.push_str(&format!(" {}", path.mangled()));
942            }
943        }
944        text.fmt(f)
945    }
946}