Add configuration variables to wiki

This commit is contained in:
mcarton 2016-02-22 14:25:51 +01:00
parent 1841804d43
commit 232710cd43
3 changed files with 52 additions and 21 deletions

View file

@ -73,16 +73,16 @@ impl From<io::Error> for ConfError {
}
macro_rules! define_Conf {
($(($toml_name: tt, $rust_name: ident, $default: expr, $ty: ident),)+) => {
($(#[$doc: meta] ($toml_name: tt, $rust_name: ident, $default: expr => $($ty: tt)+),)+) => {
/// Type used to store lint configuration.
pub struct Conf {
$(pub $rust_name: $ty,)+
$(#[$doc] pub $rust_name: define_Conf!(TY $($ty)+),)+
}
impl Default for Conf {
fn default() -> Conf {
Conf {
$($rust_name: $default,)+
$($rust_name: define_Conf!(DEFAULT $($ty)+, $default),)+
}
}
}
@ -94,12 +94,12 @@ macro_rules! define_Conf {
match name.as_str() {
$(
define_Conf!(PAT $toml_name) => {
if let Some(value) = define_Conf!(CONV $ty, value) {
if let Some(value) = define_Conf!(CONV $($ty)+, value) {
self.$rust_name = value;
}
else {
return Err(ConfError::TypeError(define_Conf!(EXPR $toml_name),
stringify!($ty),
stringify!($($ty)+),
value.type_str()));
}
},
@ -117,12 +117,13 @@ macro_rules! define_Conf {
// hack to convert tts
(PAT $pat: pat) => { $pat };
(EXPR $e: expr) => { $e };
(TY $ty: ty) => { $ty };
// how to read the value?
(CONV i64, $value: expr) => { $value.as_integer() };
(CONV u64, $value: expr) => { $value.as_integer().iter().filter_map(|&i| if i >= 0 { Some(i as u64) } else { None }).next() };
(CONV String, $value: expr) => { $value.as_str().map(Into::into) };
(CONV StringVec, $value: expr) => {{
(CONV Vec<String>, $value: expr) => {{
let slice = $value.as_slice();
if let Some(slice) = slice {
@ -137,16 +138,21 @@ macro_rules! define_Conf {
None
}
}};
// provide a nicer syntax to declare the default value of `Vec<String>` variables
(DEFAULT Vec<String>, $e: expr) => { $e.iter().map(|&e| e.to_owned()).collect() };
(DEFAULT $ty: ty, $e: expr) => { $e };
}
/// To keep the `define_Conf!` macro simple
pub type StringVec = Vec<String>;
define_Conf! {
("blacklisted-names", blacklisted_names, vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()], StringVec),
("cyclomatic-complexity-threshold", cyclomatic_complexity_threshold, 25, u64),
("too-many-arguments-threshold", too_many_arguments_threshold, 6, u64),
("type-complexity-threshold", type_complexity_threshold, 250, u64),
/// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about
("blacklisted-names", blacklisted_names, ["foo", "bar", "baz"] => Vec<String>),
/// Lint: CYCLOMATIC_COMPLEXITY. The maximum cyclomatic complexity a function can have
("cyclomatic-complexity-threshold", cyclomatic_complexity_threshold, 25 => u64),
/// Lint: TOO_MANY_ARGUMENTS. The maximum number of argument a function or method can have
("too-many-arguments-threshold", too_many_arguments_threshold, 6 => u64),
/// Lint: TYPE_COMPLEXITY. The maximum complexity a type can have
("type-complexity-threshold", type_complexity_threshold, 250 => u64),
}
/// Read the `toml` configuration file. The function will ignore “File not found” errors iif

View file

@ -1,3 +1,4 @@
#![feature(type_macros)]
#![feature(plugin_registrar, box_syntax)]
#![feature(rustc_private, collections)]
#![feature(iter_arith)]

View file

@ -9,6 +9,8 @@ import sys
level_re = re.compile(r'''(Forbid|Deny|Warn|Allow)''')
conf_re = re.compile(r'''define_Conf! {\n([^}]*)\n}''', re.MULTILINE)
confvar_re = re.compile(r'''/// Lint: (\w+). (.*).*\n *\("([^"]*)", (?:[^,]*), (.*) => (.*)\),''')
def parse_path(p="src"):
@ -16,10 +18,23 @@ def parse_path(p="src"):
for f in os.listdir(p):
if f.endswith(".rs"):
parse_file(d, os.path.join(p, f))
return d
return (d, parse_conf(p))
START = 0
LINT = 1
def parse_conf(p):
c = {}
with open(p + '/conf.rs') as f:
f = f.read()
m = re.search(conf_re, f)
m = m.groups()[0]
m = re.findall(confvar_re, m)
for (lint, doc, name, default, ty) in m:
c[lint.lower()] = (name, ty, doc, default)
return c
def parse_file(d, f):
@ -85,8 +100,14 @@ template = """\n# `%s`
%s"""
conf_template = """
**Configuration:** This lint has the following configuration variables:
def write_wiki_page(d, f):
* `%s: %s`: %s (defaults to `%s`).
"""
def write_wiki_page(d, c, f):
keys = list(d.keys())
keys.sort()
with open(f, "w") as w:
@ -102,8 +123,11 @@ def write_wiki_page(d, f):
for k in keys:
w.write(template % (k, d[k][0], "".join(d[k][1])))
if k in c:
w.write(conf_template % c[k])
def check_wiki_page(d, f):
def check_wiki_page(d, c, f):
errors = []
with open(f) as w:
for line in w:
@ -122,11 +146,11 @@ def check_wiki_page(d, f):
def main():
d = parse_path()
(d, c) = parse_path()
if "-c" in sys.argv:
check_wiki_page(d, "../rust-clippy.wiki/Home.md")
check_wiki_page(d, c, "../rust-clippy.wiki/Home.md")
else:
write_wiki_page(d, "../rust-clippy.wiki/Home.md")
write_wiki_page(d, c, "../rust-clippy.wiki/Home.md")
if __name__ == "__main__":
main()