Make edition handling a bit nicer and allow specifying edition in crate_graph macro

This commit is contained in:
Florian Diebold 2019-02-13 20:31:27 +01:00
parent d5ad38cbb8
commit 70839b7ef8
5 changed files with 28 additions and 25 deletions

View file

@ -62,6 +62,15 @@ pub enum Edition {
Edition2015, Edition2015,
} }
impl Edition {
pub fn from_string(s: &str) -> Edition {
match s {
"2015" => Edition::Edition2015,
"2018" | _ => Edition::Edition2018,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
struct CrateData { struct CrateData {
file_id: FileId, file_id: FileId,

View file

@ -59,12 +59,12 @@ impl MockDatabase {
pub fn set_crate_graph_from_fixture(&mut self, graph: CrateGraphFixture) { pub fn set_crate_graph_from_fixture(&mut self, graph: CrateGraphFixture) {
let mut ids = FxHashMap::default(); let mut ids = FxHashMap::default();
let mut crate_graph = CrateGraph::default(); let mut crate_graph = CrateGraph::default();
for (crate_name, (crate_root, _)) in graph.0.iter() { for (crate_name, (crate_root, edition, _)) in graph.0.iter() {
let crate_root = self.file_id_of(&crate_root); let crate_root = self.file_id_of(&crate_root);
let crate_id = crate_graph.add_crate_root(crate_root, Edition::Edition2018); let crate_id = crate_graph.add_crate_root(crate_root, *edition);
ids.insert(crate_name, crate_id); ids.insert(crate_name, crate_id);
} }
for (crate_name, (_, deps)) in graph.0.iter() { for (crate_name, (_, _, deps)) in graph.0.iter() {
let from = ids[crate_name]; let from = ids[crate_name];
for dep in deps { for dep in deps {
let to = ids[dep]; let to = ids[dep];
@ -233,16 +233,19 @@ impl MockDatabase {
} }
#[derive(Default)] #[derive(Default)]
pub struct CrateGraphFixture(pub FxHashMap<String, (String, Vec<String>)>); pub struct CrateGraphFixture(pub FxHashMap<String, (String, Edition, Vec<String>)>);
#[macro_export] #[macro_export]
macro_rules! crate_graph { macro_rules! crate_graph {
($($crate_name:literal: ($crate_path:literal, [$($dep:literal),*]),)*) => {{ ($($crate_name:literal: ($crate_path:literal, $($edition:literal,)? [$($dep:literal),*]),)*) => {{
let mut res = $crate::mock::CrateGraphFixture::default(); let mut res = $crate::mock::CrateGraphFixture::default();
$( $(
#[allow(unused_mut, unused_assignments)]
let mut edition = ra_db::Edition::Edition2018;
$(edition = ra_db::Edition::from_string($edition);)?
res.0.insert( res.0.insert(
$crate_name.to_string(), $crate_name.to_string(),
($crate_path.to_string(), vec![$($dep.to_string()),*]) ($crate_path.to_string(), edition, vec![$($dep.to_string()),*])
); );
)* )*
res res

View file

@ -267,7 +267,6 @@ fn glob_across_crates() {
#[test] #[test]
fn edition_2015_imports() { fn edition_2015_imports() {
use ra_db::{CrateGraph, Edition};
let mut db = MockDatabase::with_files( let mut db = MockDatabase::with_files(
" "
//- /main.rs //- /main.rs
@ -285,17 +284,12 @@ fn edition_2015_imports() {
struct FromLib; struct FromLib;
", ",
); );
let main_id = db.file_id_of("/main.rs"); db.set_crate_graph_from_fixture(crate_graph! {
let lib_id = db.file_id_of("/lib.rs"); "main": ("/main.rs", "2015", ["other_crate"]),
"other_crate": ("/lib.rs", "2018", []),
});
let foo_id = db.file_id_of("/foo.rs"); let foo_id = db.file_id_of("/foo.rs");
let mut crate_graph = CrateGraph::default();
let main_crate = crate_graph.add_crate_root(main_id, Edition::Edition2015);
let lib_crate = crate_graph.add_crate_root(lib_id, Edition::Edition2018);
crate_graph.add_dep(main_crate, "other_crate".into(), lib_crate).unwrap();
db.set_crate_graph(Arc::new(crate_graph));
let module = crate::source_binder::module_from_file_id(&db, foo_id).unwrap(); let module = crate::source_binder::module_from_file_id(&db, foo_id).unwrap();
let krate = module.krate(&db).unwrap(); let krate = module.krate(&db).unwrap();
let item_map = db.item_map(krate); let item_map = db.item_map(krate);

View file

@ -4,6 +4,7 @@ use cargo_metadata::{MetadataCommand, CargoOpt};
use ra_arena::{Arena, RawId, impl_arena_id}; use ra_arena::{Arena, RawId, impl_arena_id};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use failure::format_err; use failure::format_err;
use ra_db::Edition;
use crate::Result; use crate::Result;
@ -35,7 +36,7 @@ struct PackageData {
targets: Vec<Target>, targets: Vec<Target>,
is_member: bool, is_member: bool,
dependencies: Vec<PackageDependency>, dependencies: Vec<PackageDependency>,
edition: String, edition: Edition,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -85,8 +86,8 @@ impl Package {
pub fn root(self, ws: &CargoWorkspace) -> &Path { pub fn root(self, ws: &CargoWorkspace) -> &Path {
ws.packages[self].manifest.parent().unwrap() ws.packages[self].manifest.parent().unwrap()
} }
pub fn edition(self, ws: &CargoWorkspace) -> &str { pub fn edition(self, ws: &CargoWorkspace) -> Edition {
&ws.packages[self].edition ws.packages[self].edition
} }
pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item = Target> + 'a { pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item = Target> + 'a {
ws.packages[self].targets.iter().cloned() ws.packages[self].targets.iter().cloned()
@ -139,7 +140,7 @@ impl CargoWorkspace {
manifest: meta_pkg.manifest_path.clone(), manifest: meta_pkg.manifest_path.clone(),
targets: Vec::new(), targets: Vec::new(),
is_member, is_member,
edition: meta_pkg.edition, edition: Edition::from_string(&meta_pkg.edition),
dependencies: Vec::new(), dependencies: Vec::new(),
}); });
let pkg_data = &mut packages[pkg]; let pkg_data = &mut packages[pkg];

View file

@ -63,11 +63,7 @@ impl ProjectWorkspace {
for tgt in pkg.targets(&self.cargo) { for tgt in pkg.targets(&self.cargo) {
let root = tgt.root(&self.cargo); let root = tgt.root(&self.cargo);
if let Some(file_id) = load(root) { if let Some(file_id) = load(root) {
let edition = if pkg.edition(&self.cargo) == "2015" { let edition = pkg.edition(&self.cargo);
Edition::Edition2015
} else {
Edition::Edition2018
};
let crate_id = crate_graph.add_crate_root(file_id, edition); let crate_id = crate_graph.add_crate_root(file_id, edition);
if tgt.kind(&self.cargo) == TargetKind::Lib { if tgt.kind(&self.cargo) == TargetKind::Lib {
lib_tgt = Some(crate_id); lib_tgt = Some(crate_id);