Skip to content

Commit 2a4571d

Browse files
committed
Minimizing changes
1 parent f9c1d15 commit 2a4571d

File tree

4 files changed

+168
-112
lines changed

4 files changed

+168
-112
lines changed

Diff for: clippy_lints/src/lib.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,11 @@ mod zero_div_zero;
331331
mod zero_sized_map_values;
332332
// end lints modules, do not remove this comment, it’s used in `update_lints`
333333

334-
use crate::utils::conf::{format_error, TryConf};
335334
pub use crate::utils::conf::{lookup_conf_file, Conf};
335+
use crate::utils::{
336+
conf::{format_error, metadata::get_configuration_metadata, TryConf},
337+
FindAll,
338+
};
336339

337340
/// Register all pre expansion lints
338341
///
@@ -388,7 +391,7 @@ pub fn read_conf(sess: &Session, path: &io::Result<(Option<PathBuf>, Vec<String>
388391
conf
389392
}
390393

391-
#[derive(Default)]
394+
#[derive(Default)] //~ ERROR no such field
392395
struct RegistrationGroups {
393396
all: Vec<LintId>,
394397
cargo: Vec<LintId>,
@@ -471,7 +474,22 @@ pub(crate) struct LintInfo {
471474
pub fn explain(name: &str) {
472475
let target = format!("clippy::{}", name.to_ascii_uppercase());
473476
match declared_lints::LINTS.iter().find(|info| info.lint.name == target) {
474-
Some(info) => print!("{}", info.explanation),
477+
Some(info) => {
478+
println!("{}", info.explanation);
479+
// Check if the lint has configuration
480+
let mdconf = get_configuration_metadata();
481+
if let Some(config_vec_positions) = mdconf
482+
.iter()
483+
.find_all(|cconf| cconf.lints.contains(&info.lint.name_lower()[8..].to_owned()))
484+
{
485+
// If it has, print it
486+
println!("### Configuration for {}:", info.lint.name_lower());
487+
for position in config_vec_positions {
488+
let conf = &mdconf[position];
489+
println!(" - {}: {} (default: {})", conf.name, conf.doc, conf.default);
490+
}
491+
}
492+
},
475493
None => println!("unknown lint: {name}"),
476494
}
477495
}

Diff for: clippy_lints/src/utils/conf.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,15 @@ macro_rules! define_Conf {
174174
}
175175
}
176176

177-
#[cfg(feature = "internal")]
178177
pub mod metadata {
179-
use crate::utils::internal_lints::metadata_collector::ClippyConfiguration;
178+
use crate::utils::ClippyConfiguration;
180179

181180
macro_rules! wrap_option {
182181
() => (None);
183182
($x:literal) => (Some($x));
184183
}
185184

186-
pub(crate) fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
185+
pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
187186
vec![
188187
$(
189188
{

Diff for: clippy_lints/src/utils/internal_lints/metadata_collector.rs

+5-106
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
//! a simple mistake)
99
1010
use crate::renamed_lints::RENAMED_LINTS;
11-
use crate::utils::internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type};
11+
use crate::utils::{
12+
collect_configs,
13+
internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type},
14+
ClippyConfiguration,
15+
};
1216

1317
use clippy_utils::diagnostics::span_lint;
1418
use clippy_utils::ty::{match_type, walk_ptrs_ty_depth};
@@ -520,111 +524,6 @@ impl Serialize for ApplicabilityInfo {
520524
}
521525
}
522526

523-
// ==================================================================
524-
// Configuration
525-
// ==================================================================
526-
#[derive(Debug, Clone, Default)]
527-
pub struct ClippyConfiguration {
528-
name: String,
529-
config_type: &'static str,
530-
default: String,
531-
lints: Vec<String>,
532-
doc: String,
533-
#[allow(dead_code)]
534-
deprecation_reason: Option<&'static str>,
535-
}
536-
537-
impl ClippyConfiguration {
538-
pub fn new(
539-
name: &'static str,
540-
config_type: &'static str,
541-
default: String,
542-
doc_comment: &'static str,
543-
deprecation_reason: Option<&'static str>,
544-
) -> Self {
545-
let (lints, doc) = parse_config_field_doc(doc_comment)
546-
.unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
547-
548-
Self {
549-
name: to_kebab(name),
550-
lints,
551-
doc,
552-
config_type,
553-
default,
554-
deprecation_reason,
555-
}
556-
}
557-
558-
fn to_markdown_paragraph(&self) -> String {
559-
format!(
560-
"### {}\n{}\n\n**Default Value:** `{}` (`{}`)\n\n{}\n\n",
561-
self.name,
562-
self.doc
563-
.lines()
564-
.map(|line| line.strip_prefix(" ").unwrap_or(line))
565-
.join("\n"),
566-
self.default,
567-
self.config_type,
568-
self.lints
569-
.iter()
570-
.map(|name| name.to_string().split_whitespace().next().unwrap().to_string())
571-
.map(|name| format!("* [{name}](https://rust-lang.github.io/rust-clippy/master/index.html#{name})"))
572-
.join("\n"),
573-
)
574-
}
575-
576-
fn to_markdown_table_entry(&self) -> String {
577-
format!("| [{}](#{}) | `{}` |", self.name, self.name, self.default)
578-
}
579-
}
580-
581-
fn collect_configs() -> Vec<ClippyConfiguration> {
582-
crate::utils::conf::metadata::get_configuration_metadata()
583-
}
584-
585-
/// This parses the field documentation of the config struct.
586-
///
587-
/// ```rust, ignore
588-
/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin")
589-
/// ```
590-
///
591-
/// Would yield:
592-
/// ```rust, ignore
593-
/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin")
594-
/// ```
595-
fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec<String>, String)> {
596-
const DOC_START: &str = " Lint: ";
597-
if_chain! {
598-
if doc_comment.starts_with(DOC_START);
599-
if let Some(split_pos) = doc_comment.find('.');
600-
then {
601-
let mut doc_comment = doc_comment.to_string();
602-
let mut documentation = doc_comment.split_off(split_pos);
603-
604-
// Extract lints
605-
doc_comment.make_ascii_lowercase();
606-
let lints: Vec<String> = doc_comment
607-
.split_off(DOC_START.len())
608-
.split(", ")
609-
.map(str::to_string)
610-
.collect();
611-
612-
// Format documentation correctly
613-
// split off leading `.` from lint name list and indent for correct formatting
614-
documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n ");
615-
616-
Some((lints, documentation))
617-
} else {
618-
None
619-
}
620-
}
621-
}
622-
623-
/// Transforms a given `snake_case_string` to a tasty `kebab-case-string`
624-
fn to_kebab(config_name: &str) -> String {
625-
config_name.replace('_', "-")
626-
}
627-
628527
impl fmt::Display for ClippyConfiguration {
629528
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
630529
writeln!(

Diff for: clippy_lints/src/utils/mod.rs

+140
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,143 @@ pub mod dump_hir;
44
pub mod format_args_collector;
55
#[cfg(feature = "internal")]
66
pub mod internal_lints;
7+
#[cfg(feature = "internal")]
8+
use itertools::Itertools;
9+
10+
/// Transforms a given `snake_case_string` to a tasty `kebab-case-string`
11+
fn to_kebab(config_name: &str) -> String {
12+
config_name.replace('_', "-")
13+
}
14+
15+
// ==================================================================
16+
// Configuration
17+
// ==================================================================
18+
#[derive(Debug, Clone, Default)] //~ ERROR no such field
19+
pub struct ClippyConfiguration {
20+
pub name: String,
21+
#[allow(dead_code)]
22+
config_type: &'static str,
23+
pub default: String,
24+
pub lints: Vec<String>,
25+
pub doc: String,
26+
#[allow(dead_code)]
27+
deprecation_reason: Option<&'static str>,
28+
}
29+
30+
impl ClippyConfiguration {
31+
pub fn new(
32+
name: &'static str,
33+
config_type: &'static str,
34+
default: String,
35+
doc_comment: &'static str,
36+
deprecation_reason: Option<&'static str>,
37+
) -> Self {
38+
let (lints, doc) = parse_config_field_doc(doc_comment)
39+
.unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
40+
41+
Self {
42+
name: to_kebab(name),
43+
lints,
44+
doc,
45+
config_type,
46+
default,
47+
deprecation_reason,
48+
}
49+
}
50+
51+
#[cfg(feature = "internal")]
52+
fn to_markdown_paragraph(&self) -> String {
53+
format!(
54+
"### {}\n{}\n\n**Default Value:** `{}` (`{}`)\n\n{}\n\n",
55+
self.name,
56+
self.doc
57+
.lines()
58+
.map(|line| line.strip_prefix(" ").unwrap_or(line))
59+
.join("\n"),
60+
self.default,
61+
self.config_type,
62+
self.lints
63+
.iter()
64+
.map(|name| name.to_string().split_whitespace().next().unwrap().to_string())
65+
.map(|name| format!("* [{name}](https://rust-lang.github.io/rust-clippy/master/index.html#{name})"))
66+
.join("\n"),
67+
)
68+
}
69+
70+
#[cfg(feature = "internal")]
71+
fn to_markdown_table_entry(&self) -> String {
72+
format!("| [{}](#{}) | `{}` |", self.name, self.name, self.default)
73+
}
74+
}
75+
76+
#[cfg(feature = "internal")]
77+
fn collect_configs() -> Vec<ClippyConfiguration> {
78+
crate::utils::conf::metadata::get_configuration_metadata()
79+
}
80+
81+
/// This parses the field documentation of the config struct.
82+
///
83+
/// ```rust, ignore
84+
/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin")
85+
/// ```
86+
///
87+
/// Would yield:
88+
/// ```rust, ignore
89+
/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin")
90+
/// ```
91+
fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec<String>, String)> {
92+
const DOC_START: &str = " Lint: ";
93+
if_chain! {
94+
if doc_comment.starts_with(DOC_START);
95+
if let Some(split_pos) = doc_comment.find('.');
96+
then {
97+
let mut doc_comment = doc_comment.to_string();
98+
let mut documentation = doc_comment.split_off(split_pos);
99+
100+
// Extract lints
101+
doc_comment.make_ascii_lowercase();
102+
let lints: Vec<String> = doc_comment
103+
.split_off(DOC_START.len())
104+
.split(", ")
105+
.map(str::to_string)
106+
.collect();
107+
108+
// Format documentation correctly
109+
// split off leading `.` from lint name list and indent for correct formatting
110+
documentation = documentation.trim_start_matches('.').trim().replace("\n ", "\n ");
111+
112+
Some((lints, documentation))
113+
} else {
114+
None
115+
}
116+
}
117+
}
118+
119+
// Shamelessly stolen from find_all (https://github.com/nectariner/find_all)
120+
pub trait FindAll: Iterator + Sized {
121+
fn find_all<P>(&mut self, predicate: P) -> Option<Vec<usize>>
122+
where
123+
P: FnMut(&Self::Item) -> bool;
124+
}
125+
126+
impl<I> FindAll for I
127+
where
128+
I: Iterator,
129+
{
130+
fn find_all<P>(&mut self, mut predicate: P) -> Option<Vec<usize>>
131+
where
132+
P: FnMut(&Self::Item) -> bool,
133+
{
134+
let mut occurences = Vec::<usize>::default();
135+
for (index, element) in self.enumerate() {
136+
if predicate(&element) {
137+
occurences.push(index);
138+
}
139+
}
140+
141+
match occurences.len() {
142+
0 => None,
143+
_ => Some(occurences),
144+
}
145+
}
146+
}

0 commit comments

Comments
 (0)