Skip to content

Commit 2d597b7

Browse files
committed
Auto merge of #7246 - xFrednet:7172-add-lint-level-to-output, r=flip1995
Adding the default lint level to the metadata collection I noticed while working on the website adaption that the lint groups still had the `clippy::` prefix in the JSON output. This PR removes this prefix and adds a `level` field to each lint and with that simplifies the website display and saves performance. The deprecated lints get are assigned to the level `none`. This is a bit different in comparison to the current lint list, but I believe that this will look better overall. Unless there is any argument against this :). That's it just a small baby PR in comparison to the original monster ^^ --- See: #7172 for the full metadata collection to-do list or to suggest a new feature in connection to it. --- changelog: none r? `@flip1995`
2 parents aa1959b + 9dc366b commit 2d597b7

File tree

1 file changed

+59
-13
lines changed

1 file changed

+59
-13
lines changed

clippy_lints/src/utils/internal_lints/metadata_collector.rs

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,28 @@ const BLACK_LISTED_LINTS: [&str; 3] = ["lint_author", "deep_code_inspection", "i
3737
/// These groups will be ignored by the lint group matcher. This is useful for collections like
3838
/// `clippy::all`
3939
const IGNORED_LINT_GROUPS: [&str; 1] = ["clippy::all"];
40-
/// Lints within this group will be excluded from the collection
41-
const EXCLUDED_LINT_GROUPS: [&str; 1] = ["clippy::internal"];
40+
/// Lints within this group will be excluded from the collection. These groups
41+
/// have to be defined without the `clippy::` prefix.
42+
const EXCLUDED_LINT_GROUPS: [&str; 1] = ["internal"];
4243
/// Collected deprecated lint will be assigned to this group in the JSON output
43-
const DEPRECATED_LINT_GROUP_STR: &str = "DEPRECATED";
44+
const DEPRECATED_LINT_GROUP_STR: &str = "deprecated";
45+
/// This is the lint level for deprecated lints that will be displayed in the lint list
46+
const DEPRECATED_LINT_LEVEL: &str = "none";
47+
/// This array holds Clippy's lint groups with their corresponding default lint level. The
48+
/// lint level for deprecated lints is set in `DEPRECATED_LINT_LEVEL`.
49+
const DEFAULT_LINT_LEVELS: [(&str, &str); 8] = [
50+
("correctness", "deny"),
51+
("restriction", "allow"),
52+
("style", "warn"),
53+
("pedantic", "allow"),
54+
("complexity", "warn"),
55+
("perf", "warn"),
56+
("cargo", "allow"),
57+
("nursery", "allow"),
58+
];
59+
/// This prefix is in front of the lint groups in the lint store. The prefix will be trimmed
60+
/// to only keep the actual lint group in the output.
61+
const CLIPPY_LINT_GROUP_PREFIX: &str = "clippy::";
4462

4563
/// This template will be used to format the configuration section in the lint documentation.
4664
/// The `configurations` parameter will be replaced with one or multiple formatted
@@ -188,18 +206,20 @@ struct LintMetadata {
188206
id: String,
189207
id_span: SerializableSpan,
190208
group: String,
209+
level: &'static str,
191210
docs: String,
192211
/// This field is only used in the output and will only be
193212
/// mapped shortly before the actual output.
194213
applicability: Option<ApplicabilityInfo>,
195214
}
196215

197216
impl LintMetadata {
198-
fn new(id: String, id_span: SerializableSpan, group: String, docs: String) -> Self {
217+
fn new(id: String, id_span: SerializableSpan, group: String, level: &'static str, docs: String) -> Self {
199218
Self {
200219
id,
201220
id_span,
202221
group,
222+
level,
203223
docs,
204224
applicability: None,
205225
}
@@ -368,7 +388,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
368388
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
369389
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
370390
// metadata extraction
371-
if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
391+
if let Some((group, level)) = get_lint_group_and_level_or_lint(cx, &lint_name, item);
372392
if let Some(mut docs) = extract_attr_docs_or_lint(cx, item);
373393
then {
374394
if let Some(configuration_section) = self.get_lint_configs(&lint_name) {
@@ -379,6 +399,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
379399
lint_name,
380400
SerializableSpan::from_item(cx, item),
381401
group,
402+
level,
382403
docs,
383404
));
384405
}
@@ -396,6 +417,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
396417
lint_name,
397418
SerializableSpan::from_item(cx, item),
398419
DEPRECATED_LINT_GROUP_STR.to_string(),
420+
DEPRECATED_LINT_LEVEL,
399421
docs,
400422
));
401423
}
@@ -475,15 +497,32 @@ fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
475497
})
476498
}
477499

478-
fn get_lint_group_or_lint(cx: &LateContext<'_>, lint_name: &str, item: &'hir Item<'_>) -> Option<String> {
500+
fn get_lint_group_and_level_or_lint(
501+
cx: &LateContext<'_>,
502+
lint_name: &str,
503+
item: &'hir Item<'_>,
504+
) -> Option<(String, &'static str)> {
479505
let result = cx.lint_store.check_lint_name(lint_name, Some(sym::clippy));
480506
if let CheckLintNameResult::Tool(Ok(lint_lst)) = result {
481-
get_lint_group(cx, lint_lst[0])
482-
.or_else(|| {
483-
lint_collection_error_item(cx, item, "Unable to determine lint group");
507+
if let Some(group) = get_lint_group(cx, lint_lst[0]) {
508+
if EXCLUDED_LINT_GROUPS.contains(&group.as_str()) {
509+
return None;
510+
}
511+
512+
if let Some(level) = get_lint_level_from_group(&group) {
513+
Some((group, level))
514+
} else {
515+
lint_collection_error_item(
516+
cx,
517+
item,
518+
&format!("Unable to determine lint level for found group `{}`", group),
519+
);
484520
None
485-
})
486-
.filter(|group| !EXCLUDED_LINT_GROUPS.contains(&group.as_str()))
521+
}
522+
} else {
523+
lint_collection_error_item(cx, item, "Unable to determine lint group");
524+
None
525+
}
487526
} else {
488527
lint_collection_error_item(cx, item, "Unable to find lint in lint_store");
489528
None
@@ -496,14 +535,21 @@ fn get_lint_group(cx: &LateContext<'_>, lint_id: LintId) -> Option<String> {
496535
continue;
497536
}
498537

499-
if lints.iter().any(|x| *x == lint_id) {
500-
return Some((*group_name).to_string());
538+
if lints.iter().any(|group_lint| *group_lint == lint_id) {
539+
let group = group_name.strip_prefix(CLIPPY_LINT_GROUP_PREFIX).unwrap_or(group_name);
540+
return Some((*group).to_string());
501541
}
502542
}
503543

504544
None
505545
}
506546

547+
fn get_lint_level_from_group(lint_group: &str) -> Option<&'static str> {
548+
DEFAULT_LINT_LEVELS
549+
.iter()
550+
.find_map(|(group_name, group_level)| (*group_name == lint_group).then(|| *group_level))
551+
}
552+
507553
fn is_deprecated_lint(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
508554
if let hir::TyKind::Path(ref path) = ty.kind {
509555
if let hir::def::Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, ty.hir_id) {

0 commit comments

Comments
 (0)