ligen_python_parser/scope/
import_parser.rs

1use ligen::parser::ParserConfig;
2use ligen::parser::{Parser, utils::WithSource};
3use ligen::ir::{Import, Path, Identifier, PathSegment};
4use rustpython_parser::ast::{StmtImport, StmtImportFrom, Alias};
5
6use crate::prelude::*;
7use crate::PythonParser;
8
9impl Parser<WithSource<&StmtImport>> for PythonParser {
10    type Output = Vec<Import>;
11    fn parse(&self, input: WithSource<&StmtImport>, _config: &ParserConfig) -> Result<Self::Output> {
12        let mut imports = Vec::new();
13        for import in &input.ast.names {
14            imports.push(self.parse(input.sub(import), _config)?);
15        }
16        Ok(imports)
17    }
18}
19
20impl Parser<WithSource<&Alias>> for PythonParser {
21    type Output = Import;
22    fn parse(&self, input: WithSource<&Alias>, _config: &ParserConfig) -> Result<Self::Output> {
23        let visibility = Default::default();
24        let attributes = Default::default();
25        let renaming = input
26            .ast
27            .asname
28            .as_ref()
29            .and_then(|asname| self.identifier_parser.parse(asname.as_str(), _config).ok());
30        let path = self
31            .identifier_parser
32            .parse(input.ast.name.as_str(), _config)?
33            .into();
34        let import = Import { attributes, path, renaming, visibility };
35        Ok(import)
36    }
37}
38
39impl Parser<WithSource<&StmtImportFrom>> for PythonParser {
40    type Output = Vec<Import>;
41    fn parse(&self, input: WithSource<&StmtImportFrom>, _config: &ParserConfig) -> Result<Self::Output> {
42        let mut imports = Vec::new();
43        let levels = input
44            .ast
45            .level
46            .map(|value| value.to_usize())
47            .unwrap_or_default();
48        let segments = std::iter::once(Identifier::super_())
49            .cycle()
50            .take(levels)
51            .map(PathSegment::from)
52            .collect::<Vec<PathSegment>>();
53        let path = Path::from(segments);
54        let module_path = input
55            .ast
56            .module
57            .as_ref()
58            .map(|module| {
59                Path::from_string_with_separator(module.as_str(), ".")
60            }).unwrap_or(Path::from(Identifier::self_()));
61        let path = path.join(module_path);
62        for name in &input.ast.names {
63            let mut import = self.parse(input.sub(name), _config)?;
64            import.path = path.clone().join(import.path);
65            imports.push(import)
66        }
67        Ok(imports)
68    }
69}