chainsaw/lang/python/
mod.rs1mod parser;
4mod resolver;
5
6#[cfg(test)]
7mod conformance;
8
9use std::path::{Path, PathBuf};
10use std::sync::Arc;
11
12use crate::lang::{LanguageSupport, ParseError, ParseResult};
13use crate::vfs::{OsVfs, Vfs};
14
15use self::resolver::{PythonResolver, package_name_from_path};
16
17pub struct PythonSupport {
18 resolver: PythonResolver,
19}
20
21impl std::fmt::Debug for PythonSupport {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 f.debug_struct("PythonSupport").finish_non_exhaustive()
24 }
25}
26
27impl PythonSupport {
28 pub fn new(root: &Path) -> Self {
29 Self::with_vfs(root, Arc::new(OsVfs))
30 }
31
32 pub fn with_vfs(root: &Path, vfs: Arc<dyn Vfs>) -> Self {
33 Self {
34 resolver: PythonResolver::with_vfs(root, vfs),
35 }
36 }
37
38 pub fn source_roots(&self) -> &[PathBuf] {
39 self.resolver.source_roots()
40 }
41}
42
43impl LanguageSupport for PythonSupport {
44 fn extensions(&self) -> &'static [&'static str] {
45 &["py"]
46 }
47
48 fn parse(&self, path: &Path, source: &str) -> Result<ParseResult, ParseError> {
49 parser::parse_file(path, source)
50 }
51
52 fn resolve(&self, from_dir: &Path, specifier: &str) -> Option<PathBuf> {
53 self.resolver.resolve(from_dir, specifier)
54 }
55
56 fn package_name(&self, resolved_path: &Path) -> Option<String> {
57 package_name_from_path(resolved_path, self.resolver.site_packages())
58 }
59
60 fn workspace_package_name(&self, _file_path: &Path, _project_root: &Path) -> Option<String> {
61 None
62 }
63}