Skip to content

Commit 3a6cac7

Browse files
committed
add rewrite_struct proc-macro and test case
1 parent a79db2a commit 3a6cac7

File tree

3 files changed

+64
-19
lines changed

3 files changed

+64
-19
lines changed

tests/ui/auxiliary/proc_macro_attr.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use syn::spanned::Spanned;
1212
use syn::token::Star;
1313
use syn::{
1414
parse_macro_input, parse_quote, FnArg, ImplItem, ItemFn, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType,
15-
Signature, TraitItem, Type,
15+
Signature, TraitItem, Type, ItemStruct, Visibility,
1616
};
1717

1818
#[proc_macro_attribute]
@@ -101,9 +101,7 @@ pub fn fake_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
101101
let mut item = parse_macro_input!(item as ItemFn);
102102
let span = item.block.brace_token.span;
103103

104-
if item.sig.asyncness.is_some() {
105-
item.sig.asyncness = None;
106-
}
104+
item.sig.asyncness = None;
107105

108106
let crate_name = quote! { fake_crate };
109107
let block = item.block;
@@ -128,7 +126,7 @@ pub fn fake_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
128126

129127
#[proc_macro_attribute]
130128
pub fn fake_desugar_await(_args: TokenStream, input: TokenStream) -> TokenStream {
131-
let mut async_fn = syn::parse_macro_input!(input as syn::ItemFn);
129+
let mut async_fn = parse_macro_input!(input as syn::ItemFn);
132130

133131
for stmt in &mut async_fn.block.stmts {
134132
if let syn::Stmt::Expr(syn::Expr::Match(syn::ExprMatch { expr: scrutinee, .. }), _) = stmt {
@@ -145,3 +143,23 @@ pub fn fake_desugar_await(_args: TokenStream, input: TokenStream) -> TokenStream
145143

146144
quote!(#async_fn).into()
147145
}
146+
147+
#[proc_macro_attribute]
148+
pub fn rewrite_struct(_args: TokenStream, input: TokenStream) -> TokenStream {
149+
let mut item_struct = parse_macro_input!(input as syn::ItemStruct);
150+
// remove struct attributes including doc comments.
151+
item_struct.attrs = vec![];
152+
if let Visibility::Public(token) = item_struct.vis {
153+
// set vis to `pub(crate)` to trigger `missing_docs_in_private_items` lint.
154+
let new_vis: Visibility = syn::parse_quote_spanned!(token.span() => pub(crate));
155+
item_struct.vis = new_vis;
156+
}
157+
if let syn::Fields::Named(fields) = &mut item_struct.fields {
158+
for field in &mut fields.named {
159+
// remove all attributes from fields as well.
160+
field.attrs = vec![];
161+
}
162+
}
163+
164+
quote!(#item_struct).into()
165+
}

tests/ui/missing_doc.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@needs-asm-support
22
//@aux-build: proc_macros.rs
3+
//@aux-build: proc_macro_attr.rs
34

45
#![warn(clippy::missing_docs_in_private_items)]
56
// When denying at the crate level, be sure to not get random warnings from the
@@ -8,6 +9,8 @@
89
//! Some garbage docs for the crate here
910
#![doc = "More garbage"]
1011

12+
#[macro_use]
13+
extern crate proc_macro_attr;
1114
extern crate proc_macros;
1215

1316
use proc_macros::with_span;
@@ -112,3 +115,12 @@ with_span!(span pub enum FooPm3 { A, B(u32), C { field: u32 }});
112115
with_span!(span pub fn foo_pm() {});
113116
with_span!(span pub static FOO_PM: u32 = 0;);
114117
with_span!(span pub const FOO2_PM: u32 = 0;);
118+
119+
// issue #12197
120+
// Undocumented field originated inside of spanned proc-macro attribute
121+
/// Some dox for struct.
122+
#[rewrite_struct]
123+
pub struct Test {
124+
/// Dox
125+
a: u8,
126+
}

tests/ui/missing_doc.stderr

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: missing documentation for a type alias
2-
--> tests/ui/missing_doc.rs:16:1
2+
--> tests/ui/missing_doc.rs:19:1
33
|
44
LL | type Typedef = String;
55
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -8,19 +8,19 @@ LL | type Typedef = String;
88
= help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]`
99

1010
error: missing documentation for a module
11-
--> tests/ui/missing_doc.rs:19:1
11+
--> tests/ui/missing_doc.rs:22:1
1212
|
1313
LL | mod module_no_dox {}
1414
| ^^^^^^^^^^^^^^^^^^^^
1515

1616
error: missing documentation for a function
17-
--> tests/ui/missing_doc.rs:25:1
17+
--> tests/ui/missing_doc.rs:28:1
1818
|
1919
LL | fn foo3() {}
2020
| ^^^^^^^^^^^^
2121

2222
error: missing documentation for an enum
23-
--> tests/ui/missing_doc.rs:39:1
23+
--> tests/ui/missing_doc.rs:42:1
2424
|
2525
LL | / enum Baz {
2626
LL | | BazA { a: isize, b: isize },
@@ -29,43 +29,43 @@ LL | | }
2929
| |_^
3030

3131
error: missing documentation for a variant
32-
--> tests/ui/missing_doc.rs:40:5
32+
--> tests/ui/missing_doc.rs:43:5
3333
|
3434
LL | BazA { a: isize, b: isize },
3535
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
3636

3737
error: missing documentation for a struct field
38-
--> tests/ui/missing_doc.rs:40:12
38+
--> tests/ui/missing_doc.rs:43:12
3939
|
4040
LL | BazA { a: isize, b: isize },
4141
| ^^^^^^^^
4242

4343
error: missing documentation for a struct field
44-
--> tests/ui/missing_doc.rs:40:22
44+
--> tests/ui/missing_doc.rs:43:22
4545
|
4646
LL | BazA { a: isize, b: isize },
4747
| ^^^^^^^^
4848

4949
error: missing documentation for a variant
50-
--> tests/ui/missing_doc.rs:41:5
50+
--> tests/ui/missing_doc.rs:44:5
5151
|
5252
LL | BarB,
5353
| ^^^^
5454

5555
error: missing documentation for a constant
56-
--> tests/ui/missing_doc.rs:65:1
56+
--> tests/ui/missing_doc.rs:68:1
5757
|
5858
LL | const FOO: u32 = 0;
5959
| ^^^^^^^^^^^^^^^^^^^
6060

6161
error: missing documentation for a static
62-
--> tests/ui/missing_doc.rs:74:1
62+
--> tests/ui/missing_doc.rs:77:1
6363
|
6464
LL | static BAR: u32 = 0;
6565
| ^^^^^^^^^^^^^^^^^^^^
6666

6767
error: missing documentation for a module
68-
--> tests/ui/missing_doc.rs:83:1
68+
--> tests/ui/missing_doc.rs:86:1
6969
|
7070
LL | / mod internal_impl {
7171
LL | | /// dox
@@ -77,16 +77,31 @@ LL | | }
7777
| |_^
7878

7979
error: missing documentation for a function
80-
--> tests/ui/missing_doc.rs:88:5
80+
--> tests/ui/missing_doc.rs:91:5
8181
|
8282
LL | fn undocumented3() {}
8383
| ^^^^^^^^^^^^^^^^^^^^^
8484

8585
error: missing documentation for a function
86-
--> tests/ui/missing_doc.rs:94:9
86+
--> tests/ui/missing_doc.rs:97:9
8787
|
8888
LL | fn also_undocumented2() {}
8989
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
9090

91-
error: aborting due to 13 previous errors
91+
error: missing documentation for a struct
92+
--> tests/ui/missing_doc.rs:123:1
93+
|
94+
LL | / pub struct Test {
95+
LL | | /// Dox
96+
LL | | a: u8,
97+
LL | | }
98+
| |_^
99+
100+
error: missing documentation for a struct field
101+
--> tests/ui/missing_doc.rs:125:5
102+
|
103+
LL | a: u8,
104+
| ^^^^^
105+
106+
error: aborting due to 15 previous errors
92107

0 commit comments

Comments
 (0)