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,5 +1,5 @@
|
|||||||
use either::Either;
|
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::{
|
use ide_db::{
|
||||||
defs::{Definition, NameRefClass},
|
defs::{Definition, NameRefClass},
|
||||||
search::SearchScope,
|
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 use_tree = star.parent().and_then(ast::UseTree::cast)?;
|
||||||
let (parent, mod_path) = find_parent_and_path(&star)?;
|
let (parent, mod_path) = find_parent_and_path(&star)?;
|
||||||
let target_module = match ctx.sema.resolve_path(&mod_path)? {
|
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,
|
_ => 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(
|
fn find_parent_and_path(
|
||||||
star: &SyntaxToken,
|
star: &SyntaxToken,
|
||||||
) -> Option<(Either<ast::UseTree, ast::UseTreeList>, ast::Path)> {
|
) -> 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> {
|
fn find_refs_in_mod(
|
||||||
if !is_mod_visible_from(ctx, module, visible_from) {
|
ctx: &AssistContext<'_>,
|
||||||
|
expandable: Expandable,
|
||||||
|
visible_from: Module,
|
||||||
|
) -> Option<Refs> {
|
||||||
|
if !is_expandable_visible_from(ctx, &expandable, visible_from) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let module_scope = module.scope(ctx.db(), Some(visible_from));
|
match expandable {
|
||||||
let refs = module_scope.into_iter().filter_map(|(n, d)| Ref::from_scope_def(n, d)).collect();
|
Expandable::Module(module) => {
|
||||||
Some(Refs(refs))
|
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 {
|
fn is_expandable_visible_from(
|
||||||
match module.parent(ctx.db()) {
|
ctx: &AssistContext<'_>,
|
||||||
Some(parent) => {
|
expandable: &Expandable,
|
||||||
module.visibility(ctx.db()).is_visible_from(ctx.db(), from.into())
|
from: Module,
|
||||||
&& is_mod_visible_from(ctx, parent, from)
|
) -> 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…
x
Reference in New Issue
Block a user