summaryrefslogtreecommitdiffstats
path: root/tools/apilint
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2015-01-30 13:31:45 -0700
committerJeff Sharkey <jsharkey@android.com>2015-02-12 09:31:43 -0800
commited6aaf0f79b7b39b2d70684c902d2d689a3db841 (patch)
treedae71abcb85e6704ec5cf935940e16abce592dc1 /tools/apilint
parent0f5e1975d317a76e5db4c79bf60641733a375a1e (diff)
downloadframeworks_base-ed6aaf0f79b7b39b2d70684c902d2d689a3db841.zip
frameworks_base-ed6aaf0f79b7b39b2d70684c902d2d689a3db841.tar.gz
frameworks_base-ed6aaf0f79b7b39b2d70684c902d2d689a3db841.tar.bz2
Track line numbers in lint script.
Also create separate class to describe failures, which can be consumed by other tools. Still offers to render itself for console output by default. Change-Id: Ib0555cc289ae08a0e446489509cc964c866c564e
Diffstat (limited to 'tools/apilint')
-rw-r--r--tools/apilint/apilint.py149
1 files changed, 91 insertions, 58 deletions
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 393d2ec..1330c28 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -48,8 +48,9 @@ def format(fg=None, bg=None, bright=False, bold=False, dim=False, reset=False):
class Field():
- def __init__(self, clazz, raw, blame):
+ def __init__(self, clazz, line, raw, blame):
self.clazz = clazz
+ self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
@@ -73,8 +74,9 @@ class Field():
class Method():
- def __init__(self, clazz, raw, blame):
+ def __init__(self, clazz, line, raw, blame):
self.clazz = clazz
+ self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
@@ -110,8 +112,9 @@ class Method():
class Class():
- def __init__(self, pkg, raw, blame):
+ def __init__(self, pkg, line, raw, blame):
self.pkg = pkg
+ self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
self.ctors = []
@@ -140,7 +143,8 @@ class Class():
class Package():
- def __init__(self, raw, blame):
+ def __init__(self, line, raw, blame):
+ self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
@@ -151,64 +155,92 @@ class Package():
return self.raw
-def parse_api(fn):
+def parse_api(f):
+ line = 0
api = {}
pkg = None
clazz = None
blame = None
re_blame = re.compile("^([a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")
+ for raw in f.readlines():
+ line += 1
+ raw = raw.rstrip()
+ match = re_blame.match(raw)
+ if match is not None:
+ blame = match.groups()[0:2]
+ raw = match.groups()[2]
+ else:
+ blame = None
+
+ if raw.startswith("package"):
+ pkg = Package(line, raw, blame)
+ elif raw.startswith(" ") and raw.endswith("{"):
+ clazz = Class(pkg, line, raw, blame)
+ api[clazz.fullname] = clazz
+ elif raw.startswith(" ctor"):
+ clazz.ctors.append(Method(clazz, line, raw, blame))
+ elif raw.startswith(" method"):
+ clazz.methods.append(Method(clazz, line, raw, blame))
+ elif raw.startswith(" field"):
+ clazz.fields.append(Field(clazz, line, raw, blame))
+
+ return api
+
+def parse_api_file(fn):
with open(fn) as f:
- for raw in f.readlines():
- raw = raw.rstrip()
- match = re_blame.match(raw)
- if match is not None:
- blame = match.groups()[0:2]
- raw = match.groups()[2]
- else:
- blame = None
-
- if raw.startswith("package"):
- pkg = Package(raw, blame)
- elif raw.startswith(" ") and raw.endswith("{"):
- clazz = Class(pkg, raw, blame)
- api[clazz.fullname] = clazz
- elif raw.startswith(" ctor"):
- clazz.ctors.append(Method(clazz, raw, blame))
- elif raw.startswith(" method"):
- clazz.methods.append(Method(clazz, raw, blame))
- elif raw.startswith(" field"):
- clazz.fields.append(Field(clazz, raw, blame))
+ return parse_api(f)
- return api
+
+class Failure():
+ def __init__(self, sig, clazz, detail, error, msg):
+ self.sig = sig
+ self.clazz = clazz
+ self.detail = detail
+ self.error = error
+ self.msg = msg
+
+ if error:
+ dump = "%sError:%s %s" % (format(fg=RED, bg=BLACK, bold=True), format(reset=True), msg)
+ else:
+ dump = "%sWarning:%s %s" % (format(fg=YELLOW, bg=BLACK, bold=True), format(reset=True), msg)
+
+ self.line = clazz.line
+ blame = clazz.blame
+ if detail is not None:
+ dump += "\n in " + repr(detail)
+ self.line = detail.line
+ blame = detail.blame
+ dump += "\n in " + repr(clazz)
+ dump += "\n in " + repr(clazz.pkg)
+ dump += "\n at line " + repr(self.line)
+ if blame is not None:
+ dump += "\n last modified by %s in %s" % (blame[1], blame[0])
+
+ self.dump = dump
+
+ def __repr__(self):
+ return self.dump
failures = {}
-def _fail(clazz, detail, msg):
+def _fail(clazz, detail, error, msg):
"""Records an API failure to be processed later."""
global failures
sig = "%s-%s-%s" % (clazz.fullname, repr(detail), msg)
sig = sig.replace(" deprecated ", " ")
- res = msg
- blame = clazz.blame
- if detail is not None:
- res += "\n in " + repr(detail)
- blame = detail.blame
- res += "\n in " + repr(clazz)
- res += "\n in " + repr(clazz.pkg)
- if blame is not None:
- res += "\n last modified by %s in %s" % (blame[1], blame[0])
- failures[sig] = res
+ failures[sig] = Failure(sig, clazz, detail, error, msg)
+
def warn(clazz, detail, msg):
- _fail(clazz, detail, "%sWarning:%s %s" % (format(fg=YELLOW, bg=BLACK, bold=True), format(reset=True), msg))
+ _fail(clazz, detail, False, msg)
def error(clazz, detail, msg):
- _fail(clazz, detail, "%sError:%s %s" % (format(fg=RED, bg=BLACK, bold=True), format(reset=True), msg))
+ _fail(clazz, detail, True, msg)
def verify_constants(clazz):
@@ -770,28 +802,29 @@ def verify_compat(cur, prev):
return failures
-cur = parse_api(sys.argv[1])
-cur_fail = verify_style(cur)
+if __name__ == "__main__":
+ cur = parse_api_file(sys.argv[1])
+ cur_fail = verify_style(cur)
-if len(sys.argv) > 2:
- prev = parse_api(sys.argv[2])
- prev_fail = verify_style(prev)
+ if len(sys.argv) > 2:
+ prev = parse_api_file(sys.argv[2])
+ prev_fail = verify_style(prev)
- # ignore errors from previous API level
- for p in prev_fail:
- if p in cur_fail:
- del cur_fail[p]
+ # ignore errors from previous API level
+ for p in prev_fail:
+ if p in cur_fail:
+ del cur_fail[p]
- # look for compatibility issues
- compat_fail = verify_compat(cur, prev)
+ # look for compatibility issues
+ compat_fail = verify_compat(cur, prev)
- print "%s API compatibility issues %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
- for f in sorted(compat_fail):
- print compat_fail[f]
- print
+ print "%s API compatibility issues %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
+ for f in sorted(compat_fail):
+ print compat_fail[f]
+ print
-print "%s API style issues %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
-for f in sorted(cur_fail):
- print cur_fail[f]
- print
+ print "%s API style issues %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
+ for f in sorted(cur_fail):
+ print cur_fail[f]
+ print