use anyhow::Context;
use ra_ap_paths::Utf8PathBuf;
use ra_ap_project_model::{
ProjectManifest,
RustLibSource,
ProjectWorkspace,
CargoConfig,
};
use ra_ap_base_db::{
ProcMacroPaths,
CrateGraph,
};
use ra_ap_paths::AbsPath;
use ra_ap_paths::AbsPathBuf;
use ra_ap_vfs::FileId;
use super::types::{
SingleFileStdContext,
SysrootFileMap,
TempScriptAnchor,
};
pub(crate) fn build_single_file_std_context() -> anyhow::Result<SingleFileStdContext> {
let temp_anchor = TempScriptAnchor::new()?;
let utf8 = Utf8PathBuf::from_path_buf(temp_anchor.path().clone())
.map_err(|_| anyhow::anyhow!("Temp path is not valid UTF-8: {:?}", temp_anchor.path()))?;
let abs_path = ra_ap_paths::AbsPathBuf::assert(utf8);
let manifest = ProjectManifest::from_manifest_file(abs_path.clone())
.context("Failed to parse temporary Cargo manifest")?;
let mut cargo_config = CargoConfig::default();
cargo_config.sysroot = Some(RustLibSource::Discover);
let extra_env = cargo_config.clone().extra_env;
let progress = |msg: String| {
eprintln!("ra_ap_project_model: {msg}");
};
let ws = ProjectWorkspace::load(manifest, &cargo_config, &progress)
.context("Failed to load ProjectWorkspace for single-file std context")?;
let mut file_map = SysrootFileMap::new();
let mut loader = |path: &AbsPath| -> Option<FileId> {
let owned: AbsPathBuf = path.to_path_buf();
Some(file_map.file_id_for(owned))
};
let (base_graph, proc_macros):
(CrateGraph, ProcMacroPaths) =
ws.to_crate_graph(&mut loader, &extra_env);
Ok(SingleFileStdContext {
base_graph,
proc_macros,
sysroot_files: file_map,
})
}