Complete exported macros in #[macro_use($0)]
This commit is contained in:
parent
21b06c1beb
commit
b986d8ac92
@ -26,6 +26,7 @@ mod cfg;
|
|||||||
mod derive;
|
mod derive;
|
||||||
mod lint;
|
mod lint;
|
||||||
mod repr;
|
mod repr;
|
||||||
|
mod macro_use;
|
||||||
|
|
||||||
pub(crate) use self::derive::complete_derive_path;
|
pub(crate) use self::derive::complete_derive_path;
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ pub(crate) fn complete_known_attribute_input(
|
|||||||
ctx: &CompletionContext<'_>,
|
ctx: &CompletionContext<'_>,
|
||||||
&colon_prefix: &bool,
|
&colon_prefix: &bool,
|
||||||
fake_attribute_under_caret: &ast::Attr,
|
fake_attribute_under_caret: &ast::Attr,
|
||||||
|
extern_crate: Option<&ast::ExternCrate>,
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
let attribute = fake_attribute_under_caret;
|
let attribute = fake_attribute_under_caret;
|
||||||
let name_ref = match attribute.path() {
|
let name_ref = match attribute.path() {
|
||||||
@ -66,6 +68,9 @@ pub(crate) fn complete_known_attribute_input(
|
|||||||
lint::complete_lint(acc, ctx, colon_prefix, &existing_lints, &lints);
|
lint::complete_lint(acc, ctx, colon_prefix, &existing_lints, &lints);
|
||||||
}
|
}
|
||||||
"cfg" => cfg::complete_cfg(acc, ctx),
|
"cfg" => cfg::complete_cfg(acc, ctx),
|
||||||
|
"macro_use" => {
|
||||||
|
macro_use::complete_macro_use(acc, ctx, extern_crate, &parse_tt_as_comma_sep_paths(tt)?)
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
|
34
crates/ide-completion/src/completions/attribute/macro_use.rs
Normal file
34
crates/ide-completion/src/completions/attribute/macro_use.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use hir::ModuleDef;
|
||||||
|
use ide_db::SymbolKind;
|
||||||
|
use syntax::ast;
|
||||||
|
|
||||||
|
use crate::{context::CompletionContext, item::CompletionItem, Completions};
|
||||||
|
|
||||||
|
pub(super) fn complete_macro_use(
|
||||||
|
acc: &mut Completions,
|
||||||
|
ctx: &CompletionContext<'_>,
|
||||||
|
extern_crate: Option<&ast::ExternCrate>,
|
||||||
|
existing_imports: &[ast::Path],
|
||||||
|
) {
|
||||||
|
let Some(extern_crate) = extern_crate else { return };
|
||||||
|
let Some(extern_crate) = ctx.sema.to_def(extern_crate) else { return };
|
||||||
|
let Some(krate) = extern_crate.resolved_crate(ctx.db) else { return };
|
||||||
|
|
||||||
|
for mod_def in krate.root_module().declarations(ctx.db) {
|
||||||
|
if let ModuleDef::Macro(mac) = mod_def {
|
||||||
|
let mac_name = mac.name(ctx.db);
|
||||||
|
let Some(mac_name) = mac_name.as_str() else { continue };
|
||||||
|
|
||||||
|
let existing_import = existing_imports
|
||||||
|
.iter()
|
||||||
|
.filter_map(|p| p.as_single_name_ref())
|
||||||
|
.find(|n| n.text() == mac_name);
|
||||||
|
if existing_import.is_some() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = CompletionItem::new(SymbolKind::Macro, ctx.source_range(), mac_name);
|
||||||
|
item.add_to(acc, ctx.db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -371,6 +371,7 @@ pub(super) enum CompletionAnalysis {
|
|||||||
UnexpandedAttrTT {
|
UnexpandedAttrTT {
|
||||||
colon_prefix: bool,
|
colon_prefix: bool,
|
||||||
fake_attribute_under_caret: Option<ast::Attr>,
|
fake_attribute_under_caret: Option<ast::Attr>,
|
||||||
|
extern_crate: Option<ast::ExternCrate>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,11 +254,13 @@ fn analyze(
|
|||||||
{
|
{
|
||||||
let colon_prefix = previous_non_trivia_token(self_token.clone())
|
let colon_prefix = previous_non_trivia_token(self_token.clone())
|
||||||
.map_or(false, |it| T![:] == it.kind());
|
.map_or(false, |it| T![:] == it.kind());
|
||||||
|
|
||||||
CompletionAnalysis::UnexpandedAttrTT {
|
CompletionAnalysis::UnexpandedAttrTT {
|
||||||
fake_attribute_under_caret: fake_ident_token
|
fake_attribute_under_caret: fake_ident_token
|
||||||
.parent_ancestors()
|
.parent_ancestors()
|
||||||
.find_map(ast::Attr::cast),
|
.find_map(ast::Attr::cast),
|
||||||
colon_prefix,
|
colon_prefix,
|
||||||
|
extern_crate: p.ancestors().find_map(ast::ExternCrate::cast),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
|
@ -211,12 +211,14 @@ pub fn completions(
|
|||||||
CompletionAnalysis::UnexpandedAttrTT {
|
CompletionAnalysis::UnexpandedAttrTT {
|
||||||
colon_prefix,
|
colon_prefix,
|
||||||
fake_attribute_under_caret: Some(attr),
|
fake_attribute_under_caret: Some(attr),
|
||||||
|
extern_crate,
|
||||||
} => {
|
} => {
|
||||||
completions::attribute::complete_known_attribute_input(
|
completions::attribute::complete_known_attribute_input(
|
||||||
acc,
|
acc,
|
||||||
ctx,
|
ctx,
|
||||||
colon_prefix,
|
colon_prefix,
|
||||||
attr,
|
attr,
|
||||||
|
extern_crate.as_ref(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
CompletionAnalysis::UnexpandedAttrTT { .. } | CompletionAnalysis::String { .. } => (),
|
CompletionAnalysis::UnexpandedAttrTT { .. } | CompletionAnalysis::String { .. } => (),
|
||||||
|
@ -1067,3 +1067,82 @@ mod repr {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod macro_use {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn completes_macros() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- /dep.rs crate:dep
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! foo {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bar {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /main.rs crate:main deps:dep
|
||||||
|
#[macro_use($0)]
|
||||||
|
extern crate dep;
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
ma bar
|
||||||
|
ma foo
|
||||||
|
"#]],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn only_completes_exported_macros() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- /dep.rs crate:dep
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! foo {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bar {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /main.rs crate:main deps:dep
|
||||||
|
#[macro_use($0)]
|
||||||
|
extern crate dep;
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
ma foo
|
||||||
|
"#]],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn does_not_completes_already_imported_macros() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- /dep.rs crate:dep
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! foo {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bar {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /main.rs crate:main deps:dep
|
||||||
|
#[macro_use(foo, $0)]
|
||||||
|
extern crate dep;
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
ma bar
|
||||||
|
"#]],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user