Skip to content

Commit 88ae2d1

Browse files
committed
Metadata formatting the configuration section
1 parent 210ec72 commit 88ae2d1

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

clippy_lints/src/utils/internal_lints/metadata_collector.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
1919
use rustc_span::{sym, Loc, Span, Symbol};
2020
use serde::{ser::SerializeStruct, Serialize, Serializer};
2121
use std::collections::BinaryHeap;
22+
use std::fmt;
2223
use std::fs::{self, OpenOptions};
2324
use std::io::prelude::*;
2425
use std::path::Path;
@@ -41,6 +42,30 @@ const EXCLUDED_LINT_GROUPS: [&str; 1] = ["clippy::internal"];
4142
/// Collected deprecated lint will be assigned to this group in the JSON output
4243
const DEPRECATED_LINT_GROUP_STR: &str = "DEPRECATED";
4344

45+
/// This template will be used to format the configuration section in the lint documentation.
46+
/// The `configurations` parameter will be replaced with one or multiple formatted
47+
/// `ClippyConfiguration` instances. See `CONFIGURATION_VALUE_TEMPLATE` for further customizations
48+
macro_rules! CONFIGURATION_SECTION_TEMPLATE {
49+
() => {
50+
r#"
51+
**Configuration**
52+
This lint has the following configuration variables:
53+
54+
{configurations}
55+
"#
56+
};
57+
}
58+
/// This template will be used to format an individual `ClippyConfiguration` instance in the
59+
/// lint documentation.
60+
///
61+
/// The format function will provide strings for the following parameters: `name`, `ty`, `doc` and
62+
/// `default`
63+
macro_rules! CONFIGURATION_VALUE_TEMPLATE {
64+
() => {
65+
"* {name}: {ty}: {doc} (defaults to `{default}`)\n"
66+
};
67+
}
68+
4469
const LINT_EMISSION_FUNCTIONS: [&[&str]; 7] = [
4570
&["clippy_utils", "diagnostics", "span_lint"],
4671
&["clippy_utils", "diagnostics", "span_lint_and_help"],
@@ -120,6 +145,14 @@ impl MetadataCollector {
120145
config: collect_configs(),
121146
}
122147
}
148+
149+
fn get_lint_configs(&self, lint_name: &str) -> Option<String> {
150+
self.config
151+
.iter()
152+
.filter_map(|x| x.lints.iter().any(|x| x == lint_name).then(|| format!("{}", x)))
153+
.reduce(|acc, x| acc + &x)
154+
.map(|configurations| format!(CONFIGURATION_SECTION_TEMPLATE!(), configurations = configurations))
155+
}
123156
}
124157

125158
impl Drop for MetadataCollector {
@@ -225,6 +258,9 @@ impl Serialize for ApplicabilityInfo {
225258
}
226259
}
227260

261+
// ==================================================================
262+
// Configuration
263+
// ==================================================================
228264
#[derive(Debug)]
229265
pub(crate) struct ClippyConfigurationBasicInfo {
230266
pub name: &'static str,
@@ -242,9 +278,6 @@ struct ClippyConfiguration {
242278
default: String,
243279
}
244280

245-
// ==================================================================
246-
// Configuration
247-
// ==================================================================
248281
fn collect_configs() -> Vec<ClippyConfiguration> {
249282
let cons = crate::utils::conf::metadata::get_configuration_metadata();
250283
cons.iter()
@@ -297,6 +330,19 @@ fn to_kebab(config_name: &str) -> String {
297330
config_name.replace('_', "-")
298331
}
299332

333+
impl fmt::Display for ClippyConfiguration {
334+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
335+
write!(
336+
f,
337+
CONFIGURATION_VALUE_TEMPLATE!(),
338+
name = self.name,
339+
ty = self.config_type,
340+
doc = self.doc,
341+
default = self.default
342+
)
343+
}
344+
}
345+
300346
// ==================================================================
301347
// Lint pass
302348
// ==================================================================
@@ -321,8 +367,12 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
321367
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
322368
// metadata extraction
323369
if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
324-
if let Some(docs) = extract_attr_docs_or_lint(cx, item);
370+
if let Some(mut docs) = extract_attr_docs_or_lint(cx, item);
325371
then {
372+
if let Some(configuration_section) = self.get_lint_configs(&lint_name) {
373+
docs.push_str(&configuration_section);
374+
}
375+
326376
self.lints.push(LintMetadata::new(
327377
lint_name,
328378
SerializableSpan::from_item(cx, item),

0 commit comments

Comments
 (0)