From 6fba51c5fc05264abcbf971dcf28142746588d74 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 3 Nov 2019 23:35:48 +0300 Subject: [PATCH] move crate_def_map tests to hir_def --- Cargo.lock | 1 + crates/ra_db/src/fixture.rs | 148 +++++++++++++++++- crates/ra_db/src/input.rs | 1 + crates/ra_hir/src/nameres.rs | 3 - crates/ra_hir_def/Cargo.toml | 4 + crates/ra_hir_def/src/nameres.rs | 3 + .../src/nameres/tests.rs | 145 ++++++----------- .../src/nameres/tests/globs.rs | 10 +- .../src/nameres/tests/incremental.rs | 25 ++- .../src/nameres/tests/macros.rs | 83 +++------- .../src/nameres/tests/mod_resolution.rs | 43 +++-- .../src/nameres/tests/primitives.rs | 0 crates/ra_hir_def/src/test_db.rs | 36 ++++- 13 files changed, 308 insertions(+), 194 deletions(-) rename crates/{ra_hir => ra_hir_def}/src/nameres/tests.rs (74%) rename crates/{ra_hir => ra_hir_def}/src/nameres/tests/globs.rs (88%) rename crates/{ra_hir => ra_hir_def}/src/nameres/tests/incremental.rs (76%) rename crates/{ra_hir => ra_hir_def}/src/nameres/tests/macros.rs (86%) rename crates/{ra_hir => ra_hir_def}/src/nameres/tests/mod_resolution.rs (93%) rename crates/{ra_hir => ra_hir_def}/src/nameres/tests/primitives.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index c96e0869ca..889820c996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index 469251fe9a..f5dd59f840 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs @@ -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 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 { + 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 = 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, + deps: Vec, + cfg: CfgOptions, + edition: Edition, +} + +//- /lib.rs crate:foo deps:bar,baz +fn parse_meta(meta: &str) -> ParsedMeta { + let components = meta.split_ascii_whitespace().collect::>(); + + 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()..])) +} diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index eafa95921c..7c8dac1d38 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -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, diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index bb775cfc9d..875addc84a 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -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, diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml index 746c907e80..15055db64e 100644 --- a/crates/ra_hir_def/Cargo.toml +++ b/crates/ra_hir_def/Cargo.toml @@ -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" + diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index db59344aa3..b3640da3d7 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -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}; diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs similarity index 74% rename from crates/ra_hir/src/nameres/tests.rs rename to crates/ra_hir_def/src/nameres/tests.rs index 02db91a862..f9a8edd43c 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -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) -> Arc { - 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 { + 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###" diff --git a/crates/ra_hir/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs similarity index 88% rename from crates/ra_hir/src/nameres/tests/globs.rs rename to crates/ra_hir_def/src/nameres/tests/globs.rs index b3e4d8d945..cf4a2a8518 100644 --- a/crates/ra_hir/src/nameres/tests/globs.rs +++ b/crates/ra_hir_def/src/nameres/tests/globs.rs @@ -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 diff --git a/crates/ra_hir/src/nameres/tests/incremental.rs b/crates/ra_hir_def/src/nameres/tests/incremental.rs similarity index 76% rename from crates/ra_hir/src/nameres/tests/incremental.rs rename to crates/ra_hir_def/src/nameres/tests/incremental.rs index 723ece7b02..80dcec62f0 100644 --- a/crates/ra_hir/src/nameres/tests/incremental.rs +++ b/crates/ra_hir_def/src/nameres/tests/incremental.rs @@ -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) } diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs similarity index 86% rename from crates/ra_hir/src/nameres/tests/macros.rs rename to crates/ra_hir_def/src/nameres/tests/macros.rs index 78bb0eb0dd..9bb3895ad6 100644 --- a/crates/ra_hir/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs @@ -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 diff --git a/crates/ra_hir/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs similarity index 93% rename from crates/ra_hir/src/nameres/tests/mod_resolution.rs rename to crates/ra_hir_def/src/nameres/tests/mod_resolution.rs index abfe8b1c34..8d804a63e8 100644 --- a/crates/ra_hir/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs @@ -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", + }, + ] "### ); } diff --git a/crates/ra_hir/src/nameres/tests/primitives.rs b/crates/ra_hir_def/src/nameres/tests/primitives.rs similarity index 100% rename from crates/ra_hir/src/nameres/tests/primitives.rs rename to crates/ra_hir_def/src/nameres/tests/primitives.rs diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs index 67714c68e2..05018f8e43 100644 --- a/crates/ra_hir_def/src/test_db.rs +++ b/crates/ra_hir_def/src/test_db.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, + events: Mutex>>>, } impl salsa::Database for TestDB { fn salsa_runtime(&self) -> &salsa::Runtime { &self.runtime } + + fn salsa_event(&self, event: impl Fn() -> salsa::Event) { + 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> { + *self.events.lock().unwrap() = Some(Vec::new()); + f(); + self.events.lock().unwrap().take().unwrap() + } + + pub fn log_executed(&self, f: impl FnOnce()) -> Vec { + 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() + } +}