Status Update
Comments
yb...@google.com <yb...@google.com> #2
Related ticket:
st...@gmail.com <st...@gmail.com> #3
Branch: androidx-master-dev
commit c0fd11cab1b083d043dfd54c8431c4068aeef09a
Author: Matvei Malkov <malkov@google.com>
Date: Wed Nov 04 17:35:35 2020
Add Modifier.focusable
This CL adds Modifier.focusable, which is intended to be a primary way to add focusability to the app (without clicks or with custom clicks), since it contains proper a11y and InteractionState support
Change-Id: I41eb9d67669e19f8a7c20804c836a8c6dc0b5526
RelNote: "Modifier.focusable has need added in foundation. Use this to add focusable behavior to a component, with correct semantics and accessibility."
Bug: 152525426
Bug: 162865824
Bug: 163423216
Test: added
M compose/foundation/foundation/api/current.txt
M compose/foundation/foundation/api/public_plus_experimental_current.txt
M compose/foundation/foundation/api/restricted_current.txt
M compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
M compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/HighLevelGesturesDemo.kt
A compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt
M compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ScrollableSamples.kt
M compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ZoomableSample.kt
A compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/FocusableTest.kt
A compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Focusable.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Interaction.kt
M compose/ui/ui-test/api/current.txt
M compose/ui/ui-test/api/public_plus_experimental_current.txt
M compose/ui/ui-test/api/restricted_current.txt
M compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Assertions.kt
M compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Filters.kt
el...@google.com <el...@google.com>
ap...@google.com <ap...@google.com> #4
focusable and hoverable have been added.
Filed separate bugs for 2d scroll (
el...@google.com <el...@google.com>
ap...@google.com <ap...@google.com> #5
Branch: androidx-main
commit 39908b855705e9e0d5f93e29323d7d96ccfdb103
Author: Yigit Boyar <yboyar@google.com>
Date: Fri Dec 18 21:54:23 2020
Handle primitives overriding generics in KSP
When a kotlin class specifies a non-nullable primitive type for a
super's generic argument, kotlin will duplicate methods that receive the
generic as an argument.
This CL changes the KSP override check to ignore those overrides so that
it also reports two methods. Note that this only happens for paremeters
and not return values. For return values, only the boxed one is generated.
To handle the return type boxing, we now use the overridden desclaration
when wrapping types, which lets us choose between primitive and
non-primitive by looking at the declaration.
Bug: 160258066
Bug: 160322705
Test: XExecutableElementTest
Change-Id: Id2fb76748ff014bcabe4543daed211d82d04bd4c
M room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
M room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
M room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/ResolverExt.kt
M room/compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
ph...@gmail.com <ph...@gmail.com> #6
The fix doesn't work for a case where the generic type parameter is only used as a parameter to another generic type. I'm using the roomerror.zip from the opening post, with only these two modifications:
interface BaseDao<Key, Value> {
fun getItem(id: Key): Value?
fun delete(id: Collection<Key>) // Previously: fun delete(id: Key)
}
@Dao
interface FooDao: BaseDao<Long, Foo> {
@Query("select * from foo where id=:id")
override fun getItem(id: Long): Foo?
@Query("delete from foo where id IN (:id)") // Previously: @Query("delete from foo where id=:id")
override fun delete(id: Collection<Long>) // Previously: override fun delete(id: Long)
}
Note that if it weren't for the super interface, the delete function accepting Collection<Long>
would be treated perfectly fine by Room. But now it complains:
roomerror/app/build/tmp/kapt3/stubs/debug/com/roomerror/BaseDao.java:11: error: An abstract DAO method must be annotated with one and only one of the following annotations: Insert,Delete,Query,Update,RawQuery
public abstract void delete(@org.jetbrains.annotations.NotNull()
^
I imagine this happens because of some type erasure. For the same reason, it's incredibly difficult for me to work around this issue. If I use a signature with vararg id: Key
instead, Room is happy, but I can't call the function anymore. That's because my call site looks sth like this:
class Manager<Key, Value> {
private val dao: BaseDao<Key, Value>
private val stuff: List<Key>
fun clear() { dao.delete(*stuff.toTypedArray()) } // It seems impossible to convert stuff to vararg when Key is not reified.
}
ph...@gmail.com <ph...@gmail.com> #7
Just realized it might be cleaner to file this as a new bug, as it's not specific to primitives and rather it's specific to type erasure.
ph...@gmail.com <ph...@gmail.com> #8
I believe this test case for room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
might reproduce the underlying problem:
@Test
fun overrideMethodWithGenericTypeArgument() {
val src = Source.kotlin(
"ParentWithGenericTypeArgument.kt",
"""
interface ParentWithGenericTypeArgument: GenericInterface<String> {
override fun child(arg: Collection<String>)
}
interface GenericInterface<T> {
fun child(arg: Collection<T>)
}
""".trimIndent()
)
runProcessorTest(sources = listOf(src)) { invocation ->
val objectMethodNames = invocation.processingEnv.requireTypeElement(Any::class)
.getAllMethods().jvmNames()
fun XMethodElement.signature(
owner: XType
): String {
val methodType = this.asMemberOf(owner)
val params = methodType.parameterTypes.joinToString(",") {
it.typeName.toString()
}
return "$jvmName($params):${returnType.typeName}"
}
fun XTypeElement.allMethodSignatures(): List<String> = getAllMethods().filterNot {
it.jvmName in objectMethodNames
}.map { it.signature(this.type) }.toList()
invocation.processingEnv.requireTypeElement(
"ParentWithGenericTypeArgument"
).let { parent ->
assertWithMessage(parent.qualifiedName).that(
parent.allMethodSignatures()
).containsExactly(
"child(java.util.Collection<java.lang.String>):void"
)
}
}
}
In particular, room-compiler
fails to recognize that child(arg: Collection<String>)
overrides child(arg: Collection<T>)
. Kotlin clearly thinks that it does override, as it doesn't complain about the override
keyword.
ph...@gmail.com <ph...@gmail.com> #9
This problem happens because fun child(arg: Collection<T>)
is converted to void child(@NonNull Collection<? extends T>)
in Java, because Kotlin declares a covariant type parameter Collection<out T>
. This isn't the case for MutableCollection
, so using that instead make things work, though I consider that an ugly workaround.
Description
Component used:
Compiler
Version used:
2.2.4
Devices/Android versions reproduced on:
Any
Consider we have an interface in Kotlin:
And the implementation:
Compiling this yields:
An abstract DAO method must be annotated with one and only one of the following annotations: Insert,Delete,Query,Update,RawQuery public abstract Value getItem(Key id);
This is due to the Kotlin way of handling its primitives and even though the
Key
type will be set correctly tojava.lang.Long
but the method signature will begetItem(long id)
.