diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 538f528b6b1..851e4fe694f 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -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. diff --git a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt index 645bf5551ed..87f4ef1acf1 100644 --- a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt +++ b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt @@ -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) diff --git a/packages/pigeon/lib/src/generator_tools.dart b/packages/pigeon/lib/src/generator_tools.dart index 1e95428bcea..eef39cb00bd 100644 --- a/packages/pigeon/lib/src/generator_tools.dart +++ b/packages/pigeon/lib/src/generator_tools.dart @@ -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() { diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 52c4b1c4f20..3c3d27bc082 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -475,7 +475,9 @@ class KotlinGenerator extends StructuredGenerator { void writeEncodeLogic(EnumeratedType customType) { final String encodeString = - customType.type == CustomTypes.customClass ? 'toList()' : 'raw'; + customType.type == CustomTypes.customClass + ? 'toList()' + : 'raw.toLong()'; final String valueString = customType.enumeration < maximumCodecFieldKey ? 'value.$encodeString' diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index 71fe5b65b32..fe73e18c099 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -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) diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/EventChannelTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/EventChannelTests.gen.kt index fce3027c257..7e835701a23 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/EventChannelTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/EventChannelTests.gen.kt @@ -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) diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTests.gen.kt index 409fd62c7cc..71208c7d808 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/ProxyApiTests.gen.kt @@ -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) } diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt index c04a0dead5c..e2f80062c6e 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt @@ -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() val api = FlutterIntegrationCoreApi(binaryMessenger) @@ -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("a", 2, "three") private val matchingList = correctList.toMutableList() private val differentList = listOf("a", 2, "three", 4.0) diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index ba360b2f690..e7e2860629e 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -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