117565118: Suspended functions are not tracked
Change-Id: I2b7454a28dccf3ef07f7620e9c30e4e112045434
Fixes: 117565118
Test: Unit tests included
diff --git a/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java b/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java
index a8e11dd..f676af4 100644
--- a/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java
+++ b/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java
@@ -561,6 +561,10 @@
modifiers.setInline(true);
token = tokenizer.requireToken();
break;
+ case "suspend":
+ modifiers.setSuspend(true);
+ token = tokenizer.requireToken();
+ break;
case "vararg":
modifiers.setVarArg(true);
token = tokenizer.requireToken();
diff --git a/src/main/java/com/android/tools/metalava/model/DefaultModifierList.kt b/src/main/java/com/android/tools/metalava/model/DefaultModifierList.kt
index 941b7d4..65ebd48 100644
--- a/src/main/java/com/android/tools/metalava/model/DefaultModifierList.kt
+++ b/src/main/java/com/android/tools/metalava/model/DefaultModifierList.kt
@@ -117,6 +117,10 @@
return isSet(INFIX)
}
+ override fun isSuspend(): Boolean {
+ return isSet(SUSPEND)
+ }
+
override fun isOperator(): Boolean {
return isSet(OPERATOR)
}
@@ -201,6 +205,10 @@
set(DEPRECATED, deprecated)
}
+ fun setSuspend(suspend: Boolean) {
+ set(SUSPEND, suspend)
+ }
+
override fun addAnnotation(annotation: AnnotationItem) {
if (annotations == null) {
annotations = mutableListOf()
@@ -268,6 +276,7 @@
const val INFIX = 1 shl 16
const val OPERATOR = 1 shl 17
const val INLINE = 1 shl 18
+ const val SUSPEND = 1 shl 19
private fun bit(modifier: String): Int {
return when (modifier) {
@@ -290,6 +299,7 @@
"infix" -> INFIX
"operator" -> OPERATOR
"inline" -> INLINE
+ "suspend" -> SUSPEND
else -> error("Unsupported modifier $modifier")
}
}
@@ -300,6 +310,6 @@
*/
private const val EQUIVALENCE_MASK = PUBLIC or PROTECTED or PRIVATE or STATIC or ABSTRACT or
FINAL or TRANSIENT or VOLATILE or SYNCHRONIZED or DEPRECATED or VARARG or
- SEALED or INTERNAL or INFIX or OPERATOR
+ SEALED or INTERNAL or INFIX or OPERATOR or SUSPEND
}
}
\ No newline at end of file
diff --git a/src/main/java/com/android/tools/metalava/model/ModifierList.kt b/src/main/java/com/android/tools/metalava/model/ModifierList.kt
index 7c5c1ef..46074fc 100644
--- a/src/main/java/com/android/tools/metalava/model/ModifierList.kt
+++ b/src/main/java/com/android/tools/metalava/model/ModifierList.kt
@@ -53,6 +53,7 @@
fun isInternal(): Boolean = false
fun isInfix(): Boolean = false
+ fun isSuspend(): Boolean = false
fun isOperator(): Boolean = false
fun isInline(): Boolean = false
fun isEmpty(): Boolean
@@ -312,6 +313,10 @@
writer.write("sealed ")
}
+ if (list.isSuspend()) {
+ writer.write("suspend ")
+ }
+
if (list.isInline()) {
writer.write("inline ")
}
@@ -405,6 +410,10 @@
writer.write("sealed ")
}
+ if (list.isSuspend()) {
+ writer.write("suspend ")
+ }
+
if (list.isInline()) {
writer.write("inline ")
}
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt
index c847b8b..015b470 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt
@@ -128,6 +128,13 @@
}
}
}
+ if (ktModifierList.hasModifier(KtTokens.SUSPEND_KEYWORD)) {
+ flags = flags or SUSPEND
+
+ // Workaround for b/117565118:
+ // Switch back from private to public
+ flags = (flags and PRIVATE.inv()) or PUBLIC
+ }
}
}
diff --git a/src/test/java/com/android/tools/metalava/ApiFileTest.kt b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
index fcc53ea..be7ddbe 100644
--- a/src/test/java/com/android/tools/metalava/ApiFileTest.kt
+++ b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
@@ -463,6 +463,29 @@
}
@Test
+ fun `Suspend functions`() {
+ check(
+ sourceFiles = *arrayOf(
+ kotlin(
+ """
+ package test.pkg
+ suspend inline fun hello() { }
+ """
+ )
+ ),
+ api = """
+ package test.pkg {
+ public final class TestKt {
+ ctor public TestKt();
+ method public static suspend inline java.lang.Object hello(kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p);
+ }
+ }
+ """,
+ checkDoclava1 = false /* doesn't support Kotlin... */
+ )
+ }
+
+ @Test
fun `Propagate Platform types in Kotlin`() {
check(
compatibilityMode = false,
diff --git a/src/test/java/com/android/tools/metalava/ApiFromTextTest.kt b/src/test/java/com/android/tools/metalava/ApiFromTextTest.kt
index c8af838..f056ef8 100644
--- a/src/test/java/com/android/tools/metalava/ApiFromTextTest.kt
+++ b/src/test/java/com/android/tools/metalava/ApiFromTextTest.kt
@@ -730,4 +730,22 @@
api = source
)
}
+
+ @Test
+ fun `Suspended methods`() {
+ val source = """
+ package test.pkg {
+ public final class TestKt {
+ ctor public TestKt();
+ method public static suspend inline java.lang.Object hello(kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p);
+ }
+ }
+ """
+
+ check(
+ compatibilityMode = true,
+ signatureSource = source,
+ api = source
+ )
+ }
}
\ No newline at end of file