1 # Common utils for the several housekeeping scripts.
8 log.basicConfig(level=log.INFO, format='%(levelname)s: %(message)s')
10 Lint = collections.namedtuple('Lint', 'name level doc sourcefile group')
11 Config = collections.namedtuple('Config', 'name ty doc default')
13 lintname_re = re.compile(r'''pub\s+([A-Z_][A-Z_0-9]*)''')
14 group_re = re.compile(r'''\s*([a-z_][a-z_0-9]+)''')
15 conf_re = re.compile(r'''define_Conf! {\n([^}]*)\n}''', re.MULTILINE)
16 confvar_re = re.compile(
17 r'''/// Lint: ([\w,\s]+)\. (.*)\n\s*\(([^:]+):\s*([^\s=]+)\s*=\s*([^\.\)]+).*\),''', re.MULTILINE)
18 comment_re = re.compile(r'''\s*/// ?(.*)''')
21 "correctness": 'Deny',
25 "restriction": 'Allow',
32 def parse_lints(lints, filepath):
38 with open(filepath) as fp:
40 if clippy or deprecated:
41 m = lintname_re.search(line)
43 name = m.group(1).lower()
51 g = group_re.search(line)
53 group = g.group(1).lower()
54 level = lint_levels.get(group, None)
61 log.info("found %s with level %s in %s",
62 name, level, filepath)
63 lints.append(Lint(name, level, comment, filepath, group))
70 m = comment_re.search(line)
72 comment.append(m.group(1))
73 elif line.startswith("declare_clippy_lint!"):
76 elif line.startswith("declare_deprecated_lint!"):
79 elif line.startswith("declare_lint!"):
82 "don't use `declare_lint!` in Clippy, "
83 "use `declare_clippy_lint!` instead"
88 def parse_configs(path):
90 with open(os.path.join(path, 'utils/conf.rs')) as fp:
93 match = re.search(conf_re, contents)
94 confvars = re.findall(confvar_re, match.group(1))
96 for (lints, doc, name, ty, default) in confvars:
97 for lint in lints.split(','):
98 configs[lint.strip().lower()] = Config(name.replace("_", "-"), ty, doc, default)
102 def parse_all(path="clippy_lints/src"):
104 for root, dirs, files in os.walk(path):
106 if fn.endswith('.rs'):
107 parse_lints(lints, os.path.join(root, fn))
109 log.info("got %s lints", len(lints))
111 configs = parse_configs(path)
112 log.info("got %d configs", len(configs))
114 return lints, configs