]> git.lizzy.rs Git - rust.git/blobdiff - util/lintlib.py
Remove util/cov.sh script
[rust.git] / util / lintlib.py
index c46706352b7a881ed902ea81d7285551ff600468..5707cf0ce0f8c08177f68866b7065c6c9feb2182 100644 (file)
@@ -7,65 +7,82 @@ import collections
 import logging as log
 log.basicConfig(level=log.INFO, format='%(levelname)s: %(message)s')
 
-Lint = collections.namedtuple('Lint', 'name level doc sourcefile')
+Lint = collections.namedtuple('Lint', 'name level doc sourcefile group')
 Config = collections.namedtuple('Config', 'name ty doc default')
 
 lintname_re = re.compile(r'''pub\s+([A-Z_][A-Z_0-9]*)''')
-level_re = re.compile(r'''(Forbid|Deny|Warn|Allow)''')
+group_re = re.compile(r'''\s*([a-z_][a-z_0-9]+)''')
 conf_re = re.compile(r'''define_Conf! {\n([^}]*)\n}''', re.MULTILINE)
 confvar_re = re.compile(
-    r'''/// Lint: (\w+). (.*).*\n\s*\([^,]+,\s+"([^"]+)",\s+([^=\)]+)=>\s+(.*)\),''', re.MULTILINE)
+    r'''/// Lint: ([\w,\s]+)\. (.*)\n\s*\(([^:]+):\s*([^\s=]+)\s*=\s*([^\.\)]+).*\),''', re.MULTILINE)
+comment_re = re.compile(r'''\s*/// ?(.*)''')
+
+lint_levels = {
+    "correctness": 'Deny',
+    "style": 'Warn',
+    "complexity": 'Warn',
+    "perf": 'Warn',
+    "restriction": 'Allow',
+    "pedantic": 'Allow',
+    "nursery": 'Allow',
+    "cargo": 'Allow',
+}
 
 
 def parse_lints(lints, filepath):
-    last_comment = []
-    comment = True
+    comment = []
+    clippy = False
+    deprecated = False
+    name = ""
 
     with open(filepath) as fp:
         for line in fp:
-            if comment:
-                if line.startswith("/// "):
-                    last_comment.append(line[4:])
-                elif line.startswith("///"):
-                    last_comment.append(line[3:])
-                elif line.startswith("declare_lint!"):
-                    comment = False
-                    deprecated = False
-                    restriction = False
-                elif line.startswith("declare_restriction_lint!"):
-                    comment = False
-                    deprecated = False
-                    restriction = True
-                elif line.startswith("declare_deprecated_lint!"):
-                    comment = False
-                    deprecated = True
-                else:
-                    last_comment = []
-            if not comment:
+            if clippy or deprecated:
                 m = lintname_re.search(line)
                 if m:
                     name = m.group(1).lower()
+                    line = next(fp)
 
                     if deprecated:
                         level = "Deprecated"
-                    elif restriction:
-                        level = "Allow"
+                        group = "deprecated"
                     else:
                         while True:
-                            m = level_re.search(line)
-                            if m:
-                                level = m.group(0)
+                            g = group_re.search(line)
+                            if g:
+                                group = g.group(1).lower()
+                                level = lint_levels.get(group, None)
                                 break
                             line = next(fp)
 
+                    if level is None:
+                        continue
+
                     log.info("found %s with level %s in %s",
                              name, level, filepath)
-                    lints.append(Lint(name, level, last_comment, filepath))
-                    last_comment = []
-                    comment = True
-                if "}" in line:
-                    log.warn("Warning: missing Lint-Name in %s", filepath)
-                    comment = True
+                    lints.append(Lint(name, level, comment, filepath, group))
+                    comment = []
+
+                    clippy = False
+                    deprecated = False
+                    name = ""
+                else:
+                    m = comment_re.search(line)
+                    if m:
+                        comment.append(m.group(1))
+            elif line.startswith("declare_clippy_lint!"):
+                clippy = True
+                deprecated = False
+            elif line.startswith("declare_deprecated_lint!"):
+                clippy = False
+                deprecated = True
+            elif line.startswith("declare_lint!"):
+                import sys
+                print(
+                    "don't use `declare_lint!` in Clippy, "
+                    "use `declare_clippy_lint!` instead"
+                )
+                sys.exit(42)
 
 
 def parse_configs(path):
@@ -76,17 +93,19 @@ def parse_configs(path):
     match = re.search(conf_re, contents)
     confvars = re.findall(confvar_re, match.group(1))
 
-    for (lint, doc, name, default, ty) in confvars:
-        configs[lint.lower()] = Config(name, ty, doc, default)
-
+    for (lints, doc, name, ty, default) in confvars:
+        for lint in lints.split(','):
+            configs[lint.strip().lower()] = Config(name.replace("_", "-"), ty, doc, default)
     return configs
 
 
 def parse_all(path="clippy_lints/src"):
     lints = []
-    for filename in os.listdir(path):
-        if filename.endswith(".rs"):
-            parse_lints(lints, os.path.join(path, filename))
+    for root, dirs, files in os.walk(path):
+        for fn in files:
+            if fn.endswith('.rs'):
+                parse_lints(lints, os.path.join(root, fn))
+
     log.info("got %s lints", len(lints))
 
     configs = parse_configs(path)