mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
move tests over to crate-def-map
This commit is contained in:
parent
2195d1db6d
commit
71e5adf694
9 changed files with 706 additions and 867 deletions
|
@ -1,6 +1,6 @@
|
||||||
test_utils::marks!(
|
test_utils::marks!(
|
||||||
name_res_works_for_broken_modules
|
name_res_works_for_broken_modules
|
||||||
item_map_enum_importing
|
can_import_enum_variant
|
||||||
type_var_cycles_resolve_completely
|
type_var_cycles_resolve_completely
|
||||||
type_var_cycles_resolve_as_possible
|
type_var_cycles_resolve_as_possible
|
||||||
type_var_resolves_to_int_var
|
type_var_resolves_to_int_var
|
||||||
|
|
|
@ -661,7 +661,7 @@ impl ItemMap {
|
||||||
}
|
}
|
||||||
ModuleDef::Enum(e) => {
|
ModuleDef::Enum(e) => {
|
||||||
// enum variant
|
// enum variant
|
||||||
tested_by!(item_map_enum_importing);
|
tested_by!(can_import_enum_variant);
|
||||||
match e.variant(db, &segment.name) {
|
match e.variant(db, &segment.name) {
|
||||||
Some(variant) => PerNs::both(variant.into(), variant.into()),
|
Some(variant) => PerNs::both(variant.into(), variant.into()),
|
||||||
None => {
|
None => {
|
||||||
|
@ -693,6 +693,3 @@ impl ItemMap {
|
||||||
ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None)
|
ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
|
@ -273,7 +273,7 @@ impl CrateDefMap {
|
||||||
}
|
}
|
||||||
ModuleDef::Enum(e) => {
|
ModuleDef::Enum(e) => {
|
||||||
// enum variant
|
// enum variant
|
||||||
tested_by!(item_map_enum_importing);
|
tested_by!(can_import_enum_variant);
|
||||||
match e.variant(db, &segment.name) {
|
match e.variant(db, &segment.name) {
|
||||||
Some(variant) => PerNs::both(variant.into(), variant.into()),
|
Some(variant) => PerNs::both(variant.into(), variant.into()),
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -85,6 +85,12 @@ where
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
|
||||||
|
// show unresolved imports in completion, etc
|
||||||
|
for (module_id, import, import_data) in unresolved_imports {
|
||||||
|
self.record_resolved_import(module_id, PerNs::none(), import, &import_data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) {
|
fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) {
|
||||||
|
@ -415,7 +421,14 @@ where
|
||||||
modules[res].parent = Some(self.module_id);
|
modules[res].parent = Some(self.module_id);
|
||||||
modules[res].declaration = Some(declaration);
|
modules[res].declaration = Some(declaration);
|
||||||
modules[res].definition = definition;
|
modules[res].definition = definition;
|
||||||
modules[self.module_id].children.insert(name, res);
|
modules[self.module_id].children.insert(name.clone(), res);
|
||||||
|
let resolution = Resolution {
|
||||||
|
def: PerNs::types(
|
||||||
|
Module { krate: self.def_collector.def_map.krate, module_id: res }.into(),
|
||||||
|
),
|
||||||
|
import: None,
|
||||||
|
};
|
||||||
|
self.def_collector.update(self.module_id, None, &[(name, resolution)]);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
mod macros;
|
||||||
|
mod globs;
|
||||||
|
mod incremental;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ra_db::SourceDatabase;
|
use ra_db::SourceDatabase;
|
||||||
|
@ -62,6 +66,8 @@ fn crate_def_map_smoke_test() {
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
mod foo;
|
mod foo;
|
||||||
struct S;
|
struct S;
|
||||||
|
use crate::foo::bar::E;
|
||||||
|
use self::E::V;
|
||||||
|
|
||||||
//- /foo/mod.rs
|
//- /foo/mod.rs
|
||||||
pub mod bar;
|
pub mod bar;
|
||||||
|
@ -74,9 +80,13 @@ fn crate_def_map_smoke_test() {
|
||||||
);
|
);
|
||||||
assert_snapshot_matches!(map, @r###"
|
assert_snapshot_matches!(map, @r###"
|
||||||
crate
|
crate
|
||||||
|
V: t v
|
||||||
|
E: t
|
||||||
|
foo: t
|
||||||
S: t v
|
S: t v
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
|
bar: t
|
||||||
f: v
|
f: v
|
||||||
|
|
||||||
crate::foo::bar
|
crate::foo::bar
|
||||||
|
@ -87,91 +97,96 @@ E: t
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_rules_are_globally_visible() {
|
fn use_as() {
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
macro_rules! structs {
|
mod foo;
|
||||||
($($i:ident),*) => {
|
|
||||||
$(struct $i { field: u32 } )*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
structs!(Foo);
|
|
||||||
mod nested;
|
|
||||||
|
|
||||||
//- /nested.rs
|
use crate::foo::Baz as Foo;
|
||||||
structs!(Bar, Baz);
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub struct Baz;
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
assert_snapshot_matches!(map, @r###"
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
crate
|
crate
|
||||||
Foo: t v
|
Foo: t v
|
||||||
|
foo: t
|
||||||
|
|
||||||
crate::nested
|
crate::foo
|
||||||
Bar: t v
|
|
||||||
Baz: t v
|
Baz: t v
|
||||||
"###);
|
"###
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_rules_can_define_modules() {
|
fn use_trees() {
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
macro_rules! m {
|
mod foo;
|
||||||
($name:ident) => { mod $name; }
|
|
||||||
}
|
|
||||||
m!(n1);
|
|
||||||
|
|
||||||
//- /n1.rs
|
use crate::foo::bar::{Baz, Quux};
|
||||||
m!(n2)
|
|
||||||
//- /n1/n2.rs
|
//- /foo/mod.rs
|
||||||
struct X;
|
pub mod bar;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
pub enum Quux {};
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
assert_snapshot_matches!(map, @r###"
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
crate
|
crate
|
||||||
|
Quux: t
|
||||||
|
Baz: t v
|
||||||
|
foo: t
|
||||||
|
|
||||||
crate::n1
|
crate::foo
|
||||||
|
bar: t
|
||||||
|
|
||||||
crate::n1::n2
|
crate::foo::bar
|
||||||
X: t v
|
Quux: t
|
||||||
"###);
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_rules_from_other_crates_are_visible() {
|
fn re_exports() {
|
||||||
let map = def_map_with_crate_graph(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /main.rs
|
|
||||||
foo::structs!(Foo, Bar)
|
|
||||||
mod bar;
|
|
||||||
|
|
||||||
//- /bar.rs
|
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
#[macro_export]
|
mod foo;
|
||||||
macro_rules! structs {
|
|
||||||
($($i:ident),*) => {
|
|
||||||
$(struct $i { field: u32 } )*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
",
|
|
||||||
crate_graph! {
|
|
||||||
"main": ("/main.rs", ["foo"]),
|
|
||||||
"foo": ("/lib.rs", []),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
assert_snapshot_matches!(map, @r###"
|
|
||||||
crate
|
|
||||||
Foo: t v
|
|
||||||
Bar: t v
|
|
||||||
|
|
||||||
crate::bar
|
use self::foo::Baz;
|
||||||
Foo: t v
|
|
||||||
Bar: t v
|
//- /foo/mod.rs
|
||||||
"###);
|
pub mod bar;
|
||||||
|
|
||||||
|
pub use self::bar::Baz;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Baz: t v
|
||||||
|
foo: t
|
||||||
|
|
||||||
|
crate::foo
|
||||||
|
bar: t
|
||||||
|
Baz: t v
|
||||||
|
|
||||||
|
crate::foo::bar
|
||||||
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -203,31 +218,8 @@ Baz: t v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glob_across_crates() {
|
fn can_import_enum_variant() {
|
||||||
covers!(glob_across_crates);
|
covers!(can_import_enum_variant);
|
||||||
let map = def_map_with_crate_graph(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
use test_crate::*;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
crate_graph! {
|
|
||||||
"main": ("/main.rs", ["test_crate"]),
|
|
||||||
"test_crate": ("/lib.rs", []),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
assert_snapshot_matches!(map, @r###"
|
|
||||||
crate
|
|
||||||
Baz: t v
|
|
||||||
"###
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn item_map_enum_importing() {
|
|
||||||
covers!(item_map_enum_importing);
|
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
|
@ -244,22 +236,293 @@ E: t
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glob_enum() {
|
fn edition_2015_imports() {
|
||||||
covers!(glob_enum);
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
mod foo;
|
||||||
|
mod bar;
|
||||||
|
|
||||||
|
//- /bar.rs
|
||||||
|
struct Bar;
|
||||||
|
|
||||||
|
//- /foo.rs
|
||||||
|
use bar::Bar;
|
||||||
|
use other_crate::FromLib;
|
||||||
|
|
||||||
|
//- /lib.rs
|
||||||
|
struct FromLib;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", "2015", ["other_crate"]),
|
||||||
|
"other_crate": ("/lib.rs", "2018", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
bar: t
|
||||||
|
foo: t
|
||||||
|
|
||||||
|
crate::bar
|
||||||
|
Bar: t v
|
||||||
|
|
||||||
|
crate::foo
|
||||||
|
FromLib: t v
|
||||||
|
Bar: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_works_for_non_standard_filenames() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /my_library.rs
|
||||||
|
mod foo;
|
||||||
|
use self::foo::Bar;
|
||||||
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub struct Bar;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"my_library": ("/my_library.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Bar: t v
|
||||||
|
foo: t
|
||||||
|
|
||||||
|
crate::foo
|
||||||
|
Bar: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn name_res_works_for_broken_modules() {
|
||||||
|
covers!(name_res_works_for_broken_modules);
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
"
|
"
|
||||||
//- /lib.rs
|
//- /lib.rs
|
||||||
enum Foo {
|
mod foo // no `;`, no body
|
||||||
Bar, Baz
|
|
||||||
}
|
use self::foo::Baz;
|
||||||
use self::Foo::*;
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub mod bar;
|
||||||
|
|
||||||
|
pub use self::bar::Baz;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
assert_snapshot_matches!(map, @r###"
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
crate
|
crate
|
||||||
Foo: t
|
Baz: _
|
||||||
Bar: t v
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Baz: t v
|
||||||
|
foo: t
|
||||||
|
|
||||||
|
crate::foo
|
||||||
|
bar: t
|
||||||
|
|
||||||
|
crate::foo::bar
|
||||||
Baz: t v
|
Baz: t v
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn item_map_across_crates() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
use test_crate::Baz;
|
||||||
|
|
||||||
|
//- /lib.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", ["test_crate"]),
|
||||||
|
"test_crate": ("/lib.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extern_crate_rename() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
extern crate alloc as alloc_crate;
|
||||||
|
|
||||||
|
mod alloc;
|
||||||
|
mod sync;
|
||||||
|
|
||||||
|
//- /sync.rs
|
||||||
|
use alloc_crate::Arc;
|
||||||
|
|
||||||
|
//- /lib.rs
|
||||||
|
struct Arc;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", ["alloc"]),
|
||||||
|
"alloc": ("/lib.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Arc: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extern_crate_rename_2015_edition() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
extern crate alloc as alloc_crate;
|
||||||
|
|
||||||
|
mod alloc;
|
||||||
|
mod sync;
|
||||||
|
|
||||||
|
//- /sync.rs
|
||||||
|
use alloc_crate::Arc;
|
||||||
|
|
||||||
|
//- /lib.rs
|
||||||
|
struct Arc;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", "2015", ["alloc"]),
|
||||||
|
"alloc": ("/lib.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Arc: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn import_across_source_roots() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
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_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
C: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reexport_across_crates() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
use test_crate::Baz;
|
||||||
|
|
||||||
|
//- /lib.rs
|
||||||
|
pub use foo::Baz;
|
||||||
|
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /foo.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", ["test_crate"]),
|
||||||
|
"test_crate": ("/lib.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn values_dont_shadow_extern_crates() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
fn foo() {}
|
||||||
|
use foo::Bar;
|
||||||
|
|
||||||
|
//- /foo/lib.rs
|
||||||
|
pub struct Bar;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", ["foo"]),
|
||||||
|
"foo": ("/foo/lib.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map,
|
||||||
|
@r###"
|
||||||
|
crate
|
||||||
|
Bar: t v
|
||||||
|
foo: v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
118
crates/ra_hir/src/nameres/crate_def_map/tests/globs.rs
Normal file
118
crates/ra_hir/src/nameres/crate_def_map/tests/globs.rs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn glob_1() {
|
||||||
|
let map = def_map(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
mod foo;
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub mod bar;
|
||||||
|
pub use self::bar::Baz;
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
crate
|
||||||
|
bar: t
|
||||||
|
Foo: t v
|
||||||
|
Baz: t v
|
||||||
|
foo: t
|
||||||
|
|
||||||
|
crate::foo
|
||||||
|
bar: t
|
||||||
|
Foo: t v
|
||||||
|
Baz: t v
|
||||||
|
|
||||||
|
crate::foo::bar
|
||||||
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn glob_2() {
|
||||||
|
let map = def_map(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
mod foo;
|
||||||
|
use foo::*;
|
||||||
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub mod bar;
|
||||||
|
pub use self::bar::*;
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
pub use super::*;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
crate
|
||||||
|
bar: t
|
||||||
|
Foo: t v
|
||||||
|
Baz: t v
|
||||||
|
foo: t
|
||||||
|
|
||||||
|
crate::foo
|
||||||
|
bar: t
|
||||||
|
Foo: t v
|
||||||
|
Baz: t v
|
||||||
|
|
||||||
|
crate::foo::bar
|
||||||
|
bar: t
|
||||||
|
Foo: t v
|
||||||
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn glob_across_crates() {
|
||||||
|
covers!(glob_across_crates);
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
use test_crate::*;
|
||||||
|
|
||||||
|
//- /lib.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", ["test_crate"]),
|
||||||
|
"test_crate": ("/lib.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
crate
|
||||||
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn glob_enum() {
|
||||||
|
covers!(glob_enum);
|
||||||
|
let map = def_map(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
enum Foo {
|
||||||
|
Bar, Baz
|
||||||
|
}
|
||||||
|
use self::Foo::*;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
crate
|
||||||
|
Foo: t
|
||||||
|
Bar: t v
|
||||||
|
Baz: t v
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
123
crates/ra_hir/src/nameres/crate_def_map/tests/incremental.rs
Normal file
123
crates/ra_hir/src/nameres/crate_def_map/tests/incremental.rs
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use ra_db::SourceDatabase;
|
||||||
|
|
||||||
|
fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) {
|
||||||
|
let (mut db, pos) = MockDatabase::with_position(initial);
|
||||||
|
let crate_id = db.crate_graph().iter().next().unwrap();
|
||||||
|
let krate = Crate { crate_id };
|
||||||
|
{
|
||||||
|
let events = db.log_executed(|| {
|
||||||
|
db.crate_def_map(krate);
|
||||||
|
});
|
||||||
|
assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
|
||||||
|
}
|
||||||
|
db.set_file_text(pos.file_id, Arc::new(file_change.to_string()));
|
||||||
|
|
||||||
|
{
|
||||||
|
let events = db.log_executed(|| {
|
||||||
|
db.crate_def_map(krate);
|
||||||
|
});
|
||||||
|
assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn typing_inside_a_function_should_not_invalidate_def_map() {
|
||||||
|
check_def_map_is_not_recomputed(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
mod foo;<|>
|
||||||
|
|
||||||
|
use crate::foo::bar::Baz;
|
||||||
|
|
||||||
|
fn foo() -> i32 {
|
||||||
|
1 + 1
|
||||||
|
}
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub mod bar;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
"
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
use crate::foo::bar::Baz;
|
||||||
|
|
||||||
|
fn foo() -> i32 { 92 }
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn adding_inner_items_should_not_invalidate_def_map() {
|
||||||
|
check_def_map_is_not_recomputed(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
struct S { a: i32}
|
||||||
|
enum E { A }
|
||||||
|
trait T {
|
||||||
|
fn a() {}
|
||||||
|
}
|
||||||
|
mod foo;<|>
|
||||||
|
impl S {
|
||||||
|
fn a() {}
|
||||||
|
}
|
||||||
|
use crate::foo::bar::Baz;
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub mod bar;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
"
|
||||||
|
struct S { a: i32, b: () }
|
||||||
|
enum E { A, B }
|
||||||
|
trait T {
|
||||||
|
fn a() {}
|
||||||
|
fn b() {}
|
||||||
|
}
|
||||||
|
mod foo;<|>
|
||||||
|
impl S {
|
||||||
|
fn a() {}
|
||||||
|
fn b() {}
|
||||||
|
}
|
||||||
|
use crate::foo::bar::Baz;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// It would be awesome to make this work, but it's unclear how
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn typing_inside_a_function_inside_a_macro_should_not_invalidate_def_map() {
|
||||||
|
check_def_map_is_not_recomputed(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
use crate::foo::bar::Baz;
|
||||||
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
pub mod bar;
|
||||||
|
|
||||||
|
//- /foo/bar.rs
|
||||||
|
<|>
|
||||||
|
salsa::query_group! {
|
||||||
|
trait Baz {
|
||||||
|
fn foo() -> i32 { 1 + 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
salsa::query_group! {
|
||||||
|
trait Baz {
|
||||||
|
fn foo() -> i32 { 92 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
94
crates/ra_hir/src/nameres/crate_def_map/tests/macros.rs
Normal file
94
crates/ra_hir/src/nameres/crate_def_map/tests/macros.rs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn macro_rules_are_globally_visible() {
|
||||||
|
let map = def_map(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
macro_rules! structs {
|
||||||
|
($($i:ident),*) => {
|
||||||
|
$(struct $i { field: u32 } )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
structs!(Foo);
|
||||||
|
mod nested;
|
||||||
|
|
||||||
|
//- /nested.rs
|
||||||
|
structs!(Bar, Baz);
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
crate
|
||||||
|
nested: t
|
||||||
|
Foo: t v
|
||||||
|
|
||||||
|
crate::nested
|
||||||
|
Bar: t v
|
||||||
|
Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn macro_rules_can_define_modules() {
|
||||||
|
let map = def_map(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
macro_rules! m {
|
||||||
|
($name:ident) => { mod $name; }
|
||||||
|
}
|
||||||
|
m!(n1);
|
||||||
|
|
||||||
|
//- /n1.rs
|
||||||
|
m!(n2)
|
||||||
|
//- /n1/n2.rs
|
||||||
|
struct X;
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
crate
|
||||||
|
n1: t
|
||||||
|
|
||||||
|
crate::n1
|
||||||
|
n2: t
|
||||||
|
|
||||||
|
crate::n1::n2
|
||||||
|
X: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn macro_rules_from_other_crates_are_visible() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
foo::structs!(Foo, Bar)
|
||||||
|
mod bar;
|
||||||
|
|
||||||
|
//- /bar.rs
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
//- /lib.rs
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! structs {
|
||||||
|
($($i:ident),*) => {
|
||||||
|
$(struct $i { field: u32 } )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", ["foo"]),
|
||||||
|
"foo": ("/lib.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
crate
|
||||||
|
bar: t
|
||||||
|
Foo: t v
|
||||||
|
Bar: t v
|
||||||
|
|
||||||
|
crate::bar
|
||||||
|
bar: t
|
||||||
|
Foo: t v
|
||||||
|
Bar: t v
|
||||||
|
"###);
|
||||||
|
}
|
|
@ -1,769 +0,0 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use ra_db::SourceDatabase;
|
|
||||||
use test_utils::{assert_eq_text, covers};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
ItemMap,
|
|
||||||
PersistentHirDatabase,
|
|
||||||
mock::MockDatabase,
|
|
||||||
nameres::crate_def_map::ModuleId,
|
|
||||||
};
|
|
||||||
use super::Resolution;
|
|
||||||
|
|
||||||
fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
|
|
||||||
let (db, pos) = MockDatabase::with_position(fixture);
|
|
||||||
let module = crate::source_binder::module_from_position(&db, pos).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let module_id = module.module_id;
|
|
||||||
(db.item_map(krate), module_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) {
|
|
||||||
let mut lines = map[module_id]
|
|
||||||
.items
|
|
||||||
.iter()
|
|
||||||
.map(|(name, res)| format!("{}: {}", name, dump_resolution(res)))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
lines.sort();
|
|
||||||
let actual = lines.join("\n");
|
|
||||||
let expected = expected.trim().lines().map(|it| it.trim()).collect::<Vec<_>>().join("\n");
|
|
||||||
assert_eq_text!(&expected, &actual);
|
|
||||||
|
|
||||||
fn dump_resolution(resolution: &Resolution) -> &'static str {
|
|
||||||
match (resolution.def.types.is_some(), resolution.def.values.is_some()) {
|
|
||||||
(true, true) => "t v",
|
|
||||||
(true, false) => "t",
|
|
||||||
(false, true) => "v",
|
|
||||||
(false, false) => "_",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn item_map_smoke_test() {
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
|
|
||||||
use crate::foo::bar::Baz;
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn use_as() {
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
|
|
||||||
use crate::foo::Baz as Foo;
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Foo: t v
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn use_trees() {
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
|
|
||||||
use crate::foo::bar::{Baz, Quux};
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
pub enum Quux {};
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
Quux: t
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn re_exports() {
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
|
|
||||||
use self::foo::Baz;
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
|
|
||||||
pub use self::bar::Baz;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn glob_1() {
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
use foo::*;
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
pub use self::bar::Baz;
|
|
||||||
pub struct Foo;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
Foo: t v
|
|
||||||
bar: t
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn glob_2() {
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
use foo::*;
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
pub use self::bar::*;
|
|
||||||
pub struct Foo;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
pub use super::*;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
Foo: t v
|
|
||||||
bar: t
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn glob_enum() {
|
|
||||||
covers!(glob_enum);
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
enum Foo {
|
|
||||||
Bar, Baz
|
|
||||||
}
|
|
||||||
use self::Foo::*;
|
|
||||||
<|>
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Bar: t v
|
|
||||||
Baz: t v
|
|
||||||
Foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn glob_across_crates() {
|
|
||||||
covers!(glob_across_crates);
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
use test_crate::*;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", ["test_crate"]),
|
|
||||||
"test_crate": ("/lib.rs", []),
|
|
||||||
});
|
|
||||||
let main_id = db.file_id_of("/main.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn edition_2015_imports() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
mod foo;
|
|
||||||
mod bar;
|
|
||||||
|
|
||||||
//- /bar.rs
|
|
||||||
struct Bar;
|
|
||||||
|
|
||||||
//- /foo.rs
|
|
||||||
use bar::Bar;
|
|
||||||
use other_crate::FromLib;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
struct FromLib;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", "2015", ["other_crate"]),
|
|
||||||
"other_crate": ("/lib.rs", "2018", []),
|
|
||||||
});
|
|
||||||
let foo_id = db.file_id_of("/foo.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, foo_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Bar: t v
|
|
||||||
FromLib: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn module_resolution_works_for_non_standard_filenames() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /my_library.rs
|
|
||||||
mod foo;
|
|
||||||
use self::foo::Bar;
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub struct Bar;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"my_library": ("/my_library.rs", []),
|
|
||||||
});
|
|
||||||
let file_id = db.file_id_of("/my_library.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, file_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let module_id = module.module_id;
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Bar: t v
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn std_prelude() {
|
|
||||||
covers!(std_prelude);
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
use Foo::*;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
mod prelude;
|
|
||||||
#[prelude_import]
|
|
||||||
use prelude::*;
|
|
||||||
|
|
||||||
//- /prelude.rs
|
|
||||||
pub enum Foo { Bar, Baz };
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", ["test_crate"]),
|
|
||||||
"test_crate": ("/lib.rs", []),
|
|
||||||
});
|
|
||||||
let main_id = db.file_id_of("/main.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
|
|
||||||
eprintln!("module = {:?}", module);
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Bar: t v
|
|
||||||
Baz: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn name_res_works_for_broken_modules() {
|
|
||||||
covers!(name_res_works_for_broken_modules);
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo // no `;`, no body
|
|
||||||
|
|
||||||
use self::foo::Baz;
|
|
||||||
<|>
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
|
|
||||||
pub use self::bar::Baz;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Baz: _
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn item_map_using_self() {
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
use crate::foo::bar::Baz::{self};
|
|
||||||
<|>
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
foo: t
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn item_map_enum_importing() {
|
|
||||||
covers!(item_map_enum_importing);
|
|
||||||
let (item_map, module_id) = item_map(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
enum E { V }
|
|
||||||
use self::E::V;
|
|
||||||
<|>
|
|
||||||
",
|
|
||||||
);
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module_id,
|
|
||||||
"
|
|
||||||
E: t
|
|
||||||
V: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn item_map_across_crates() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
use test_crate::Baz;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", ["test_crate"]),
|
|
||||||
"test_crate": ("/lib.rs", []),
|
|
||||||
});
|
|
||||||
let main_id = db.file_id_of("/main.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn extern_crate_rename() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
extern crate alloc as alloc_crate;
|
|
||||||
|
|
||||||
mod alloc;
|
|
||||||
mod sync;
|
|
||||||
|
|
||||||
//- /sync.rs
|
|
||||||
use alloc_crate::Arc;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
struct Arc;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", ["alloc"]),
|
|
||||||
"alloc": ("/lib.rs", []),
|
|
||||||
});
|
|
||||||
let sync_id = db.file_id_of("/sync.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, sync_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Arc: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn extern_crate_rename_2015_edition() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
extern crate alloc as alloc_crate;
|
|
||||||
|
|
||||||
mod alloc;
|
|
||||||
mod sync;
|
|
||||||
|
|
||||||
//- /sync.rs
|
|
||||||
use alloc_crate::Arc;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
struct Arc;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", "2015", ["alloc"]),
|
|
||||||
"alloc": ("/lib.rs", []),
|
|
||||||
});
|
|
||||||
let sync_id = db.file_id_of("/sync.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, sync_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Arc: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn import_across_source_roots() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
pub mod a {
|
|
||||||
pub mod b {
|
|
||||||
pub struct C;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//- root /main/
|
|
||||||
|
|
||||||
//- /main/main.rs
|
|
||||||
use test_crate::a::b::C;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main/main.rs", ["test_crate"]),
|
|
||||||
"test_crate": ("/lib.rs", []),
|
|
||||||
});
|
|
||||||
let main_id = db.file_id_of("/main/main.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
C: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn reexport_across_crates() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
use test_crate::Baz;
|
|
||||||
|
|
||||||
//- /lib.rs
|
|
||||||
pub use foo::Baz;
|
|
||||||
|
|
||||||
mod foo;
|
|
||||||
|
|
||||||
//- /foo.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", ["test_crate"]),
|
|
||||||
"test_crate": ("/lib.rs", []),
|
|
||||||
});
|
|
||||||
let main_id = db.file_id_of("/main.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Baz: t v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn values_dont_shadow_extern_crates() {
|
|
||||||
let mut db = MockDatabase::with_files(
|
|
||||||
"
|
|
||||||
//- /main.rs
|
|
||||||
fn foo() {}
|
|
||||||
use foo::Bar;
|
|
||||||
|
|
||||||
//- /foo/lib.rs
|
|
||||||
pub struct Bar;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
db.set_crate_graph_from_fixture(crate_graph! {
|
|
||||||
"main": ("/main.rs", ["foo"]),
|
|
||||||
"foo": ("/foo/lib.rs", []),
|
|
||||||
});
|
|
||||||
let main_id = db.file_id_of("/main.rs");
|
|
||||||
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
let item_map = db.item_map(krate);
|
|
||||||
|
|
||||||
check_module_item_map(
|
|
||||||
&item_map,
|
|
||||||
module.module_id,
|
|
||||||
"
|
|
||||||
Bar: t v
|
|
||||||
foo: v
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
|
|
||||||
let (mut db, pos) = MockDatabase::with_position(initial);
|
|
||||||
let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
|
|
||||||
let krate = module.krate(&db).unwrap();
|
|
||||||
{
|
|
||||||
let events = db.log_executed(|| {
|
|
||||||
db.item_map(krate);
|
|
||||||
});
|
|
||||||
assert!(format!("{:?}", events).contains("item_map"))
|
|
||||||
}
|
|
||||||
db.set_file_text(pos.file_id, Arc::new(file_change.to_string()));
|
|
||||||
|
|
||||||
{
|
|
||||||
let events = db.log_executed(|| {
|
|
||||||
db.item_map(krate);
|
|
||||||
});
|
|
||||||
assert!(!format!("{:?}", events).contains("item_map"), "{:#?}", events)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn typing_inside_a_function_should_not_invalidate_item_map() {
|
|
||||||
check_item_map_is_not_recomputed(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;<|>
|
|
||||||
|
|
||||||
use crate::foo::bar::Baz;
|
|
||||||
|
|
||||||
fn foo() -> i32 {
|
|
||||||
1 + 1
|
|
||||||
}
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
"
|
|
||||||
mod foo;
|
|
||||||
|
|
||||||
use crate::foo::bar::Baz;
|
|
||||||
|
|
||||||
fn foo() -> i32 { 92 }
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn adding_inner_items_should_not_invalidate_item_map() {
|
|
||||||
check_item_map_is_not_recomputed(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
struct S { a: i32}
|
|
||||||
enum E { A }
|
|
||||||
trait T {
|
|
||||||
fn a() {}
|
|
||||||
}
|
|
||||||
mod foo;<|>
|
|
||||||
impl S {
|
|
||||||
fn a() {}
|
|
||||||
}
|
|
||||||
use crate::foo::bar::Baz;
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
pub struct Baz;
|
|
||||||
",
|
|
||||||
"
|
|
||||||
struct S { a: i32, b: () }
|
|
||||||
enum E { A, B }
|
|
||||||
trait T {
|
|
||||||
fn a() {}
|
|
||||||
fn b() {}
|
|
||||||
}
|
|
||||||
mod foo;<|>
|
|
||||||
impl S {
|
|
||||||
fn a() {}
|
|
||||||
fn b() {}
|
|
||||||
}
|
|
||||||
use crate::foo::bar::Baz;
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn typing_inside_a_function_inside_a_macro_should_not_invalidate_item_map() {
|
|
||||||
check_item_map_is_not_recomputed(
|
|
||||||
"
|
|
||||||
//- /lib.rs
|
|
||||||
mod foo;
|
|
||||||
|
|
||||||
use crate::foo::bar::Baz;
|
|
||||||
|
|
||||||
//- /foo/mod.rs
|
|
||||||
pub mod bar;
|
|
||||||
|
|
||||||
//- /foo/bar.rs
|
|
||||||
<|>
|
|
||||||
salsa::query_group! {
|
|
||||||
trait Baz {
|
|
||||||
fn foo() -> i32 { 1 + 1 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
",
|
|
||||||
"
|
|
||||||
salsa::query_group! {
|
|
||||||
trait Baz {
|
|
||||||
fn foo() -> i32 { 92 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
",
|
|
||||||
);
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue