Status Update
Comments
yb...@google.com <yb...@google.com> #2
For Kotlin 2.0 and KSP 2.0 the Cannot change attributes of configuration ':composeApp:debugFrameworkIosX64' after it has been locked for mutation
really seems like a KSP issue. You should file a bug in their repository with a sample app if possible.
If you downgrade to Kotlin 1.9 then things 'should' work, there are example apps out there with such configuration, like the following one:
yb...@google.com <yb...@google.com> #3
Will try to use the example provided by you to check if it fixes the issue.
ah...@gmail.com <ah...@gmail.com> #4
Note that this issue happens when applying the Compose, KSP and Room Plugin together in Kotlin 2.0.x, the workaround for now is to not use the Room Gradle Plugin and instead specify the schema location vis KSP arguments:
// In the build.gradle
ksp {
arg("room.schemaLocation", "${projectDir}/schemas")
}
ap...@google.com <ap...@google.com> #5
Hi, I encountered a similar problem and was able to resolve it by updating the dependencies
room = "2.7.0-alpha08"
ksp = "2.0.20-1.0.25"
compose-plugin = "1.6.11"
kotlin = "2.0.20"
ap...@google.com <ap...@google.com> #6
Branch: androidx-main
commit 3b17b091cbc5b3c069b4a0c8121ee82fdb762e42
Author: Yigit Boyar <yboyar@google.com>
Date: Fri Aug 27 18:38:33 2021
Allow type converters to not set new values
This CL enhances TypeConverters to have the ability to
generate code without actually assigning new variables.
For instance, right now we have NoOpConverter which always
assigns the input variable to the output variable even though
it does not do anything. Sometimes this is OK as the output
variable name is set by a higher level but on other cases,
it just becomes unnecessary code. It was OK for one case but
as we will add new no-op converters that check nullability,
we might end up generating really unnecessary code.
I assume r8 takes care of collapsing it but still,
it is very unnecessary and generates unpleasant code. e.g.
String tmp = tmp_1;
if (tmp == null) throw ..
String tmp_2 = tmp;
String outVarName = tmp_2;
etc.
This CL does not remove the ability to set output variable
name when calling the type converter but it adds the ability
to not pass down an output variable name and let type converter
decide. As most of our type converters are single statement,
I've also added a SingleStatementTypeConverter that handles
both cases nicely such that we can generate:
final boolean tmp = x == 0 ? false : true
instead of
final boolean tmp;
tmp = x == 0 ? false : true;
Bug: 193437407
Test: existing tests (with updates for codegen tests)
Change-Id: I44f0277978bf4b4102535499202744a94b6cfc32
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/BoxedBooleanToBoxedIntConverter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/CompositeAdapter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/CompositeTypeConverter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/CustomTypeConverterWrapper.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/NoOpConverter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/PrimitiveBooleanToIntConverter.kt
A room/room-compiler/src/main/kotlin/androidx/room/solver/types/SingleStatementTypeConverter.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/TypeConverter.kt
M room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
yb...@google.com <yb...@google.com> #7
Quick update, i finally have a WIP CL for this that seems very promising.
I'll work on cleaning it up.
In this new version, you'll only need converters that receive/return non-null (unless you have a special handling of a nullable type). Room will start synthesizing a nullable version of each converter if necessary.
e.g if there is a converter from A to B
@TypeConverter
fun conv(a :A):B
room will assume there is a conversion from A? to B? such that it can generate:
val a: A? = ...
val b: B? = a?.let { conv(a) }
Note that, it will still use the user provided one if the user's converter receives nullable.
Also, thanks for the sample app, i've converted it into a test:
ap...@google.com <ap...@google.com> #8
Branch: androidx-main
commit 3972356c2bad8e77adbec04f735246c91dc7024d
Author: Yigit Boyar <yboyar@google.com>
Date: Mon Oct 04 15:08:42 2021
Add alternative TypeConverterStore for KSP
This CL introduces a new TypeConverterStore implementation that uses a
more fine granular cost calculation.
The current TypeConverterStore has a constant cost for each type
converter. Moreover, it does not optimize for nullability, resulting in
Room possibly picking a less optimal path (or wrong). With KSP, we now
get better nullability information so this new converter takes advantage
of it. To avoid breaking existing clients, this new converter store is
implemented as an alternative implementation that is only enabled in KSP
and can be turned off/on with a flag. That being said, we will still run
java tests with this new converter with hopes to turn down the old one
eventually.
This new converter store tries to preserve nullability. That means, if
we are writing a nullable field into database, it will first try to
convert it into a nullable db column. Detailed design of the heuristic
can be found here: go/room-null-aware-converter
Moreover, it has the ability to wrap user provided type converters such
that if the converter receives a nonnull value, the new Store can
synthesize a converter that receives null and returns null and use that.
In practical terms, this is great for usability as developers don't need
to worry about creating nullable versions of their converters.
Furthermore, it takes these null checks or up casts into account when
calculating path cost. Last but not least, if it cannot find a type
converter path to return a non-null value, it tries to read the same
value as nullable and if it succeds, wraps it in a null checking
converter. Even though this sounds questionable, we don't always have
the right types from db so it is OK to assume this if developer asked
for it (rather than forcing developer to return nullable). More details
on the justification can be found in the design doc.
There is also an inefficiency in the original type converter where,
while doing N -> N path finding, it always goes from start to end. In
practice, this method usually gets called with N -> 1 or 1 -> N and
always searching from start means branching out more than necessary.
This new implementation always goes from the smaller node set to the
larger size, significantly reducing the branching factor. I noticed this
while profiling the old one so the impact is quite sigificant but didn't
change the original one not to introduce risk.
Relnote: "We've added a new TypeConverter analyzer that takes nullability
information in types into account. As this information is only available
in KSP, it is turned on by default only in KSP. If it causes any issues,
you can turn it off by passing
room.useNullAwareTypeAnalysis=false to the annotation
processor. If that happens, please a file bug as this flag will be
removed in the future.
With this new TypeConverter analyzer, it is suggested to only provide
non-null receiving TypeConverters as the new analyzer has the ability
to wrap them with a null check.
Note that this has no impact for users using KAPT or Java as the
annotation processors (unlike KSP), don't have nullability information
in types."
Bug: 193437407
Test: NullabilityAwareTypeConverterStoreTest, NullabilityAwareTypeConversionTest.
Also added a variant to the java test app even though it is not really a goal
here, it would be good to ensure this new converter store works without KSP.
Change-Id: Ia88f916de3c15424ac8cc275d23223c6b5e47a6d
M room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/TypeConverter.kt
M buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt
M room/integration-tests/testapp/build.gradle
A room/integration-tests/kotlintestapp/src/androidTestWithKsp/java/androidx/room/integration/kotlintestapp/NullabilityAwareTypeConversionTest.kt
A room/room-compiler/src/test/kotlin/androidx/room/solver/NullabilityAwareTypeConverterStoreTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt
M room/room-compiler/src/main/kotlin/androidx/room/solver/types/CompositeTypeConverter.kt
A room/room-compiler/src/main/kotlin/androidx/room/solver/types/UpCastTypeConverter.kt
A room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStoreImpl.kt
A room/room-compiler/src/main/kotlin/androidx/room/solver/types/NullAwareTypeConverters.kt
M room/room-compiler/src/main/kotlin/androidx/room/processor/Context.kt
A room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterCostTest.kt
A room/room-compiler/src/test/kotlin/androidx/room/solver/Signatures.kt
A room/room-compiler/src/main/kotlin/androidx/room/solver/NullAwareTypeConverterStore.kt
M room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
M room/room-compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt
yb...@google.com <yb...@google.com> #9
This is fixed now. It would be great if you can try w/ a snapshot from androidx.dev. This is a major change to make room more nullability aware so might have some unexpected side effects. To avoid blocking people, we did add a flag to turn it off but it is just temporary until we are comfortable.
Description
Version used: Room 2.4.0-alpha03 with KSP 1.5.20-1.0.0-beta04
Devices/Android versions reproduced on: n/a (compile-time issue)
Attached is a project with a Room database in AppDatabase.kt, where in several situations Room doesn't use the type converter because the nullability didn't match.
Unfortunately in this case since the type is an enum, Room silently generated a type converter using Enum.name, so it wasn't even a compile error for this type, it just quietly does the wrong thing.
Looks related to