Skip to content

Commit 8a806c0

Browse files
committed
feat: add content to SourceMap struct
1 parent ac51f63 commit 8a806c0

2 files changed

Lines changed: 52 additions & 40 deletions

File tree

src/driver/mod.rs

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -72,36 +72,48 @@ pub struct SourceMap {
7272
/// This serves as the exact inverse of the `lookup` map.
7373
///
7474
/// This is highly useful for error reporting and diagnostics.
75-
paths: Vec<CanonPath>,
75+
entries: Vec<CanonSourceFile>,
7676
}
7777

7878
impl SourceMap {
7979
fn new(root_source: CanonSourceFile) -> Self {
8080
let mut ids = HashMap::new();
81+
8182
ids.insert(root_source.name().clone(), MAIN_MODULE);
83+
8284
Self {
8385
ids,
84-
paths: vec![root_source.name().clone()],
86+
entries: vec![root_source],
8587
}
8688
}
8789

88-
fn insert(&mut self, path: CanonPath) {
89-
let id = self.paths.len();
90-
self.ids.insert(path.clone(), id);
91-
self.paths.push(path);
92-
debug_assert_eq!(self.ids.len(), self.paths.len());
90+
fn insert(&mut self, entry: CanonSourceFile) {
91+
let id = self.entries.len();
92+
93+
self.ids.insert(entry.name().clone(), id);
94+
self.entries.push(entry);
95+
96+
debug_assert_eq!(self.ids.len(), self.entries.len());
9397
}
9498

9599
fn len(&self) -> usize {
96-
self.paths.len()
100+
self.entries.len()
97101
}
98102

99-
pub fn get_id(&self, path: &CanonPath) -> Option<usize> {
103+
pub fn id(&self, path: &CanonPath) -> Option<usize> {
100104
self.ids.get(path).copied()
101105
}
102106

103-
pub fn get_path(&self, id: usize) -> Option<&CanonPath> {
104-
self.paths.get(id)
107+
pub fn entry(&self, id: usize) -> Option<&CanonSourceFile> {
108+
self.entries.get(id)
109+
}
110+
111+
pub fn content(&self, id: usize) -> Option<Arc<str>> {
112+
self.entries.get(id).map(|e| e.content().clone())
113+
}
114+
115+
pub fn path(&self, id: usize) -> Option<&CanonPath> {
116+
self.entries.get(id).map(|e| e.name())
105117
}
106118

107119
pub fn iter(&self) -> impl Iterator<Item = (&CanonPath, &usize)> {
@@ -289,7 +301,7 @@ impl DependencyGraph {
289301
continue;
290302
}
291303

292-
if let Some(existing_id) = self.source_map.get_id(&path) {
304+
if let Some(existing_id) = self.source_map.id(&path) {
293305
let deps = self.dependencies.entry(current.id).or_default();
294306
if !deps.contains(&existing_id) {
295307
deps.push(existing_id);
@@ -299,11 +311,27 @@ impl DependencyGraph {
299311

300312
let new_id = self.source_map.len();
301313

314+
let Ok(content) = std::fs::read_to_string(path.as_path()) else {
315+
let err = RichError::new(
316+
Error::FileNotFound {
317+
filename: PathBuf::from(path.as_path()),
318+
},
319+
import_span,
320+
)
321+
.with_source(current.source.clone());
322+
323+
ctx.handler.push(err);
324+
325+
// Safe to ignore output: previous `.contains` check prevents collisions.
326+
let _ = ctx.invalid_imports.insert(path);
327+
continue;
328+
};
329+
330+
let source = CanonSourceFile::new(path.clone(), Arc::from(content));
331+
302332
let Some(module) = Self::parse_and_get_source_module(
303333
new_id,
304-
&path,
305-
&current.source,
306-
import_span,
334+
source.clone(),
307335
ctx.handler,
308336
ctx.unstable_features,
309337
) else {
@@ -312,7 +340,7 @@ impl DependencyGraph {
312340
continue;
313341
};
314342

315-
self.source_map.insert(path.clone());
343+
self.source_map.insert(source);
316344
self.modules.push(module);
317345

318346
self.dependencies
@@ -323,33 +351,17 @@ impl DependencyGraph {
323351
}
324352
}
325353

326-
/// This helper cleanly encapsulates the process of loading source text, parsing it
327-
/// into an `parse::Program`, and combining them so the compiler can easily work with the file.
328-
/// If the file is missing or contains syntax errors, it logs the diagnostic to the
354+
/// This helper cleanly encapsulates the process of parsing source text into an
355+
/// `parse::Program`, and combining them so the compiler can easily work with the file.
356+
/// If the file is contains syntax errors, it logs the diagnostic to the
329357
/// `ErrorCollector` and safely returns `None`.
330358
fn parse_and_get_source_module(
331359
new_id: usize,
332-
path: &CanonPath,
333-
importer_source: &CanonSourceFile,
334-
span: Span,
360+
source: CanonSourceFile,
335361
handler: &mut ErrorCollector,
336362
unstable_features: &UnstableFeatures,
337363
) -> Option<SourceModule> {
338-
let Ok(content) = std::fs::read_to_string(path.as_path()) else {
339-
let err = RichError::new(
340-
Error::FileNotFound {
341-
filename: PathBuf::from(path.as_path()),
342-
},
343-
span,
344-
)
345-
.with_source(importer_source.clone());
346-
347-
handler.push(err);
348-
return None;
349-
};
350-
351364
let mut error_handler = ErrorCollector::new();
352-
let source = CanonSourceFile::new(path.clone(), Arc::from(content));
353365
let ast = parse::Program::parse_from_str_with_errors(
354366
new_id,
355367
source.clone(),
@@ -715,7 +727,7 @@ pub(crate) mod tests {
715727

716728
// Assert: Size checks
717729
assert_eq!(graph.modules.len(), 3);
718-
assert_eq!(graph.source_map.paths.len(), 3);
730+
assert_eq!(graph.source_map.entries.len(), 3);
719731

720732
// Assert: Ensure BFS assigned the IDs in the exact correct order
721733
let main_id = ids["main"];

src/driver/resolve_order.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,17 @@ impl DependencyGraph {
8686
///
8787
/// The resolved path becomes `crate::<module>::<mod_path...>`, where
8888
/// `<module>` is `file_N` for dependency files and is omitted when the
89-
/// target is `MAIN_MODULE` (via `get_module_name`).
89+
/// target is [`MAIN_MODULE`] (via [`DependencyGraph::get_module_name`]).
9090
///
9191
/// ## Examples
9292
///
9393
/// - `use base_math::simple_op::hash` → `use crate::file_2::hash`
94-
/// - `use some_dep::item` (target = `MAIN_MODULE`) → `use crate::item`
94+
/// - `use some_dep::item` (target = [`MAIN_MODULE`]) → `use crate::item`
9595
fn rewrite_use(&self, use_decl: &parse::UseDecl) -> parse::Item {
9696
let resolved = &self.use_cache[use_decl.span()];
9797
let target_id = self
9898
.source_map
99-
.get_id(&resolved.path)
99+
.id(&resolved.path)
100100
.expect("resolved path must be registered");
101101

102102
let mut new_path = Vec::with_capacity(resolved.mod_path.len() + 2);

0 commit comments

Comments
 (0)