]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/util/lintlib.py
New upstream version 1.55.0+dfsg1
[rustc.git] / src / tools / clippy / util / lintlib.py
1 # Common utils for the several housekeeping scripts.
2
3 import os
4 import re
5 import collections
6
7 import logging as log
8 log.basicConfig(level=log.INFO, format='%(levelname)s: %(message)s')
9
10 Lint = collections.namedtuple('Lint', 'name level doc sourcefile group')
11 Config = collections.namedtuple('Config', 'name ty doc default')
12
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})[\s\S])*\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*/// ?(.*)''')
19
20 lint_levels = {
21 "correctness": 'Deny',
22 "suspicious": 'Warn',
23 "style": 'Warn',
24 "complexity": 'Warn',
25 "perf": 'Warn',
26 "restriction": 'Allow',
27 "pedantic": 'Allow',
28 "nursery": 'Allow',
29 "cargo": 'Allow',
30 }
31
32
33 def parse_lints(lints, filepath):
34 comment = []
35 clippy = False
36 deprecated = False
37 name = ""
38
39 with open(filepath) as fp:
40 for line in fp:
41 if clippy or deprecated:
42 m = lintname_re.search(line)
43 if m:
44 name = m.group(1).lower()
45 line = next(fp)
46
47 if deprecated:
48 level = "Deprecated"
49 group = "deprecated"
50 else:
51 while True:
52 g = group_re.search(line)
53 if g:
54 group = g.group(1).lower()
55 level = lint_levels.get(group, None)
56 break
57 line = next(fp)
58
59 if level is None:
60 continue
61
62 log.info("found %s with level %s in %s",
63 name, level, filepath)
64 lints.append(Lint(name, level, comment, filepath, group))
65 comment = []
66
67 clippy = False
68 deprecated = False
69 name = ""
70 else:
71 m = comment_re.search(line)
72 if m:
73 comment.append(m.group(1))
74 elif line.startswith("declare_clippy_lint!"):
75 clippy = True
76 deprecated = False
77 elif line.startswith("declare_deprecated_lint!"):
78 clippy = False
79 deprecated = True
80 elif line.startswith("declare_lint!"):
81 import sys
82 print(
83 "don't use `declare_lint!` in Clippy, "
84 "use `declare_clippy_lint!` instead"
85 )
86 sys.exit(42)
87
88
89 def parse_configs(path):
90 configs = {}
91 with open(os.path.join(path, 'utils/conf.rs')) as fp:
92 contents = fp.read()
93
94 match = re.search(conf_re, contents)
95 confvars = re.findall(confvar_re, match.group(0))
96
97 for (lints, doc, name, ty, default) in confvars:
98 for lint in lints.split(','):
99 configs[lint.strip().lower()] = Config(name.replace("_", "-"), ty, doc, default)
100 return configs
101
102
103 def parse_all(path="clippy_lints/src"):
104 lints = []
105 for root, dirs, files in os.walk(path):
106 for fn in files:
107 if fn.endswith('.rs'):
108 parse_lints(lints, os.path.join(root, fn))
109
110 log.info("got %s lints", len(lints))
111
112 configs = parse_configs(path)
113 log.info("got %d configs", len(configs))
114
115 return lints, configs