From: Adrian Roos Date: Sat, 5 Jan 2019 19:09:38 +0000 (+0100) Subject: ApiLint: Performance improvements for verification X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=1f1b6a84644916bd2b48f26ccb8cb31b336d4e2f;p=android-x86%2Fframeworks-base.git ApiLint: Performance improvements for verification Test: tools/apilint/apilint_sha.sh HEAD Test: python tools/apilint/apilint_test.py Change-Id: I90f18181cd0d3c43f176d7c9d1b198f6f5172390 (cherry picked from commit 7f8886a9933abbb6f1fdd97d920185b80d439339) --- diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py index 5680c8ca3a6a..441c1209a742 100644 --- a/tools/apilint/apilint.py +++ b/tools/apilint/apilint.py @@ -26,7 +26,7 @@ $ git blame api/current.txt -t -e > /tmp/currentblame.txt $ apilint.py /tmp/currentblame.txt previous.txt --no-color """ -import re, sys, collections, traceback, argparse +import re, sys, collections, traceback, argparse, itertools BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) @@ -1073,48 +1073,66 @@ def verify_internal(clazz): if clazz.pkg.name.startswith("com.android"): error(clazz, None, None, "Internal classes must not be exposed") +def layering_build_ranking(ranking_list): + r = {} + for rank, ps in enumerate(ranking_list): + if not isinstance(ps, list): + ps = [ps] + for p in ps: + rs = r + for n in p.split('.'): + if n not in rs: + rs[n] = {} + rs = rs[n] + rs['-rank'] = rank + return r + +LAYERING_PACKAGE_RANKING = layering_build_ranking([ + ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"], + "android.app", + "android.widget", + "android.view", + "android.animation", + "android.provider", + ["android.content","android.graphics.drawable"], + "android.database", + "android.text", + "android.graphics", + "android.os", + "android.util" +]) def verify_layering(clazz): """Catch package layering violations. For example, something in android.os depending on android.app.""" - ranking = [ - ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"], - "android.app", - "android.widget", - "android.view", - "android.animation", - "android.provider", - ["android.content","android.graphics.drawable"], - "android.database", - "android.text", - "android.graphics", - "android.os", - "android.util" - ] def rank(p): - for i in range(len(ranking)): - if isinstance(ranking[i], list): - for j in ranking[i]: - if p.startswith(j): return i + r = None + l = LAYERING_PACKAGE_RANKING + for n in p.split('.'): + if n in l: + l = l[n] + if '-rank' in l: + r = l['-rank'] else: - if p.startswith(ranking[i]): return i + break + return r cr = rank(clazz.pkg.name) if cr is None: return for f in clazz.fields: ir = rank(f.typ) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, f, "FW6", "Field type violates package layering") - for m in clazz.methods: + for m in itertools.chain(clazz.methods, clazz.ctors): ir = rank(m.typ) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, m, "FW6", "Method return type violates package layering") for arg in m.args: ir = rank(arg) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, m, "FW6", "Method argument type violates package layering") @@ -1205,21 +1223,18 @@ def verify_exception(clazz): if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]: warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException") +GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE) def verify_google(clazz): """Verifies that APIs never reference Google.""" - if re.search("google", clazz.raw, re.IGNORECASE): + if GOOGLE_IGNORECASE.search(clazz.raw) is not None: error(clazz, None, None, "Must never reference Google") - test = [] - test.extend(clazz.ctors) - test.extend(clazz.fields) - test.extend(clazz.methods) - - for t in test: - if re.search("google", t.raw, re.IGNORECASE): - error(clazz, t, None, "Must never reference Google") + for test in clazz.ctors, clazz.fields, clazz.methods: + for t in test: + if GOOGLE_IGNORECASE.search(t.raw) is not None: + error(clazz, t, None, "Must never reference Google") def verify_bitset(clazz):