Metadata collection monster searching for configurations
This commit is contained in:
parent
aa15a5442a
commit
210ec728e5
@ -1009,7 +1009,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||
#[cfg(feature = "metadata-collector-lint")]
|
||||
{
|
||||
if std::env::var("ENABLE_METADATA_COLLECTION").eq(&Ok("1".to_string())) {
|
||||
store.register_late_pass(|| box utils::internal_lints::metadata_collector::MetadataCollector::default());
|
||||
store.register_late_pass(|| box utils::internal_lints::metadata_collector::MetadataCollector::new());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,13 +26,13 @@ fn from_error(error: impl Error) -> Self {
|
||||
|
||||
macro_rules! define_Conf {
|
||||
($(
|
||||
#[$doc:meta]
|
||||
#[doc = $doc:literal]
|
||||
$(#[conf_deprecated($dep:literal)])?
|
||||
($name:ident: $ty:ty = $default:expr),
|
||||
)*) => {
|
||||
/// Clippy lint configuration
|
||||
pub struct Conf {
|
||||
$(#[$doc] pub $name: $ty,)*
|
||||
$(#[doc = $doc] pub $name: $ty,)*
|
||||
}
|
||||
|
||||
mod defaults {
|
||||
@ -89,6 +89,24 @@ fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapA
|
||||
Ok(TryConf { conf, errors })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "metadata-collector-lint")]
|
||||
pub mod metadata {
|
||||
use crate::utils::internal_lints::metadata_collector::ClippyConfigurationBasicInfo;
|
||||
|
||||
pub(crate) fn get_configuration_metadata() -> Vec<ClippyConfigurationBasicInfo> {
|
||||
vec![
|
||||
$(
|
||||
ClippyConfigurationBasicInfo {
|
||||
name: stringify!($name),
|
||||
config_type: stringify!($ty),
|
||||
default: stringify!($default),
|
||||
doc_comment: $doc,
|
||||
},
|
||||
)+
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -100,7 +118,7 @@ fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapA
|
||||
(blacklisted_names: Vec<String> = ["foo", "baz", "quux"].iter().map(ToString::to_string).collect()),
|
||||
/// Lint: COGNITIVE_COMPLEXITY. The maximum cognitive complexity a function can have
|
||||
(cognitive_complexity_threshold: u64 = 25),
|
||||
/// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY. Use the Cognitive Complexity lint instead.
|
||||
/// Lint: CYCLOMATIC_COMPLEXITY. Use the Cognitive Complexity lint instead.
|
||||
#[conf_deprecated("Please use `cognitive-complexity-threshold` instead")]
|
||||
(cyclomatic_complexity_threshold: Option<u64> = None),
|
||||
/// Lint: DOC_MARKDOWN. The list of words this lint should not consider as identifiers needing ticks
|
||||
|
@ -102,13 +102,24 @@
|
||||
impl_lint_pass!(MetadataCollector => [INTERNAL_METADATA_COLLECTOR]);
|
||||
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MetadataCollector {
|
||||
/// All collected lints
|
||||
///
|
||||
/// We use a Heap here to have the lints added in alphabetic order in the export
|
||||
lints: BinaryHeap<LintMetadata>,
|
||||
applicability_info: FxHashMap<String, ApplicabilityInfo>,
|
||||
config: Vec<ClippyConfiguration>,
|
||||
}
|
||||
|
||||
impl MetadataCollector {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
lints: BinaryHeap::<LintMetadata>::default(),
|
||||
applicability_info: FxHashMap::<String, ApplicabilityInfo>::default(),
|
||||
config: collect_configs(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MetadataCollector {
|
||||
@ -214,6 +225,81 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ClippyConfigurationBasicInfo {
|
||||
pub name: &'static str,
|
||||
pub config_type: &'static str,
|
||||
pub default: &'static str,
|
||||
pub doc_comment: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct ClippyConfiguration {
|
||||
name: String,
|
||||
lints: Vec<String>,
|
||||
doc: String,
|
||||
config_type: &'static str,
|
||||
default: String,
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
// Configuration
|
||||
// ==================================================================
|
||||
fn collect_configs() -> Vec<ClippyConfiguration> {
|
||||
let cons = crate::utils::conf::metadata::get_configuration_metadata();
|
||||
cons.iter()
|
||||
.map(move |x| {
|
||||
let (lints, doc) = parse_config_field_doc(x.doc_comment)
|
||||
.unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
|
||||
|
||||
ClippyConfiguration {
|
||||
name: to_kebab(x.name),
|
||||
lints,
|
||||
doc,
|
||||
config_type: x.config_type,
|
||||
default: x.default.to_string(),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// This parses the field documentation of the config struct.
|
||||
///
|
||||
/// ```rust, ignore
|
||||
/// parse_config_field_doc(cx, "Lint: LINT_NAME_1, LINT_NAME_2. Papa penguin, papa penguin")
|
||||
/// ```
|
||||
///
|
||||
/// Would yield:
|
||||
/// ```rust, ignore
|
||||
/// Some(["lint_name_1", "lint_name_2"], "Papa penguin, papa penguin")
|
||||
/// ```
|
||||
fn parse_config_field_doc(doc_comment: &str) -> Option<(Vec<String>, String)> {
|
||||
const DOC_START: &str = " Lint: ";
|
||||
if_chain! {
|
||||
if doc_comment.starts_with(DOC_START);
|
||||
if let Some(split_pos) = doc_comment.find('.');
|
||||
then {
|
||||
let mut doc_comment = doc_comment.to_string();
|
||||
let documentation = doc_comment.split_off(split_pos);
|
||||
|
||||
doc_comment.make_ascii_lowercase();
|
||||
let lints: Vec<String> = doc_comment.split_off(DOC_START.len()).split(", ").map(str::to_string).collect();
|
||||
|
||||
Some((lints, documentation))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transforms a given `snake_case_string` to a tasty `kebab-case-string`
|
||||
fn to_kebab(config_name: &str) -> String {
|
||||
config_name.replace('_', "-")
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
// Lint pass
|
||||
// ==================================================================
|
||||
impl<'hir> LateLintPass<'hir> for MetadataCollector {
|
||||
/// Collecting lint declarations like:
|
||||
/// ```rust, ignore
|
||||
|
Loading…
Reference in New Issue
Block a user