Loading tools/apilint/apilint.py +25 −4 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ class Package(): class V2Tokenizer(object): __slots__ = ["raw"] DELIMITER = re.compile(r'\s+|[()@<>;,={}/"]|\[\]') DELIMITER = re.compile(r'\s+|[()@<>;,={}/"!?]|\[\]|\.\.\.') STRING_SPECIAL = re.compile(r'["\\]') def __init__(self, raw): Loading Loading @@ -435,19 +435,32 @@ class V2LineParser(object): ret.append(self.parse_token()) return ret def parse_kotlin_nullability(self): t = self.lookahead() if t == "?" or t == "!": return self.parse_token() return None def parse_type(self): type = self.parse_token() if type in V2LineParser.JAVA_LANG_TYPES: type = "java.lang." + type self.parse_matching_paren("<", ">") while self.parse_if("[]"): type += "[]" while True: t = self.lookahead() if t == "[]": type += self.parse_token() elif self.parse_kotlin_nullability() is not None: pass # discard nullability for now else: break return type def parse_arg_type(self): type = self.parse_type() if self.parse_if("..."): type += "..." self.parse_kotlin_nullability() # discard nullability for now return type def parse_name(self): Loading @@ -466,7 +479,15 @@ class V2LineParser(object): def parse_arg(self): self.parse_annotations() return self.parse_arg_type() type = self.parse_arg_type() l = self.lookahead() if l != "," and l != ")": self.parse_token() # kotlin argument name if self.parse_if('='): # kotlin default value (self.parse_matching_paren('(', ')') or self.parse_matching_paren('{', '}') or self.parse_token() and self.parse_matching_paren('(', ')')) return type def parse_throws(self): ret = [] Loading tools/apilint/apilint_test.py +15 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,14 @@ class V2TokenizerTests(unittest.TestCase): self._test("class Some.Class extends SomeOther {", ['class', 'Some.Class', 'extends', 'SomeOther', '{']) def test_varargs(self): self._test("name(String...)", ['name', '(', 'String', '...', ')']) def test_kotlin(self): self._test("String? name(String!...)", ['String', '?', 'name', '(', 'String', '!', '...', ')']) def test_annotation(self): self._test("method @Nullable public void name();", ['method', '@', 'Nullable', 'public', 'void', 'name', '(', ')', ';']) Loading Loading @@ -271,5 +279,12 @@ class V2ParserTests(unittest.TestCase): self.assertEquals('NAME', f.name) self.assertEquals('( 0.0 / 0.0 )', f.value) def test_kotlin_types(self): self._field('field public List<Integer[]?[]!>?[]![]? NAME;') self._method("method <T?> Class<T!>?[]![][]? name(Type!, Type argname," + "Class<T?>[][]?[]!...!) throws Exception, T;") self._method("method <T> T name(T a = 1, T b = A(1), Lambda f = { false }, N? n = null, " + """double c = (1/0), float d = 1.0f, String s = "heyo", char c = 'a');""") if __name__ == "__main__": unittest.main() Loading
tools/apilint/apilint.py +25 −4 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ class Package(): class V2Tokenizer(object): __slots__ = ["raw"] DELIMITER = re.compile(r'\s+|[()@<>;,={}/"]|\[\]') DELIMITER = re.compile(r'\s+|[()@<>;,={}/"!?]|\[\]|\.\.\.') STRING_SPECIAL = re.compile(r'["\\]') def __init__(self, raw): Loading Loading @@ -435,19 +435,32 @@ class V2LineParser(object): ret.append(self.parse_token()) return ret def parse_kotlin_nullability(self): t = self.lookahead() if t == "?" or t == "!": return self.parse_token() return None def parse_type(self): type = self.parse_token() if type in V2LineParser.JAVA_LANG_TYPES: type = "java.lang." + type self.parse_matching_paren("<", ">") while self.parse_if("[]"): type += "[]" while True: t = self.lookahead() if t == "[]": type += self.parse_token() elif self.parse_kotlin_nullability() is not None: pass # discard nullability for now else: break return type def parse_arg_type(self): type = self.parse_type() if self.parse_if("..."): type += "..." self.parse_kotlin_nullability() # discard nullability for now return type def parse_name(self): Loading @@ -466,7 +479,15 @@ class V2LineParser(object): def parse_arg(self): self.parse_annotations() return self.parse_arg_type() type = self.parse_arg_type() l = self.lookahead() if l != "," and l != ")": self.parse_token() # kotlin argument name if self.parse_if('='): # kotlin default value (self.parse_matching_paren('(', ')') or self.parse_matching_paren('{', '}') or self.parse_token() and self.parse_matching_paren('(', ')')) return type def parse_throws(self): ret = [] Loading
tools/apilint/apilint_test.py +15 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,14 @@ class V2TokenizerTests(unittest.TestCase): self._test("class Some.Class extends SomeOther {", ['class', 'Some.Class', 'extends', 'SomeOther', '{']) def test_varargs(self): self._test("name(String...)", ['name', '(', 'String', '...', ')']) def test_kotlin(self): self._test("String? name(String!...)", ['String', '?', 'name', '(', 'String', '!', '...', ')']) def test_annotation(self): self._test("method @Nullable public void name();", ['method', '@', 'Nullable', 'public', 'void', 'name', '(', ')', ';']) Loading Loading @@ -271,5 +279,12 @@ class V2ParserTests(unittest.TestCase): self.assertEquals('NAME', f.name) self.assertEquals('( 0.0 / 0.0 )', f.value) def test_kotlin_types(self): self._field('field public List<Integer[]?[]!>?[]![]? NAME;') self._method("method <T?> Class<T!>?[]![][]? name(Type!, Type argname," + "Class<T?>[][]?[]!...!) throws Exception, T;") self._method("method <T> T name(T a = 1, T b = A(1), Lambda f = { false }, N? n = null, " + """double c = (1/0), float d = 1.0f, String s = "heyo", char c = 'a');""") if __name__ == "__main__": unittest.main()