8
8
use clippy_utils:: attrs:: is_doc_hidden;
9
9
use clippy_utils:: diagnostics:: span_lint;
10
10
use clippy_utils:: is_from_proc_macro;
11
+ use hir:: def_id:: LocalDefId ;
11
12
use if_chain:: if_chain;
12
13
use rustc_ast:: ast:: { self , MetaItem , MetaItemKind } ;
13
14
use rustc_hir as hir;
14
15
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
15
- use rustc_middle:: ty:: DefIdTree ;
16
+ use rustc_middle:: ty:: { DefIdTree , Visibility } ;
16
17
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
17
18
use rustc_span:: def_id:: CRATE_DEF_ID ;
18
19
use rustc_span:: source_map:: Span ;
@@ -35,6 +36,9 @@ declare_clippy_lint! {
35
36
}
36
37
37
38
pub struct MissingDoc {
39
+ /// Whether to **only** check for missing documentation in items visible within the current
40
+ /// crate. For example, `pub(crate)` items.
41
+ crate_items_only : bool ,
38
42
/// Stack of whether #[doc(hidden)] is set
39
43
/// at each level which has lint attributes.
40
44
doc_hidden_stack : Vec < bool > ,
@@ -43,14 +47,15 @@ pub struct MissingDoc {
43
47
impl Default for MissingDoc {
44
48
#[ must_use]
45
49
fn default ( ) -> Self {
46
- Self :: new ( )
50
+ Self :: new ( false )
47
51
}
48
52
}
49
53
50
54
impl MissingDoc {
51
55
#[ must_use]
52
- pub fn new ( ) -> Self {
56
+ pub fn new ( crate_items_only : bool ) -> Self {
53
57
Self {
58
+ crate_items_only,
54
59
doc_hidden_stack : vec ! [ false ] ,
55
60
}
56
61
}
@@ -76,6 +81,7 @@ impl MissingDoc {
76
81
fn check_missing_docs_attrs (
77
82
& self ,
78
83
cx : & LateContext < ' _ > ,
84
+ def_id : LocalDefId ,
79
85
attrs : & [ ast:: Attribute ] ,
80
86
sp : Span ,
81
87
article : & ' static str ,
@@ -96,6 +102,13 @@ impl MissingDoc {
96
102
return ;
97
103
}
98
104
105
+ if self . crate_items_only && def_id != CRATE_DEF_ID {
106
+ let vis = cx. tcx . visibility ( def_id) ;
107
+ if vis == Visibility :: Public || vis != Visibility :: Restricted ( CRATE_DEF_ID . into ( ) ) {
108
+ return ;
109
+ }
110
+ }
111
+
99
112
let has_doc = attrs
100
113
. iter ( )
101
114
. any ( |a| a. doc_str ( ) . is_some ( ) || Self :: has_include ( a. meta ( ) ) ) ;
@@ -124,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
124
137
125
138
fn check_crate ( & mut self , cx : & LateContext < ' tcx > ) {
126
139
let attrs = cx. tcx . hir ( ) . attrs ( hir:: CRATE_HIR_ID ) ;
127
- self . check_missing_docs_attrs ( cx, attrs, cx. tcx . def_span ( CRATE_DEF_ID ) , "the" , "crate" ) ;
140
+ self . check_missing_docs_attrs ( cx, CRATE_DEF_ID , attrs, cx. tcx . def_span ( CRATE_DEF_ID ) , "the" , "crate" ) ;
128
141
}
129
142
130
143
fn check_item ( & mut self , cx : & LateContext < ' tcx > , it : & ' tcx hir:: Item < ' _ > ) {
@@ -160,7 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
160
173
161
174
let attrs = cx. tcx . hir ( ) . attrs ( it. hir_id ( ) ) ;
162
175
if !is_from_proc_macro ( cx, it) {
163
- self . check_missing_docs_attrs ( cx, attrs, it. span , article, desc) ;
176
+ self . check_missing_docs_attrs ( cx, it . owner_id . def_id , attrs, it. span , article, desc) ;
164
177
}
165
178
}
166
179
@@ -169,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
169
182
170
183
let attrs = cx. tcx . hir ( ) . attrs ( trait_item. hir_id ( ) ) ;
171
184
if !is_from_proc_macro ( cx, trait_item) {
172
- self . check_missing_docs_attrs ( cx, attrs, trait_item. span , article, desc) ;
185
+ self . check_missing_docs_attrs ( cx, trait_item . owner_id . def_id , attrs, trait_item. span , article, desc) ;
173
186
}
174
187
}
175
188
@@ -186,23 +199,23 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
186
199
let ( article, desc) = cx. tcx . article_and_description ( impl_item. owner_id . to_def_id ( ) ) ;
187
200
let attrs = cx. tcx . hir ( ) . attrs ( impl_item. hir_id ( ) ) ;
188
201
if !is_from_proc_macro ( cx, impl_item) {
189
- self . check_missing_docs_attrs ( cx, attrs, impl_item. span , article, desc) ;
202
+ self . check_missing_docs_attrs ( cx, impl_item . owner_id . def_id , attrs, impl_item. span , article, desc) ;
190
203
}
191
204
}
192
205
193
206
fn check_field_def ( & mut self , cx : & LateContext < ' tcx > , sf : & ' tcx hir:: FieldDef < ' _ > ) {
194
207
if !sf. is_positional ( ) {
195
208
let attrs = cx. tcx . hir ( ) . attrs ( sf. hir_id ) ;
196
209
if !is_from_proc_macro ( cx, sf) {
197
- self . check_missing_docs_attrs ( cx, attrs, sf. span , "a" , "struct field" ) ;
210
+ self . check_missing_docs_attrs ( cx, sf . def_id , attrs, sf. span , "a" , "struct field" ) ;
198
211
}
199
212
}
200
213
}
201
214
202
215
fn check_variant ( & mut self , cx : & LateContext < ' tcx > , v : & ' tcx hir:: Variant < ' _ > ) {
203
216
let attrs = cx. tcx . hir ( ) . attrs ( v. hir_id ) ;
204
217
if !is_from_proc_macro ( cx, v) {
205
- self . check_missing_docs_attrs ( cx, attrs, v. span , "a" , "variant" ) ;
218
+ self . check_missing_docs_attrs ( cx, v . def_id , attrs, v. span , "a" , "variant" ) ;
206
219
}
207
220
}
208
221
}
0 commit comments