Skip to content

Commit 30a9926

Browse files
robertoaloimeta-codesync[bot]
authored andcommitted
Convert the undocumented_function linter to use trait
Summary: Even if the `undocumented_function` is supposed to be disabled by default, it still runs. This is due to a flawed logic in `diagnostics.rs`, originally introduced in D59272525. This is problematic, since open-source projects such as OTP see a huge number of errors when running the `elp lint` command without specifying a custom configuration. By converting the linter to use the new trait, we incidentally fix the bug. This was the last linter using the `default_disabled: true` logic. At this point the enabled/disabled logic can be simplified. Reviewed By: alanz Differential Revision: D87060203 fbshipit-source-id: 1121d286c766fb461420e3268aca817169020d7d
1 parent 20b8d99 commit 30a9926

File tree

3 files changed

+73
-42
lines changed

3 files changed

+73
-42
lines changed

crates/elp/src/resources/test/buck_tests_2/resolves_generated_includes.stdout

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ Diagnostics reported in 3 modules:
55
top_includer: 2
66
0:1-0:1::[Error] [L0000] Issue in included file
77
12:4-12:10::[Error] [E1508] undefined macro 'THIRD/2'
8-
wa_buck2_module_search: 5
9-
19:0-19:18::[WeakWarning] [W0040] The function is non-trivial, exported, but not documented.
8+
wa_buck2_module_search: 4
109
54:18-54:31::[WeakWarning] [W0051] Binary string can be written using sigil syntax.
1110
56:18-56:28::[WeakWarning] [W0051] Binary string can be written using sigil syntax.
1211
56:38-56:51::[WeakWarning] [W0051] Binary string can be written using sigil syntax.

crates/ide/src/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1500,7 +1500,6 @@ pub fn diagnostics_descriptors<'a>() -> Vec<&'a DiagnosticDescriptor<'a>> {
15001500
&unspecific_include::DESCRIPTOR,
15011501
&edoc::DESCRIPTOR,
15021502
&macro_precedence_suprise::DESCRIPTOR,
1503-
&undocumented_function::DESCRIPTOR,
15041503
&duplicate_module::DESCRIPTOR,
15051504
&no_dialyzer_attribute::DESCRIPTOR,
15061505
&no_catch::DESCRIPTOR,
@@ -1584,6 +1583,7 @@ const GENERIC_LINTERS: &[&dyn GenericDiagnostics] = &[
15841583
&unused_macro::LINTER,
15851584
&missing_compile_warn_missing_spec::LINTER,
15861585
&undocumented_module::LINTER,
1586+
&undocumented_function::LINTER,
15871587
];
15881588

15891589
/// Unified registry for all types of linters

crates/ide/src/diagnostics/undocumented_function.rs

Lines changed: 71 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
* above-listed licenses.
99
*/
1010

11-
use elp_ide_assists::helpers::unwrap_parens;
1211
// Diagnostic: undocumented-function
12+
use elp_ide_assists::helpers::unwrap_parens;
1313
use elp_ide_db::elp_base_db::FileId;
1414
use elp_syntax::ast;
1515
use elp_syntax::ast::Atom;
16+
use elp_text_edit::TextRange;
1617
use fxhash::FxHashSet;
1718
use hir::AsName;
1819
use hir::FunctionDef;
@@ -21,37 +22,66 @@ use hir::Semantic;
2122
use hir::form_list::ModuleDocAttribute;
2223
use hir::known;
2324

24-
use super::Diagnostic;
25-
use super::DiagnosticCode;
26-
use super::DiagnosticConditions;
27-
use super::DiagnosticDescriptor;
28-
use super::Severity;
29-
30-
const DIAGNOSTIC_CODE: DiagnosticCode = DiagnosticCode::UndocumentedFunction;
31-
const DIAGNOSTIC_MESSAGE: &str = "The function is non-trivial, exported, but not documented.";
32-
const DIAGNOSTIC_SEVERITY: Severity = Severity::WeakWarning;
33-
34-
pub(crate) static DESCRIPTOR: DiagnosticDescriptor = DiagnosticDescriptor {
35-
conditions: DiagnosticConditions {
36-
experimental: false,
37-
include_generated: false,
38-
include_tests: false,
39-
default_disabled: true,
40-
},
41-
checker: &|diags, sema, file_id, _ext| {
42-
check(diags, sema, file_id);
43-
},
44-
};
45-
46-
fn check(diagnostics: &mut Vec<Diagnostic>, sema: &Semantic, file_id: FileId) {
47-
let callbacks = sema.resolve_callbacks(file_id);
48-
if !contains_moduledoc_hidden_attribute(sema, file_id) {
49-
sema.def_map_local(file_id)
50-
.get_functions()
51-
.for_each(|(_arity, def)| check_function(diagnostics, sema, def, &callbacks));
25+
use crate::diagnostics::DiagnosticCode;
26+
use crate::diagnostics::GenericLinter;
27+
use crate::diagnostics::GenericLinterMatchContext;
28+
use crate::diagnostics::Linter;
29+
use crate::diagnostics::Severity;
30+
31+
pub(crate) struct UndocumentedFunctionLinter;
32+
33+
impl Linter for UndocumentedFunctionLinter {
34+
fn id(&self) -> DiagnosticCode {
35+
DiagnosticCode::UndocumentedFunction
36+
}
37+
38+
fn description(&self) -> &'static str {
39+
"The function is non-trivial, exported, but not documented."
40+
}
41+
42+
fn severity(&self) -> Severity {
43+
Severity::WeakWarning
44+
}
45+
46+
fn is_enabled(&self) -> bool {
47+
false
48+
}
49+
50+
fn should_process_test_files(&self) -> bool {
51+
false
5252
}
5353
}
5454

55+
#[derive(Debug, Default, Clone, PartialEq, Eq)]
56+
pub struct Context {
57+
range: TextRange,
58+
}
59+
60+
impl GenericLinter for UndocumentedFunctionLinter {
61+
type Context = Context;
62+
63+
fn matches(
64+
&self,
65+
sema: &Semantic,
66+
file_id: FileId,
67+
) -> Option<Vec<GenericLinterMatchContext<Context>>> {
68+
let mut res = Vec::new();
69+
let callbacks = sema.resolve_callbacks(file_id);
70+
if !contains_moduledoc_hidden_attribute(sema, file_id) {
71+
sema.def_map_local(file_id)
72+
.get_functions()
73+
.for_each(|(_arity, def)| {
74+
if let Some(match_context) = check_function(sema, def, &callbacks) {
75+
res.push(match_context);
76+
}
77+
});
78+
}
79+
Some(res)
80+
}
81+
}
82+
83+
pub static LINTER: UndocumentedFunctionLinter = UndocumentedFunctionLinter;
84+
5585
fn contains_moduledoc_hidden_attribute(sema: &Semantic, file_id: FileId) -> bool {
5686
sema.form_list(file_id)
5787
.moduledoc_attributes()
@@ -87,20 +117,22 @@ fn function_should_be_checked(
87117
}
88118

89119
fn check_function(
90-
diagnostics: &mut Vec<Diagnostic>,
91120
sema: &Semantic,
92121
def: &FunctionDef,
93122
callbacks: &FxHashSet<NameArity>,
94-
) {
123+
) -> Option<GenericLinterMatchContext<Context>> {
95124
if function_should_be_checked(sema, def, callbacks)
96125
&& !def.has_doc_attribute()
97126
&& !def.has_doc_attribute_metadata()
98127
&& def.edoc_comments(sema.db).is_none()
99128
&& let Some(name_range) = def.name_range(sema.db)
100129
{
101-
let diagnostic = Diagnostic::new(DIAGNOSTIC_CODE, DIAGNOSTIC_MESSAGE, name_range)
102-
.with_severity(DIAGNOSTIC_SEVERITY);
103-
diagnostics.push(diagnostic);
130+
Some(GenericLinterMatchContext {
131+
range: name_range,
132+
context: Context { range: name_range },
133+
})
134+
} else {
135+
None
104136
}
105137
}
106138

@@ -130,7 +162,7 @@ mod tests {
130162
-module(main).
131163
-export([main/0]).
132164
main() ->
133-
%% ^^^^ weak: W0040: The function is non-trivial, exported, but not documented.
165+
%% ^^^^ 💡 weak: W0040: The function is non-trivial, exported, but not documented.
134166
[ok,
135167
ok,
136168
ok,
@@ -147,7 +179,7 @@ mod tests {
147179
-module(main).
148180
-export([main/0]).
149181
main() ->
150-
%% ^^^^ weak: W0040: The function is non-trivial, exported, but not documented.
182+
%% ^^^^ 💡 weak: W0040: The function is non-trivial, exported, but not documented.
151183
[ok,
152184
ok,
153185
ok,
@@ -317,7 +349,7 @@ mod tests {
317349
-export([handle_call/1]).
318350
319351
main() ->
320-
%%<^ weak: W0040: The function is non-trivial, exported, but not documented.
352+
%%<^ 💡 weak: W0040: The function is non-trivial, exported, but not documented.
321353
[ok,
322354
ok,
323355
ok,
@@ -349,7 +381,7 @@ mod tests {
349381
ok.
350382
351383
complex() ->
352-
%%<^^^^ weak: W0040: The function is non-trivial, exported, but not documented.
384+
%%<^^^^ 💡 weak: W0040: The function is non-trivial, exported, but not documented.
353385
[ok,
354386
ok,
355387
ok,
@@ -370,7 +402,7 @@ mod tests {
370402
ok.
371403
372404
complex(a) ->
373-
%%<^^^^ weak: W0040: The function is non-trivial, exported, but not documented.
405+
%%<^^^^ 💡 weak: W0040: The function is non-trivial, exported, but not documented.
374406
[ok];
375407
complex(b) ->
376408
[ok,

0 commit comments

Comments
 (0)