Skip to main content

lisette_syntax/program/
file.rs

1use std::collections::HashMap;
2use std::hash::BuildHasher;
3
4use ecow::EcoString;
5
6use crate::ast::{Expression, ImportAlias, Span};
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct File {
10    pub id: u32,
11    pub module_id: String,
12    pub name: String,
13    pub source: String,
14    pub items: Vec<Expression>,
15}
16
17#[derive(Debug, Clone, PartialEq)]
18pub struct FileImport {
19    pub name: EcoString,
20    pub name_span: Span,
21    pub alias: Option<ImportAlias>,
22    pub span: Span,
23}
24
25impl FileImport {
26    pub fn effective_alias<S: BuildHasher>(
27        &self,
28        go_package_names: &HashMap<String, String, S>,
29    ) -> Option<String> {
30        match &self.alias {
31            Some(ImportAlias::Named(name, _)) => Some(name.to_string()),
32            Some(ImportAlias::Blank(_)) => None,
33            None => {
34                if let Some(pkg_name) = go_package_names.get(self.name.as_str()) {
35                    return Some(pkg_name.clone());
36                }
37                Some(
38                    self.name
39                        .strip_prefix("go:")
40                        .unwrap_or(&self.name)
41                        .split('/')
42                        .next_back()
43                        .unwrap_or(&self.name)
44                        .to_string(),
45                )
46            }
47        }
48    }
49}
50
51impl File {
52    pub fn new(module_id: &str, name: &str, source: &str, items: Vec<Expression>, id: u32) -> Self {
53        File {
54            id,
55            module_id: module_id.to_string(),
56            name: name.to_string(),
57            source: source.to_string(),
58            items,
59        }
60    }
61
62    pub fn new_cached(module_id: &str, name: &str, source: &str, id: u32) -> Self {
63        Self {
64            id,
65            module_id: module_id.to_string(),
66            name: name.to_string(),
67            source: source.to_string(),
68            items: vec![],
69        }
70    }
71
72    pub fn is_d_lis(&self) -> bool {
73        self.name.ends_with(".d.lis")
74    }
75
76    pub fn is_lis(&self) -> bool {
77        !self.is_d_lis()
78    }
79
80    pub fn imports(&self) -> Vec<FileImport> {
81        self.items
82            .iter()
83            .filter_map(|item| match item {
84                Expression::ModuleImport {
85                    name,
86                    name_span,
87                    alias,
88                    span,
89                } => Some(FileImport {
90                    name: name.clone(),
91                    name_span: *name_span,
92                    alias: alias.clone(),
93                    span: *span,
94                }),
95                _ => None,
96            })
97            .collect()
98    }
99
100    pub fn go_filename(&self) -> String {
101        std::path::Path::new(&self.name)
102            .with_extension("go")
103            .display()
104            .to_string()
105    }
106}