Add extern source

This commit is contained in:
Edwin Cheng 2020-03-11 11:04:02 +08:00
parent 5a292309c5
commit 6ea7c31915
8 changed files with 49 additions and 11 deletions

View file

@ -61,7 +61,14 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId
};
let mut crate_graph = CrateGraph::default();
crate_graph.add_crate_root(file_id, meta.edition, meta.krate, meta.cfg, meta.env);
crate_graph.add_crate_root(
file_id,
meta.edition,
meta.krate,
meta.cfg,
meta.env,
Default::default(),
);
crate_graph
} else {
let mut crate_graph = CrateGraph::default();
@ -71,6 +78,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
crate_graph
};
@ -119,6 +127,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
Some(krate.clone()),
meta.cfg,
meta.env,
Default::default(),
);
let prev = crates.insert(krate.clone(), crate_id);
assert!(prev.is_none());
@ -155,6 +164,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
} else {
for (from, to) in crate_deps {

View file

@ -113,6 +113,7 @@ pub struct CrateData {
pub display_name: Option<String>,
pub cfg_options: CfgOptions,
pub env: Env,
pub extern_source: ExternSource,
pub dependencies: Vec<Dependency>,
}
@ -128,9 +129,13 @@ pub struct ExternSourceId(pub u32);
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Env {
entries: FxHashMap<String, String>,
}
// Note: Some env variables (e.g. OUT_DIR) are located outside of the
// crate. We store a map to allow remap it to ExternSourceId
// FIXME: Redesign vfs for solve the following limitation ?
// Note: Some env variables (e.g. OUT_DIR) are located outside of the
// crate. We store a map to allow remap it to ExternSourceId
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct ExternSource {
extern_paths: FxHashMap<String, ExternSourceId>,
}
@ -148,6 +153,7 @@ impl CrateGraph {
display_name: Option<String>,
cfg_options: CfgOptions,
env: Env,
extern_source: ExternSource,
) -> CrateId {
let data = CrateData {
root_file_id: file_id,
@ -155,6 +161,7 @@ impl CrateGraph {
display_name,
cfg_options,
env,
extern_source,
dependencies: Vec::new(),
};
let crate_id = CrateId(self.arena.len() as u32);
@ -276,7 +283,9 @@ impl Env {
pub fn get(&self, env: &str) -> Option<String> {
self.entries.get(env).cloned()
}
}
impl ExternSource {
pub fn extern_path(&self, path: &str) -> Option<(ExternSourceId, RelativePathBuf)> {
self.extern_paths.iter().find_map(|(root_path, id)| {
if path.starts_with(root_path) {
@ -292,8 +301,7 @@ impl Env {
})
}
pub fn set_extern_path(&mut self, env: &str, root_path: &str, root: ExternSourceId) {
self.entries.insert(env.to_owned(), root_path.to_owned());
pub fn set_extern_path(&mut self, root_path: &str, root: ExternSourceId) {
self.extern_paths.insert(root_path.to_owned(), root);
}
}
@ -327,6 +335,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
@ -334,6 +343,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
let crate3 = graph.add_crate_root(
FileId(3u32),
@ -341,6 +351,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
@ -356,6 +367,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
@ -363,6 +375,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
let crate3 = graph.add_crate_root(
FileId(3u32),
@ -370,6 +383,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
@ -384,6 +398,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
let crate2 = graph.add_crate_root(
FileId(2u32),
@ -391,6 +406,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
assert!(graph
.add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2)

View file

@ -11,8 +11,8 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit};
pub use crate::{
cancellation::Canceled,
input::{
CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSourceId, FileId,
SourceRoot, SourceRootId,
CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSource, ExternSourceId,
FileId, SourceRoot, SourceRootId,
},
};
pub use relative_path::{RelativePath, RelativePathBuf};

View file

@ -262,7 +262,8 @@ fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Opti
// Extern paths ?
let krate = db.relevant_crates(call_site).get(0)?.clone();
let (extern_source_id, relative_file) = db.crate_graph()[krate].env.extern_path(path)?;
let (extern_source_id, relative_file) =
db.crate_graph()[krate].extern_source.extern_path(path)?;
db.resolve_extern_path(extern_source_id, &relative_file)
}

View file

@ -217,6 +217,7 @@ impl Analysis {
None,
cfg_options,
Env::default(),
Default::default(),
);
change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text));
change.set_crate_graph(crate_graph);

View file

@ -102,6 +102,7 @@ impl MockAnalysis {
None,
cfg_options,
Env::default(),
Default::default(),
));
} else if path.ends_with("/lib.rs") {
let crate_name = path.parent().unwrap().file_name().unwrap();
@ -111,6 +112,7 @@ impl MockAnalysis {
Some(crate_name.to_owned()),
cfg_options,
Env::default(),
Default::default(),
);
if let Some(root_crate) = root_crate {
crate_graph

View file

@ -136,6 +136,7 @@ mod tests {
None,
CfgOptions::default(),
Env::default(),
Default::default(),
);
let mut change = AnalysisChange::new();
change.set_crate_graph(crate_graph);

View file

@ -14,7 +14,7 @@ use std::{
use anyhow::{bail, Context, Result};
use ra_cfg::CfgOptions;
use ra_db::{CrateGraph, CrateName, Edition, Env, ExternSourceId, FileId};
use ra_db::{CrateGraph, CrateName, Edition, Env, ExternSource, ExternSourceId, FileId};
use rustc_hash::FxHashMap;
use serde_json::from_reader;
@ -197,6 +197,7 @@ impl ProjectWorkspace {
None,
cfg_options,
Env::default(),
Default::default(),
),
);
}
@ -235,8 +236,10 @@ impl ProjectWorkspace {
};
let mut env = Env::default();
let mut extern_source = ExternSource::default();
if let Some((id, path)) = outdirs.get(krate.name(&sysroot)) {
env.set_extern_path("OUT_DIR", &path, *id);
env.set("OUT_DIR", path.clone());
extern_source.set_extern_path(&path, *id);
}
let crate_id = crate_graph.add_crate_root(
@ -245,6 +248,7 @@ impl ProjectWorkspace {
Some(krate.name(&sysroot).to_string()),
cfg_options,
env,
extern_source,
);
sysroot_crates.insert(krate, crate_id);
}
@ -284,8 +288,10 @@ impl ProjectWorkspace {
opts
};
let mut env = Env::default();
let mut extern_source = ExternSource::default();
if let Some((id, path)) = outdirs.get(pkg.name(&cargo)) {
env.set_extern_path("OUT_DIR", &path, *id);
env.set("OUT_DIR", path.clone());
extern_source.set_extern_path(&path, *id);
}
let crate_id = crate_graph.add_crate_root(
file_id,
@ -293,6 +299,7 @@ impl ProjectWorkspace {
Some(pkg.name(&cargo).to_string()),
cfg_options,
env,
extern_source,
);
if tgt.kind(&cargo) == TargetKind::Lib {
lib_tgt = Some(crate_id);