mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-24 12:03:31 +00:00
move crate_def_map tests to hir_def
This commit is contained in:
parent
0933d914a3
commit
6fba51c5fc
13 changed files with 308 additions and 194 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1028,6 +1028,7 @@ dependencies = [
|
|||
name = "ra_hir_def"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ra_arena 0.1.0",
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use ra_cfg::CfgOptions;
|
||||
use rustc_hash::FxHashMap;
|
||||
use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER};
|
||||
|
||||
use crate::{
|
||||
CrateGraph, Edition, FileId, RelativePathBuf, SourceDatabaseExt, SourceRoot, SourceRootId,
|
||||
CrateGraph, Edition, FileId, FilePosition, RelativePathBuf, SourceDatabaseExt, SourceRoot,
|
||||
SourceRootId,
|
||||
};
|
||||
|
||||
pub const WORKSPACE: SourceRootId = SourceRootId(0);
|
||||
|
@ -16,6 +19,19 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
|
|||
let file_id = with_single_file(&mut db, text);
|
||||
(db, file_id)
|
||||
}
|
||||
|
||||
fn with_files(fixture: &str) -> Self {
|
||||
let mut db = Self::default();
|
||||
let pos = with_files(&mut db, fixture);
|
||||
assert!(pos.is_none());
|
||||
db
|
||||
}
|
||||
|
||||
fn with_position(fixture: &str) -> (Self, FilePosition) {
|
||||
let mut db = Self::default();
|
||||
let pos = with_files(&mut db, fixture);
|
||||
(db, pos.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB: SourceDatabaseExt + Default + 'static> WithFixture for DB {}
|
||||
|
@ -38,3 +54,133 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId {
|
|||
|
||||
file_id
|
||||
}
|
||||
|
||||
fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosition> {
|
||||
let fixture = parse_fixture(fixture);
|
||||
|
||||
let mut crate_graph = CrateGraph::default();
|
||||
let mut crates = FxHashMap::default();
|
||||
let mut crate_deps = Vec::new();
|
||||
let mut default_crate_root: Option<FileId> = None;
|
||||
|
||||
let mut source_root = SourceRoot::default();
|
||||
let mut source_root_id = WORKSPACE;
|
||||
let mut source_root_prefix: RelativePathBuf = "/".into();
|
||||
let mut file_id = FileId(0);
|
||||
|
||||
let mut file_position = None;
|
||||
|
||||
for entry in fixture.iter() {
|
||||
let meta = match parse_meta(&entry.meta) {
|
||||
ParsedMeta::Root { path } => {
|
||||
let source_root = std::mem::replace(&mut source_root, SourceRoot::default());
|
||||
db.set_source_root(source_root_id, Arc::new(source_root));
|
||||
source_root_id.0 += 1;
|
||||
source_root_prefix = path;
|
||||
continue;
|
||||
}
|
||||
ParsedMeta::File(it) => it,
|
||||
};
|
||||
assert!(meta.path.starts_with(&source_root_prefix));
|
||||
|
||||
if let Some(krate) = meta.krate {
|
||||
let crate_id = crate_graph.add_crate_root(file_id, meta.edition, meta.cfg);
|
||||
let prev = crates.insert(krate.clone(), crate_id);
|
||||
assert!(prev.is_none());
|
||||
for dep in meta.deps {
|
||||
crate_deps.push((krate.clone(), dep))
|
||||
}
|
||||
} else if meta.path == "/main.rs" || meta.path == "/lib.rs" {
|
||||
assert!(default_crate_root.is_none());
|
||||
default_crate_root = Some(file_id);
|
||||
}
|
||||
|
||||
let text = if entry.text.contains(CURSOR_MARKER) {
|
||||
let (offset, text) = extract_offset(&entry.text);
|
||||
assert!(file_position.is_none());
|
||||
file_position = Some(FilePosition { file_id, offset });
|
||||
text.to_string()
|
||||
} else {
|
||||
entry.text.to_string()
|
||||
};
|
||||
|
||||
db.set_file_text(file_id, Arc::new(text));
|
||||
db.set_file_relative_path(file_id, meta.path.clone());
|
||||
db.set_file_source_root(file_id, source_root_id);
|
||||
source_root.insert_file(meta.path, file_id);
|
||||
|
||||
file_id.0 += 1;
|
||||
}
|
||||
|
||||
if crates.is_empty() {
|
||||
let crate_root = default_crate_root.unwrap();
|
||||
crate_graph.add_crate_root(crate_root, Edition::Edition2018, CfgOptions::default());
|
||||
} else {
|
||||
for (from, to) in crate_deps {
|
||||
let from_id = crates[&from];
|
||||
let to_id = crates[&to];
|
||||
crate_graph.add_dep(from_id, to.into(), to_id).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
db.set_source_root(source_root_id, Arc::new(source_root));
|
||||
db.set_crate_graph(Arc::new(crate_graph));
|
||||
|
||||
file_position
|
||||
}
|
||||
|
||||
enum ParsedMeta {
|
||||
Root { path: RelativePathBuf },
|
||||
File(FileMeta),
|
||||
}
|
||||
|
||||
struct FileMeta {
|
||||
path: RelativePathBuf,
|
||||
krate: Option<String>,
|
||||
deps: Vec<String>,
|
||||
cfg: CfgOptions,
|
||||
edition: Edition,
|
||||
}
|
||||
|
||||
//- /lib.rs crate:foo deps:bar,baz
|
||||
fn parse_meta(meta: &str) -> ParsedMeta {
|
||||
let components = meta.split_ascii_whitespace().collect::<Vec<_>>();
|
||||
|
||||
if components[0] == "root" {
|
||||
let path: RelativePathBuf = components[1].into();
|
||||
assert!(path.starts_with("/") && path.ends_with("/"));
|
||||
return ParsedMeta::Root { path };
|
||||
}
|
||||
|
||||
let path: RelativePathBuf = components[0].into();
|
||||
assert!(path.starts_with("/"));
|
||||
|
||||
let mut krate = None;
|
||||
let mut deps = Vec::new();
|
||||
let mut edition = Edition::Edition2018;
|
||||
let mut cfg = CfgOptions::default();
|
||||
for component in components[1..].iter() {
|
||||
let (key, value) = split1(component, ':').unwrap();
|
||||
match key {
|
||||
"crate" => krate = Some(value.to_string()),
|
||||
"deps" => deps = value.split(',').map(|it| it.to_string()).collect(),
|
||||
"edition" => edition = Edition::from_string(&value),
|
||||
"cfg" => {
|
||||
for key in value.split(',') {
|
||||
match split1(key, '=') {
|
||||
None => cfg.insert_atom(key.into()),
|
||||
Some((k, v)) => cfg.insert_key_value(k.into(), v.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => panic!("bad component: {:?}", component),
|
||||
}
|
||||
}
|
||||
|
||||
ParsedMeta::File(FileMeta { path, krate, deps, edition, cfg })
|
||||
}
|
||||
|
||||
fn split1(haystack: &str, delim: char) -> Option<(&str, &str)> {
|
||||
let idx = haystack.find(delim)?;
|
||||
Some((&haystack[..idx], &haystack[idx + delim.len_utf8()..]))
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ pub enum Edition {
|
|||
}
|
||||
|
||||
impl Edition {
|
||||
//FIXME: replace with FromStr with proper error handling
|
||||
pub fn from_string(s: &str) -> Edition {
|
||||
match s {
|
||||
"2015" => Edition::Edition2015,
|
||||
|
|
|
@ -47,9 +47,6 @@
|
|||
//! path and, upon success, we run macro expansion and "collect module" phase
|
||||
//! on the result
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use hir_def::nameres::{
|
||||
per_ns::{Namespace, PerNs},
|
||||
raw::ImportId,
|
||||
|
|
|
@ -19,3 +19,7 @@ test_utils = { path = "../test_utils" }
|
|||
mbe = { path = "../ra_mbe", package = "ra_mbe" }
|
||||
ra_cfg = { path = "../ra_cfg" }
|
||||
tt = { path = "../ra_tt", package = "ra_tt" }
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "0.12.0"
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@ pub mod per_ns;
|
|||
pub mod collector;
|
||||
pub mod mod_resolution;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use hir_expand::{diagnostics::DiagnosticSink, name::Name, MacroDefId};
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
mod macros;
|
||||
mod globs;
|
||||
mod incremental;
|
||||
mod primitives;
|
||||
mod macros;
|
||||
mod mod_resolution;
|
||||
mod primitives;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use hir_def::{db::DefDatabase2, nameres::*, CrateModuleId};
|
||||
use insta::assert_snapshot;
|
||||
use ra_db::SourceDatabase;
|
||||
use ra_db::{fixture::WithFixture, SourceDatabase};
|
||||
// use test_utils::covers;
|
||||
|
||||
use crate::mock::{CrateGraphFixture, MockDatabase};
|
||||
use crate::{db::DefDatabase2, nameres::*, test_db::TestDB, CrateModuleId};
|
||||
|
||||
fn compute_crate_def_map(fixture: &str, graph: Option<CrateGraphFixture>) -> Arc<CrateDefMap> {
|
||||
let mut db = MockDatabase::with_files(fixture);
|
||||
if let Some(graph) = graph {
|
||||
db.set_crate_graph_from_fixture(graph);
|
||||
}
|
||||
fn def_map(fixtute: &str) -> String {
|
||||
let dm = compute_crate_def_map(fixtute);
|
||||
render_crate_def_map(&dm)
|
||||
}
|
||||
|
||||
fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> {
|
||||
let db = TestDB::with_files(fixture);
|
||||
let krate = db.crate_graph().iter().next().unwrap();
|
||||
db.crate_def_map(krate)
|
||||
}
|
||||
|
@ -65,16 +66,6 @@ fn render_crate_def_map(map: &CrateDefMap) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn def_map(fixtute: &str) -> String {
|
||||
let dm = compute_crate_def_map(fixtute, None);
|
||||
render_crate_def_map(&dm)
|
||||
}
|
||||
|
||||
fn def_map_with_crate_graph(fixture: &str, graph: CrateGraphFixture) -> String {
|
||||
let dm = compute_crate_def_map(fixture, Some(graph));
|
||||
render_crate_def_map(&dm)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crate_def_map_smoke_test() {
|
||||
let map = def_map(
|
||||
|
@ -229,12 +220,12 @@ fn re_exports() {
|
|||
#[test]
|
||||
fn std_prelude() {
|
||||
// covers!(std_prelude);
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:test_crate
|
||||
use Foo::*;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:test_crate
|
||||
mod prelude;
|
||||
#[prelude_import]
|
||||
use prelude::*;
|
||||
|
@ -242,10 +233,6 @@ fn std_prelude() {
|
|||
//- /prelude.rs
|
||||
pub enum Foo { Bar, Baz };
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["test_crate"]),
|
||||
"test_crate": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -274,9 +261,9 @@ fn can_import_enum_variant() {
|
|||
|
||||
#[test]
|
||||
fn edition_2015_imports() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:other_crate edition:2015
|
||||
mod foo;
|
||||
mod bar;
|
||||
|
||||
|
@ -287,13 +274,9 @@ fn edition_2015_imports() {
|
|||
use bar::Bar;
|
||||
use other_crate::FromLib;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:other_crate edition:2018
|
||||
struct FromLib;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", "2015", ["other_crate"]),
|
||||
"other_crate": ("/lib.rs", "2018", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -338,18 +321,14 @@ fn item_map_using_self() {
|
|||
|
||||
#[test]
|
||||
fn item_map_across_crates() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:test_crate
|
||||
use test_crate::Baz;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:test_crate
|
||||
pub struct Baz;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["test_crate"]),
|
||||
"test_crate": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -360,9 +339,9 @@ fn item_map_across_crates() {
|
|||
|
||||
#[test]
|
||||
fn extern_crate_rename() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:alloc
|
||||
extern crate alloc as alloc_crate;
|
||||
|
||||
mod alloc;
|
||||
|
@ -371,13 +350,9 @@ fn extern_crate_rename() {
|
|||
//- /sync.rs
|
||||
use alloc_crate::Arc;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:alloc
|
||||
struct Arc;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["alloc"]),
|
||||
"alloc": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -392,9 +367,9 @@ fn extern_crate_rename() {
|
|||
|
||||
#[test]
|
||||
fn extern_crate_rename_2015_edition() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:alloc edition:2015
|
||||
extern crate alloc as alloc_crate;
|
||||
|
||||
mod alloc;
|
||||
|
@ -403,13 +378,9 @@ fn extern_crate_rename_2015_edition() {
|
|||
//- /sync.rs
|
||||
use alloc_crate::Arc;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:alloc
|
||||
struct Arc;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", "2015", ["alloc"]),
|
||||
"alloc": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map,
|
||||
|
@ -426,24 +397,21 @@ fn extern_crate_rename_2015_edition() {
|
|||
|
||||
#[test]
|
||||
fn import_across_source_roots() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /lib.rs
|
||||
//- /main.rs crate:main deps:test_crate
|
||||
use test_crate::a::b::C;
|
||||
|
||||
//- root /test_crate/
|
||||
|
||||
//- /test_crate/lib.rs crate:test_crate
|
||||
pub mod a {
|
||||
pub mod b {
|
||||
pub struct C;
|
||||
}
|
||||
}
|
||||
|
||||
//- root /main/
|
||||
|
||||
//- /main/main.rs
|
||||
use test_crate::a::b::C;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main/main.rs", ["test_crate"]),
|
||||
"test_crate": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -454,12 +422,12 @@ fn import_across_source_roots() {
|
|||
|
||||
#[test]
|
||||
fn reexport_across_crates() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:test_crate
|
||||
use test_crate::Baz;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:test_crate
|
||||
pub use foo::Baz;
|
||||
|
||||
mod foo;
|
||||
|
@ -467,10 +435,6 @@ fn reexport_across_crates() {
|
|||
//- /foo.rs
|
||||
pub struct Baz;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["test_crate"]),
|
||||
"test_crate": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -481,19 +445,15 @@ fn reexport_across_crates() {
|
|||
|
||||
#[test]
|
||||
fn values_dont_shadow_extern_crates() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
fn foo() {}
|
||||
use foo::Bar;
|
||||
|
||||
//- /foo/lib.rs
|
||||
//- /foo/lib.rs crate:foo
|
||||
pub struct Bar;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/foo/lib.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -505,11 +465,12 @@ fn values_dont_shadow_extern_crates() {
|
|||
|
||||
#[test]
|
||||
fn cfg_not_test() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r#"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:std
|
||||
use {Foo, Bar, Baz};
|
||||
//- /lib.rs
|
||||
|
||||
//- /lib.rs crate:std
|
||||
#[prelude_import]
|
||||
pub use self::prelude::*;
|
||||
mod prelude {
|
||||
|
@ -521,10 +482,6 @@ fn cfg_not_test() {
|
|||
pub struct Baz;
|
||||
}
|
||||
"#,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["std"]),
|
||||
"std": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -537,11 +494,12 @@ fn cfg_not_test() {
|
|||
|
||||
#[test]
|
||||
fn cfg_test() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r#"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:std
|
||||
use {Foo, Bar, Baz};
|
||||
//- /lib.rs
|
||||
|
||||
//- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
|
||||
#[prelude_import]
|
||||
pub use self::prelude::*;
|
||||
mod prelude {
|
||||
|
@ -553,15 +511,6 @@ fn cfg_test() {
|
|||
pub struct Baz;
|
||||
}
|
||||
"#,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["std"]),
|
||||
"std": ("/lib.rs", [], cfg = {
|
||||
"test",
|
||||
"feature" = "foo",
|
||||
"feature" = "bar",
|
||||
"opt" = "42",
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
|
@ -76,18 +76,14 @@ fn glob_2() {
|
|||
#[test]
|
||||
fn glob_across_crates() {
|
||||
// covers!(glob_across_crates);
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:test_crate
|
||||
use test_crate::*;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:test_crate
|
||||
pub struct Baz;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["test_crate"]),
|
||||
"test_crate": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
|
@ -5,7 +5,7 @@ use ra_db::{SourceDatabase, SourceDatabaseExt};
|
|||
use super::*;
|
||||
|
||||
fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) {
|
||||
let (mut db, pos) = MockDatabase::with_position(initial);
|
||||
let (mut db, pos) = TestDB::with_position(initial);
|
||||
let krate = db.crate_graph().iter().next().unwrap();
|
||||
{
|
||||
let events = db.log_executed(|| {
|
||||
|
@ -91,7 +91,7 @@ fn adding_inner_items_should_not_invalidate_def_map() {
|
|||
|
||||
#[test]
|
||||
fn typing_inside_a_macro_should_not_invalidate_def_map() {
|
||||
let (mut db, pos) = MockDatabase::with_position(
|
||||
let (mut db, pos) = TestDB::with_position(
|
||||
"
|
||||
//- /lib.rs
|
||||
macro_rules! m {
|
||||
|
@ -111,15 +111,12 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
|
|||
m!(X);
|
||||
",
|
||||
);
|
||||
let krate = db.crate_graph().iter().next().unwrap();
|
||||
{
|
||||
let events = db.log_executed(|| {
|
||||
let src = crate::Source {
|
||||
file_id: pos.file_id.into(),
|
||||
ast: crate::ModuleSource::new(&db, Some(pos.file_id), None),
|
||||
};
|
||||
let module = crate::Module::from_definition(&db, src).unwrap();
|
||||
let decls = module.declarations(&db);
|
||||
assert_eq!(decls.len(), 18);
|
||||
let crate_def_map = db.crate_def_map(krate);
|
||||
let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
|
||||
assert_eq!(module_data.scope.items.len(), 1);
|
||||
});
|
||||
assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
|
||||
}
|
||||
|
@ -127,13 +124,9 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
|
|||
|
||||
{
|
||||
let events = db.log_executed(|| {
|
||||
let src = crate::Source {
|
||||
file_id: pos.file_id.into(),
|
||||
ast: crate::ModuleSource::new(&db, Some(pos.file_id), None),
|
||||
};
|
||||
let module = crate::Module::from_definition(&db, src).unwrap();
|
||||
let decls = module.declarations(&db);
|
||||
assert_eq!(decls.len(), 18);
|
||||
let crate_def_map = db.crate_def_map(krate);
|
||||
let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
|
||||
assert_eq!(module_data.scope.items.len(), 1);
|
||||
});
|
||||
assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
|
||||
}
|
|
@ -71,16 +71,16 @@ fn macro_rules_can_define_modules() {
|
|||
|
||||
#[test]
|
||||
fn macro_rules_from_other_crates_are_visible() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
foo::structs!(Foo, Bar)
|
||||
mod bar;
|
||||
|
||||
//- /bar.rs
|
||||
use crate::*;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:foo
|
||||
#[macro_export]
|
||||
macro_rules! structs {
|
||||
($($i:ident),*) => {
|
||||
|
@ -88,10 +88,6 @@ fn macro_rules_from_other_crates_are_visible() {
|
|||
}
|
||||
}
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -108,16 +104,16 @@ fn macro_rules_from_other_crates_are_visible() {
|
|||
|
||||
#[test]
|
||||
fn macro_rules_export_with_local_inner_macros_are_visible() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
foo::structs!(Foo, Bar)
|
||||
mod bar;
|
||||
|
||||
//- /bar.rs
|
||||
use crate::*;
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:foo
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! structs {
|
||||
($($i:ident),*) => {
|
||||
|
@ -125,10 +121,6 @@ fn macro_rules_export_with_local_inner_macros_are_visible() {
|
|||
}
|
||||
}
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -145,9 +137,9 @@ fn macro_rules_export_with_local_inner_macros_are_visible() {
|
|||
|
||||
#[test]
|
||||
fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
macro_rules! baz {
|
||||
() => {
|
||||
use foo::bar;
|
||||
|
@ -158,7 +150,7 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
|
|||
bar!();
|
||||
baz!();
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:foo
|
||||
#[macro_export]
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
|
@ -172,10 +164,6 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
|
|||
}
|
||||
}
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -188,9 +176,9 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
|
|||
#[test]
|
||||
fn macro_rules_from_other_crates_are_visible_with_macro_use() {
|
||||
// covers!(macro_rules_from_other_crates_are_visible_with_macro_use);
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
structs!(Foo);
|
||||
structs_priv!(Bar);
|
||||
structs_not_exported!(MacroNotResolved1);
|
||||
|
@ -205,7 +193,7 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
|
|||
structs!(Baz);
|
||||
crate::structs!(MacroNotResolved3);
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:foo
|
||||
#[macro_export]
|
||||
macro_rules! structs {
|
||||
($i:ident) => { struct $i; }
|
||||
|
@ -222,10 +210,6 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
|
|||
}
|
||||
}
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -242,9 +226,9 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
|
|||
#[test]
|
||||
fn prelude_is_macro_use() {
|
||||
// covers!(prelude_is_macro_use);
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
structs!(Foo);
|
||||
structs_priv!(Bar);
|
||||
structs_outside!(Out);
|
||||
|
@ -256,7 +240,7 @@ fn prelude_is_macro_use() {
|
|||
structs!(Baz);
|
||||
crate::structs!(MacroNotResolved3);
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:foo
|
||||
#[prelude_import]
|
||||
use self::prelude::*;
|
||||
|
||||
|
@ -279,10 +263,6 @@ fn prelude_is_macro_use() {
|
|||
($i:ident) => { struct $i; }
|
||||
}
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -447,16 +427,16 @@ fn type_value_macro_live_in_different_scopes() {
|
|||
|
||||
#[test]
|
||||
fn macro_use_can_be_aliased() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
#[macro_use]
|
||||
extern crate foo;
|
||||
|
||||
foo!(Direct);
|
||||
bar!(Alias);
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:foo
|
||||
use crate::foo as bar;
|
||||
|
||||
mod m {
|
||||
|
@ -466,10 +446,6 @@ fn macro_use_can_be_aliased() {
|
|||
}
|
||||
}
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -533,9 +509,9 @@ fn path_qualified_macros() {
|
|||
fn macro_dollar_crate_is_correct_in_item() {
|
||||
// covers!(macro_dollar_crate_self);
|
||||
// covers!(macro_dollar_crate_other);
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:foo
|
||||
#[macro_use]
|
||||
extern crate foo;
|
||||
|
||||
|
@ -554,7 +530,7 @@ fn macro_dollar_crate_is_correct_in_item() {
|
|||
not_current1!();
|
||||
foo::not_current2!();
|
||||
|
||||
//- /lib.rs
|
||||
//- /lib.rs crate:foo
|
||||
mod m {
|
||||
#[macro_export]
|
||||
macro_rules! not_current1 {
|
||||
|
@ -574,10 +550,6 @@ fn macro_dollar_crate_is_correct_in_item() {
|
|||
struct Bar;
|
||||
struct Baz;
|
||||
",
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["foo"]),
|
||||
"foo": ("/lib.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
|
@ -596,12 +568,12 @@ fn macro_dollar_crate_is_correct_in_item() {
|
|||
fn macro_dollar_crate_is_correct_in_indirect_deps() {
|
||||
// covers!(macro_dollar_crate_other);
|
||||
// From std
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r#"
|
||||
//- /main.rs
|
||||
//- /main.rs crate:main deps:std
|
||||
foo!();
|
||||
|
||||
//- /std.rs
|
||||
//- /std.rs crate:std deps:core
|
||||
#[prelude_import]
|
||||
use self::prelude::*;
|
||||
|
||||
|
@ -612,7 +584,7 @@ fn macro_dollar_crate_is_correct_in_indirect_deps() {
|
|||
#[macro_use]
|
||||
mod std_macros;
|
||||
|
||||
//- /core.rs
|
||||
//- /core.rs crate:core
|
||||
#[macro_export]
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
|
@ -622,11 +594,6 @@ fn macro_dollar_crate_is_correct_in_indirect_deps() {
|
|||
|
||||
pub struct bar;
|
||||
"#,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", ["std"]),
|
||||
"std": ("/std.rs", ["core"]),
|
||||
"core": ("/core.rs", []),
|
||||
},
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
|
@ -54,18 +54,15 @@ fn nested_module_resolution() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_works_for_non_standard_filenames() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /my_library.rs
|
||||
//- /my_library.rs crate:my_library
|
||||
mod foo;
|
||||
use self::foo::Bar;
|
||||
|
||||
//- /foo/mod.rs
|
||||
pub struct Bar;
|
||||
",
|
||||
crate_graph! {
|
||||
"my_library": ("/my_library.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -650,7 +647,7 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
|
|||
|
||||
#[test]
|
||||
fn unresolved_module_diagnostics() {
|
||||
let diagnostics = MockDatabase::with_files(
|
||||
let db = TestDB::with_files(
|
||||
r"
|
||||
//- /lib.rs
|
||||
mod foo;
|
||||
|
@ -658,11 +655,37 @@ fn unresolved_module_diagnostics() {
|
|||
mod baz {}
|
||||
//- /foo.rs
|
||||
",
|
||||
)
|
||||
.diagnostics();
|
||||
);
|
||||
let krate = db.crate_graph().iter().next().unwrap();
|
||||
|
||||
assert_snapshot!(diagnostics, @r###"
|
||||
"mod bar;": unresolved module
|
||||
let crate_def_map = db.crate_def_map(krate);
|
||||
|
||||
insta::assert_debug_snapshot!(
|
||||
crate_def_map.diagnostics,
|
||||
@r###"
|
||||
[
|
||||
UnresolvedModule {
|
||||
module: CrateModuleId(
|
||||
0,
|
||||
),
|
||||
declaration: AstId {
|
||||
file_id: HirFileId(
|
||||
FileId(
|
||||
FileId(
|
||||
0,
|
||||
),
|
||||
),
|
||||
),
|
||||
file_ast_id: FileAstId {
|
||||
raw: ErasedFileAstId(
|
||||
1,
|
||||
),
|
||||
_ty: PhantomData,
|
||||
},
|
||||
},
|
||||
candidate: "bar.rs",
|
||||
},
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
use std::{panic, sync::Arc};
|
||||
use std::{
|
||||
panic,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate};
|
||||
use relative_path::RelativePath;
|
||||
|
@ -13,12 +16,20 @@ use relative_path::RelativePath;
|
|||
#[derive(Debug, Default)]
|
||||
pub struct TestDB {
|
||||
runtime: salsa::Runtime<TestDB>,
|
||||
events: Mutex<Option<Vec<salsa::Event<TestDB>>>>,
|
||||
}
|
||||
|
||||
impl salsa::Database for TestDB {
|
||||
fn salsa_runtime(&self) -> &salsa::Runtime<Self> {
|
||||
&self.runtime
|
||||
}
|
||||
|
||||
fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) {
|
||||
let mut events = self.events.lock().unwrap();
|
||||
if let Some(events) = &mut *events {
|
||||
events.push(event());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl panic::RefUnwindSafe for TestDB {}
|
||||
|
@ -38,3 +49,26 @@ impl FileLoader for TestDB {
|
|||
FileLoaderDelegate(self).relevant_crates(file_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl TestDB {
|
||||
pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<TestDB>> {
|
||||
*self.events.lock().unwrap() = Some(Vec::new());
|
||||
f();
|
||||
self.events.lock().unwrap().take().unwrap()
|
||||
}
|
||||
|
||||
pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
|
||||
let events = self.log(f);
|
||||
events
|
||||
.into_iter()
|
||||
.filter_map(|e| match e.kind {
|
||||
// This pretty horrible, but `Debug` is the only way to inspect
|
||||
// QueryDescriptor at the moment.
|
||||
salsa::EventKind::WillExecute { database_key } => {
|
||||
Some(format!("{:?}", database_key))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue