rust/crates/ra_hir_def/src/nameres/tests.rs

588 lines
10 KiB
Rust
Raw Normal View History

2019-03-14 03:53:40 -05:00
mod globs;
mod incremental;
2019-11-03 14:35:48 -06:00
mod macros;
2019-09-05 13:43:32 -05:00
mod mod_resolution;
2019-11-03 14:35:48 -06:00
mod primitives;
2019-03-14 03:53:40 -05:00
use std::sync::Arc;
2019-08-29 08:49:10 -05:00
use insta::assert_snapshot;
2019-11-03 14:35:48 -06:00
use ra_db::{fixture::WithFixture, SourceDatabase};
2019-11-03 14:44:23 -06:00
use test_utils::covers;
2019-11-23 07:49:53 -06:00
use crate::{db::DefDatabase, nameres::*, test_db::TestDB, LocalModuleId};
fn def_map(fixture: &str) -> String {
let dm = compute_crate_def_map(fixture);
2019-11-03 14:35:48 -06:00
render_crate_def_map(&dm)
}
fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> {
let db = TestDB::with_files(fixture);
2019-10-31 10:45:10 -05:00
let krate = db.crate_graph().iter().next().unwrap();
2019-03-13 08:38:02 -05:00
db.crate_def_map(krate)
}
fn render_crate_def_map(map: &CrateDefMap) -> String {
let mut buf = String::new();
2019-11-24 09:48:29 -06:00
go(&mut buf, map, "\ncrate", map.root);
2019-05-21 05:18:30 -05:00
return buf.trim().to_string();
2019-11-23 07:49:53 -06:00
fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) {
*buf += path;
*buf += "\n";
2019-05-21 05:18:30 -05:00
let mut entries: Vec<_> = map.modules[module].scope.resolutions().collect();
2019-12-20 10:09:13 -06:00
entries.sort_by_key(|(name, _)| name.clone());
2019-12-22 08:37:07 -06:00
for (name, def) in entries {
*buf += &format!("{}:", name);
2019-12-22 08:37:07 -06:00
if def.types.is_some() {
*buf += " t";
}
2019-12-22 08:37:07 -06:00
if def.values.is_some() {
*buf += " v";
}
2019-12-22 08:37:07 -06:00
if def.macros.is_some() {
*buf += " m";
}
2019-12-22 08:37:07 -06:00
if def.is_none() {
*buf += " _";
2019-05-26 07:11:18 -05:00
}
*buf += "\n";
}
for (name, child) in map.modules[module].children.iter() {
let path = path.to_string() + &format!("::{}", name);
go(buf, map, &path, *child);
}
}
}
#[test]
fn crate_def_map_smoke_test() {
let map = def_map(
"
//- /lib.rs
mod foo;
struct S;
2019-03-14 03:53:40 -05:00
use crate::foo::bar::E;
use self::E::V;
//- /foo/mod.rs
pub mod bar;
fn f() {}
//- /foo/bar.rs
pub struct Baz;
2019-11-25 08:30:50 -06:00
union U {
to_be: bool,
not_to_be: u8,
}
enum E { V }
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
E: t
S: t v
V: t v
foo: t
crate::foo
bar: t
f: v
crate::foo::bar
Baz: t v
E: t
2019-11-25 08:30:50 -06:00
U: t v
2019-05-21 05:18:30 -05:00
"###)
}
2019-03-16 10:06:45 -05:00
#[test]
fn bogus_paths() {
2019-11-03 14:44:23 -06:00
covers!(bogus_paths);
2019-03-16 10:06:45 -05:00
let map = def_map(
"
//- /lib.rs
mod foo;
struct S;
use self;
//- /foo/mod.rs
use super;
use crate;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
S: t v
foo: t
crate::foo
"###
2019-03-16 10:06:45 -05:00
)
}
#[test]
2019-03-14 03:53:40 -05:00
fn use_as() {
let map = def_map(
"
//- /lib.rs
2019-03-14 03:53:40 -05:00
mod foo;
use crate::foo::Baz as Foo;
2019-03-14 03:53:40 -05:00
//- /foo/mod.rs
pub struct Baz;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map,
2019-03-14 03:53:40 -05:00
@r###"
2019-05-21 05:18:30 -05:00
crate
Foo: t v
foo: t
crate::foo
Baz: t v
"###
2019-03-14 03:53:40 -05:00
);
}
#[test]
2019-03-14 03:53:40 -05:00
fn use_trees() {
let map = def_map(
"
//- /lib.rs
2019-03-14 03:53:40 -05:00
mod foo;
use crate::foo::bar::{Baz, Quux};
//- /foo/mod.rs
pub mod bar;
2019-03-14 03:53:40 -05:00
//- /foo/bar.rs
pub struct Baz;
pub enum Quux {};
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
Baz: t v
Quux: t
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
Quux: t
"###);
}
#[test]
2019-03-14 03:53:40 -05:00
fn re_exports() {
let map = def_map(
"
2019-03-14 03:53:40 -05:00
//- /lib.rs
mod foo;
2019-03-14 03:53:40 -05:00
use self::foo::Baz;
2019-03-14 03:53:40 -05:00
//- /foo/mod.rs
pub mod bar;
pub use self::bar::Baz;
//- /foo/bar.rs
pub struct Baz;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
Baz: t v
foo: t
crate::foo
Baz: t v
bar: t
crate::foo::bar
Baz: t v
"###);
}
#[test]
fn std_prelude() {
2019-11-03 14:44:23 -06:00
covers!(std_prelude);
2019-11-03 14:35:48 -06:00
let map = def_map(
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:test_crate
use Foo::*;
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:test_crate
mod prelude;
#[prelude_import]
use prelude::*;
//- /prelude.rs
pub enum Foo { Bar, Baz };
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
Bar: t v
Baz: t v
"###);
}
#[test]
2019-03-14 03:53:40 -05:00
fn can_import_enum_variant() {
2019-11-03 14:44:23 -06:00
covers!(can_import_enum_variant);
2019-03-14 03:53:40 -05:00
let map = def_map(
"
//- /lib.rs
enum E { V }
use self::E::V;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
E: t
V: t v
"###
2019-03-14 03:53:40 -05:00
);
}
#[test]
fn edition_2015_imports() {
2019-11-03 14:35:48 -06:00
let map = def_map(
2019-03-14 03:53:40 -05:00
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:other_crate edition:2015
2019-03-14 03:53:40 -05:00
mod foo;
mod bar;
//- /bar.rs
struct Bar;
//- /foo.rs
use bar::Bar;
use other_crate::FromLib;
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:other_crate edition:2018
2019-03-14 03:53:40 -05:00
struct FromLib;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
bar: t
foo: t
crate::bar
Bar: t v
crate::foo
Bar: t v
FromLib: t v
"###);
2019-03-14 03:53:40 -05:00
}
#[test]
fn item_map_using_self() {
let map = def_map(
"
//- /lib.rs
mod foo;
use crate::foo::bar::Baz::{self};
//- /foo/mod.rs
pub mod bar;
//- /foo/bar.rs
pub struct Baz;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
Baz: t v
foo: t
crate::foo
bar: t
crate::foo::bar
Baz: t v
"###);
2019-03-14 03:53:40 -05:00
}
#[test]
fn item_map_across_crates() {
2019-11-03 14:35:48 -06:00
let map = def_map(
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:test_crate
2019-03-14 03:53:40 -05:00
use test_crate::Baz;
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:test_crate
pub struct Baz;
",
);
2019-03-14 03:53:40 -05:00
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
Baz: t v
"###);
}
#[test]
2019-03-14 03:53:40 -05:00
fn extern_crate_rename() {
2019-11-03 14:35:48 -06:00
let map = def_map(
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:alloc
2019-03-14 03:53:40 -05:00
extern crate alloc as alloc_crate;
mod alloc;
mod sync;
//- /sync.rs
use alloc_crate::Arc;
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:alloc
2019-03-14 03:53:40 -05:00
struct Arc;
",
);
2019-03-14 03:53:40 -05:00
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 06:51:52 -05:00
crate
alloc_crate: t
sync: t
crate::sync
Arc: t v
2019-05-21 05:18:30 -05:00
"###);
}
#[test]
2019-03-14 03:53:40 -05:00
fn extern_crate_rename_2015_edition() {
2019-11-03 14:35:48 -06:00
let map = def_map(
2019-03-14 03:53:40 -05:00
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:alloc edition:2015
2019-03-14 03:53:40 -05:00
extern crate alloc as alloc_crate;
mod alloc;
mod sync;
//- /sync.rs
use alloc_crate::Arc;
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:alloc
2019-03-14 03:53:40 -05:00
struct Arc;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map,
2019-03-14 03:53:40 -05:00
@r###"
2019-05-21 05:18:30 -05:00
crate
2019-05-21 06:51:52 -05:00
alloc_crate: t
sync: t
crate::sync
2019-05-21 05:18:30 -05:00
Arc: t v
"###
2019-03-14 03:53:40 -05:00
);
}
#[test]
fn import_across_source_roots() {
2019-11-03 14:35:48 -06:00
let map = def_map(
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:test_crate
use test_crate::a::b::C;
//- root /test_crate/
//- /test_crate/lib.rs crate:test_crate
2019-03-14 03:53:40 -05:00
pub mod a {
pub mod b {
pub struct C;
}
}
2019-03-14 03:53:40 -05:00
",
);
2019-03-14 03:53:40 -05:00
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
C: t v
"###);
2019-03-14 03:53:40 -05:00
}
#[test]
fn reexport_across_crates() {
2019-11-03 14:35:48 -06:00
let map = def_map(
2019-03-14 03:53:40 -05:00
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:test_crate
2019-03-14 03:53:40 -05:00
use test_crate::Baz;
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:test_crate
2019-03-14 03:53:40 -05:00
pub use foo::Baz;
mod foo;
//- /foo.rs
pub struct Baz;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
Baz: t v
"###);
}
2019-03-14 03:53:40 -05:00
#[test]
fn values_dont_shadow_extern_crates() {
2019-11-03 14:35:48 -06:00
let map = def_map(
2019-03-14 03:53:40 -05:00
"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:foo
2019-03-14 03:53:40 -05:00
fn foo() {}
use foo::Bar;
2019-11-03 14:35:48 -06:00
//- /foo/lib.rs crate:foo
2019-03-14 03:53:40 -05:00
pub struct Bar;
",
);
2019-08-29 08:49:10 -05:00
assert_snapshot!(map, @r###"
2019-05-21 05:18:30 -05:00
crate
Bar: t v
foo: v
"###);
2019-03-14 03:53:40 -05:00
}
#[test]
fn std_prelude_takes_precedence_above_core_prelude() {
let map = def_map(
r#"
//- /main.rs crate:main deps:core,std
use {Foo, Bar};
//- /std.rs crate:std deps:core
#[prelude_import]
pub use self::prelude::*;
mod prelude {
pub struct Foo;
pub use core::prelude::Bar;
}
//- /core.rs crate:core
#[prelude_import]
pub use self::prelude::*;
mod prelude {
pub struct Bar;
}
"#,
);
assert_snapshot!(map, @r###"
crate
Bar: t v
Foo: t v
"###);
}
#[test]
fn cfg_not_test() {
2019-11-03 14:35:48 -06:00
let map = def_map(
r#"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:std
use {Foo, Bar, Baz};
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:std
#[prelude_import]
pub use self::prelude::*;
mod prelude {
#[cfg(test)]
pub struct Foo;
#[cfg(not(test))]
pub struct Bar;
#[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
pub struct Baz;
}
"#,
);
assert_snapshot!(map, @r###"
crate
Bar: t v
Baz: _
Foo: _
"###);
}
#[test]
fn cfg_test() {
2019-11-03 14:35:48 -06:00
let map = def_map(
r#"
2019-11-03 14:35:48 -06:00
//- /main.rs crate:main deps:std
use {Foo, Bar, Baz};
2019-11-03 14:35:48 -06:00
//- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
#[prelude_import]
pub use self::prelude::*;
mod prelude {
#[cfg(test)]
pub struct Foo;
#[cfg(not(test))]
pub struct Bar;
#[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
pub struct Baz;
}
"#,
);
assert_snapshot!(map, @r###"
crate
Bar: _
Baz: t v
Foo: t v
"###);
}
2019-12-03 05:33:48 -06:00
#[test]
fn infer_multiple_namespace() {
let map = def_map(
r#"
//- /main.rs
mod a {
pub type T = ();
pub use crate::b::*;
}
use crate::a::T;
mod b {
pub const T: () = ();
}
"#,
);
assert_snapshot!(map, @r###"
crate
T: t v
a: t
b: t
crate::b
T: v
crate::a
2019-12-20 10:09:13 -06:00
T: t v
2019-12-03 05:33:48 -06:00
"###);
}