diff options
author | 2019-01-05 22:04:55 +0100 | |
---|---|---|
committer | 2019-01-22 11:36:37 +0100 | |
commit | 5cdfb69429eb60fc274424d4dcb6b166ed550a42 (patch) | |
tree | b433cb91085562876a2216b2d835bfd03f9c455f /tools/apilint | |
parent | 1f1b6a84644916bd2b48f26ccb8cb31b336d4e2f (diff) |
ApiLint: Add Kotlin-style type support
Test: tools/apilint/apilint_sha.sh HEAD && python tools/apilint/apilint_test.py
Change-Id: Iac1fdabcbeffe57c8288d73b2359e8ce0b2bc3eb
(cherry picked from commit 7884d6b9090c586ac0d72abe0e6efab191a143a7)
Diffstat (limited to 'tools/apilint')
-rw-r--r-- | tools/apilint/apilint.py | 29 | ||||
-rw-r--r-- | tools/apilint/apilint_test.py | 15 |
2 files changed, 40 insertions, 4 deletions
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py index 441c1209a742..acf1f1e9902e 100644 --- a/tools/apilint/apilint.py +++ b/tools/apilint/apilint.py @@ -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): @@ -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): @@ -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 = [] diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py index 4e3c0349c0bc..081e98defa17 100644 --- a/tools/apilint/apilint_test.py +++ b/tools/apilint/apilint_test.py @@ -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', '(', ')', ';']) @@ -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() |