Don't parse source files to generate macro completion details

This commit is contained in:
Lukas Wirth 2022-03-10 22:21:58 +01:00
parent b1ab5770c9
commit 6c8c02f625
15 changed files with 157 additions and 204 deletions

View file

@ -18,8 +18,8 @@ use syntax::SmolStr;
use crate::{
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasCrate, HasVisibility,
LifetimeParam, Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeOrConstParam,
TypeParam, Union, Variant,
LifetimeParam, Macro, Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias,
TypeOrConstParam, TypeParam, Union, Variant,
};
impl HirDisplay for Function {
@ -509,3 +509,14 @@ impl HirDisplay for Module {
}
}
}
impl HirDisplay for Macro {
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
match self.id {
hir_def::MacroId::Macro2Id(_) => write!(f, "macro"),
hir_def::MacroId::MacroRulesId(_) => write!(f, "macro_rules!"),
hir_def::MacroId::ProcMacroId(_) => write!(f, "proc_macro"),
}?;
write!(f, " {}", self.name(f.db))
}
}

View file

@ -2,7 +2,7 @@
use std::fmt::Display;
use either::Either;
use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HirDisplay, Semantics, TypeInfo};
use ide_db::{
base_db::SourceDatabase,
defs::Definition,
@ -13,9 +13,7 @@ use ide_db::{
use itertools::Itertools;
use stdx::format_to;
use syntax::{
algo, ast,
display::{fn_as_proc_macro_label, macro_label},
match_ast, AstNode, Direction,
algo, ast, match_ast, AstNode, Direction,
SyntaxKind::{LET_EXPR, LET_STMT},
SyntaxToken, T,
};
@ -342,14 +340,8 @@ pub(super) fn definition(
) -> Option<Markup> {
let mod_path = definition_mod_path(db, &def);
let (label, docs) = match def {
Definition::Macro(it) => (
match &it.source(db)?.value {
Either::Left(mac) => macro_label(mac),
Either::Right(mac_fn) => fn_as_proc_macro_label(mac_fn),
},
it.attrs(db).docs(),
),
Definition::Field(def) => label_and_docs(db, def),
Definition::Macro(it) => label_and_docs(db, it),
Definition::Field(it) => label_and_docs(db, it),
Definition::Module(it) => label_and_docs(db, it),
Definition::Function(it) => label_and_docs(db, it),
Definition::Adt(it) => label_and_docs(db, it),

View file

@ -4102,16 +4102,16 @@ identity!{
}
"#,
expect![[r#"
*Copy*
*Copy*
```rust
test
```
```rust
test
```
```rust
pub macro Copy
```
"#]],
```rust
macro Copy
```
"#]],
);
}
@ -4126,16 +4126,16 @@ pub macro Copy {}
struct Foo;
"#,
expect![[r#"
*Copy*
*Copy*
```rust
test
```
```rust
test
```
```rust
pub macro Copy
```
"#]],
```rust
macro Copy
```
"#]],
);
check(
r#"
@ -4148,16 +4148,16 @@ mod foo {
struct Foo;
"#,
expect![[r#"
*Copy*
*Copy*
```rust
test::foo
```
```rust
test::foo
```
```rust
pub macro Copy
```
"#]],
```rust
macro Copy
```
"#]],
);
}

View file

@ -421,10 +421,10 @@ macro_rules! foo { () => {} }
fn main() { let _ = crate::$0 }
"#,
expect![[r##"
expect![[r#"
fn main() fn()
ma foo!() #[macro_export] macro_rules! foo
"##]],
ma foo!() macro_rules! foo
"#]],
);
}

View file

@ -208,12 +208,12 @@ mod macros {
macro_rules! concat { }
}
"#,
expect![[r##"
expect![[r#"
fn f() fn()
ma concat!() #[macro_export] macro_rules! concat
ma concat!() macro_rules! concat
md std
bt u32
"##]],
"#]],
);
}

View file

@ -1,12 +1,8 @@
//! Renderer for macro invocations.
use either::Either;
use hir::{Documentation, HasSource, InFile, Semantics};
use ide_db::{RootDatabase, SymbolKind};
use syntax::{
display::{fn_as_proc_macro_label, macro_label},
SmolStr,
};
use hir::{Documentation, HirDisplay};
use ide_db::SymbolKind;
use syntax::SmolStr;
use crate::{
context::PathKind,
@ -52,7 +48,7 @@ fn render(
label(&ctx, needs_bang, bra, ket, &name),
);
item.set_deprecated(ctx.is_deprecated(macro_))
.set_detail(detail(&completion.sema, macro_))
.detail(macro_.display(completion.db).to_string())
.set_documentation(docs)
.set_relevance(ctx.completion_relevance());
@ -103,18 +99,6 @@ fn banged_name(name: &str) -> SmolStr {
SmolStr::from_iter([name, "!"])
}
fn detail(sema: &Semantics<RootDatabase>, macro_: hir::Macro) -> Option<String> {
// FIXME: This is parsing the file!
let InFile { file_id, value } = macro_.source(sema.db)?;
let _ = sema.parse_or_expand(file_id);
let detail = match value {
Either::Left(node) => macro_label(&node),
// FIXME: this should render with the derive name, not the function name
Either::Right(node) => fn_as_proc_macro_label(&node),
};
Some(detail)
}
fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static str) {
let mut votes = [0, 0, 0];
for (idx, s) in docs.match_indices(&macro_name) {

View file

@ -62,7 +62,7 @@ fn proc_macros_qualified() {
struct Foo;
"#,
expect![[r#"
at identity pub macro identity
at identity proc_macro identity
"#]],
)
}
@ -302,7 +302,7 @@ struct Foo;
"#,
expect![[r#"
md core
at derive pub macro derive
at derive macro derive
kw self::
kw super::
kw crate::
@ -689,12 +689,12 @@ mod derive {
"#,
expect![[r#"
md core
de Default pub macro Default
de Default macro Default
de Clone, Copy
de PartialEq pub macro PartialEq
de PartialEq macro PartialEq
de PartialEq, Eq
de PartialEq, Eq, PartialOrd, Ord
de Clone pub macro Clone
de Clone macro Clone
de PartialEq, PartialOrd
kw self::
kw super::
@ -712,11 +712,11 @@ mod derive {
"#,
expect![[r#"
md core
de Default pub macro Default
de Default macro Default
de Clone, Copy
de Eq
de Eq, PartialOrd, Ord
de Clone pub macro Clone
de Clone macro Clone
de PartialOrd
kw self::
kw super::
@ -734,17 +734,17 @@ mod derive {
"#,
expect![[r#"
md core
de Default pub macro Default
de Default macro Default
de Clone, Copy
de Eq
de Eq, PartialOrd, Ord
de Clone pub macro Clone
de Clone macro Clone
de PartialOrd
kw self::
kw super::
kw crate::
"#]],
)
);
}
#[test]
@ -761,7 +761,7 @@ mod derive {
kw self::
kw super::
kw crate::
de DeriveIdentity (use proc_macros::DeriveIdentity) pub macro derive_identity
de DeriveIdentity (use proc_macros::DeriveIdentity) proc_macro DeriveIdentity
"#]],
);
check_derive(
@ -772,7 +772,7 @@ use proc_macros::DeriveIdentity;
#[derive(der$0)] struct Test;
"#,
expect![[r#"
de DeriveIdentity pub macro derive_identity
de DeriveIdentity proc_macro DeriveIdentity
md proc_macros
md core
kw self::
@ -808,7 +808,7 @@ use proc_macros::DeriveIdentity;
#[derive(proc_macros::$0)] struct Test;
"#,
expect![[r#"
de DeriveIdentity pub macro derive_identity
de DeriveIdentity proc_macro DeriveIdentity
"#]],
);
check_derive(
@ -818,7 +818,7 @@ use proc_macros::DeriveIdentity;
#[derive(proc_macros::C$0)] struct Test;
"#,
expect![[r#"
de DeriveIdentity pub macro derive_identity
de DeriveIdentity proc_macro DeriveIdentity
"#]],
);
}

View file

@ -30,7 +30,7 @@ fn baz() {
}
"#,
// This should not contain `FooDesc {…}`.
expect![[r##"
expect![[r#"
kw unsafe
kw match
kw while
@ -57,13 +57,13 @@ fn baz() {
fn baz() fn()
st Unit
md _69latrick
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
fn function() fn()
sc STATIC
un Union
ev TupleV() (u32)
ct CONST
"##]],
"#]],
)
}
@ -125,7 +125,7 @@ impl Unit {
}
"#,
// `self` is in here twice, once as the module, once as the local
expect![[r##"
expect![[r#"
me self.foo() fn(self)
kw unsafe
kw fn
@ -166,14 +166,14 @@ impl Unit {
md module
st Unit
md qualified
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
?? Unresolved
fn function() fn()
sc STATIC
un Union
ev TupleV() (u32)
ct CONST
"##]],
"#]],
);
check(
r#"
@ -187,7 +187,7 @@ impl Unit {
}
}
"#,
expect![[r##"
expect![[r#"
tt Trait
en Enum
st Record
@ -195,14 +195,14 @@ impl Unit {
md module
st Unit
md qualified
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
?? Unresolved
fn function() fn()
sc STATIC
un Union
ev TupleV() (u32)
ct CONST
"##]],
"#]],
);
}

View file

@ -1108,7 +1108,7 @@ fn flyimport_attribute() {
struct Foo;
"#,
expect![[r#"
at identity (use proc_macros::identity) pub macro identity
at identity (use proc_macros::identity) proc_macro identity
"#]],
);
check_edit(

View file

@ -17,7 +17,7 @@ fn target_type_or_trait_in_impl_block() {
r#"
impl Tra$0
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -27,10 +27,10 @@ impl Tra$0
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
)
}
@ -40,7 +40,7 @@ fn target_type_in_trait_impl_block() {
r#"
impl Trait for Str$0
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -50,10 +50,10 @@ impl Trait for Str$0
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
)
}
@ -85,7 +85,7 @@ fn after_struct_name() {
// FIXME: This should emit `kw where` only
check(
r"struct Struct $0",
expect![[r##"
expect![[r#"
kw pub(crate)
kw pub(super)
kw pub
@ -109,8 +109,8 @@ fn after_struct_name() {
kw super
kw crate
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}
@ -119,7 +119,7 @@ fn after_fn_name() {
// FIXME: This should emit `kw where` only
check(
r"fn func() $0",
expect![[r##"
expect![[r#"
kw pub(crate)
kw pub(super)
kw pub
@ -143,8 +143,8 @@ fn after_fn_name() {
kw super
kw crate
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}

View file

@ -12,7 +12,7 @@ fn check(ra_fixture: &str, expect: Expect) {
fn in_mod_item_list() {
check(
r#"mod tests { $0 }"#,
expect![[r##"
expect![[r#"
kw pub(crate)
kw pub(super)
kw pub
@ -35,8 +35,8 @@ fn in_mod_item_list() {
kw self
kw super
kw crate
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
)
}
@ -44,7 +44,7 @@ fn in_mod_item_list() {
fn in_source_file_item_list() {
check(
r#"$0"#,
expect![[r##"
expect![[r#"
kw pub(crate)
kw pub(super)
kw pub
@ -68,8 +68,8 @@ fn in_source_file_item_list() {
kw super
kw crate
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
)
}
@ -106,10 +106,10 @@ fn in_qualified_path() {
cov_mark::check!(no_keyword_completion_in_non_trivial_path);
check(
r#"crate::$0"#,
expect![[r##"
expect![[r#"
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
)
}
@ -162,7 +162,7 @@ fn after_visibility_unsafe() {
fn in_impl_assoc_item_list() {
check(
r#"impl Struct { $0 }"#,
expect![[r##"
expect![[r#"
kw pub(crate)
kw pub(super)
kw pub
@ -174,8 +174,8 @@ fn in_impl_assoc_item_list() {
kw super
kw crate
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
)
}
@ -199,7 +199,7 @@ fn in_impl_assoc_item_list_after_attr() {
fn in_trait_assoc_item_list() {
check(
r"trait Foo { $0 }",
expect![[r##"
expect![[r#"
kw unsafe
kw fn
kw const
@ -208,8 +208,8 @@ fn in_trait_assoc_item_list() {
kw super
kw crate
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}
@ -233,7 +233,7 @@ impl Test for () {
$0
}
"#,
expect![[r##"
expect![[r#"
kw pub(crate)
kw pub(super)
kw pub
@ -245,7 +245,7 @@ impl Test for () {
kw super
kw crate
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}

View file

@ -102,7 +102,7 @@ fn foo() {
if let a$0
}
"#,
expect![[r##"
expect![[r#"
kw ref
kw mut
en Enum
@ -112,11 +112,11 @@ fn foo() {
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
bn TupleV TupleV($1)$0
ev TupleV
ct CONST
"##]],
"#]],
);
}
@ -132,7 +132,7 @@ fn foo() {
let a$0
}
"#,
expect![[r##"
expect![[r#"
kw ref
kw mut
bn Record Record { field$1 }$0
@ -142,8 +142,8 @@ fn foo() {
ev Variant
en SingleVariantEnum
st Unit
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}
@ -154,7 +154,7 @@ fn in_param() {
fn foo(a$0) {
}
"#,
expect![[r##"
expect![[r#"
kw ref
kw mut
bn Record Record { field$1 }: Record$0
@ -162,15 +162,15 @@ fn foo(a$0) {
bn Tuple Tuple($1): Tuple$0
st Tuple
st Unit
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
check(
r#"
fn foo(a$0: Tuple) {
}
"#,
expect![[r##"
expect![[r#"
kw ref
kw mut
bn Record Record { field$1 }$0
@ -178,8 +178,8 @@ fn foo(a$0: Tuple) {
bn Tuple Tuple($1)$0
st Tuple
st Unit
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}

View file

@ -15,7 +15,7 @@ fn predicate_start() {
r#"
struct Foo<'lt, T, const C: usize> where $0 {}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -26,10 +26,10 @@ struct Foo<'lt, T, const C: usize> where $0 {}
md module
st Foo<>
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
);
}
@ -39,14 +39,14 @@ fn bound_for_type_pred() {
r#"
struct Foo<'lt, T, const C: usize> where T: $0 {}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
tt Trait
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}
@ -58,14 +58,14 @@ fn bound_for_lifetime_pred() {
r#"
struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
tt Trait
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}
@ -75,14 +75,14 @@ fn bound_for_for_pred() {
r#"
struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
tt Trait
md module
ma makro!() #[macro_export] macro_rules! makro
"##]],
ma makro!() macro_rules! makro
"#]],
);
}
@ -92,7 +92,7 @@ fn param_list_for_for_pred() {
r#"
struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -103,10 +103,10 @@ struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
md module
st Foo<>
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
);
}
@ -118,7 +118,7 @@ impl Record {
fn method(self) where $0 {}
}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -129,9 +129,9 @@ impl Record {
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
);
}

View file

@ -16,7 +16,7 @@ struct Foo<'lt, T, const C: usize> {
f: $0
}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -29,10 +29,10 @@ struct Foo<'lt, T, const C: usize> {
md module
st Foo<>
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
)
}
@ -42,7 +42,7 @@ fn tuple_struct_field() {
r#"
struct Foo<'lt, T, const C: usize>(f$0);
"#,
expect![[r##"
expect![[r#"
kw pub(crate)
kw pub(super)
kw pub
@ -58,10 +58,10 @@ struct Foo<'lt, T, const C: usize>(f$0);
md module
st Foo<>
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
)
}
@ -71,7 +71,7 @@ fn fn_return_type() {
r#"
fn x<'lt, T, const C: usize>() -> $0
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -82,10 +82,10 @@ fn x<'lt, T, const C: usize>() -> $0
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
);
}
@ -98,7 +98,7 @@ fn foo<'lt, T, const C: usize>() {
let _: $0;
}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -109,10 +109,10 @@ fn foo<'lt, T, const C: usize>() {
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
bt u32
"##]],
"#]],
);
check(
r#"
@ -121,16 +121,16 @@ fn foo<'lt, T, const C: usize>() {
let _: self::$0;
}
"#,
expect![[r##"
expect![[r#"
tt Trait
en Enum
st Record
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
un Union
"##]],
"#]],
);
}
@ -144,7 +144,7 @@ trait Trait2 {
fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
"#,
expect![[r##"
expect![[r#"
kw self
kw super
kw crate
@ -157,12 +157,12 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
tt Trait2
un Union
ct CONST
bt u32
"##]],
"#]],
);
check(
r#"
@ -172,18 +172,18 @@ trait Trait2 {
fn foo<'lt, T: Trait2<self::$0>, const CONST_PARAM: usize>(_: T) {}
"#,
expect![[r##"
expect![[r#"
tt Trait
en Enum
st Record
st Tuple
md module
st Unit
ma makro!() #[macro_export] macro_rules! makro
ma makro!() macro_rules! makro
tt Trait2
un Union
ct CONST
"##]],
"#]],
);
}

View file

@ -1,6 +1,6 @@
//! This module contains utilities for rendering syntax nodes into a string representing their signature.
use crate::ast::{self, HasAttrs, HasGenericParams, HasName};
use crate::ast::{self, HasGenericParams, HasName};
use ast::HasVisibility;
use stdx::format_to;
@ -49,37 +49,3 @@ pub fn function_declaration(node: &ast::Fn) -> String {
}
buf
}
pub fn macro_label(node: &ast::Macro) -> String {
let name = node.name();
let mut s = String::new();
match node {
ast::Macro::MacroRules(node) => {
let vis = if node.has_atom_attr("macro_export") { "#[macro_export] " } else { "" };
format_to!(s, "{}macro_rules!", vis);
}
ast::Macro::MacroDef(node) => {
if let Some(vis) = node.visibility() {
format_to!(s, "{} ", vis);
}
format_to!(s, "macro");
}
}
if let Some(name) = name {
format_to!(s, " {}", name);
}
s
}
pub fn fn_as_proc_macro_label(node: &ast::Fn) -> String {
let name = node.name();
let mut s = String::new();
if let Some(vis) = node.visibility() {
format_to!(s, "{} ", vis);
}
format_to!(s, "macro");
if let Some(name) = name {
format_to!(s, " {}", name);
}
s
}