Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/pigeon/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 26.0.5

* [kotlin] Serialize custom enums as `Long` instead of `Int` to avoid `ClassCastException` on decoding.

## 26.0.4

* Adds compatibility with `analyzer` 8.x.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private open class MessagesPigeonCodec : StandardMessageCodec() {
when (value) {
is Code -> {
stream.write(129)
writeValue(stream, value.raw)
writeValue(stream, value.raw.toLong())
}
is MessageData -> {
stream.write(130)
Expand Down
2 changes: 1 addition & 1 deletion packages/pigeon/lib/src/generator_tools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'generator.dart';
/// The current version of pigeon.
///
/// This must match the version in pubspec.yaml.
const String pigeonVersion = '26.0.4';
const String pigeonVersion = '26.0.5';

/// Read all the content from [stdin] to a String.
String readStdin() {
Expand Down
4 changes: 3 additions & 1 deletion packages/pigeon/lib/src/kotlin/kotlin_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,9 @@ class KotlinGenerator extends StructuredGenerator<InternalKotlinOptions> {

void writeEncodeLogic(EnumeratedType customType) {
final String encodeString =
customType.type == CustomTypes.customClass ? 'toList()' : 'raw';
customType.type == CustomTypes.customClass
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tarrinneal At some point we should consider converting statements like these to the new expression switches (final String encodeString = switch (customType.type) {...};), so that if we ever add another custom type the compiler will find all the places we need to adjust the logic, instead of having the new type randomly opted into one or the other existing codepath everywhere.

? 'toList()'
: 'raw.toLong()';
final String valueString =
customType.enumeration < maximumCodecFieldKey
? 'value.$encodeString'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,11 +704,11 @@ private open class CoreTestsPigeonCodec : StandardMessageCodec() {
when (value) {
is AnEnum -> {
stream.write(129)
writeValue(stream, value.raw)
writeValue(stream, value.raw.toLong())
}
is AnotherEnum -> {
stream.write(130)
writeValue(stream, value.raw)
writeValue(stream, value.raw.toLong())
}
is UnusedClass -> {
stream.write(131)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,11 +477,11 @@ private open class EventChannelTestsPigeonCodec : StandardMessageCodec() {
when (value) {
is EventEnum -> {
stream.write(129)
writeValue(stream, value.raw)
writeValue(stream, value.raw.toLong())
}
is AnotherEventEnum -> {
stream.write(130)
writeValue(stream, value.raw)
writeValue(stream, value.raw.toLong())
}
is EventAllNullableTypes -> {
stream.write(131)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ private open class ProxyApiTestsPigeonCodec : StandardMessageCodec() {
when (value) {
is ProxyApiTestEnum -> {
stream.write(129)
writeValue(stream, value.raw)
writeValue(stream, value.raw.toLong())
}
else -> super.writeValue(stream, value)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,33 +46,52 @@ internal class AllDatatypesTest {
}

@Test
fun testHasValues() {
fun testRoundtripNullValues() {
val everything = AllNullableTypes()
val codec = FlutterIntegrationCoreApi.codec
val encoded = codec.encodeMessage(everything)
encoded?.rewind()
val decoded = codec.decodeMessage(encoded)
assertEquals(everything, decoded)
}

fun getFullyPopulatedAllNullableTypes(): AllNullableTypes {
val stringList = listOf("string", "another one")
val everything =
AllNullableTypes(
aNullableBool = false,
aNullableInt = 1234L,
aNullableDouble = 2.0,
aNullableString = "hello",
aNullableByteArray = byteArrayOf(1, 2, 3, 4),
aNullable4ByteArray = intArrayOf(1, 2, 3, 4),
aNullable8ByteArray = longArrayOf(1, 2, 3, 4),
aNullableFloatArray = doubleArrayOf(0.5, 0.25, 1.5, 1.25),
aNullableObject = 0,
list = listOf(1, 2, 3),
stringList = stringList,
boolList = listOf(true, false),
intList = listOf(1, 2),
doubleList = listOf(1.1, 2.2),
objectList = listOf(1, 2, 3),
listList = listOf(stringList, stringList.toList()),
mapList = listOf(mapOf("hello" to 1234), mapOf("hello" to 1234)),
map = mapOf("hello" to 1234),
stringMap = mapOf("hello" to "you"),
intMap = mapOf(1L to 0L),
objectMap = mapOf("hello" to 1234),
listMap = mapOf(1L to stringList),
mapMap = mapOf(1L to mapOf()))

return AllNullableTypes(
aNullableBool = false,
aNullableInt = 1234L,
aNullableDouble = 2.0,
aNullableString = "hello",
aNullableByteArray = byteArrayOf(1, 2, 3, 4),
aNullable4ByteArray = intArrayOf(1, 2, 3, 4),
aNullable8ByteArray = longArrayOf(1, 2, 3, 4),
aNullableFloatArray = doubleArrayOf(0.5, 0.25, 1.5, 1.25),
aNullableEnum = AnEnum.TWO,
anotherNullableEnum = AnotherEnum.JUST_IN_CASE,
aNullableObject = 0,
list = listOf(1, 2, 3),
stringList = stringList,
boolList = listOf(true, false),
enumList = listOf(AnEnum.ONE, AnEnum.TWO),
intList = listOf(1, 2),
doubleList = listOf(1.1, 2.2),
objectList = listOf(1, 2, 3),
listList = listOf(stringList, stringList.toList()),
mapList = listOf(mapOf("hello" to 1234), mapOf("hello" to 1234)),
map = mapOf("hello" to 1234),
stringMap = mapOf("hello" to "you"),
intMap = mapOf(1L to 0L),
objectMap = mapOf("hello" to 1234),
enumMap =
mapOf(AnEnum.ONE to AnEnum.FORTY_TWO, AnEnum.TWO to AnEnum.FOUR_HUNDRED_TWENTY_TWO),
listMap = mapOf(1L to stringList),
mapMap = mapOf(1L to mapOf()))
}

@Test
fun testHasValues() {
val everything = getFullyPopulatedAllNullableTypes()
val binaryMessenger = mockk<BinaryMessenger>()
val api = FlutterIntegrationCoreApi(binaryMessenger)

Expand All @@ -97,6 +116,16 @@ internal class AllDatatypesTest {
assertTrue(didCall)
}

@Test
fun testRoundtripHasValues() {
val everything = getFullyPopulatedAllNullableTypes()
val codec = FlutterIntegrationCoreApi.codec
val encoded = codec.encodeMessage(everything)
encoded?.rewind()
val decoded = codec.decodeMessage(encoded)
assertEquals(everything, decoded)
}

private val correctList = listOf<Any?>("a", 2, "three")
private val matchingList = correctList.toMutableList()
private val differentList = listOf<Any?>("a", 2, "three", 4.0)
Expand Down
2 changes: 1 addition & 1 deletion packages/pigeon/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: pigeon
description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
repository: https://github.com/flutter/packages/tree/main/packages/pigeon
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pigeon%22
version: 26.0.4 # This must match the version in lib/src/generator_tools.dart
version: 26.0.5 # This must match the version in lib/src/generator_tools.dart

environment:
sdk: ^3.7.0
Expand Down