mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 01:17:27 +00:00
Auto merge of #15226 - alibektas:15109, r=Veykril
assist : add enum to glob_import_expand fixes #15109
This commit is contained in:
commit
954a341008
1 changed files with 149 additions and 13 deletions
|
@ -1,5 +1,5 @@
|
|||
use either::Either;
|
||||
use hir::{AssocItem, HasVisibility, Module, ModuleDef, Name, PathResolution, ScopeDef};
|
||||
use hir::{AssocItem, Enum, HasVisibility, Module, ModuleDef, Name, PathResolution, ScopeDef};
|
||||
use ide_db::{
|
||||
defs::{Definition, NameRefClass},
|
||||
search::SearchScope,
|
||||
|
@ -45,7 +45,8 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext<'_>) ->
|
|||
let use_tree = star.parent().and_then(ast::UseTree::cast)?;
|
||||
let (parent, mod_path) = find_parent_and_path(&star)?;
|
||||
let target_module = match ctx.sema.resolve_path(&mod_path)? {
|
||||
PathResolution::Def(ModuleDef::Module(it)) => it,
|
||||
PathResolution::Def(ModuleDef::Module(it)) => Expandable::Module(it),
|
||||
PathResolution::Def(ModuleDef::Adt(hir::Adt::Enum(e))) => Expandable::Enum(e),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
|
@ -90,6 +91,11 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext<'_>) ->
|
|||
)
|
||||
}
|
||||
|
||||
enum Expandable {
|
||||
Module(Module),
|
||||
Enum(Enum),
|
||||
}
|
||||
|
||||
fn find_parent_and_path(
|
||||
star: &SyntaxToken,
|
||||
) -> Option<(Either<ast::UseTree, ast::UseTreeList>, ast::Path)> {
|
||||
|
@ -168,23 +174,59 @@ impl Refs {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_refs_in_mod(ctx: &AssistContext<'_>, module: Module, visible_from: Module) -> Option<Refs> {
|
||||
if !is_mod_visible_from(ctx, module, visible_from) {
|
||||
fn find_refs_in_mod(
|
||||
ctx: &AssistContext<'_>,
|
||||
expandable: Expandable,
|
||||
visible_from: Module,
|
||||
) -> Option<Refs> {
|
||||
if !is_expandable_visible_from(ctx, &expandable, visible_from) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let module_scope = module.scope(ctx.db(), Some(visible_from));
|
||||
let refs = module_scope.into_iter().filter_map(|(n, d)| Ref::from_scope_def(n, d)).collect();
|
||||
Some(Refs(refs))
|
||||
match expandable {
|
||||
Expandable::Module(module) => {
|
||||
let module_scope = module.scope(ctx.db(), Some(visible_from));
|
||||
let refs =
|
||||
module_scope.into_iter().filter_map(|(n, d)| Ref::from_scope_def(n, d)).collect();
|
||||
Some(Refs(refs))
|
||||
}
|
||||
Expandable::Enum(enm) => Some(Refs(
|
||||
enm.variants(ctx.db())
|
||||
.into_iter()
|
||||
.map(|v| Ref { visible_name: v.name(ctx.db()), def: Definition::Variant(v) })
|
||||
.collect(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_mod_visible_from(ctx: &AssistContext<'_>, module: Module, from: Module) -> bool {
|
||||
match module.parent(ctx.db()) {
|
||||
Some(parent) => {
|
||||
module.visibility(ctx.db()).is_visible_from(ctx.db(), from.into())
|
||||
&& is_mod_visible_from(ctx, parent, from)
|
||||
fn is_expandable_visible_from(
|
||||
ctx: &AssistContext<'_>,
|
||||
expandable: &Expandable,
|
||||
from: Module,
|
||||
) -> bool {
|
||||
fn is_mod_visible_from(ctx: &AssistContext<'_>, module: Module, from: Module) -> bool {
|
||||
match module.parent(ctx.db()) {
|
||||
Some(parent) => {
|
||||
module.visibility(ctx.db()).is_visible_from(ctx.db(), from.into())
|
||||
&& is_mod_visible_from(ctx, parent, from)
|
||||
}
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
match expandable {
|
||||
Expandable::Module(module) => match module.parent(ctx.db()) {
|
||||
Some(parent) => {
|
||||
module.visibility(ctx.db()).is_visible_from(ctx.db(), from.into())
|
||||
&& is_mod_visible_from(ctx, parent, from)
|
||||
}
|
||||
None => true,
|
||||
},
|
||||
Expandable::Enum(enm) => {
|
||||
let module = enm.module(ctx.db());
|
||||
enm.visibility(ctx.db()).is_visible_from(ctx.db(), from.into())
|
||||
&& is_mod_visible_from(ctx, module, from)
|
||||
}
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,4 +939,98 @@ struct Baz {
|
|||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_support_for_enums() {
|
||||
check_assist(
|
||||
expand_glob_import,
|
||||
r#"
|
||||
mod foo {
|
||||
pub enum Foo {
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
}
|
||||
|
||||
use foo::Foo;
|
||||
use foo::Foo::*$0;
|
||||
|
||||
struct Strukt {
|
||||
bar: Foo,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s: Strukt = Strukt { bar: Bar };
|
||||
}"#,
|
||||
r#"
|
||||
mod foo {
|
||||
pub enum Foo {
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
}
|
||||
|
||||
use foo::Foo;
|
||||
use foo::Foo::Bar;
|
||||
|
||||
struct Strukt {
|
||||
bar: Foo,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s: Strukt = Strukt { bar: Bar };
|
||||
}"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expanding_multiple_variants_at_once() {
|
||||
check_assist(
|
||||
expand_glob_import,
|
||||
r#"
|
||||
mod foo {
|
||||
pub enum Foo {
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
}
|
||||
|
||||
mod abc {
|
||||
use super::foo;
|
||||
use super::foo::Foo::*$0;
|
||||
|
||||
struct Strukt {
|
||||
baz: foo::Foo,
|
||||
bar: foo::Foo,
|
||||
}
|
||||
|
||||
fn trying_calling() {
|
||||
let s: Strukt = Strukt { bar: Bar , baz : Baz };
|
||||
}
|
||||
|
||||
}"#,
|
||||
r#"
|
||||
mod foo {
|
||||
pub enum Foo {
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
}
|
||||
|
||||
mod abc {
|
||||
use super::foo;
|
||||
use super::foo::Foo::{Bar, Baz};
|
||||
|
||||
struct Strukt {
|
||||
baz: foo::Foo,
|
||||
bar: foo::Foo,
|
||||
}
|
||||
|
||||
fn trying_calling() {
|
||||
let s: Strukt = Strukt { bar: Bar , baz : Baz };
|
||||
}
|
||||
|
||||
}"#,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue