Loading tools/apilint/apilint.py +71 −16 Original line number Diff line number Diff line Loading @@ -183,6 +183,11 @@ class Class(): self.name = self.fullname[self.fullname.rindex(".")+1:] def merge_from(self, other): self.ctors.extend(other.ctors) self.fields.extend(other.fields) self.methods.extend(other.methods) def __hash__(self): return hash((self.raw, tuple(self.ctors), tuple(self.fields), tuple(self.methods))) Loading @@ -204,9 +209,28 @@ class Package(): return self.raw def _parse_stream(f, clazz_cb=None): line = 0 def _parse_stream(f, clazz_cb=None, base_f=None): api = {} if base_f: base_classes = _parse_stream_to_generator(base_f) else: base_classes = [] for clazz in _parse_stream_to_generator(f): base_class = _parse_to_matching_class(base_classes, clazz) if base_class: clazz.merge_from(base_class) if clazz_cb: clazz_cb(clazz) else: # In callback mode, don't keep track of the full API api[clazz.fullname] = clazz return api def _parse_stream_to_generator(f): line = 0 pkg = None clazz = None blame = None Loading @@ -225,26 +249,41 @@ def _parse_stream(f, clazz_cb=None): if raw.startswith("package"): pkg = Package(line, raw, blame) elif raw.startswith(" ") and raw.endswith("{"): # When provided with class callback, we treat as incremental # parse and don't build up entire API if clazz and clazz_cb: clazz_cb(clazz) clazz = Class(pkg, line, raw, blame) if not clazz_cb: 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)) elif raw.startswith(" }") and clazz: while True: retry = yield clazz if not retry: break # send() was called, asking us to redeliver clazz on next(). Still need to yield # a dummy value to the send() first though. if (yield "Returning clazz on next()"): raise TypeError("send() must be followed by next(), not send()") # Handle last trailing class if clazz and clazz_cb: clazz_cb(clazz) return api def _parse_to_matching_class(classes, needle): """Takes a classes generator and parses it until it returns the class we're looking for This relies on classes being sorted by package and class name.""" for clazz in classes: if clazz.pkg.name < needle.pkg.name: # We haven't reached the right package yet continue if clazz.name < needle.name: # We haven't reached the right class yet continue if clazz.fullname == needle.fullname: return clazz # We ran past the right class. Send it back into the generator, then report failure. classes.send(clazz) return None class Failure(): def __init__(self, sig, clazz, detail, error, rule, msg): Loading Loading @@ -1504,12 +1543,12 @@ def examine_clazz(clazz): verify_singleton(clazz) def examine_stream(stream): def examine_stream(stream, base_stream=None): """Find all style issues in the given API stream.""" global failures, noticed failures = {} noticed = {} _parse_stream(stream, examine_clazz) _parse_stream(stream, examine_clazz, base_f=base_stream) return (failures, noticed) Loading Loading @@ -1650,6 +1689,12 @@ if __name__ == "__main__": parser.add_argument("current.txt", type=argparse.FileType('r'), help="current.txt") parser.add_argument("previous.txt", nargs='?', type=argparse.FileType('r'), default=None, help="previous.txt") parser.add_argument("--base-current", nargs='?', type=argparse.FileType('r'), default=None, help="The base current.txt to use when examining system-current.txt or" " test-current.txt") parser.add_argument("--base-previous", nargs='?', type=argparse.FileType('r'), default=None, help="The base previous.txt to use when examining system-previous.txt or" " test-previous.txt") parser.add_argument("--no-color", action='store_const', const=True, help="Disable terminal colors") parser.add_argument("--allow-google", action='store_const', const=True, Loading @@ -1669,7 +1714,9 @@ if __name__ == "__main__": ALLOW_GOOGLE = True current_file = args['current.txt'] base_current_file = args['base_current'] previous_file = args['previous.txt'] base_previous_file = args['base_previous'] if args['show_deprecations_at_birth']: with current_file as f: Loading @@ -1688,9 +1735,17 @@ if __name__ == "__main__": sys.exit() with current_file as f: if base_current_file: with base_current_file as base_f: cur_fail, cur_noticed = examine_stream(f, base_f) else: cur_fail, cur_noticed = examine_stream(f) if not previous_file is None: with previous_file as f: if base_previous_file: with base_previous_file as base_f: prev_fail, prev_noticed = examine_stream(f, base_f) else: prev_fail, prev_noticed = examine_stream(f) # ignore errors from previous API level Loading Loading
tools/apilint/apilint.py +71 −16 Original line number Diff line number Diff line Loading @@ -183,6 +183,11 @@ class Class(): self.name = self.fullname[self.fullname.rindex(".")+1:] def merge_from(self, other): self.ctors.extend(other.ctors) self.fields.extend(other.fields) self.methods.extend(other.methods) def __hash__(self): return hash((self.raw, tuple(self.ctors), tuple(self.fields), tuple(self.methods))) Loading @@ -204,9 +209,28 @@ class Package(): return self.raw def _parse_stream(f, clazz_cb=None): line = 0 def _parse_stream(f, clazz_cb=None, base_f=None): api = {} if base_f: base_classes = _parse_stream_to_generator(base_f) else: base_classes = [] for clazz in _parse_stream_to_generator(f): base_class = _parse_to_matching_class(base_classes, clazz) if base_class: clazz.merge_from(base_class) if clazz_cb: clazz_cb(clazz) else: # In callback mode, don't keep track of the full API api[clazz.fullname] = clazz return api def _parse_stream_to_generator(f): line = 0 pkg = None clazz = None blame = None Loading @@ -225,26 +249,41 @@ def _parse_stream(f, clazz_cb=None): if raw.startswith("package"): pkg = Package(line, raw, blame) elif raw.startswith(" ") and raw.endswith("{"): # When provided with class callback, we treat as incremental # parse and don't build up entire API if clazz and clazz_cb: clazz_cb(clazz) clazz = Class(pkg, line, raw, blame) if not clazz_cb: 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)) elif raw.startswith(" }") and clazz: while True: retry = yield clazz if not retry: break # send() was called, asking us to redeliver clazz on next(). Still need to yield # a dummy value to the send() first though. if (yield "Returning clazz on next()"): raise TypeError("send() must be followed by next(), not send()") # Handle last trailing class if clazz and clazz_cb: clazz_cb(clazz) return api def _parse_to_matching_class(classes, needle): """Takes a classes generator and parses it until it returns the class we're looking for This relies on classes being sorted by package and class name.""" for clazz in classes: if clazz.pkg.name < needle.pkg.name: # We haven't reached the right package yet continue if clazz.name < needle.name: # We haven't reached the right class yet continue if clazz.fullname == needle.fullname: return clazz # We ran past the right class. Send it back into the generator, then report failure. classes.send(clazz) return None class Failure(): def __init__(self, sig, clazz, detail, error, rule, msg): Loading Loading @@ -1504,12 +1543,12 @@ def examine_clazz(clazz): verify_singleton(clazz) def examine_stream(stream): def examine_stream(stream, base_stream=None): """Find all style issues in the given API stream.""" global failures, noticed failures = {} noticed = {} _parse_stream(stream, examine_clazz) _parse_stream(stream, examine_clazz, base_f=base_stream) return (failures, noticed) Loading Loading @@ -1650,6 +1689,12 @@ if __name__ == "__main__": parser.add_argument("current.txt", type=argparse.FileType('r'), help="current.txt") parser.add_argument("previous.txt", nargs='?', type=argparse.FileType('r'), default=None, help="previous.txt") parser.add_argument("--base-current", nargs='?', type=argparse.FileType('r'), default=None, help="The base current.txt to use when examining system-current.txt or" " test-current.txt") parser.add_argument("--base-previous", nargs='?', type=argparse.FileType('r'), default=None, help="The base previous.txt to use when examining system-previous.txt or" " test-previous.txt") parser.add_argument("--no-color", action='store_const', const=True, help="Disable terminal colors") parser.add_argument("--allow-google", action='store_const', const=True, Loading @@ -1669,7 +1714,9 @@ if __name__ == "__main__": ALLOW_GOOGLE = True current_file = args['current.txt'] base_current_file = args['base_current'] previous_file = args['previous.txt'] base_previous_file = args['base_previous'] if args['show_deprecations_at_birth']: with current_file as f: Loading @@ -1688,9 +1735,17 @@ if __name__ == "__main__": sys.exit() with current_file as f: if base_current_file: with base_current_file as base_f: cur_fail, cur_noticed = examine_stream(f, base_f) else: cur_fail, cur_noticed = examine_stream(f) if not previous_file is None: with previous_file as f: if base_previous_file: with base_previous_file as base_f: prev_fail, prev_noticed = examine_stream(f, base_f) else: prev_fail, prev_noticed = examine_stream(f) # ignore errors from previous API level Loading