rem_extract/startup/
types.rs

1use std::fs::{self, File};
2use std::io::Write;
3use std::path::PathBuf;
4use anyhow::Context;
5
6use ra_ap_base_db::{
7    CrateGraph, FileSet, ProcMacroPaths
8};
9use ra_ap_paths::AbsPathBuf;
10use ra_ap_vfs::{FileId, VfsPath};
11
12/// Shared context for analysis. Constructd once and cloned as needed.
13pub struct SingleFileStdContext {
14    pub base_graph: CrateGraph,
15    pub proc_macros: ProcMacroPaths,
16    pub sysroot_files: SysrootFileMap,
17}
18
19
20/// Dumb path→FileId map; good enough for a first cut.
21#[derive(Default, Clone)]
22pub struct SysrootFileMap {
23    next_id: u32,
24    paths: Vec<(AbsPathBuf, FileId)>,
25}
26
27
28impl SysrootFileMap {
29    pub fn new() -> Self {
30        Self { next_id: 0, paths: Vec::new() }
31    }
32
33    pub fn file_id_for(&mut self, path: AbsPathBuf) -> FileId {
34        if let Some((_, id)) = self.paths.iter().find(|(p, _)| *p == path) {
35            return *id;
36        }
37
38        let id = FileId::from_raw(self.next_id);
39        self.next_id += 1;
40        self.paths.push((path, id));
41        id
42    }
43
44    /// Iterate all sysroot file IDs.
45    pub fn file_ids(&self) -> impl Iterator<Item = FileId> + '_ {
46        self.paths.iter().map(|(_, id)| *id)
47    }
48
49    /// Build a FileSet containing all sysroot files.
50    pub fn to_file_set(&self) -> FileSet {
51        let mut fs = FileSet::default();
52        for (abs, id) in &self.paths {
53            // In ra_ap, VfsPath usually has a From<AbsPathBuf> impl.
54            let vfs_path = VfsPath::from(abs.clone());
55            fs.insert(*id, vfs_path);
56        }
57        fs
58    }
59
60    pub fn entries(&self) -> &[(AbsPathBuf, FileId)] {
61        &self.paths
62    }
63}
64
65pub struct TempScriptAnchor {
66    path: PathBuf,
67}
68
69impl TempScriptAnchor {
70    pub fn new() -> anyhow::Result<Self> {
71        let mut path = std::env::temp_dir();
72        path.push("rem_dummy_detached.rs");
73
74        // Create or truncate the file and write some minimal Rust so RA
75        // doesn’t choke if it does try to read it.
76        let mut file = File::create(&path)
77            .with_context(|| format!("failed to create temp dummy script at {path:?}"))?;
78        file.write_all(b"fn main() {}\n")?;
79
80        Ok(Self { path })
81    }
82
83    pub fn path(&self) -> &PathBuf {
84        &self.path
85    }
86}
87
88// impl Drop for TempScriptAnchor {
89//     fn drop(&mut self) {
90//         if let Err(err) = fs::remove_file(&self.path) {
91//             // Best-effort cleanup; log and move on.
92//             eprintln!("warn: failed to remove temp dummy script {:?}: {err}", self.path);
93//         }
94//     }
95// }