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