Skip to content

Commit 1201940

Browse files
authored
Store module file path in analysis (#11)
1 parent 0db258d commit 1201940

File tree

4 files changed

+40
-14
lines changed

4 files changed

+40
-14
lines changed

crates/analyzer/src/analyze/crate_.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ use serde::{Deserialize, Serialize};
55
use super::{Enum, Module, Struct};
66

77
pub fn analyze_crate(path: &str) -> Result<AnalysisResult> {
8+
// make the path absolute
9+
let path =
10+
std::fs::canonicalize(path).context(format!("Error resolving crate path: {}", path))?;
811
// check the path is a directory
9-
let path = std::path::Path::new(path);
1012
if !path.is_dir() {
1113
return Err(anyhow::anyhow!(format!(
12-
"Path is not a directory: {}",
14+
"Crate path is not a directory: {}",
1315
path.to_string_lossy()
1416
)));
1517
}
@@ -73,10 +75,11 @@ pub fn analyze_crate(path: &str) -> Result<AnalysisResult> {
7375

7476
// read the top-level module
7577
let content = std::fs::read_to_string(&root_file)?;
76-
let (module, structs, enums) = Module::parse(&[&crate_.name], &content).context(format!(
77-
"Error parsing module {}",
78-
root_file.to_string_lossy()
79-
))?;
78+
let (module, structs, enums) = Module::parse(Some(&root_file), &[&crate_.name], &content)
79+
.context(format!(
80+
"Error parsing module {}",
81+
root_file.to_string_lossy()
82+
))?;
8083
result_.crate_.docstring = module.docstring.clone();
8184
let mut modules_to_read = module
8285
.declarations
@@ -119,6 +122,7 @@ pub fn analyze_crate(path: &str) -> Result<AnalysisResult> {
119122
let content = std::fs::read_to_string(&module_path)?;
120123
let path: Vec<String> = [&parent[..], &[module_name]].concat();
121124
let (module, structs, enums) = Module::parse(
125+
Some(&module_path),
122126
&path.iter().map(|s| s.as_str()).collect::<Vec<&str>>(),
123127
&content,
124128
)
@@ -256,22 +260,29 @@ mod tests {
256260
)?;
257261

258262
// Analyze the dummy crate
259-
let crate_ = analyze_crate(temp_dir_path.to_str().unwrap())?;
263+
let mut result = analyze_crate(temp_dir_path.to_str().unwrap())?;
260264

261-
assert_yaml_snapshot!(crate_, @r###"
265+
// Remove the file paths for snapshot testing, as they are non-deterministic
266+
for module in result.modules.iter_mut() {
267+
module.file = None;
268+
}
269+
270+
assert_yaml_snapshot!(result, @r###"
262271
---
263272
crate_:
264273
name: my_crate
265274
version: 0.1.0
266275
docstring: The crate docstring
267276
modules:
268-
- path:
277+
- file: ~
278+
path:
269279
- my_crate
270280
- my_module
271281
docstring: The module docstring
272282
declarations:
273283
- my_submodule
274-
- path:
284+
- file: ~
285+
path:
275286
- my_crate
276287
- my_module
277288
- my_submodule

crates/analyzer/src/analyze/module.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//! Analyze modules
2+
use std::path::Path;
3+
24
use anyhow::Result;
35
use serde::{Deserialize, Serialize};
46
use syn::parse_file;
@@ -13,6 +15,8 @@ use super::{docstring_from_attrs, enum_::Enum, struct_::Struct};
1315
/// :tags: rust
1416
/// :status: in-progress
1517
pub struct Module {
18+
/// The path to the module file
19+
pub file: Option<String>,
1620
/// The fully qualified name of the module
1721
pub path: Vec<String>,
1822
pub docstring: String,
@@ -26,9 +30,14 @@ impl Module {
2630
self.path.join("::")
2731
}
2832
/// Extract the relevant information from the AST
29-
pub fn parse(path: &[&str], content: &str) -> Result<(Self, Vec<Struct>, Vec<Enum>)> {
33+
pub fn parse(
34+
file: Option<&Path>,
35+
path: &[&str],
36+
content: &str,
37+
) -> Result<(Self, Vec<Struct>, Vec<Enum>)> {
3038
let syntax = parse_file(content)?;
3139
let mut mod_ = Self {
40+
file: file.map(|f| f.to_string_lossy().to_string()), // TODO better way to serialize the path, also ?
3241
path: path.iter().map(|s| s.to_string()).collect(),
3342
docstring: docstring_from_attrs(&syntax.attrs),
3443
declarations: vec![],
@@ -76,7 +85,7 @@ mod tests {
7685
use insta::assert_yaml_snapshot;
7786

7887
#[test]
79-
fn test_parse_enum() {
88+
fn test_parse_module() {
8089
let content = r###"
8190
//! Multi-line
8291
//! docstring
@@ -85,10 +94,11 @@ pub enum MyEnum {
8594
MyVariant1,
8695
}
8796
"###;
88-
let mod_ = Module::parse(&["test"], content).unwrap();
97+
let mod_ = Module::parse(None, &["test"], content).unwrap();
8998
assert_yaml_snapshot!(mod_, @r###"
9099
---
91-
- path:
100+
- file: ~
101+
path:
92102
- test
93103
docstring: "Multi-line\ndocstring"
94104
declarations: []

crates/py_binding/src/objects.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ impl From<analyze::Crate> for Crate {
4343
#[derive(Clone)]
4444
/// pyo3 representation of a module
4545
pub struct Module {
46+
#[pyo3(get)]
47+
pub file: Option<String>,
4648
#[pyo3(get)]
4749
pub path: Vec<String>,
4850
#[pyo3(get)]
@@ -67,6 +69,7 @@ impl Module {
6769
impl From<analyze::Module> for Module {
6870
fn from(module: analyze::Module) -> Self {
6971
Module {
72+
file: module.file,
7073
path: module.path,
7174
docstring: module.docstring,
7275
}

python/sphinx_rust/sphinx_rust.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ class Crate:
8989
class Module:
9090
"""Representation of a module."""
9191

92+
file: str | None
93+
"""The absolute path to the file containing the module."""
9294
name: str
9395
"""The name of the module."""
9496
path: list[str]

0 commit comments

Comments
 (0)