OSDN Git Service

Handle new current.txt format.
authorJeff Sharkey <jsharkey@android.com>
Tue, 17 Jul 2018 19:29:40 +0000 (13:29 -0600)
committerJeff Sharkey <jsharkey@android.com>
Tue, 17 Jul 2018 19:59:04 +0000 (13:59 -0600)
We're starting to see "@interface" show up, so handle them like any
other interface.  We're also seeing more details argument lists
with names and annotations; ignore them for now, since all our
existing lint checks work on the "real" data type.

Verified that it handles new support library current.txt files
without causing any regressions against existing framework
current.txt files.

Test: manual inspection
Bug: 111555356
Change-Id: Id11c3561edd317e4ba1a9b43993fd96d8243e00d

tools/apilint/apilint.py

index 9db3f02..018e9c9 100644 (file)
@@ -69,12 +69,19 @@ class Field():
         self.raw = raw.strip(" {;")
         self.blame = blame
 
+        # drop generics for now; may need multiple passes
+        raw = re.sub("<[^<]+?>", "", raw)
+        raw = re.sub("<[^<]+?>", "", raw)
+
         raw = raw.split()
         self.split = list(raw)
 
         for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]:
             while r in raw: raw.remove(r)
 
+        # ignore annotations for now
+        raw = [ r for r in raw if not r.startswith("@") ]
+
         self.typ = raw[0]
         self.name = raw[1].strip(";")
         if len(raw) >= 4 and raw[2] == "=":
@@ -97,25 +104,39 @@ class Method():
         self.raw = raw.strip(" {;")
         self.blame = blame
 
-        # drop generics for now
-        raw = re.sub("<.+?>", "", raw)
+        # drop generics for now; may need multiple passes
+        raw = re.sub("<[^<]+?>", "", raw)
+        raw = re.sub("<[^<]+?>", "", raw)
+
+        # handle each clause differently
+        raw_prefix, raw_args, _, raw_throws = re.match(r"(.*?)\((.*?)\)( throws )?(.*?);$", raw).groups()
 
-        raw = re.split("[\s(),;]+", raw)
+        # parse prefixes
+        raw = re.split("[\s]+", raw_prefix)
         for r in ["", ";"]:
             while r in raw: raw.remove(r)
         self.split = list(raw)
 
-        for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default"]:
+        for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default", "operator"]:
             while r in raw: raw.remove(r)
 
         self.typ = raw[0]
         self.name = raw[1]
+
+        # parse args
         self.args = []
+        for arg in re.split(",\s*", raw_args):
+            arg = re.split("\s", arg)
+            # ignore annotations for now
+            arg = [ a for a in arg if not a.startswith("@") ]
+            if len(arg[0]) > 0:
+                self.args.append(arg[0])
+
+        # parse throws
         self.throws = []
-        target = self.args
-        for r in raw[2:]:
-            if r == "throws": target = self.throws
-            else: target.append(r)
+        for throw in re.split(",\s*", raw_throws):
+            self.throws.append(throw)
+
         self.ident = ident(self.raw)
 
     def __hash__(self):
@@ -135,12 +156,18 @@ class Class():
         self.fields = []
         self.methods = []
 
+        # drop generics for now; may need multiple passes
+        raw = re.sub("<[^<]+?>", "", raw)
+        raw = re.sub("<[^<]+?>", "", raw)
+
         raw = raw.split()
         self.split = list(raw)
         if "class" in raw:
             self.fullname = raw[raw.index("class")+1]
         elif "interface" in raw:
             self.fullname = raw[raw.index("interface")+1]
+        elif "@interface" in raw:
+            self.fullname = raw[raw.index("@interface")+1]
         else:
             raise ValueError("Funky class type %s" % (self.raw))