summaryrefslogtreecommitdiff
path: root/tools/apilint
diff options
context:
space:
mode:
author Adrian Roos <roosa@google.com> 2019-01-05 22:04:55 +0100
committer Adrian Roos <roosa@google.com> 2019-01-22 11:36:37 +0100
commit5cdfb69429eb60fc274424d4dcb6b166ed550a42 (patch)
treeb433cb91085562876a2216b2d835bfd03f9c455f /tools/apilint
parent1f1b6a84644916bd2b48f26ccb8cb31b336d4e2f (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.py29
-rw-r--r--tools/apilint/apilint_test.py15
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()