diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 3b9ee79da122..dab9b7ac831a 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,5 +1,8 @@ -## NEXT +## 27.0.0 +* **Breaking Change** Overrides `toString` (or equivalent) methods on generated data classes + * This can conflict with custom `description` implementations in Swift. +* [swift] Updates `isNullish` to handle double nested `Any?` values. * Updates minimum supported SDK version to Flutter 3.38/Dart 3.10. ## 26.3.4 @@ -919,7 +922,7 @@ ## 3.0.3 -* Adds ability for generators to do AST validation. This can help generators +* Adds ability for generators to do AST validation. This can help generators without complete implementations to report gaps in coverage. ## 3.0.2 @@ -1082,11 +1085,11 @@ `dart:mirrors` doesn't support null-safe code so there were a class of features we couldn't implement without this migration. * **BREAKING CHANGE** - the `configurePigeon` function has been migrated to a - `@ConfigurePigeon` annotation. See `./pigeons/message.dart` for an example. + `@ConfigurePigeon` annotation. See `./pigeons/message.dart` for an example. The annotation can be attached to anything in the file to take effect. * **BREAKING CHANGE** - Now Pigeon files must be in one file per invocation of - Pigeon. For example, the classes your APIs use must be in the same file as - your APIs. If your Pigeon file imports another source file, it won't actually + Pigeon. For example, the classes your APIs use must be in the same file as + your APIs. If your Pigeon file imports another source file, it won't actually import it. ## 0.2.4 @@ -1108,10 +1111,10 @@ ## 0.2.0 -* **BREAKING CHANGE** - Pigeon files must be null-safe now. That means the +* **BREAKING CHANGE** - Pigeon files must be null-safe now. That means the fields inside of the classes must be declared nullable ( [non-null fields](https://github.com/flutter/flutter/issues/59118) aren't yet - supported). Migration example: + supported). Migration example: ```dart // Version 0.1.x @@ -1127,7 +1130,7 @@ class Foo { } ``` -* **BREAKING CHANGE** - The default output from Pigeon is now null-safe. If you +* **BREAKING CHANGE** - The default output from Pigeon is now null-safe. If you want non-null-safe code you must provide the `--no-dart_null_safety` flag. * The Pigeon source code is now null-safe. * Fixed niladic non-value returning async functions in the Java generator. @@ -1213,7 +1216,7 @@ class Foo { ## 0.1.8 -* Started spawning pigeon_lib in an isolate instead of a subprocess. The +* Started spawning pigeon_lib in an isolate instead of a subprocess. The subprocess could have lead to errors if the dart version on $PATH didn't match the one that comes with flutter. diff --git a/packages/pigeon/CONTRIBUTING.md b/packages/pigeon/CONTRIBUTING.md index 41ead7842651..304d1a8c7906 100644 --- a/packages/pigeon/CONTRIBUTING.md +++ b/packages/pigeon/CONTRIBUTING.md @@ -3,7 +3,7 @@ ## Description Pigeon is a code generation tool that adds type safety to Flutter’s Platform -Channels. This document serves as an overview of how it functions to help +Channels. This document serves as an overview of how it functions to help people who would like to contribute to the project. ## Source Index @@ -32,15 +32,15 @@ Pigeon has 3 types of tests; you'll find them all in * Unit tests - These are the fastest tests that are just typical unit tests, they may be generating code and checking it against a regular expression to - see if it's correct. Example: + see if it's correct. Example: [dart_generator_test.dart](./test/dart_generator_test.dart) * Compilation tests - These tests generate code, then attempt to compile that - code. These are tests are much slower than unit tests, but not as slow as - integration tests. These tests are typically run against the Pigeon files in + code. These are tests are much slower than unit tests, but not as slow as + integration tests. These tests are typically run against the Pigeon files in [pigeons](./pigeons). * Integration tests - These tests generate code, then compile the generated - code, then execute the generated code. It can be thought of as unit-tests run - against the generated code. Examples: [platform_tests](./platform_tests) + code, then execute the generated code. It can be thought of as unit-tests run + against the generated code. Examples: [platform_tests](./platform_tests) For local testing, always use `test.dart` rather than `run_tests.dart`, as `run_tests.dart` is specifically a CI entrypoint. When iterating on a specific diff --git a/packages/pigeon/README.md b/packages/pigeon/README.md index 0e5b91c25128..1029d51f3be9 100644 --- a/packages/pigeon/README.md +++ b/packages/pigeon/README.md @@ -101,7 +101,7 @@ to the api to allow for multiple instances to be created and operate in parallel 1) Custom classes used by APIs are defined as classes with fields of the supported datatypes (see the supported Datatypes section). 1) APIs should be defined as an `abstract class` with either `@HostApi()` or - `@FlutterApi()` as metadata. `@HostApi()` being for procedures that are defined + `@FlutterApi()` as metadata. `@HostApi()` being for procedures that are defined on the host platform and the `@FlutterApi()` for procedures that are defined in Dart. 1) Method declarations on the API classes should have arguments and a return value whose types are defined in the file, are supported datatypes, or are @@ -150,7 +150,7 @@ to the api to allow for multiple instances to be created and operate in parallel ### Calling into Flutter from the host platform Pigeon also supports calling in the opposite direction. The steps are similar -but reversed. For more information look at the annotation `@FlutterApi()` which +but reversed. For more information look at the annotation `@FlutterApi()` which denotes APIs that live in Flutter but are invoked from the host platform. [Example](./example/README.md#FlutterApi_Example). diff --git a/packages/pigeon/example/README.md b/packages/pigeon/example/README.md index 78feb668fb89..489a4aed60b0 100644 --- a/packages/pigeon/example/README.md +++ b/packages/pigeon/example/README.md @@ -61,7 +61,7 @@ enum Code { one, two } class MessageData { MessageData({required this.code, required this.data}); String? name; - String? description; + String? messageDescription; Code code; Map data; } @@ -106,7 +106,7 @@ Future sendMessage(String messageText) { final message = MessageData( code: Code.one, data: {'header': 'this is a header'}, - description: 'uri text', + messageDescription: 'uri text', ); try { return _api.sendMessage(message); diff --git a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java index b649738648ab..75a676627eca 100644 --- a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java +++ b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java @@ -251,14 +251,14 @@ public void setName(@Nullable String setterArg) { this.name = setterArg; } - private @Nullable String description; + private @Nullable String messageDescription; - public @Nullable String getDescription() { - return description; + public @Nullable String getMessageDescription() { + return messageDescription; } - public void setDescription(@Nullable String setterArg) { - this.description = setterArg; + public void setMessageDescription(@Nullable String setterArg) { + this.messageDescription = setterArg; } private @NonNull Code code; @@ -300,17 +300,34 @@ public boolean equals(Object o) { } MessageData that = (MessageData) o; return pigeonDeepEquals(name, that.name) - && pigeonDeepEquals(description, that.description) + && pigeonDeepEquals(messageDescription, that.messageDescription) && pigeonDeepEquals(code, that.code) && pigeonDeepEquals(data, that.data); } @Override public int hashCode() { - Object[] fields = new Object[] {getClass(), name, description, code, data}; + Object[] fields = new Object[] {getClass(), name, messageDescription, code, data}; return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "MessageData{" + + "name=" + + name + + ", " + + "messageDescription=" + + messageDescription + + ", " + + "code=" + + code + + ", " + + "data=" + + data + + "}"; + } + public static final class Builder { private @Nullable String name; @@ -321,11 +338,11 @@ public static final class Builder { return this; } - private @Nullable String description; + private @Nullable String messageDescription; @CanIgnoreReturnValue - public @NonNull Builder setDescription(@Nullable String setterArg) { - this.description = setterArg; + public @NonNull Builder setMessageDescription(@Nullable String setterArg) { + this.messageDescription = setterArg; return this; } @@ -348,7 +365,7 @@ public static final class Builder { public @NonNull MessageData build() { MessageData pigeonReturn = new MessageData(); pigeonReturn.setName(name); - pigeonReturn.setDescription(description); + pigeonReturn.setMessageDescription(messageDescription); pigeonReturn.setCode(code); pigeonReturn.setData(data); return pigeonReturn; @@ -359,7 +376,7 @@ public static final class Builder { ArrayList toList() { ArrayList toListResult = new ArrayList<>(4); toListResult.add(name); - toListResult.add(description); + toListResult.add(messageDescription); toListResult.add(code); toListResult.add(data); return toListResult; @@ -369,8 +386,8 @@ ArrayList toList() { MessageData pigeonResult = new MessageData(); Object name = pigeonVar_list.get(0); pigeonResult.setName((String) name); - Object description = pigeonVar_list.get(1); - pigeonResult.setDescription((String) description); + Object messageDescription = pigeonVar_list.get(1); + pigeonResult.setMessageDescription((String) messageDescription); Object code = pigeonVar_list.get(2); pigeonResult.setCode((Code) code); Object data = pigeonVar_list.get(3); diff --git a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/EventChannelMessages.g.kt b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/EventChannelMessages.g.kt index 9029c9425018..c2e8d93cf99a 100644 --- a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/EventChannelMessages.g.kt +++ b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/EventChannelMessages.g.kt @@ -194,6 +194,10 @@ data class IntEvent(val data: Long) : PlatformEvent() { result = 31 * result + EventChannelMessagesPigeonUtils.deepHash(this.data) return result } + + override fun toString(): String { + return "IntEvent(data=$data)" + } } /** Generated class from Pigeon that represents data sent in messages. */ @@ -227,6 +231,10 @@ data class StringEvent(val data: String) : PlatformEvent() { result = 31 * result + EventChannelMessagesPigeonUtils.deepHash(this.data) return result } + + override fun toString(): String { + return "StringEvent(data=$data)" + } } private open class EventChannelMessagesPigeonCodec : StandardMessageCodec() { 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 9557d8c13297..e81766320f31 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 @@ -207,24 +207,24 @@ enum class Code(val raw: Int) { /** Generated class from Pigeon that represents data sent in messages. */ data class MessageData( val name: String? = null, - val description: String? = null, + val messageDescription: String? = null, val code: Code, val data: Map ) { companion object { fun fromList(pigeonVar_list: List): MessageData { val name = pigeonVar_list[0] as String? - val description = pigeonVar_list[1] as String? + val messageDescription = pigeonVar_list[1] as String? val code = pigeonVar_list[2] as Code val data = pigeonVar_list[3] as Map - return MessageData(name, description, code, data) + return MessageData(name, messageDescription, code, data) } } fun toList(): List { return listOf( name, - description, + messageDescription, code, data, ) @@ -239,7 +239,7 @@ data class MessageData( } val other = other as MessageData return MessagesPigeonUtils.deepEquals(this.name, other.name) && - MessagesPigeonUtils.deepEquals(this.description, other.description) && + MessagesPigeonUtils.deepEquals(this.messageDescription, other.messageDescription) && MessagesPigeonUtils.deepEquals(this.code, other.code) && MessagesPigeonUtils.deepEquals(this.data, other.data) } @@ -247,11 +247,15 @@ data class MessageData( override fun hashCode(): Int { var result = javaClass.hashCode() result = 31 * result + MessagesPigeonUtils.deepHash(this.name) - result = 31 * result + MessagesPigeonUtils.deepHash(this.description) + result = 31 * result + MessagesPigeonUtils.deepHash(this.messageDescription) result = 31 * result + MessagesPigeonUtils.deepHash(this.code) result = 31 * result + MessagesPigeonUtils.deepHash(this.data) return result } + + override fun toString(): String { + return "MessageData(name=$name, messageDescription=$messageDescription, code=$code, data=$data)" + } } private open class MessagesPigeonCodec : StandardMessageCodec() { diff --git a/packages/pigeon/example/app/ios/Runner/EventChannelMessages.g.swift b/packages/pigeon/example/app/ios/Runner/EventChannelMessages.g.swift index 70cab0a27bec..16d0bad07c6b 100644 --- a/packages/pigeon/example/app/ios/Runner/EventChannelMessages.g.swift +++ b/packages/pigeon/example/app/ios/Runner/EventChannelMessages.g.swift @@ -14,122 +14,132 @@ import Foundation #error("Unsupported platform.") #endif -private func isNullish(_ value: Any?) -> Bool { - return value is NSNull || value == nil -} +enum EventChannelMessagesPigeonInternal { + static func isNullish(_ value: Any?) -> Bool { + guard let innerValue = value else { + return true + } -private func nilOrValue(_ value: Any?) -> T? { - if value is NSNull { return nil } - return value as! T? -} + if case Optional.some(Optional.none) = value { + return true + } -private func doubleEqualsEventChannelMessages(_ lhs: Double, _ rhs: Double) -> Bool { - return (lhs.isNaN && rhs.isNaN) || lhs == rhs -} + return innerValue is NSNull + } + static func doubleEquals(_ lhs: Double, _ rhs: Double) -> Bool { + return (lhs.isNaN && rhs.isNaN) || lhs == rhs + } -private func doubleHashEventChannelMessages(_ value: Double, _ hasher: inout Hasher) { - if value.isNaN { - hasher.combine(0x7FF8_0000_0000_0000) - } else { - // Normalize -0.0 to 0.0 - hasher.combine(value == 0 ? 0 : value) + static func doubleHash(_ value: Double, _ hasher: inout Hasher) { + if value.isNaN { + hasher.combine(0x7FF8_0000_0000_0000) + } else { + // Normalize -0.0 to 0.0 + hasher.combine(value == 0 ? 0 : value) + } } -} -func deepEqualsEventChannelMessages(_ lhs: Any?, _ rhs: Any?) -> Bool { - let cleanLhs = nilOrValue(lhs) as Any? - let cleanRhs = nilOrValue(rhs) as Any? - switch (cleanLhs, cleanRhs) { - case (nil, nil): - return true + static func deepEquals(_ lhs: Any?, _ rhs: Any?) -> Bool { + let cleanLhs = nilOrValue(lhs) as Any? + let cleanRhs = nilOrValue(rhs) as Any? + switch (cleanLhs, cleanRhs) { + case (nil, nil): + return true - case (nil, _), (_, nil): - return false + case (nil, _), (_, nil): + return false - case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: - return true + case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: + return true - case is (Void, Void): - return true + case is (Void, Void): + return true - case (let lhsArray, let rhsArray) as ([Any?], [Any?]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !deepEqualsEventChannelMessages(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Any?], [Any?]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !deepEquals(element, rhsArray[index]) { + return false + } } - } - return true + return true - case (let lhsArray, let rhsArray) as ([Double], [Double]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !doubleEqualsEventChannelMessages(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Double], [Double]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !doubleEquals(element, rhsArray[index]) { + return false + } } - } - return true - - case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): - guard lhsDictionary.count == rhsDictionary.count else { return false } - for (lhsKey, lhsValue) in lhsDictionary { - var found = false - for (rhsKey, rhsValue) in rhsDictionary { - if deepEqualsEventChannelMessages(lhsKey, rhsKey) { - if deepEqualsEventChannelMessages(lhsValue, rhsValue) { - found = true - break - } else { - return false + return true + + case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): + guard lhsDictionary.count == rhsDictionary.count else { return false } + for (lhsKey, lhsValue) in lhsDictionary { + var found = false + for (rhsKey, rhsValue) in rhsDictionary { + if deepEquals(lhsKey, rhsKey) { + if deepEquals(lhsValue, rhsValue) { + found = true + break + } else { + return false + } } } + if !found { return false } } - if !found { return false } - } - return true + return true - case (let lhs as Double, let rhs as Double): - return doubleEqualsEventChannelMessages(lhs, rhs) + case (let lhs as Double, let rhs as Double): + return doubleEquals(lhs, rhs) - case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): - return lhsHashable == rhsHashable + case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): + return lhsHashable == rhsHashable - default: - return false + default: + return false + } } -} -func deepHashEventChannelMessages(value: Any?, hasher: inout Hasher) { - let cleanValue = nilOrValue(value) as Any? - if let cleanValue = cleanValue { - if let doubleValue = cleanValue as? Double { - doubleHashEventChannelMessages(doubleValue, &hasher) - } else if let valueList = cleanValue as? [Any?] { - for item in valueList { - deepHashEventChannelMessages(value: item, hasher: &hasher) - } - } else if let valueList = cleanValue as? [Double] { - for item in valueList { - doubleHashEventChannelMessages(item, &hasher) - } - } else if let valueDict = cleanValue as? [AnyHashable: Any?] { - var result = 0 - for (key, value) in valueDict { - var entryKeyHasher = Hasher() - deepHashEventChannelMessages(value: key, hasher: &entryKeyHasher) - var entryValueHasher = Hasher() - deepHashEventChannelMessages(value: value, hasher: &entryValueHasher) - result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + static func deepHash(value: Any?, hasher: inout Hasher) { + let cleanValue = nilOrValue(value) as Any? + if let cleanValue = cleanValue { + if let doubleValue = cleanValue as? Double { + doubleHash(doubleValue, &hasher) + } else if let valueList = cleanValue as? [Any?] { + for item in valueList { + deepHash(value: item, hasher: &hasher) + } + } else if let valueList = cleanValue as? [Double] { + for item in valueList { + doubleHash(item, &hasher) + } + } else if let valueDict = cleanValue as? [AnyHashable: Any?] { + var result = 0 + for (key, value) in valueDict { + var entryKeyHasher = Hasher() + deepHash(value: key, hasher: &entryKeyHasher) + var entryValueHasher = Hasher() + deepHash(value: value, hasher: &entryValueHasher) + result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + } + hasher.combine(result) + } else if let hashableValue = cleanValue as? AnyHashable { + hasher.combine(hashableValue) + } else { + hasher.combine(String(describing: cleanValue)) } - hasher.combine(result) - } else if let hashableValue = cleanValue as? AnyHashable { - hasher.combine(hashableValue) } else { - hasher.combine(String(describing: cleanValue)) + hasher.combine(0) } - } else { - hasher.combine(0) } + +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? } /// Generated class from Pigeon that represents data sent in messages. @@ -159,12 +169,16 @@ struct IntEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelMessages(lhs.data, rhs.data) + return EventChannelMessagesPigeonInternal.deepEquals(lhs.data, rhs.data) } func hash(into hasher: inout Hasher) { hasher.combine("IntEvent") - deepHashEventChannelMessages(value: data, hasher: &hasher) + EventChannelMessagesPigeonInternal.deepHash(value: data, hasher: &hasher) + } + + public var description: String { + return "IntEvent(data: \(String(describing: data)))" } } @@ -189,12 +203,16 @@ struct StringEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelMessages(lhs.data, rhs.data) + return EventChannelMessagesPigeonInternal.deepEquals(lhs.data, rhs.data) } func hash(into hasher: inout Hasher) { hasher.combine("StringEvent") - deepHashEventChannelMessages(value: data, hasher: &hasher) + EventChannelMessagesPigeonInternal.deepHash(value: data, hasher: &hasher) + } + + public var description: String { + return "StringEvent(data: \(String(describing: data)))" } } diff --git a/packages/pigeon/example/app/ios/Runner/Messages.g.swift b/packages/pigeon/example/app/ios/Runner/Messages.g.swift index f8b12f846c22..0922d9f1dac9 100644 --- a/packages/pigeon/example/app/ios/Runner/Messages.g.swift +++ b/packages/pigeon/example/app/ios/Runner/Messages.g.swift @@ -64,122 +64,132 @@ private func createConnectionError(withChannelName channelName: String) -> Pigeo details: "") } -private func isNullish(_ value: Any?) -> Bool { - return value is NSNull || value == nil -} +enum MessagesPigeonInternal { + static func isNullish(_ value: Any?) -> Bool { + guard let innerValue = value else { + return true + } -private func nilOrValue(_ value: Any?) -> T? { - if value is NSNull { return nil } - return value as! T? -} + if case Optional.some(Optional.none) = value { + return true + } -private func doubleEqualsMessages(_ lhs: Double, _ rhs: Double) -> Bool { - return (lhs.isNaN && rhs.isNaN) || lhs == rhs -} + return innerValue is NSNull + } + static func doubleEquals(_ lhs: Double, _ rhs: Double) -> Bool { + return (lhs.isNaN && rhs.isNaN) || lhs == rhs + } -private func doubleHashMessages(_ value: Double, _ hasher: inout Hasher) { - if value.isNaN { - hasher.combine(0x7FF8_0000_0000_0000) - } else { - // Normalize -0.0 to 0.0 - hasher.combine(value == 0 ? 0 : value) + static func doubleHash(_ value: Double, _ hasher: inout Hasher) { + if value.isNaN { + hasher.combine(0x7FF8_0000_0000_0000) + } else { + // Normalize -0.0 to 0.0 + hasher.combine(value == 0 ? 0 : value) + } } -} -func deepEqualsMessages(_ lhs: Any?, _ rhs: Any?) -> Bool { - let cleanLhs = nilOrValue(lhs) as Any? - let cleanRhs = nilOrValue(rhs) as Any? - switch (cleanLhs, cleanRhs) { - case (nil, nil): - return true + static func deepEquals(_ lhs: Any?, _ rhs: Any?) -> Bool { + let cleanLhs = nilOrValue(lhs) as Any? + let cleanRhs = nilOrValue(rhs) as Any? + switch (cleanLhs, cleanRhs) { + case (nil, nil): + return true - case (nil, _), (_, nil): - return false + case (nil, _), (_, nil): + return false - case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: - return true + case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: + return true - case is (Void, Void): - return true + case is (Void, Void): + return true - case (let lhsArray, let rhsArray) as ([Any?], [Any?]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !deepEqualsMessages(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Any?], [Any?]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !deepEquals(element, rhsArray[index]) { + return false + } } - } - return true + return true - case (let lhsArray, let rhsArray) as ([Double], [Double]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !doubleEqualsMessages(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Double], [Double]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !doubleEquals(element, rhsArray[index]) { + return false + } } - } - return true - - case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): - guard lhsDictionary.count == rhsDictionary.count else { return false } - for (lhsKey, lhsValue) in lhsDictionary { - var found = false - for (rhsKey, rhsValue) in rhsDictionary { - if deepEqualsMessages(lhsKey, rhsKey) { - if deepEqualsMessages(lhsValue, rhsValue) { - found = true - break - } else { - return false + return true + + case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): + guard lhsDictionary.count == rhsDictionary.count else { return false } + for (lhsKey, lhsValue) in lhsDictionary { + var found = false + for (rhsKey, rhsValue) in rhsDictionary { + if deepEquals(lhsKey, rhsKey) { + if deepEquals(lhsValue, rhsValue) { + found = true + break + } else { + return false + } } } + if !found { return false } } - if !found { return false } - } - return true + return true - case (let lhs as Double, let rhs as Double): - return doubleEqualsMessages(lhs, rhs) + case (let lhs as Double, let rhs as Double): + return doubleEquals(lhs, rhs) - case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): - return lhsHashable == rhsHashable + case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): + return lhsHashable == rhsHashable - default: - return false + default: + return false + } } -} -func deepHashMessages(value: Any?, hasher: inout Hasher) { - let cleanValue = nilOrValue(value) as Any? - if let cleanValue = cleanValue { - if let doubleValue = cleanValue as? Double { - doubleHashMessages(doubleValue, &hasher) - } else if let valueList = cleanValue as? [Any?] { - for item in valueList { - deepHashMessages(value: item, hasher: &hasher) - } - } else if let valueList = cleanValue as? [Double] { - for item in valueList { - doubleHashMessages(item, &hasher) - } - } else if let valueDict = cleanValue as? [AnyHashable: Any?] { - var result = 0 - for (key, value) in valueDict { - var entryKeyHasher = Hasher() - deepHashMessages(value: key, hasher: &entryKeyHasher) - var entryValueHasher = Hasher() - deepHashMessages(value: value, hasher: &entryValueHasher) - result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + static func deepHash(value: Any?, hasher: inout Hasher) { + let cleanValue = nilOrValue(value) as Any? + if let cleanValue = cleanValue { + if let doubleValue = cleanValue as? Double { + doubleHash(doubleValue, &hasher) + } else if let valueList = cleanValue as? [Any?] { + for item in valueList { + deepHash(value: item, hasher: &hasher) + } + } else if let valueList = cleanValue as? [Double] { + for item in valueList { + doubleHash(item, &hasher) + } + } else if let valueDict = cleanValue as? [AnyHashable: Any?] { + var result = 0 + for (key, value) in valueDict { + var entryKeyHasher = Hasher() + deepHash(value: key, hasher: &entryKeyHasher) + var entryValueHasher = Hasher() + deepHash(value: value, hasher: &entryValueHasher) + result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + } + hasher.combine(result) + } else if let hashableValue = cleanValue as? AnyHashable { + hasher.combine(hashableValue) + } else { + hasher.combine(String(describing: cleanValue)) } - hasher.combine(result) - } else if let hashableValue = cleanValue as? AnyHashable { - hasher.combine(hashableValue) } else { - hasher.combine(String(describing: cleanValue)) + hasher.combine(0) } - } else { - hasher.combine(0) } + +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? } enum Code: Int { @@ -188,22 +198,22 @@ enum Code: Int { } /// Generated class from Pigeon that represents data sent in messages. -struct MessageData: Hashable { +struct MessageData: Hashable, CustomStringConvertible { var name: String? = nil - var description: String? = nil + var messageDescription: String? = nil var code: Code var data: [String: String] // swift-format-ignore: AlwaysUseLowerCamelCase static func fromList(_ pigeonVar_list: [Any?]) -> MessageData? { let name: String? = nilOrValue(pigeonVar_list[0]) - let description: String? = nilOrValue(pigeonVar_list[1]) + let messageDescription: String? = nilOrValue(pigeonVar_list[1]) let code = pigeonVar_list[2] as! Code let data = pigeonVar_list[3] as! [String: String] return MessageData( name: name, - description: description, + messageDescription: messageDescription, code: code, data: data ) @@ -211,7 +221,7 @@ struct MessageData: Hashable { func toList() -> [Any?] { return [ name, - description, + messageDescription, code, data, ] @@ -220,17 +230,23 @@ struct MessageData: Hashable { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsMessages(lhs.name, rhs.name) - && deepEqualsMessages(lhs.description, rhs.description) - && deepEqualsMessages(lhs.code, rhs.code) && deepEqualsMessages(lhs.data, rhs.data) + return MessagesPigeonInternal.deepEquals(lhs.name, rhs.name) + && MessagesPigeonInternal.deepEquals(lhs.messageDescription, rhs.messageDescription) + && MessagesPigeonInternal.deepEquals(lhs.code, rhs.code) + && MessagesPigeonInternal.deepEquals(lhs.data, rhs.data) } func hash(into hasher: inout Hasher) { hasher.combine("MessageData") - deepHashMessages(value: name, hasher: &hasher) - deepHashMessages(value: description, hasher: &hasher) - deepHashMessages(value: code, hasher: &hasher) - deepHashMessages(value: data, hasher: &hasher) + MessagesPigeonInternal.deepHash(value: name, hasher: &hasher) + MessagesPigeonInternal.deepHash(value: messageDescription, hasher: &hasher) + MessagesPigeonInternal.deepHash(value: code, hasher: &hasher) + MessagesPigeonInternal.deepHash(value: data, hasher: &hasher) + } + + public var description: String { + return + "MessageData(name: \(String(describing: name)), messageDescription: \(String(describing: messageDescription)), code: \(String(describing: code)), data: \(String(describing: data)))" } } @@ -349,6 +365,7 @@ class ExampleHostApiSetup { } } } + /// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. protocol MessageFlutterApiProtocol { func flutterMethod( diff --git a/packages/pigeon/example/app/lib/main.dart b/packages/pigeon/example/app/lib/main.dart index 0af0dd738335..754e0327eb21 100644 --- a/packages/pigeon/example/app/lib/main.dart +++ b/packages/pigeon/example/app/lib/main.dart @@ -78,7 +78,7 @@ class _MyHomePageState extends State { final message = MessageData( code: Code.one, data: {'header': 'this is a header'}, - description: 'uri text', + messageDescription: 'uri text', ); try { return _api.sendMessage(message); diff --git a/packages/pigeon/example/app/lib/src/event_channel_messages.g.dart b/packages/pigeon/example/app/lib/src/event_channel_messages.g.dart index a7e34a0ed60a..28217b3755f5 100644 --- a/packages/pigeon/example/app/lib/src/event_channel_messages.g.dart +++ b/packages/pigeon/example/app/lib/src/event_channel_messages.g.dart @@ -108,6 +108,11 @@ class IntEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'IntEvent(data: $data)'; + } } class StringEvent extends PlatformEvent { @@ -143,6 +148,11 @@ class StringEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'StringEvent(data: $data)'; + } } class _PigeonCodec extends StandardMessageCodec { diff --git a/packages/pigeon/example/app/lib/src/messages.g.dart b/packages/pigeon/example/app/lib/src/messages.g.dart index 2a200ae7a8b1..10f648a9f714 100644 --- a/packages/pigeon/example/app/lib/src/messages.g.dart +++ b/packages/pigeon/example/app/lib/src/messages.g.dart @@ -111,18 +111,18 @@ int _deepHash(Object? value) { enum Code { one, two } class MessageData { - MessageData({this.name, this.description, required this.code, required this.data}); + MessageData({this.name, this.messageDescription, required this.code, required this.data}); String? name; - String? description; + String? messageDescription; Code code; Map data; List _toList() { - return [name, description, code, data]; + return [name, messageDescription, code, data]; } Object encode() { @@ -133,7 +133,7 @@ class MessageData { result as List; return MessageData( name: result[0] as String?, - description: result[1] as String?, + messageDescription: result[1] as String?, code: result[2]! as Code, data: (result[3]! as Map).cast(), ); @@ -149,7 +149,7 @@ class MessageData { return true; } return _deepEquals(name, other.name) && - _deepEquals(description, other.description) && + _deepEquals(messageDescription, other.messageDescription) && _deepEquals(code, other.code) && _deepEquals(data, other.data); } @@ -157,6 +157,11 @@ class MessageData { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'MessageData(name: $name, messageDescription: $messageDescription, code: $code, data: $data)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -192,8 +197,8 @@ class _PigeonCodec extends StandardMessageCodec { } class ExampleHostApi { - /// Constructor for [ExampleHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [ExampleHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. ExampleHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/example/app/linux/messages.g.cc b/packages/pigeon/example/app/linux/messages.g.cc index f1b0e818d11f..8d00b5cc1c79 100644 --- a/packages/pigeon/example/app/linux/messages.g.cc +++ b/packages/pigeon/example/app/linux/messages.g.cc @@ -196,12 +196,114 @@ static guint G_GNUC_UNUSED flpigeon_deep_hash(FlValue* value) { } return 0; } +static gchar* G_GNUC_UNUSED flpigeon_to_string(FlValue* value) { + if (value == nullptr) { + return g_strdup("null"); + } + switch (fl_value_get_type(value)) { + case FL_VALUE_TYPE_NULL: + return g_strdup("null"); + case FL_VALUE_TYPE_BOOL: + return g_strdup(fl_value_get_bool(value) ? "true" : "false"); + case FL_VALUE_TYPE_INT: + return g_strdup_printf("%" G_GINT64_FORMAT, fl_value_get_int(value)); + case FL_VALUE_TYPE_FLOAT: + return g_strdup_printf("%g", fl_value_get_float(value)); + case FL_VALUE_TYPE_STRING: + return g_strdup_printf("\"%s\"", fl_value_get_string(value)); + case FL_VALUE_TYPE_UINT8_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const uint8_t* data = fl_value_get_uint8_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_INT32_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const int32_t* data = fl_value_get_int32_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_INT64_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const int64_t* data = fl_value_get_int64_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%" G_GINT64_FORMAT, data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_FLOAT_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const double* data = fl_value_get_float_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%g", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + gchar* item_str = flpigeon_to_string(fl_value_get_list_value(value, i)); + g_string_append(str, item_str); + g_free(item_str); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_MAP: { + GString* str = g_string_new("{"); + size_t len = fl_value_get_length(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + gchar* key_str = flpigeon_to_string(fl_value_get_map_key(value, i)); + gchar* val_str = flpigeon_to_string(fl_value_get_map_value(value, i)); + g_string_append_printf(str, "%s: %s", key_str, val_str); + g_free(key_str); + g_free(val_str); + } + g_string_append(str, "}"); + return g_string_free(str, FALSE); + } + default: + return g_strdup("[custom]"); + } + return g_strdup("null"); +} struct _PigeonExamplePackageMessageData { GObject parent_instance; gchar* name; - gchar* description; + gchar* message_description; PigeonExamplePackageCode code; FlValue* data; }; @@ -213,7 +315,7 @@ static void pigeon_example_package_message_data_dispose(GObject* object) { PigeonExamplePackageMessageData* self = PIGEON_EXAMPLE_PACKAGE_MESSAGE_DATA(object); g_clear_pointer(&self->name, g_free); - g_clear_pointer(&self->description, g_free); + g_clear_pointer(&self->message_description, g_free); g_clear_pointer(&self->data, fl_value_unref); G_OBJECT_CLASS(pigeon_example_package_message_data_parent_class) ->dispose(object); @@ -228,8 +330,8 @@ static void pigeon_example_package_message_data_class_init( } PigeonExamplePackageMessageData* pigeon_example_package_message_data_new( - const gchar* name, const gchar* description, PigeonExamplePackageCode code, - FlValue* data) { + const gchar* name, const gchar* message_description, + PigeonExamplePackageCode code, FlValue* data) { PigeonExamplePackageMessageData* self = PIGEON_EXAMPLE_PACKAGE_MESSAGE_DATA( g_object_new(pigeon_example_package_message_data_get_type(), nullptr)); if (name != nullptr) { @@ -237,10 +339,10 @@ PigeonExamplePackageMessageData* pigeon_example_package_message_data_new( } else { self->name = nullptr; } - if (description != nullptr) { - self->description = g_strdup(description); + if (message_description != nullptr) { + self->message_description = g_strdup(message_description); } else { - self->description = nullptr; + self->message_description = nullptr; } self->code = code; self->data = fl_value_ref(data); @@ -253,10 +355,10 @@ const gchar* pigeon_example_package_message_data_get_name( return self->name; } -const gchar* pigeon_example_package_message_data_get_description( +const gchar* pigeon_example_package_message_data_get_message_description( PigeonExamplePackageMessageData* self) { g_return_val_if_fail(PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_DATA(self), nullptr); - return self->description; + return self->message_description; } PigeonExamplePackageCode pigeon_example_package_message_data_get_code( @@ -278,9 +380,10 @@ static FlValue* pigeon_example_package_message_data_to_list( fl_value_append_take(values, self->name != nullptr ? fl_value_new_string(self->name) : fl_value_new_null()); - fl_value_append_take(values, self->description != nullptr - ? fl_value_new_string(self->description) - : fl_value_new_null()); + fl_value_append_take(values, + self->message_description != nullptr + ? fl_value_new_string(self->message_description) + : fl_value_new_null()); fl_value_append_take(values, fl_value_new_custom(pigeon_example_package_code_type_id, fl_value_new_int(self->code), @@ -297,9 +400,9 @@ pigeon_example_package_message_data_new_from_list(FlValue* values) { name = fl_value_get_string(value0); } FlValue* value1 = fl_value_get_list_value(values, 1); - const gchar* description = nullptr; + const gchar* message_description = nullptr; if (fl_value_get_type(value1) != FL_VALUE_TYPE_NULL) { - description = fl_value_get_string(value1); + message_description = fl_value_get_string(value1); } FlValue* value2 = fl_value_get_list_value(values, 2); PigeonExamplePackageCode code = static_cast( @@ -307,7 +410,8 @@ pigeon_example_package_message_data_new_from_list(FlValue* values) { const_cast(fl_value_get_custom_value(value2))))); FlValue* value3 = fl_value_get_list_value(values, 3); FlValue* data = value3; - return pigeon_example_package_message_data_new(name, description, code, data); + return pigeon_example_package_message_data_new(name, message_description, + code, data); } gboolean pigeon_example_package_message_data_equals( @@ -321,7 +425,7 @@ gboolean pigeon_example_package_message_data_equals( if (g_strcmp0(a->name, b->name) != 0) { return FALSE; } - if (g_strcmp0(a->description, b->description) != 0) { + if (g_strcmp0(a->message_description, b->message_description) != 0) { return FALSE; } if (a->code != b->code) { @@ -338,13 +442,44 @@ guint pigeon_example_package_message_data_hash( g_return_val_if_fail(PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_DATA(self), 0); guint result = 0; result = result * 31 + (self->name != nullptr ? g_str_hash(self->name) : 0); - result = result * 31 + - (self->description != nullptr ? g_str_hash(self->description) : 0); + result = result * 31 + (self->message_description != nullptr + ? g_str_hash(self->message_description) + : 0); result = result * 31 + static_cast(self->code); result = result * 31 + flpigeon_deep_hash(self->data); return result; } +gchar* pigeon_example_package_message_data_to_string( + PigeonExamplePackageMessageData* self) { + g_return_val_if_fail(PIGEON_EXAMPLE_PACKAGE_IS_MESSAGE_DATA(self), NULL); + GString* str = g_string_new("MessageData("); + g_string_append(str, "name: "); + if (self->name != nullptr) { + g_string_append_printf(str, "\"%s\"", self->name); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", message_description: "); + if (self->message_description != nullptr) { + g_string_append_printf(str, "\"%s\"", self->message_description); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", code: "); + g_string_append_printf(str, "%d", static_cast(self->code)); + g_string_append(str, ", data: "); + if (self->data != nullptr) { + gchar* val_str = flpigeon_to_string(self->data); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _PigeonExamplePackageMessageCodec { FlStandardMessageCodec parent_instance; }; diff --git a/packages/pigeon/example/app/linux/messages.g.h b/packages/pigeon/example/app/linux/messages.g.h index c03ecb20a01d..45a903dbb4c2 100644 --- a/packages/pigeon/example/app/linux/messages.g.h +++ b/packages/pigeon/example/app/linux/messages.g.h @@ -34,7 +34,7 @@ G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageData, /** * pigeon_example_package_message_data_new: * name: field in this object. - * description: field in this object. + * message_description: field in this object. * code: field in this object. * data: field in this object. * @@ -43,8 +43,8 @@ G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageData, * Returns: a new #PigeonExamplePackageMessageData */ PigeonExamplePackageMessageData* pigeon_example_package_message_data_new( - const gchar* name, const gchar* description, PigeonExamplePackageCode code, - FlValue* data); + const gchar* name, const gchar* message_description, + PigeonExamplePackageCode code, FlValue* data); /** * pigeon_example_package_message_data_get_name @@ -58,14 +58,14 @@ const gchar* pigeon_example_package_message_data_get_name( PigeonExamplePackageMessageData* object); /** - * pigeon_example_package_message_data_get_description + * pigeon_example_package_message_data_get_message_description * @object: a #PigeonExamplePackageMessageData. * - * Gets the value of the description field of @object. + * Gets the value of the messageDescription field of @object. * * Returns: the field value. */ -const gchar* pigeon_example_package_message_data_get_description( +const gchar* pigeon_example_package_message_data_get_message_description( PigeonExamplePackageMessageData* object); /** @@ -113,6 +113,17 @@ gboolean pigeon_example_package_message_data_equals( guint pigeon_example_package_message_data_hash( PigeonExamplePackageMessageData* object); +/** + * pigeon_example_package_message_data_to_string: + * @object: a #PigeonExamplePackageMessageData. + * + * Returns a string representation of a #PigeonExamplePackageMessageData object. + * + * Returns: (transfer full): a new string, free with g_free(). + */ +gchar* pigeon_example_package_message_data_to_string( + PigeonExamplePackageMessageData* object); + G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageCodec, pigeon_example_package_message_codec, PIGEON_EXAMPLE_PACKAGE, MESSAGE_CODEC, diff --git a/packages/pigeon/example/app/macos/Runner/messages.g.h b/packages/pigeon/example/app/macos/Runner/messages.g.h index c44b9361e8b9..3f08b096986f 100644 --- a/packages/pigeon/example/app/macos/Runner/messages.g.h +++ b/packages/pigeon/example/app/macos/Runner/messages.g.h @@ -30,11 +30,11 @@ typedef NS_ENUM(NSUInteger, PGNCode) { /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithName:(nullable NSString *)name - description:(nullable NSString *)description + messageDescription:(nullable NSString *)messageDescription code:(PGNCode)code data:(NSDictionary *)data; @property(nonatomic, copy, nullable) NSString *name; -@property(nonatomic, copy, nullable) NSString *description; +@property(nonatomic, copy, nullable) NSString *messageDescription; @property(nonatomic, assign) PGNCode code; @property(nonatomic, copy) NSDictionary *data; @end diff --git a/packages/pigeon/example/app/macos/Runner/messages.g.m b/packages/pigeon/example/app/macos/Runner/messages.g.m index ed7655039d25..10334a87e855 100644 --- a/packages/pigeon/example/app/macos/Runner/messages.g.m +++ b/packages/pigeon/example/app/macos/Runner/messages.g.m @@ -144,12 +144,12 @@ + (nullable PGNMessageData *)nullableFromList:(NSArray *)list; @implementation PGNMessageData + (instancetype)makeWithName:(nullable NSString *)name - description:(nullable NSString *)description + messageDescription:(nullable NSString *)messageDescription code:(PGNCode)code data:(NSDictionary *)data { PGNMessageData *pigeonResult = [[PGNMessageData alloc] init]; pigeonResult.name = name; - pigeonResult.description = description; + pigeonResult.messageDescription = messageDescription; pigeonResult.code = code; pigeonResult.data = data; return pigeonResult; @@ -157,7 +157,7 @@ + (instancetype)makeWithName:(nullable NSString *)name + (PGNMessageData *)fromList:(NSArray *)list { PGNMessageData *pigeonResult = [[PGNMessageData alloc] init]; pigeonResult.name = GetNullableObjectAtIndex(list, 0); - pigeonResult.description = GetNullableObjectAtIndex(list, 1); + pigeonResult.messageDescription = GetNullableObjectAtIndex(list, 1); PGNCodeBox *boxedPGNCode = GetNullableObjectAtIndex(list, 2); pigeonResult.code = boxedPGNCode.value; pigeonResult.data = GetNullableObjectAtIndex(list, 3); @@ -169,7 +169,7 @@ + (nullable PGNMessageData *)nullableFromList:(NSArray *)list { - (NSArray *)toList { return @[ self.name ?: [NSNull null], - self.description ?: [NSNull null], + self.messageDescription ?: [NSNull null], [[PGNCodeBox alloc] initWithValue:self.code], self.data ?: [NSNull null], ]; @@ -183,18 +183,23 @@ - (BOOL)isEqual:(id)object { } PGNMessageData *other = (PGNMessageData *)object; return FLTPigeonDeepEquals(self.name, other.name) && - FLTPigeonDeepEquals(self.description, other.description) && self.code == other.code && - FLTPigeonDeepEquals(self.data, other.data); + FLTPigeonDeepEquals(self.messageDescription, other.messageDescription) && + self.code == other.code && FLTPigeonDeepEquals(self.data, other.data); } - (NSUInteger)hash { NSUInteger result = [self class].hash; result = result * 31 + FLTPigeonDeepHash(self.name); - result = result * 31 + FLTPigeonDeepHash(self.description); + result = result * 31 + FLTPigeonDeepHash(self.messageDescription); result = result * 31 + @(self.code).hash; result = result * 31 + FLTPigeonDeepHash(self.data); return result; } +- (NSString *)description { + return [NSString + stringWithFormat:@"PGNMessageData(name: %@, messageDescription: %@, code: %ld, data: %@)", + self.name, self.messageDescription, (long)self.code, self.data]; +} @end @interface PGNMessagesPigeonCodecReader : FlutterStandardReader diff --git a/packages/pigeon/example/app/pigeons/messages.dart b/packages/pigeon/example/app/pigeons/messages.dart index 71aa704f22bf..585fe650e3e7 100644 --- a/packages/pigeon/example/app/pigeons/messages.dart +++ b/packages/pigeon/example/app/pigeons/messages.dart @@ -36,7 +36,7 @@ enum Code { one, two } class MessageData { MessageData({required this.code, required this.data}); String? name; - String? description; + String? messageDescription; Code code; Map data; } diff --git a/packages/pigeon/example/app/windows/runner/messages.g.cpp b/packages/pigeon/example/app/windows/runner/messages.g.cpp index 11453da4e053..a1d349b7a66d 100644 --- a/packages/pigeon/example/app/windows/runner/messages.g.cpp +++ b/packages/pigeon/example/app/windows/runner/messages.g.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace pigeon_example { @@ -238,6 +239,101 @@ size_t PigeonInternalDeepHash(const ::flutter::EncodableValue& v) { return result; } +template +std::string PigeonInternalToString(const T& v); + +std::string PigeonInternalToString(const bool& v); + +template +std::string PigeonInternalToString(const std::vector& v); + +template +std::string PigeonInternalToString(const std::map& v); + +template +std::string PigeonInternalToString(const std::optional& v); + +template +std::string PigeonInternalToString(const std::unique_ptr& v); + +std::string PigeonInternalToString(const ::flutter::EncodableValue& v); + +template +std::string PigeonInternalToString(const T& v) { + std::stringstream ss; + if constexpr (std::is_enum_v) { + ss << static_cast(v); + } else { + ss << v; + } + return ss.str(); +} + +std::string PigeonInternalToString(const bool& v) { + return v ? "true" : "false"; +} + +template +std::string PigeonInternalToString(const std::vector& v) { + std::stringstream ss; + ss << "["; + for (size_t i = 0; i < v.size(); ++i) { + if (i > 0) { + ss << ", "; + } + ss << PigeonInternalToString(v[i]); + } + ss << "]"; + return ss.str(); +} + +template +std::string PigeonInternalToString(const std::map& v) { + std::stringstream ss; + ss << "{"; + bool first = true; + for (const auto& kv : v) { + if (!first) { + ss << ", "; + } + first = false; + ss << PigeonInternalToString(kv.first) << ": " + << PigeonInternalToString(kv.second); + } + ss << "}"; + return ss.str(); +} + +template +std::string PigeonInternalToString(const std::optional& v) { + return v ? PigeonInternalToString(*v) : "null"; +} + +template +std::string PigeonInternalToString(const std::unique_ptr& v) { + return v ? PigeonInternalToString(*v) : "null"; +} + +std::string PigeonInternalToString(const ::flutter::EncodableValue& v) { + return std::visit( + [](const auto& val) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return std::string("null"); + } else if constexpr (std::is_same_v) { + return val ? std::string("true") : std::string("false"); + } else if constexpr (std::is_same_v) { + return "\"" + val + "\""; + } else if constexpr (std::is_same_v) { + return std::string("[custom]"); + } else { + return PigeonInternalToString(val); + } + }, + v); +} + } // namespace // MessageData @@ -245,11 +341,12 @@ MessageData::MessageData(const Code& code, const EncodableMap& data) : code_(code), data_(data) {} MessageData::MessageData(const std::string* name, - const std::string* description, const Code& code, - const EncodableMap& data) + const std::string* message_description, + const Code& code, const EncodableMap& data) : name_(name ? std::optional(*name) : std::nullopt), - description_(description ? std::optional(*description) - : std::nullopt), + message_description_( + message_description ? std::optional(*message_description) + : std::nullopt), code_(code), data_(data) {} @@ -263,17 +360,17 @@ void MessageData::set_name(const std::string_view* value_arg) { void MessageData::set_name(std::string_view value_arg) { name_ = value_arg; } -const std::string* MessageData::description() const { - return description_ ? &(*description_) : nullptr; +const std::string* MessageData::message_description() const { + return message_description_ ? &(*message_description_) : nullptr; } -void MessageData::set_description(const std::string_view* value_arg) { - description_ = +void MessageData::set_message_description(const std::string_view* value_arg) { + message_description_ = value_arg ? std::optional(*value_arg) : std::nullopt; } -void MessageData::set_description(std::string_view value_arg) { - description_ = value_arg; +void MessageData::set_message_description(std::string_view value_arg) { + message_description_ = value_arg; } const Code& MessageData::code() const { return code_; } @@ -288,8 +385,8 @@ EncodableList MessageData::ToEncodableList() const { EncodableList list; list.reserve(4); list.push_back(name_ ? EncodableValue(*name_) : EncodableValue()); - list.push_back(description_ ? EncodableValue(*description_) - : EncodableValue()); + list.push_back(message_description_ ? EncodableValue(*message_description_) + : EncodableValue()); list.push_back(CustomEncodableValue(code_)); list.push_back(EncodableValue(data_)); return list; @@ -303,16 +400,18 @@ MessageData MessageData::FromEncodableList(const EncodableList& list) { if (!encodable_name.IsNull()) { decoded.set_name(std::get(encodable_name)); } - auto& encodable_description = list[1]; - if (!encodable_description.IsNull()) { - decoded.set_description(std::get(encodable_description)); + auto& encodable_message_description = list[1]; + if (!encodable_message_description.IsNull()) { + decoded.set_message_description( + std::get(encodable_message_description)); } return decoded; } bool MessageData::operator==(const MessageData& other) const { return PigeonInternalDeepEquals(name_, other.name_) && - PigeonInternalDeepEquals(description_, other.description_) && + PigeonInternalDeepEquals(message_description_, + other.message_description_) && PigeonInternalDeepEquals(code_, other.code_) && PigeonInternalDeepEquals(data_, other.data_); } @@ -324,12 +423,34 @@ bool MessageData::operator!=(const MessageData& other) const { size_t MessageData::Hash() const { size_t result = 1; result = result * 31 + PigeonInternalDeepHash(name_); - result = result * 31 + PigeonInternalDeepHash(description_); + result = result * 31 + PigeonInternalDeepHash(message_description_); result = result * 31 + PigeonInternalDeepHash(code_); result = result * 31 + PigeonInternalDeepHash(data_); return result; } +std::ostream& operator<<(std::ostream& os, const MessageData& obj) { + os << "MessageData("; + os << "name: "; + if (obj.name_) { + os << PigeonInternalToString(*obj.name_); + } else { + os << "null"; + } + os << ", message_description: "; + if (obj.message_description_) { + os << PigeonInternalToString(*obj.message_description_); + } else { + os << "null"; + } + os << ", code: "; + os << PigeonInternalToString(obj.code_); + os << ", data: "; + os << PigeonInternalToString(obj.data_); + os << ")"; + return os; +} + size_t PigeonInternalDeepHash(const MessageData& v) { return v.Hash(); } PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} diff --git a/packages/pigeon/example/app/windows/runner/messages.g.h b/packages/pigeon/example/app/windows/runner/messages.g.h index b23312baccff..2ad87b1205df 100644 --- a/packages/pigeon/example/app/windows/runner/messages.g.h +++ b/packages/pigeon/example/app/windows/runner/messages.g.h @@ -13,6 +13,7 @@ #include #include +#include #include namespace pigeon_example { @@ -68,16 +69,17 @@ class MessageData { explicit MessageData(const Code& code, const ::flutter::EncodableMap& data); // Constructs an object setting all fields. - explicit MessageData(const std::string* name, const std::string* description, - const Code& code, const ::flutter::EncodableMap& data); + explicit MessageData(const std::string* name, + const std::string* message_description, const Code& code, + const ::flutter::EncodableMap& data); const std::string* name() const; void set_name(const std::string_view* value_arg); void set_name(std::string_view value_arg); - const std::string* description() const; - void set_description(const std::string_view* value_arg); - void set_description(std::string_view value_arg); + const std::string* message_description() const; + void set_message_description(const std::string_view* value_arg); + void set_message_description(std::string_view value_arg); const Code& code() const; void set_code(const Code& value_arg); @@ -90,6 +92,8 @@ class MessageData { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + /// Stream output operator for formatted string representation. + friend std::ostream& operator<<(std::ostream& os, const MessageData& obj); private: static MessageData FromEncodableList(const ::flutter::EncodableList& list); @@ -98,7 +102,7 @@ class MessageData { friend class MessageFlutterApi; friend class PigeonInternalCodecSerializer; std::optional name_; - std::optional description_; + std::optional message_description_; Code code_; ::flutter::EncodableMap data_; }; diff --git a/packages/pigeon/lib/src/cpp/cpp_generator.dart b/packages/pigeon/lib/src/cpp/cpp_generator.dart index 73abb6e6ffbf..36bc99653a12 100644 --- a/packages/pigeon/lib/src/cpp/cpp_generator.dart +++ b/packages/pigeon/lib/src/cpp/cpp_generator.dart @@ -212,7 +212,7 @@ class CppHeaderGenerator extends StructuredGenerator { 'flutter/standard_message_codec.h', ]); indent.newln(); - _writeSystemHeaderIncludeBlock(indent, ['map', 'string', 'optional']); + _writeSystemHeaderIncludeBlock(indent, ['map', 'string', 'optional', 'ostream']); indent.newln(); if (generatorOptions.namespace != null) { indent.writeln('namespace ${generatorOptions.namespace} {'); @@ -439,6 +439,10 @@ class CppHeaderGenerator extends StructuredGenerator { '/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.', ); _writeFunctionDeclaration(indent, 'Hash', returnType: 'size_t', isConst: true); + indent.writeln('/// Stream output operator for formatted string representation.'); + indent.writeln( + 'friend std::ostream& operator<<(std::ostream& os, const ${classDefinition.name}& obj);', + ); }); _writeAccessBlock(indent, _ClassAccess.private, () { @@ -872,6 +876,7 @@ class CppSourceGenerator extends StructuredGenerator { 'map', 'string', 'optional', + 'sstream', ]); indent.newln(); } @@ -923,6 +928,7 @@ class CppSourceGenerator extends StructuredGenerator { indent.writeln('namespace {'); _writeDeepEquals(indent); _writeDeepHash(indent); + _writeDeepToString(indent); indent.writeln('} // namespace'); } @@ -1028,6 +1034,41 @@ class CppSourceGenerator extends StructuredGenerator { }, ); + _writeFunctionDefinition( + indent, + 'operator<<', + returnType: 'std::ostream&', + parameters: ['std::ostream& os', 'const ${classDefinition.name}& obj'], + body: () { + indent.writeln('os << "${classDefinition.name}(";'); + enumerate(orderedFields, (int index, NamedType field) { + final name = 'obj.${_makeInstanceVariableName(field)}'; + final comma = index == 0 ? '' : ', '; + indent.writeln('os << "$comma${_makeVariableName(field)}: ";'); + if (field.type.isNullable) { + indent.writeScoped('if ($name) {', '}', () { + if (field.type.isClass) { + indent.writeln('os << *$name;'); + } else { + indent.writeln('os << PigeonInternalToString(*$name);'); + } + }); + indent.writeScoped('else {', '}', () { + indent.writeln('os << "null";'); + }); + } else { + if (field.type.isClass) { + indent.writeln('os << $name;'); + } else { + indent.writeln('os << PigeonInternalToString($name);'); + } + } + }); + indent.writeln('os << ")";'); + indent.writeln('return os;'); + }, + ); + _writeFunctionDefinition( indent, 'PigeonInternalDeepHash', @@ -1240,6 +1281,103 @@ size_t PigeonInternalDeepHash(const ::flutter::EncodableValue& v) { '''); } + void _writeDeepToString(Indent indent) { + indent.format(r''' +template +std::string PigeonInternalToString(const T& v); + +std::string PigeonInternalToString(const bool& v); + +template +std::string PigeonInternalToString(const std::vector& v); + +template +std::string PigeonInternalToString(const std::map& v); + +template +std::string PigeonInternalToString(const std::optional& v); + +template +std::string PigeonInternalToString(const std::unique_ptr& v); + +std::string PigeonInternalToString(const ::flutter::EncodableValue& v); + +template +std::string PigeonInternalToString(const T& v) { + std::stringstream ss; + if constexpr (std::is_enum_v) { + ss << static_cast(v); + } else { + ss << v; + } + return ss.str(); +} + +std::string PigeonInternalToString(const bool& v) { + return v ? "true" : "false"; +} + +template +std::string PigeonInternalToString(const std::vector& v) { + std::stringstream ss; + ss << "["; + for (size_t i = 0; i < v.size(); ++i) { + if (i > 0) { + ss << ", "; + } + ss << PigeonInternalToString(v[i]); + } + ss << "]"; + return ss.str(); +} + +template +std::string PigeonInternalToString(const std::map& v) { + std::stringstream ss; + ss << "{"; + bool first = true; + for (const auto& kv : v) { + if (!first) { + ss << ", "; + } + first = false; + ss << PigeonInternalToString(kv.first) << ": " << PigeonInternalToString(kv.second); + } + ss << "}"; + return ss.str(); +} + +template +std::string PigeonInternalToString(const std::optional& v) { + return v ? PigeonInternalToString(*v) : "null"; +} + +template +std::string PigeonInternalToString(const std::unique_ptr& v) { + return v ? PigeonInternalToString(*v) : "null"; +} + +std::string PigeonInternalToString(const ::flutter::EncodableValue& v) { + return std::visit( + [](const auto& val) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return std::string("null"); + } else if constexpr (std::is_same_v) { + return val ? std::string("true") : std::string("false"); + } else if constexpr (std::is_same_v) { + return "\"" + val + "\""; + } else if constexpr (std::is_same_v) { + return std::string("[custom]"); + } else { + return PigeonInternalToString(val); + } + }, + v); +} +'''); + } + @override void writeClassEncode( InternalCppOptions generatorOptions, diff --git a/packages/pigeon/lib/src/dart/dart_generator.dart b/packages/pigeon/lib/src/dart/dart_generator.dart index 8a73d81edda8..ae0614a4a788 100644 --- a/packages/pigeon/lib/src/dart/dart_generator.dart +++ b/packages/pigeon/lib/src/dart/dart_generator.dart @@ -355,6 +355,16 @@ class DartGenerator extends StructuredGenerator { indent.writeln('@override'); indent.writeln('// ignore: avoid_equals_and_hash_code_on_mutable_classes'); indent.writeln('int get hashCode => _deepHash([runtimeType, ..._toList()]);'); + + indent.newln(); + indent.writeln('@override'); + indent.writeScoped('String toString() {', '}', () { + final Iterable fields = getFieldsInSerializationOrder(classDefinition); + final Iterable fieldStrings = fields.map((NamedType field) { + return '${field.name}: \$${field.name}'; + }); + indent.writeln("return '${classDefinition.name}(${fieldStrings.join(', ')})';"); + }); } @override @@ -577,8 +587,8 @@ class DartGenerator extends StructuredGenerator { indent.write('class ${api.name} '); indent.addScoped('{', '}', () { indent.format(''' -/// Constructor for [${api.name}]. The [binaryMessenger] named argument is -/// available for dependency injection. If it is left null, the default +/// Constructor for [${api.name}]. The [binaryMessenger] named argument is +/// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. ${api.name}({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : ${varNamePrefix}binaryMessenger = binaryMessenger, @@ -1139,7 +1149,7 @@ Object? _extractReplyValueOrThrow( \t\t\tdetails: replyList[2], \t\t);'''); // On iOS we can return nil from functions to accommodate error - // handling. Returning a nil value and not returning an error is an + // handling. Returning a nil value and not returning an error is an // exception. indent.format(''' \t} else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { diff --git a/packages/pigeon/lib/src/functional.dart b/packages/pigeon/lib/src/functional.dart index 7ec9fd4eef3e..e3b0e904afb8 100644 --- a/packages/pigeon/lib/src/functional.dart +++ b/packages/pigeon/lib/src/functional.dart @@ -21,7 +21,7 @@ void enumerate(Iterable iterable, void Function(int, T) func) { } } -/// A [map] function that takes in 2 iterables. The [Iterable]s must be of +/// A [map] function that takes in 2 iterables. The [Iterable]s must be of /// equal length. Iterable map2(Iterable ts, Iterable us, V Function(T t, U u) func) sync* { final Iterator itt = ts.iterator; @@ -34,7 +34,7 @@ Iterable map2(Iterable ts, Iterable us, V Function(T t, U u) f } } -/// A [map] function that takes in 3 iterables. The [Iterable]s must be of +/// A [map] function that takes in 3 iterables. The [Iterable]s must be of /// equal length. Iterable map3( Iterable ts, diff --git a/packages/pigeon/lib/src/generator_tools.dart b/packages/pigeon/lib/src/generator_tools.dart index 072b895eeddb..8ab2bbb4031b 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.3.4'; +const String pigeonVersion = '27.0.0'; /// Default plugin package name. const String defaultPluginPackageName = 'dev.flutter.pigeon'; diff --git a/packages/pigeon/lib/src/gobject/gobject_generator.dart b/packages/pigeon/lib/src/gobject/gobject_generator.dart index 8c3fa23481c8..ce01cfccdfa1 100644 --- a/packages/pigeon/lib/src/gobject/gobject_generator.dart +++ b/packages/pigeon/lib/src/gobject/gobject_generator.dart @@ -5,6 +5,7 @@ import 'package:path/path.dart' as path; import '../ast.dart'; +import '../functional.dart'; import '../generator.dart'; import '../generator_tools.dart'; @@ -328,6 +329,17 @@ class GObjectHeaderGenerator extends StructuredGenerator 'Returns: the hash code.', ], _docCommentSpec); indent.writeln('guint ${methodPrefix}_hash($className* object);'); + + indent.newln(); + addDocumentationComments(indent, [ + '${methodPrefix}_to_string:', + '@object: a #$className.', + '', + 'Returns a string representation of a #$className object.', + '', + 'Returns: (transfer full): a new string, free with g_free().', + ], _docCommentSpec); + indent.writeln('gchar* ${methodPrefix}_to_string($className* object);'); } @override @@ -781,6 +793,7 @@ class GObjectSourceGenerator extends StructuredGenerator _writeHashHelpers(indent); _writeDeepEquals(indent); _writeDeepHash(indent); + _writeDeepToString(indent); } @override @@ -1195,6 +1208,133 @@ class GObjectSourceGenerator extends StructuredGenerator } indent.writeln('return result;'); }); + + indent.newln(); + indent.writeScoped('gchar* ${methodPrefix}_to_string($className* self) {', '}', () { + indent.writeln('g_return_val_if_fail($testMacro(self), NULL);'); + indent.writeln('GString* str = g_string_new("${classDefinition.name}(");'); + + enumerate(classDefinition.fields, (int index, NamedType field) { + final String fieldName = _getFieldName(field.name); + final comma = index == 0 ? '' : ', '; + indent.writeln('g_string_append(str, "$comma${_getFieldName(field.name)}: ");'); + + if (field.type.isClass) { + final String fieldMethodPrefix = _getMethodPrefix(module, field.type.baseName); + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln( + 'gchar* field_str = ${fieldMethodPrefix}_to_string(self->$fieldName);', + ); + indent.writeln('g_string_append(str, field_str);'); + indent.writeln('g_free(field_str);'); + }, + ); + } else if (field.type.baseName == 'String') { + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln('g_string_append_printf(str, "\\"%s\\"", self->$fieldName);'); + }, + ); + } else if (field.type.isEnum) { + if (field.type.isNullable) { + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln( + 'g_string_append_printf(str, "%d", static_cast(*self->$fieldName));', + ); + }, + ); + } else { + indent.writeln( + 'g_string_append_printf(str, "%d", static_cast(self->$fieldName));', + ); + } + } else if (_isNumericListType(field.type)) { + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln('g_string_append(str, "[");'); + indent.writeln('size_t len = self->${fieldName}_length;'); + final String elementTypeName = _getType(module, field.type, isElementType: true); + indent.writeln('const $elementTypeName* data = self->$fieldName;'); + indent.writeScoped('for (size_t i = 0; i < len; i++) {', '}', () { + indent.writeScoped('if (i > 0) {', '}', () { + indent.writeln('g_string_append(str, ", ");'); + }); + if (field.type.baseName == 'Int64List') { + indent.writeln('g_string_append_printf(str, "%" G_GINT64_FORMAT, data[i]);'); + } else if (field.type.baseName == 'Float32List' || + field.type.baseName == 'Float64List') { + indent.writeln('g_string_append_printf(str, "%g", data[i]);'); + } else { + indent.writeln('g_string_append_printf(str, "%d", static_cast(data[i]));'); + } + }); + indent.writeln('g_string_append(str, "]");'); + }, + ); + } else if (field.type.baseName == 'bool') { + if (field.type.isNullable) { + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln('g_string_append(str, *self->$fieldName ? "true" : "false");'); + }, + ); + } else { + indent.writeln('g_string_append(str, self->$fieldName ? "true" : "false");'); + } + } else if (field.type.baseName == 'int') { + if (field.type.isNullable) { + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln( + 'g_string_append_printf(str, "%" G_GINT64_FORMAT, *self->$fieldName);', + ); + }, + ); + } else { + indent.writeln('g_string_append_printf(str, "%" G_GINT64_FORMAT, self->$fieldName);'); + } + } else if (field.type.baseName == 'double') { + if (field.type.isNullable) { + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln('g_string_append_printf(str, "%g", *self->$fieldName);'); + }, + ); + } else { + indent.writeln('g_string_append_printf(str, "%g", self->$fieldName);'); + } + } else { + _writeAppendValueOrNull( + indent, + fieldName: fieldName, + nonNullBuilder: () { + indent.writeln('gchar* val_str = flpigeon_to_string(self->$fieldName);'); + indent.writeln('g_string_append(str, val_str);'); + indent.writeln('g_free(val_str);'); + }, + ); + } + }); + + indent.writeln('g_string_append(str, ")");'); + indent.writeln('return g_string_free(str, FALSE);'); + }); } @override @@ -2695,3 +2835,121 @@ void _writeDeepHash(Indent indent) { indent.writeln('return 0;'); }); } + +void _writeDeepToString(Indent indent) { + indent.format(r''' +static gchar* G_GNUC_UNUSED flpigeon_to_string(FlValue* value) { + if (value == nullptr) { + return g_strdup("null"); + } + switch (fl_value_get_type(value)) { + case FL_VALUE_TYPE_NULL: + return g_strdup("null"); + case FL_VALUE_TYPE_BOOL: + return g_strdup(fl_value_get_bool(value) ? "true" : "false"); + case FL_VALUE_TYPE_INT: + return g_strdup_printf("%" G_GINT64_FORMAT, fl_value_get_int(value)); + case FL_VALUE_TYPE_FLOAT: + return g_strdup_printf("%g", fl_value_get_float(value)); + case FL_VALUE_TYPE_STRING: + return g_strdup_printf("\"%s\"", fl_value_get_string(value)); + case FL_VALUE_TYPE_UINT8_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const uint8_t* data = fl_value_get_uint8_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_INT32_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const int32_t* data = fl_value_get_int32_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_INT64_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const int64_t* data = fl_value_get_int64_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%" G_GINT64_FORMAT, data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_FLOAT_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const double* data = fl_value_get_float_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%g", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + gchar* item_str = flpigeon_to_string(fl_value_get_list_value(value, i)); + g_string_append(str, item_str); + g_free(item_str); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_MAP: { + GString* str = g_string_new("{"); + size_t len = fl_value_get_length(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + gchar* key_str = flpigeon_to_string(fl_value_get_map_key(value, i)); + gchar* val_str = flpigeon_to_string(fl_value_get_map_value(value, i)); + g_string_append_printf(str, "%s: %s", key_str, val_str); + g_free(key_str); + g_free(val_str); + } + g_string_append(str, "}"); + return g_string_free(str, FALSE); + } + default: + return g_strdup("[custom]"); + } + return g_strdup("null"); +} +'''); +} + +void _writeAppendValueOrNull( + Indent indent, { + required String fieldName, + required void Function() nonNullBuilder, +}) { + indent.writeScoped('if (self->$fieldName != nullptr) {', '}', nonNullBuilder); + indent.writeScoped('else {', '}', () { + indent.writeln('g_string_append(str, "null");'); + }); +} diff --git a/packages/pigeon/lib/src/java/java_generator.dart b/packages/pigeon/lib/src/java/java_generator.dart index c77de76650d3..f37769520866 100644 --- a/packages/pigeon/lib/src/java/java_generator.dart +++ b/packages/pigeon/lib/src/java/java_generator.dart @@ -271,6 +271,7 @@ class JavaGenerator extends StructuredGenerator { indent.newln(); } _writeEquality(indent, classDefinition); + _writeToString(indent, classDefinition); _writeClassBuilder(generatorOptions, root, indent, classDefinition); writeClassEncode( @@ -368,6 +369,30 @@ class JavaGenerator extends StructuredGenerator { indent.newln(); } + void _writeToString(Indent indent, Class classDefinition) { + indent.writeln('@Override'); + indent.writeScoped('public String toString() {', '}', () { + final Iterable fieldStrings = classDefinition.fields.map((NamedType field) { + final String fieldName = field.name; + if (field.type.baseName == 'Uint8List' || + field.type.baseName == 'Int32List' || + field.type.baseName == 'Int64List' || + field.type.baseName == 'Float64List') { + return '"$fieldName=" + java.util.Arrays.toString($fieldName)'; + } + return '"$fieldName=" + $fieldName'; + }); + if (fieldStrings.isEmpty) { + indent.writeln('return "${classDefinition.name}{}";'); + } else { + indent.writeln( + 'return "${classDefinition.name}{" + ${fieldStrings.join(' + ", " + ')} + "}";', + ); + } + }); + indent.newln(); + } + void _writeDeepEquals(Indent indent) { indent.writeScoped('static boolean pigeonDeepEquals(Object a, Object b) {', '}', () { indent.writeln('if (a == b) { return true; }'); diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 5319f5568d5f..91b605fc78fe 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -322,6 +322,13 @@ class KotlinGenerator extends StructuredGenerator { classDefinition, dartPackageName: dartPackageName, ); + writeClassToString( + generatorOptions, + root, + indent, + classDefinition, + dartPackageName: dartPackageName, + ); }); } @@ -366,6 +373,30 @@ class KotlinGenerator extends StructuredGenerator { }); } + /// Writes the `toString` method for a class. + void writeClassToString( + InternalKotlinOptions generatorOptions, + Root root, + Indent indent, + Class classDefinition, { + required String dartPackageName, + }) { + indent.writeScoped('override fun toString(): String {', '}', () { + final Iterable fieldStrings = classDefinition.fields.map((NamedType field) { + final String name = field.name; + if (field.type.baseName == 'Uint8List' || + field.type.baseName == 'Int32List' || + field.type.baseName == 'Int64List' || + field.type.baseName == 'Float64List') { + final nullSafe = field.type.isNullable ? '?' : ''; + return '$name=\${$name$nullSafe.contentToString()}'; + } + return '$name=\$$name'; + }); + indent.writeln('return "${classDefinition.name}(${fieldStrings.join(', ')})"'); + }); + } + void _writeDataClassSignature(Indent indent, Class classDefinition, {bool private = false}) { final privateString = private ? 'private ' : ''; final classType = classDefinition.isSealed ? 'sealed' : 'data'; diff --git a/packages/pigeon/lib/src/kotlin/templates.dart b/packages/pigeon/lib/src/kotlin/templates.dart index d8a7b9141d0b..af0ce6abbd6f 100644 --- a/packages/pigeon/lib/src/kotlin/templates.dart +++ b/packages/pigeon/lib/src/kotlin/templates.dart @@ -37,7 +37,7 @@ String instanceManagerTemplate(InternalKotlinOptions options) { */ @Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") class ${kotlinInstanceManagerClassName(options)}(private val finalizationListener: $_finalizationListenerClassName) { - /** Interface for listening when a weak reference of an instance is removed from the manager. */ + /** Interface for listening when a weak reference of an instance is removed from the manager. */ interface $_finalizationListenerClassName { fun onFinalize(identifier: Long) } diff --git a/packages/pigeon/lib/src/objc/objc_generator.dart b/packages/pigeon/lib/src/objc/objc_generator.dart index fb975935b7b0..9751b5f8e9f3 100644 --- a/packages/pigeon/lib/src/objc/objc_generator.dart +++ b/packages/pigeon/lib/src/objc/objc_generator.dart @@ -535,6 +535,7 @@ class ObjcSourceGenerator extends StructuredGenerator { dartPackageName: dartPackageName, ); _writeObjcEquality(generatorOptions, indent, classDefinition); + _writeObjcDescription(generatorOptions, indent, classDefinition); indent.writeln('@end'); indent.newln(); } @@ -593,6 +594,53 @@ class ObjcSourceGenerator extends StructuredGenerator { }); } + void _writeObjcDescription( + InternalObjcOptions languageOptions, + Indent indent, + Class classDefinition, + ) { + final String className = _className(languageOptions.prefix, classDefinition.name); + indent.writeScoped('- (NSString *)description {', '}', () { + final Iterable fieldLabels = classDefinition.fields.map((NamedType field) { + if (_usesPrimitive(field.type)) { + if (field.type.isEnum) { + return '${field.name}: %ld'; + } + switch (field.type.baseName) { + case 'bool': + return '${field.name}: %@'; + case 'int': + return '${field.name}: %ld'; + case 'double': + return '${field.name}: %f'; + } + } + return '${field.name}: %@'; + }); + final formatString = '$className(${fieldLabels.join(', ')})'; + + final Iterable fieldValues = classDefinition.fields.map((NamedType field) { + if (_usesPrimitive(field.type)) { + if (field.type.isEnum) { + return '(long)self.${field.name}'; + } + switch (field.type.baseName) { + case 'bool': + return 'self.${field.name} ? @"true" : @"false"'; + case 'int': + return '(long)self.${field.name}'; + case 'double': + return 'self.${field.name}'; + } + } + return 'self.${field.name}'; + }); + + final String args = ['@"$formatString"', ...fieldValues].join(', '); + indent.writeln('return [NSString stringWithFormat:$args];'); + }); + } + @override void writeClassEncode( InternalObjcOptions generatorOptions, @@ -1677,7 +1725,7 @@ String _propertyTypeForDartType( String _capitalize(String str) => str.isEmpty ? '' : str[0].toUpperCase() + str.substring(1); /// Returns the components of the objc selector that will be generated from -/// [func], ie the strings between the semicolons. [lastSelectorComponent] is +/// [func], ie the strings between the semicolons. [lastSelectorComponent] is /// the last component of the selector aka the label of the last parameter which /// isn't included in [func]. /// Example: @@ -1705,13 +1753,13 @@ Iterable _getSelectorComponents(Method func, String lastSelectorComponen } } -/// Generates the objc source code method signature for [func]. [returnType] is +/// Generates the objc source code method signature for [func]. [returnType] is /// the return value of method, this may not match the return value in [func] -/// since [func] may be asynchronous. The function requires you specify a +/// since [func] may be asynchronous. The function requires you specify a /// [lastArgType] and [lastArgName] for arguments that aren't represented in -/// [func]. This is typically used for passing in 'error' or 'completion' +/// [func]. This is typically used for passing in 'error' or 'completion' /// arguments that don't exist in the pigeon file but are required in the objc -/// output. [argNameFunc] is the function used to generate the argument name +/// output. [argNameFunc] is the function used to generate the argument name /// [func.parameters]. String _makeObjcSignature({ required Method func, diff --git a/packages/pigeon/lib/src/pigeon_cl.dart b/packages/pigeon/lib/src/pigeon_cl.dart index 9548d968986c..dd0cd272079b 100644 --- a/packages/pigeon/lib/src/pigeon_cl.dart +++ b/packages/pigeon/lib/src/pigeon_cl.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'pigeon_lib.dart'; -/// This is the main entrypoint for the command-line tool. [args] are the +/// This is the main entrypoint for the command-line tool. [args] are the /// command line arguments and there is an optional [packageConfig] to /// accommodate users that want to integrate pigeon with other build systems. /// [sdkPath] for specifying an optional Dart SDK path. diff --git a/packages/pigeon/lib/src/pigeon_lib.dart b/packages/pigeon/lib/src/pigeon_lib.dart index f844a052566d..0df84a8eb6a5 100644 --- a/packages/pigeon/lib/src/pigeon_lib.dart +++ b/packages/pigeon/lib/src/pigeon_lib.dart @@ -108,7 +108,7 @@ class HostApi { /// to specify where to generate the test file. /// /// Prefer to use a mock of the real [HostApi] with a mocking library for unit - /// tests. Generating this Dart handler is sometimes useful in integration + /// tests. Generating this Dart handler is sometimes useful in integration /// testing. /// /// Defaults to `null` in which case no handler will be generated. @@ -588,7 +588,7 @@ ${_argParser.usage}'''; /// Convert command-line arguments to [PigeonOptions]. static PigeonOptions parseArgs(List args) { // Note: This function shouldn't perform any logic, just translate the args - // to PigeonOptions. Synthesized values inside of the PigeonOption should + // to PigeonOptions. Synthesized values inside of the PigeonOption should // get set in the `run` function to accommodate users that are using the // `configurePigeon` function. final ArgResults results = _argParser.parse(args); @@ -645,8 +645,8 @@ ${_argParser.usage}'''; } } - /// The 'main' entrypoint used by the command-line tool. [args] are the - /// command-line arguments. The optional parameter [adapters] allows you to + /// The 'main' entrypoint used by the command-line tool. [args] are the + /// command-line arguments. The optional parameter [adapters] allows you to /// customize the generators that pigeon will use. The optional parameter /// [sdkPath] allows you to specify the Dart SDK path. static Future run(List args, {List? adapters, String? sdkPath}) { @@ -654,8 +654,8 @@ ${_argParser.usage}'''; return runWithOptions(options, adapters: adapters, sdkPath: sdkPath); } - /// The 'main' entrypoint used by external packages. [options] is - /// used when running the code generator. The optional parameter [adapters] allows you to + /// The 'main' entrypoint used by external packages. [options] is + /// used when running the code generator. The optional parameter [adapters] allows you to /// customize the generators that pigeon will use. The optional parameter /// [sdkPath] allows you to specify the Dart SDK path. static Future runWithOptions( diff --git a/packages/pigeon/lib/src/pigeon_lib_internal.dart b/packages/pigeon/lib/src/pigeon_lib_internal.dart index dcb7aa5362ae..b9607e12f528 100644 --- a/packages/pigeon/lib/src/pigeon_lib_internal.dart +++ b/packages/pigeon/lib/src/pigeon_lib_internal.dart @@ -413,7 +413,22 @@ class SwiftGeneratorAdapter implements GeneratorAdapter { _openSink(options.swiftOptions?.swiftOut, basePath: options.basePath ?? ''); @override - List validate(InternalPigeonOptions options, Root root) => []; + List validate(InternalPigeonOptions options, Root root) { + final errors = []; + for (final Class classDefinition in root.classes) { + for (final NamedType field in classDefinition.fields) { + if (field.name == 'description') { + errors.add( + Error( + message: + 'Field "description" is not allowed in class "${classDefinition.name}" because it conflicts with Swift\'s NSObject/CustomStringConvertible.description property.', + ), + ); + } + } + } + return errors; + } } /// A [GeneratorAdapter] that generates C++ source code. diff --git a/packages/pigeon/lib/src/swift/swift_generator.dart b/packages/pigeon/lib/src/swift/swift_generator.dart index c4e659210feb..be2c096e1f80 100644 --- a/packages/pigeon/lib/src/swift/swift_generator.dart +++ b/packages/pigeon/lib/src/swift/swift_generator.dart @@ -389,13 +389,21 @@ class SwiftGenerator extends StructuredGenerator { Class classDefinition, { bool private = false, bool hashable = true, + bool customStringConvertible = true, }) { final privateString = private ? 'private ' : ''; - final extendsString = classDefinition.superClass != null - ? ': ${classDefinition.superClass!.name}' - : hashable - ? ': Hashable' - : ''; + final protocols = []; + if (classDefinition.superClass != null) { + protocols.add(classDefinition.superClass!.name); + } else { + if (hashable) { + protocols.add('Hashable'); + } + if (customStringConvertible) { + protocols.add('CustomStringConvertible'); + } + } + final extendsString = protocols.isEmpty ? '' : ': ${protocols.join(', ')}'; if (classDefinition.isSwiftClass) { indent.write('${privateString}class ${classDefinition.name}$extendsString '); } else if (classDefinition.isSealed) { @@ -438,7 +446,13 @@ class SwiftGenerator extends StructuredGenerator { final overflowFields = [overflowInt, overflowObject]; final overflowClass = Class(name: _overflowClassName, fields: overflowFields); indent.newln(); - _writeDataClassSignature(indent, overflowClass, private: true, hashable: false); + _writeDataClassSignature( + indent, + overflowClass, + private: true, + hashable: false, + customStringConvertible: false, + ); indent.addScoped('', '}', () { writeClassEncode( generatorOptions, @@ -537,6 +551,14 @@ if (wrapped == nil) { classDefinition, dartPackageName: dartPackageName, ); + indent.newln(); + writeClassToString( + generatorOptions, + root, + indent, + classDefinition, + dartPackageName: dartPackageName, + ); }); } @@ -618,7 +640,7 @@ if (wrapped == nil) { final String comparisons = fields .map( (NamedType field) => - 'deepEquals${generatorOptions.fileSpecificClassNameComponent ?? ''}(lhs.${field.name}, rhs.${field.name})', + '${generatorOptions.fileSpecificClassNameComponent ?? ''}PigeonInternal.deepEquals(lhs.${field.name}, rhs.${field.name})', ) .join(' && '); indent.writeln('return $comparisons'); @@ -632,12 +654,31 @@ if (wrapped == nil) { final Iterable fields = getFieldsInSerializationOrder(classDefinition); for (final field in fields) { indent.writeln( - 'deepHash${generatorOptions.fileSpecificClassNameComponent ?? ''}(value: ${field.name}, hasher: &hasher)', + '${generatorOptions.fileSpecificClassNameComponent ?? ''}PigeonInternal.deepHash(value: ${field.name}, hasher: &hasher)', ); } }); } + /// Writes the `CustomStringConvertible` conformance for a class. + void writeClassToString( + InternalSwiftOptions generatorOptions, + Root root, + Indent indent, + Class classDefinition, { + required String dartPackageName, + }) { + final overrideString = (classDefinition.superClass != null && classDefinition.isSwiftClass) + ? 'override ' + : ''; + indent.writeScoped('${overrideString}public var description: String {', '}', () { + final Iterable fieldStrings = classDefinition.fields.map((NamedType field) { + return '${field.name}: \\(String(describing: ${field.name}))'; + }); + indent.writeln('return "${classDefinition.name}(${fieldStrings.join(', ')})"'); + }); + } + @override void writeClassDecode( InternalSwiftOptions generatorOptions, @@ -712,6 +753,7 @@ if (wrapped == nil) { AstFlutterApi api, { required String dartPackageName, }) { + indent.newln(); const generatedComments = [ ' Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.', ]; @@ -1286,12 +1328,19 @@ if (wrapped == nil) { } } - void _writeIsNullish(Indent indent) { - indent.newln(); - indent.write('private func isNullish(_ value: Any?) -> Bool '); - indent.addScoped('{', '}', () { - indent.writeln('return value is NSNull || value == nil'); - }); + void _writeIsNullish(InternalSwiftOptions generatorOptions, Indent indent) { + indent.format(''' +static func isNullish(_ value: Any?) -> Bool { + guard let innerValue = value else { + return true + } + + if case Optional.some(Optional.none) = value { + return true + } + + return innerValue is NSNull +}'''); } void _writeWrapResult(Indent indent) { @@ -1357,16 +1406,12 @@ private func nilOrValue(_ value: Any?) -> T? { } void _writeDeepEquals(InternalSwiftOptions generatorOptions, Indent indent) { - final deepEqualsName = 'deepEquals${generatorOptions.fileSpecificClassNameComponent ?? ''}'; - final deepHashName = 'deepHash${generatorOptions.fileSpecificClassNameComponent ?? ''}'; - final doubleEqualsName = 'doubleEquals${generatorOptions.fileSpecificClassNameComponent ?? ''}'; - final doubleHashName = 'doubleHash${generatorOptions.fileSpecificClassNameComponent ?? ''}'; indent.format(''' -private func $doubleEqualsName(_ lhs: Double, _ rhs: Double) -> Bool { +static func doubleEquals(_ lhs: Double, _ rhs: Double) -> Bool { return (lhs.isNaN && rhs.isNaN) || lhs == rhs } -private func $doubleHashName(_ value: Double, _ hasher: inout Hasher) { +static func doubleHash(_ value: Double, _ hasher: inout Hasher) { if value.isNaN { hasher.combine(0x7FF8000000000000) } else { @@ -1375,7 +1420,7 @@ private func $doubleHashName(_ value: Double, _ hasher: inout Hasher) { } } -func $deepEqualsName(_ lhs: Any?, _ rhs: Any?) -> Bool { +static func deepEquals(_ lhs: Any?, _ rhs: Any?) -> Bool { let cleanLhs = nilOrValue(lhs) as Any? let cleanRhs = nilOrValue(rhs) as Any? switch (cleanLhs, cleanRhs) { @@ -1394,7 +1439,7 @@ func $deepEqualsName(_ lhs: Any?, _ rhs: Any?) -> Bool { case (let lhsArray, let rhsArray) as ([Any?], [Any?]): guard lhsArray.count == rhsArray.count else { return false } for (index, element) in lhsArray.enumerated() { - if !$deepEqualsName(element, rhsArray[index]) { + if !deepEquals(element, rhsArray[index]) { return false } } @@ -1403,7 +1448,7 @@ func $deepEqualsName(_ lhs: Any?, _ rhs: Any?) -> Bool { case (let lhsArray, let rhsArray) as ([Double], [Double]): guard lhsArray.count == rhsArray.count else { return false } for (index, element) in lhsArray.enumerated() { - if !$doubleEqualsName(element, rhsArray[index]) { + if !doubleEquals(element, rhsArray[index]) { return false } } @@ -1414,8 +1459,8 @@ func $deepEqualsName(_ lhs: Any?, _ rhs: Any?) -> Bool { for (lhsKey, lhsValue) in lhsDictionary { var found = false for (rhsKey, rhsValue) in rhsDictionary { - if $deepEqualsName(lhsKey, rhsKey) { - if $deepEqualsName(lhsValue, rhsValue) { + if deepEquals(lhsKey, rhsKey) { + if deepEquals(lhsValue, rhsValue) { found = true break } else { @@ -1428,7 +1473,7 @@ func $deepEqualsName(_ lhs: Any?, _ rhs: Any?) -> Bool { return true case (let lhs as Double, let rhs as Double): - return $doubleEqualsName(lhs, rhs) + return doubleEquals(lhs, rhs) case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): return lhsHashable == rhsHashable @@ -1438,26 +1483,26 @@ func $deepEqualsName(_ lhs: Any?, _ rhs: Any?) -> Bool { } } -func $deepHashName(value: Any?, hasher: inout Hasher) { +static func deepHash(value: Any?, hasher: inout Hasher) { let cleanValue = nilOrValue(value) as Any? if let cleanValue = cleanValue { if let doubleValue = cleanValue as? Double { - $doubleHashName(doubleValue, &hasher) + doubleHash(doubleValue, &hasher) } else if let valueList = cleanValue as? [Any?] { for item in valueList { - $deepHashName(value: item, hasher: &hasher) + deepHash(value: item, hasher: &hasher) } } else if let valueList = cleanValue as? [Double] { for item in valueList { - $doubleHashName(item, &hasher) + doubleHash(item, &hasher) } } else if let valueDict = cleanValue as? [AnyHashable: Any?] { var result = 0 for (key, value) in valueDict { var entryKeyHasher = Hasher() - $deepHashName(value: key, hasher: &entryKeyHasher) + deepHash(value: key, hasher: &entryKeyHasher) var entryValueHasher = Hasher() - $deepHashName(value: value, hasher: &entryValueHasher) + deepHash(value: value, hasher: &entryValueHasher) result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) } hasher.combine(result) @@ -1473,6 +1518,17 @@ func $deepHashName(value: Any?, hasher: inout Hasher) { '''); } + void _writePigeonInternal(InternalSwiftOptions generatorOptions, Root root, Indent indent) { + indent.newln(); + final String uniqueComponent = generatorOptions.fileSpecificClassNameComponent ?? ''; + indent.writeScoped('enum ${uniqueComponent}PigeonInternal {', '}', () { + _writeIsNullish(generatorOptions, indent); + if (root.classes.isNotEmpty) { + _writeDeepEquals(generatorOptions, indent); + } + }); + } + @override void writeGeneralUtilities( InternalSwiftOptions generatorOptions, @@ -1492,11 +1548,8 @@ func $deepHashName(value: Any?, hasher: inout Hasher) { _writeCreateConnectionError(generatorOptions, indent); } - _writeIsNullish(indent); + _writePigeonInternal(generatorOptions, root, indent); _writeNilOrValue(indent); - if (root.classes.isNotEmpty) { - _writeDeepEquals(generatorOptions, indent); - } } @override diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index 572dac448ba9..e93cecf067c2 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -334,6 +334,26 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echo(_:)') List echoList(List list); + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoStringList:') + @SwiftFunction('echo(stringList:)') + List echoStringList(List stringList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoIntList:') + @SwiftFunction('echo(intList:)') + List echoIntList(List intList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoDoubleList:') + @SwiftFunction('echo(doubleList:)') + List echoDoubleList(List doubleList); + + /// Returns the passed list, to test serialization and deserialization. + @ObjCSelector('echoBoolList:') + @SwiftFunction('echo(boolList:)') + List echoBoolList(List boolList); + /// Returns the passed list, to test serialization and deserialization. @ObjCSelector('echoEnumList:') @SwiftFunction('echo(enumList:)') diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java index 5c46688a6d95..5622b4b3f2a3 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java @@ -134,6 +134,26 @@ public void throwErrorFromVoid() { return list; } + @Override + public @NonNull List echoStringList(@NonNull List stringList) { + return stringList; + } + + @Override + public @NonNull List echoIntList(@NonNull List intList) { + return intList; + } + + @Override + public @NonNull List echoDoubleList(@NonNull List doubleList) { + return doubleList; + } + + @Override + public @NonNull List echoBoolList(@NonNull List boolList) { + return boolList; + } + @Override public @NonNull List echoEnumList(@NonNull List enumList) { return enumList; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index a21588a5c9df..da1de3d6a4da 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -285,6 +285,11 @@ public int hashCode() { return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "UnusedClass{" + "aField=" + aField + "}"; + } + public static final class Builder { private @Nullable Object aField; @@ -766,6 +771,95 @@ public int hashCode() { return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "AllTypes{" + + "aBool=" + + aBool + + ", " + + "anInt=" + + anInt + + ", " + + "anInt64=" + + anInt64 + + ", " + + "aDouble=" + + aDouble + + ", " + + "aByteArray=" + + java.util.Arrays.toString(aByteArray) + + ", " + + "a4ByteArray=" + + java.util.Arrays.toString(a4ByteArray) + + ", " + + "a8ByteArray=" + + java.util.Arrays.toString(a8ByteArray) + + ", " + + "aFloatArray=" + + java.util.Arrays.toString(aFloatArray) + + ", " + + "anEnum=" + + anEnum + + ", " + + "anotherEnum=" + + anotherEnum + + ", " + + "aString=" + + aString + + ", " + + "anObject=" + + anObject + + ", " + + "list=" + + list + + ", " + + "stringList=" + + stringList + + ", " + + "intList=" + + intList + + ", " + + "doubleList=" + + doubleList + + ", " + + "boolList=" + + boolList + + ", " + + "enumList=" + + enumList + + ", " + + "objectList=" + + objectList + + ", " + + "listList=" + + listList + + ", " + + "mapList=" + + mapList + + ", " + + "map=" + + map + + ", " + + "stringMap=" + + stringMap + + ", " + + "intMap=" + + intMap + + ", " + + "enumMap=" + + enumMap + + ", " + + "objectMap=" + + objectMap + + ", " + + "listMap=" + + listMap + + ", " + + "mapMap=" + + mapMap + + "}"; + } + public static final class Builder { private @Nullable Boolean aBool; @@ -1520,6 +1614,104 @@ public int hashCode() { return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "AllNullableTypes{" + + "aNullableBool=" + + aNullableBool + + ", " + + "aNullableInt=" + + aNullableInt + + ", " + + "aNullableInt64=" + + aNullableInt64 + + ", " + + "aNullableDouble=" + + aNullableDouble + + ", " + + "aNullableByteArray=" + + java.util.Arrays.toString(aNullableByteArray) + + ", " + + "aNullable4ByteArray=" + + java.util.Arrays.toString(aNullable4ByteArray) + + ", " + + "aNullable8ByteArray=" + + java.util.Arrays.toString(aNullable8ByteArray) + + ", " + + "aNullableFloatArray=" + + java.util.Arrays.toString(aNullableFloatArray) + + ", " + + "aNullableEnum=" + + aNullableEnum + + ", " + + "anotherNullableEnum=" + + anotherNullableEnum + + ", " + + "aNullableString=" + + aNullableString + + ", " + + "aNullableObject=" + + aNullableObject + + ", " + + "allNullableTypes=" + + allNullableTypes + + ", " + + "list=" + + list + + ", " + + "stringList=" + + stringList + + ", " + + "intList=" + + intList + + ", " + + "doubleList=" + + doubleList + + ", " + + "boolList=" + + boolList + + ", " + + "enumList=" + + enumList + + ", " + + "objectList=" + + objectList + + ", " + + "listList=" + + listList + + ", " + + "mapList=" + + mapList + + ", " + + "recursiveClassList=" + + recursiveClassList + + ", " + + "map=" + + map + + ", " + + "stringMap=" + + stringMap + + ", " + + "intMap=" + + intMap + + ", " + + "enumMap=" + + enumMap + + ", " + + "objectMap=" + + objectMap + + ", " + + "listMap=" + + listMap + + ", " + + "mapMap=" + + mapMap + + ", " + + "recursiveClassMap=" + + recursiveClassMap + + "}"; + } + public static final class Builder { private @Nullable Boolean aNullableBool; @@ -2276,6 +2468,95 @@ public int hashCode() { return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "AllNullableTypesWithoutRecursion{" + + "aNullableBool=" + + aNullableBool + + ", " + + "aNullableInt=" + + aNullableInt + + ", " + + "aNullableInt64=" + + aNullableInt64 + + ", " + + "aNullableDouble=" + + aNullableDouble + + ", " + + "aNullableByteArray=" + + java.util.Arrays.toString(aNullableByteArray) + + ", " + + "aNullable4ByteArray=" + + java.util.Arrays.toString(aNullable4ByteArray) + + ", " + + "aNullable8ByteArray=" + + java.util.Arrays.toString(aNullable8ByteArray) + + ", " + + "aNullableFloatArray=" + + java.util.Arrays.toString(aNullableFloatArray) + + ", " + + "aNullableEnum=" + + aNullableEnum + + ", " + + "anotherNullableEnum=" + + anotherNullableEnum + + ", " + + "aNullableString=" + + aNullableString + + ", " + + "aNullableObject=" + + aNullableObject + + ", " + + "list=" + + list + + ", " + + "stringList=" + + stringList + + ", " + + "intList=" + + intList + + ", " + + "doubleList=" + + doubleList + + ", " + + "boolList=" + + boolList + + ", " + + "enumList=" + + enumList + + ", " + + "objectList=" + + objectList + + ", " + + "listList=" + + listList + + ", " + + "mapList=" + + mapList + + ", " + + "map=" + + map + + ", " + + "stringMap=" + + stringMap + + ", " + + "intMap=" + + intMap + + ", " + + "enumMap=" + + enumMap + + ", " + + "objectMap=" + + objectMap + + ", " + + "listMap=" + + listMap + + ", " + + "mapMap=" + + mapMap + + "}"; + } + public static final class Builder { private @Nullable Boolean aNullableBool; @@ -2762,6 +3043,32 @@ public int hashCode() { return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "AllClassesWrapper{" + + "allNullableTypes=" + + allNullableTypes + + ", " + + "allNullableTypesWithoutRecursion=" + + allNullableTypesWithoutRecursion + + ", " + + "allTypes=" + + allTypes + + ", " + + "classList=" + + classList + + ", " + + "nullableClassList=" + + nullableClassList + + ", " + + "classMap=" + + classMap + + ", " + + "nullableClassMap=" + + nullableClassMap + + "}"; + } + public static final class Builder { private @Nullable AllNullableTypes allNullableTypes; @@ -2905,6 +3212,11 @@ public int hashCode() { return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "TestMessage{" + "testList=" + testList + "}"; + } + public static final class Builder { private @Nullable List testList; @@ -3086,6 +3398,22 @@ public interface HostIntegrationCoreApi { @NonNull List echoList(@NonNull List list); + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoStringList(@NonNull List stringList); + + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoIntList(@NonNull List intList); + + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoDoubleList(@NonNull List doubleList); + + /** Returns the passed list, to test serialization and deserialization. */ + @NonNull + List echoBoolList(@NonNull List boolList); + /** Returns the passed list, to test serialization and deserialization. */ @NonNull List echoEnumList(@NonNull List enumList); @@ -3929,6 +4257,106 @@ static void setUp( channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List stringListArg = (List) args.get(0); + try { + List output = api.echoStringList(stringListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List intListArg = (List) args.get(0); + try { + List output = api.echoIntList(intListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoDoubleList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List doubleListArg = (List) args.get(0); + try { + List output = api.echoDoubleList(doubleListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoBoolList" + + messageChannelSuffix, + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList<>(); + ArrayList args = (ArrayList) message; + List boolListArg = (List) args.get(0); + try { + List output = api.echoBoolList(boolListArg); + wrapped.add(0, output); + } catch (Throwable exception) { + wrapped = wrapError(exception); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } { BasicMessageChannel channel = new BasicMessageChannel<>( diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/DataClassMethodsTest.java similarity index 83% rename from packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java rename to packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/DataClassMethodsTest.java index 5671cc465163..7b0c28355014 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/DataClassMethodsTest.java @@ -19,7 +19,7 @@ import java.util.Map; import org.junit.Test; -public class AllDatatypesTest { +public class DataClassMethodsTest { void compareAllTypes(AllTypes firstTypes, AllTypes secondTypes) { assertEquals(firstTypes == null, secondTypes == null); @@ -267,6 +267,63 @@ public void error(Throwable error) { assertTrue(didCall[0]); } + @Test + public void testToStringFullOutput() { + final List genericList = Arrays.asList(new Object[] {"hello", 1, true, false, null}); + final List> listList = new ArrayList<>(Arrays.asList()); + final List> mapList = new ArrayList<>(Arrays.asList()); + final Map> listMap = new HashMap>(); + final Map> mapMap = new HashMap>(); + listList.add(genericList); + mapList.add(makeMap("hello", 1234)); + listMap.put(1L, genericList); + mapMap.put(1L, makeMap("hello", 1234)); + AllTypes allEverything = + new AllTypes.Builder() + .setABool(false) + .setAnInt(1234L) + .setAnInt64(4321L) + .setADouble(2.0) + .setAString("hello") + .setAByteArray(new byte[] {1, 2, 3, 4}) + .setA4ByteArray(new int[] {1, 2, 3, 4}) + .setA8ByteArray(new long[] {1, 2, 3, 4}) + .setAFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}) + .setAnEnum(CoreTests.AnEnum.ONE) + .setAnotherEnum(CoreTests.AnotherEnum.JUST_IN_CASE) + .setAnObject(0) + .setList(genericList) + .setBoolList(Arrays.asList(new Boolean[] {true, false})) + .setDoubleList(Arrays.asList(new Double[] {0.5, 0.25, 1.5, 1.25})) + .setIntList(Arrays.asList(new Long[] {1l, 2l, 3l, 4l})) + .setStringList(Arrays.asList(new String[] {"string", "another one"})) + .setObjectList(genericList) + .setEnumList( + Arrays.asList( + new CoreTests.AnEnum[] {CoreTests.AnEnum.ONE, CoreTests.AnEnum.FORTY_TWO})) + .setListList(listList) + .setMapList(mapList) + .setMap(makeMap("hello", 1234)) + .setIntMap(makeMap(1L, 0L)) + .setStringMap(makeMap("hello", "you")) + .setObjectMap(makeMap("E", 4321)) + .setEnumMap(makeMap(CoreTests.AnEnum.ONE, CoreTests.AnEnum.FOUR_HUNDRED_TWENTY_TWO)) + .setListMap(listMap) + .setMapMap(mapMap) + .build(); + assertEquals( + "AllTypes{aBool=false, anInt=1234, anInt64=4321, aDouble=2.0, aByteArray=[1, 2, 3, 4]," + + " a4ByteArray=[1, 2, 3, 4], a8ByteArray=[1, 2, 3, 4], aFloatArray=[0.5, 0.25, 1.5," + + " 1.25], anEnum=ONE, anotherEnum=JUST_IN_CASE, aString=hello, anObject=0," + + " list=[hello, 1, true, false, null], stringList=[string, another one], intList=[1," + + " 2, 3, 4], doubleList=[0.5, 0.25, 1.5, 1.25], boolList=[true, false], enumList=[ONE," + + " FORTY_TWO], objectList=[hello, 1, true, false, null], listList=[[hello, 1, true," + + " false, null]], mapList=[{hello=1234}], map={hello=1234}, stringMap={hello=you}," + + " intMap={1=0}, enumMap={ONE=FOUR_HUNDRED_TWENTY_TWO}, objectMap={E=4321}," + + " listMap={1=[hello, 1, true, false, null]}, mapMap={1={hello=1234}}}", + allEverything.toString()); + } + @Test public void equalityWithNaN() { AllNullableTypes withNaN = diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/AlternateLanguageTestPlugin.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/AlternateLanguageTestPlugin.m index fdd0a0563ae5..0778fcb4f524 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/AlternateLanguageTestPlugin.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/AlternateLanguageTestPlugin.m @@ -95,6 +95,26 @@ - (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull) return list; } +- (nullable NSArray *)echoStringList:(NSArray *)stringList + error:(FlutterError *_Nullable *_Nonnull)error { + return stringList; +} + +- (nullable NSArray *)echoIntList:(NSArray *)intList + error:(FlutterError *_Nullable *_Nonnull)error { + return intList; +} + +- (nullable NSArray *)echoDoubleList:(NSArray *)doubleList + error:(FlutterError *_Nullable *_Nonnull)error { + return doubleList; +} + +- (nullable NSArray *)echoBoolList:(NSArray *)boolList + error:(FlutterError *_Nullable *_Nonnull)error { + return boolList; +} + - (nullable NSArray *)echoEnumList:(NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error { return enumList; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/CoreTests.gen.m index 7c114f8fa47b..9692e443f74f 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/CoreTests.gen.m @@ -218,6 +218,9 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.aField); return result; } +- (NSString *)description { + return [NSString stringWithFormat:@"FLTUnusedClass(aField: %@)", self.aField]; +} @end @implementation FLTAllTypes @@ -417,6 +420,21 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.mapMap); return result; } +- (NSString *)description { + return [NSString + stringWithFormat: + @"FLTAllTypes(aBool: %@, anInt: %ld, anInt64: %ld, aDouble: %f, aByteArray: %@, " + @"a4ByteArray: %@, a8ByteArray: %@, aFloatArray: %@, anEnum: %ld, anotherEnum: %ld, " + @"aString: %@, anObject: %@, list: %@, stringList: %@, intList: %@, doubleList: %@, " + @"boolList: %@, enumList: %@, objectList: %@, listList: %@, mapList: %@, map: %@, " + @"stringMap: %@, intMap: %@, enumMap: %@, objectMap: %@, listMap: %@, mapMap: %@)", + self.aBool ? @"true" : @"false", (long)self.anInt, (long)self.anInt64, self.aDouble, + self.aByteArray, self.a4ByteArray, self.a8ByteArray, self.aFloatArray, (long)self.anEnum, + (long)self.anotherEnum, self.aString, self.anObject, self.list, self.stringList, + self.intList, self.doubleList, self.boolList, self.enumList, self.objectList, + self.listList, self.mapList, self.map, self.stringMap, self.intMap, self.enumMap, + self.objectMap, self.listMap, self.mapMap]; +} @end @implementation FLTAllNullableTypes @@ -636,6 +654,26 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.recursiveClassMap); return result; } +- (NSString *)description { + return [NSString + stringWithFormat:@"FLTAllNullableTypes(aNullableBool: %@, aNullableInt: %@, aNullableInt64: " + @"%@, aNullableDouble: %@, aNullableByteArray: %@, aNullable4ByteArray: %@, " + @"aNullable8ByteArray: %@, aNullableFloatArray: %@, aNullableEnum: %@, " + @"anotherNullableEnum: %@, aNullableString: %@, aNullableObject: %@, " + @"allNullableTypes: %@, list: %@, stringList: %@, intList: %@, doubleList: " + @"%@, boolList: %@, enumList: %@, objectList: %@, listList: %@, mapList: " + @"%@, recursiveClassList: %@, map: %@, stringMap: %@, intMap: %@, enumMap: " + @"%@, objectMap: %@, listMap: %@, mapMap: %@, recursiveClassMap: %@)", + self.aNullableBool, self.aNullableInt, self.aNullableInt64, + self.aNullableDouble, self.aNullableByteArray, self.aNullable4ByteArray, + self.aNullable8ByteArray, self.aNullableFloatArray, self.aNullableEnum, + self.anotherNullableEnum, self.aNullableString, self.aNullableObject, + self.allNullableTypes, self.list, self.stringList, self.intList, + self.doubleList, self.boolList, self.enumList, self.objectList, + self.listList, self.mapList, self.recursiveClassList, self.map, + self.stringMap, self.intMap, self.enumMap, self.objectMap, self.listMap, + self.mapMap, self.recursiveClassMap]; +} @end @implementation FLTAllNullableTypesWithoutRecursion @@ -838,6 +876,24 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.mapMap); return result; } +- (NSString *)description { + return [NSString + stringWithFormat: + @"FLTAllNullableTypesWithoutRecursion(aNullableBool: %@, aNullableInt: %@, " + @"aNullableInt64: %@, aNullableDouble: %@, aNullableByteArray: %@, aNullable4ByteArray: " + @"%@, aNullable8ByteArray: %@, aNullableFloatArray: %@, aNullableEnum: %@, " + @"anotherNullableEnum: %@, aNullableString: %@, aNullableObject: %@, list: %@, " + @"stringList: %@, intList: %@, doubleList: %@, boolList: %@, enumList: %@, objectList: " + @"%@, listList: %@, mapList: %@, map: %@, stringMap: %@, intMap: %@, enumMap: %@, " + @"objectMap: %@, listMap: %@, mapMap: %@)", + self.aNullableBool, self.aNullableInt, self.aNullableInt64, self.aNullableDouble, + self.aNullableByteArray, self.aNullable4ByteArray, self.aNullable8ByteArray, + self.aNullableFloatArray, self.aNullableEnum, self.anotherNullableEnum, + self.aNullableString, self.aNullableObject, self.list, self.stringList, self.intList, + self.doubleList, self.boolList, self.enumList, self.objectList, self.listList, + self.mapList, self.map, self.stringMap, self.intMap, self.enumMap, self.objectMap, + self.listMap, self.mapMap]; +} @end @implementation FLTAllClassesWrapper @@ -917,6 +973,15 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.nullableClassMap); return result; } +- (NSString *)description { + return + [NSString stringWithFormat:@"FLTAllClassesWrapper(allNullableTypes: %@, " + @"allNullableTypesWithoutRecursion: %@, allTypes: %@, classList: " + @"%@, nullableClassList: %@, classMap: %@, nullableClassMap: %@)", + self.allNullableTypes, self.allNullableTypesWithoutRecursion, + self.allTypes, self.classList, self.nullableClassList, + self.classMap, self.nullableClassMap]; +} @end @implementation FLTTestMessage @@ -954,6 +1019,9 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.testList); return result; } +- (NSString *)description { + return [NSString stringWithFormat:@"FLTTestMessage(testList: %@)", self.testList]; +} @end @interface FLTCoreTestsPigeonCodecReader : FlutterStandardReader @@ -1353,6 +1421,106 @@ void SetUpFLTHostIntegrationCoreApiWithSuffix(id binaryM } } /// Returns the passed list, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoStringList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(echoStringList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoStringList:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_stringList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoStringList:arg_stringList error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoIntList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(echoIntList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoIntList:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_intList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoIntList:arg_intList error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoDoubleList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(echoDoubleList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoDoubleList:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_doubleList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoDoubleList:arg_doubleList error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.pigeon_integration_tests." + @"HostIntegrationCoreApi.echoBoolList", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FLTGetCoreTestsCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(echoBoolList:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to @selector(echoBoolList:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSArray *arg_boolList = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSArray *output = [api echoBoolList:arg_boolList error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + /// Returns the passed list, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/include/alternate_language_test_plugin/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/include/alternate_language_test_plugin/CoreTests.gen.h index 2b620a11104a..03be8ebb358d 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/include/alternate_language_test_plugin/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/darwin/alternate_language_test_plugin/Sources/alternate_language_test_plugin/include/alternate_language_test_plugin/CoreTests.gen.h @@ -336,6 +336,26 @@ NSObject *FLTGetCoreTestsCodec(void); /// Returns the passed list, to test serialization and deserialization. /// /// @return `nil` only when `error != nil`. +- (nullable NSArray *)echoStringList:(NSArray *)stringList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *)echoIntList:(NSArray *)intList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *)echoDoubleList:(NSArray *)doubleList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable NSArray *)echoBoolList:(NSArray *)boolList + error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed list, to test serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. - (nullable NSArray *)echoEnumList:(NSArray *)enumList error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the passed list, to test serialization and deserialization. diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/Runner.xcodeproj/project.pbxproj b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/Runner.xcodeproj/project.pbxproj index 9ec8521a194a..e0137ec729eb 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/Runner.xcodeproj/project.pbxproj @@ -11,7 +11,7 @@ 33A341A5291EBA9100D34E0F /* AsyncHandlersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A34196291EBA9000D34E0F /* AsyncHandlersTest.m */; }; 33A341A6291EBA9100D34E0F /* HandlerBinaryMessenger.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A34197291EBA9000D34E0F /* HandlerBinaryMessenger.m */; }; 33A341A7291EBA9100D34E0F /* ListTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A34198291EBA9000D34E0F /* ListTest.m */; }; - 33A341A8291EBA9100D34E0F /* AllDatatypesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A34199291EBA9000D34E0F /* AllDatatypesTest.m */; }; + 33A341A8291EBA9100D34E0F /* DataClassMethodsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A34199291EBA9000D34E0F /* DataClassMethodsTest.m */; }; 33A341A9291EBA9100D34E0F /* NonNullFieldsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A3419B291EBA9000D34E0F /* NonNullFieldsTest.m */; }; 33A341AA291EBA9100D34E0F /* NullableReturnsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A3419D291EBA9000D34E0F /* NullableReturnsTest.m */; }; 33A341AB291EBA9100D34E0F /* EnumTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A3419E291EBA9000D34E0F /* EnumTest.m */; }; @@ -59,7 +59,7 @@ 33A34196291EBA9000D34E0F /* AsyncHandlersTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AsyncHandlersTest.m; sourceTree = ""; }; 33A34197291EBA9000D34E0F /* HandlerBinaryMessenger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HandlerBinaryMessenger.m; sourceTree = ""; }; 33A34198291EBA9000D34E0F /* ListTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ListTest.m; sourceTree = ""; }; - 33A34199291EBA9000D34E0F /* AllDatatypesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AllDatatypesTest.m; sourceTree = ""; }; + 33A34199291EBA9000D34E0F /* DataClassMethodsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataClassMethodsTest.m; sourceTree = ""; }; 33A3419A291EBA9000D34E0F /* MockBinaryMessenger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockBinaryMessenger.h; sourceTree = ""; }; 33A3419B291EBA9000D34E0F /* NonNullFieldsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NonNullFieldsTest.m; sourceTree = ""; }; 33A3419C291EBA9000D34E0F /* EchoMessenger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EchoMessenger.h; sourceTree = ""; }; @@ -112,7 +112,7 @@ 33AA1660291EB8B600ECBEEB /* RunnerTests */ = { isa = PBXGroup; children = ( - 33A34199291EBA9000D34E0F /* AllDatatypesTest.m */, + 33A34199291EBA9000D34E0F /* DataClassMethodsTest.m */, 33A34196291EBA9000D34E0F /* AsyncHandlersTest.m */, 33A3419C291EBA9000D34E0F /* EchoMessenger.h */, 33A341A1291EBA9000D34E0F /* EchoMessenger.m */, @@ -341,7 +341,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 33A341A8291EBA9100D34E0F /* AllDatatypesTest.m in Sources */, + 33A341A8291EBA9100D34E0F /* DataClassMethodsTest.m in Sources */, 33A341AC291EBA9100D34E0F /* MultipleArityTest.m in Sources */, 33AA1662291EB8B600ECBEEB /* RunnerTests.m in Sources */, 33A341AE291EBA9100D34E0F /* NullFieldsTest.m in Sources */, diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/DataClassMethodsTest.m similarity index 92% rename from packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m rename to packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/DataClassMethodsTest.m index 4e5b5b196f5a..dbe11c1a5aa7 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/DataClassMethodsTest.m @@ -10,11 +10,11 @@ #import "EchoMessenger.h" /////////////////////////////////////////////////////////////////////////////////////////// -@interface AllDatatypesTest : XCTestCase +@interface DataClassMethodsTest : XCTestCase @end /////////////////////////////////////////////////////////////////////////////////////////// -@implementation AllDatatypesTest +@implementation DataClassMethodsTest - (void)testAllNull { FLTAllNullableTypes *everything = [[FLTAllNullableTypes alloc] init]; @@ -114,6 +114,24 @@ - (void)testAllEquals { [self waitForExpectations:@[ expectation ] timeout:1.0]; } +- (void)testDescriptionFullOutput { + FLTAllNullableTypes *everything = [[FLTAllNullableTypes alloc] init]; + everything.aNullableBool = @NO; + everything.aNullableInt = @(1); + everything.aNullableDouble = @(2.0); + everything.aNullableString = @"123"; + everything.list = @[ @"string", @1 ]; + everything.stringMap = @{@"hello" : @"you", @"goodbye" : @"world"}; + + NSString *desc = everything.description; + XCTAssertTrue([desc hasPrefix:@"FLTAllNullableTypes("]); + XCTAssertTrue([desc containsString:@"aNullableBool: "]); + XCTAssertTrue([desc containsString:@"aNullableInt: "]); + XCTAssertTrue([desc containsString:@"aNullableDouble: "]); + XCTAssertTrue([desc containsString:@"123"]); + XCTAssertTrue([desc containsString:@"stringMap: "]); +} + - (void)testEquality { FLTAllNullableTypes *everything1 = [[FLTAllNullableTypes alloc] init]; everything1.aNullableBool = @NO; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart index 5cc6b0041cfd..8c0188464675 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart @@ -41,8 +41,8 @@ class _PigeonCodec extends StandardMessageCodec { } class BackgroundApi2Host { - /// Constructor for [BackgroundApi2Host]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [BackgroundApi2Host]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. BackgroundApi2Host({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index 70c013eceb54..c1164b5c7892 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -146,6 +146,11 @@ class UnusedClass { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'UnusedClass(aField: $aField)'; + } } /// A class containing all supported types. @@ -350,6 +355,11 @@ class AllTypes { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'AllTypes(aBool: $aBool, anInt: $anInt, anInt64: $anInt64, aDouble: $aDouble, aByteArray: $aByteArray, a4ByteArray: $a4ByteArray, a8ByteArray: $a8ByteArray, aFloatArray: $aFloatArray, anEnum: $anEnum, anotherEnum: $anotherEnum, aString: $aString, anObject: $anObject, list: $list, stringList: $stringList, intList: $intList, doubleList: $doubleList, boolList: $boolList, enumList: $enumList, objectList: $objectList, listList: $listList, mapList: $mapList, map: $map, stringMap: $stringMap, intMap: $intMap, enumMap: $enumMap, objectMap: $objectMap, listMap: $listMap, mapMap: $mapMap)'; + } } /// A class containing all supported nullable types. @@ -572,6 +582,11 @@ class AllNullableTypes { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'AllNullableTypes(aNullableBool: $aNullableBool, aNullableInt: $aNullableInt, aNullableInt64: $aNullableInt64, aNullableDouble: $aNullableDouble, aNullableByteArray: $aNullableByteArray, aNullable4ByteArray: $aNullable4ByteArray, aNullable8ByteArray: $aNullable8ByteArray, aNullableFloatArray: $aNullableFloatArray, aNullableEnum: $aNullableEnum, anotherNullableEnum: $anotherNullableEnum, aNullableString: $aNullableString, aNullableObject: $aNullableObject, allNullableTypes: $allNullableTypes, list: $list, stringList: $stringList, intList: $intList, doubleList: $doubleList, boolList: $boolList, enumList: $enumList, objectList: $objectList, listList: $listList, mapList: $mapList, recursiveClassList: $recursiveClassList, map: $map, stringMap: $stringMap, intMap: $intMap, enumMap: $enumMap, objectMap: $objectMap, listMap: $listMap, mapMap: $mapMap, recursiveClassMap: $recursiveClassMap)'; + } } /// The primary purpose for this class is to ensure coverage of Swift structs @@ -778,6 +793,11 @@ class AllNullableTypesWithoutRecursion { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'AllNullableTypesWithoutRecursion(aNullableBool: $aNullableBool, aNullableInt: $aNullableInt, aNullableInt64: $aNullableInt64, aNullableDouble: $aNullableDouble, aNullableByteArray: $aNullableByteArray, aNullable4ByteArray: $aNullable4ByteArray, aNullable8ByteArray: $aNullable8ByteArray, aNullableFloatArray: $aNullableFloatArray, aNullableEnum: $aNullableEnum, anotherNullableEnum: $anotherNullableEnum, aNullableString: $aNullableString, aNullableObject: $aNullableObject, list: $list, stringList: $stringList, intList: $intList, doubleList: $doubleList, boolList: $boolList, enumList: $enumList, objectList: $objectList, listList: $listList, mapList: $mapList, map: $map, stringMap: $stringMap, intMap: $intMap, enumMap: $enumMap, objectMap: $objectMap, listMap: $listMap, mapMap: $mapMap)'; + } } /// A class for testing nested class handling. @@ -861,6 +881,11 @@ class AllClassesWrapper { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'AllClassesWrapper(allNullableTypes: $allNullableTypes, allNullableTypesWithoutRecursion: $allNullableTypesWithoutRecursion, allTypes: $allTypes, classList: $classList, nullableClassList: $nullableClassList, classMap: $classMap, nullableClassMap: $nullableClassMap)'; + } } /// A data class containing a List, used in unit tests. @@ -897,6 +922,11 @@ class TestMessage { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'TestMessage(testList: $testList)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -965,8 +995,8 @@ class _PigeonCodec extends StandardMessageCodec { /// The core interface that each host language plugin must implement in /// platform_test integration tests. class HostIntegrationCoreApi { - /// Constructor for [HostIntegrationCoreApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [HostIntegrationCoreApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. HostIntegrationCoreApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, @@ -1210,6 +1240,86 @@ class HostIntegrationCoreApi { return pigeonVar_replyValue! as List; } + /// Returns the passed list, to test serialization and deserialization. + Future> echoStringList(List stringList) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringList$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([stringList]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return (pigeonVar_replyValue! as List).cast(); + } + + /// Returns the passed list, to test serialization and deserialization. + Future> echoIntList(List intList) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntList$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([intList]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return (pigeonVar_replyValue! as List).cast(); + } + + /// Returns the passed list, to test serialization and deserialization. + Future> echoDoubleList(List doubleList) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoDoubleList$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([doubleList]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return (pigeonVar_replyValue! as List).cast(); + } + + /// Returns the passed list, to test serialization and deserialization. + Future> echoBoolList(List boolList) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoBoolList$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([boolList]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return (pigeonVar_replyValue! as List).cast(); + } + /// Returns the passed list, to test serialization and deserialization. Future> echoEnumList(List enumList) async { final pigeonVar_channelName = @@ -5619,8 +5729,8 @@ abstract class FlutterIntegrationCoreApi { /// An API that can be implemented for minimal, compile-only tests. class HostTrivialApi { - /// Constructor for [HostTrivialApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [HostTrivialApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. HostTrivialApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, @@ -5650,8 +5760,8 @@ class HostTrivialApi { /// A simple API implemented in some unit tests. class HostSmallApi { - /// Constructor for [HostSmallApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [HostSmallApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. HostSmallApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart index 9cf0c40d99ee..e06bdaca4009 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart @@ -159,6 +159,11 @@ class DataWithEnum { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'DataWithEnum(state: $state)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -195,8 +200,8 @@ class _PigeonCodec extends StandardMessageCodec { /// This comment is to test api documentation comments. class EnumApi2Host { - /// Constructor for [EnumApi2Host]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [EnumApi2Host]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. EnumApi2Host({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart index 5f8750388f88..48d008b00929 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/event_channel_tests.gen.dart @@ -299,6 +299,11 @@ class EventAllNullableTypes { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'EventAllNullableTypes(aNullableBool: $aNullableBool, aNullableInt: $aNullableInt, aNullableInt64: $aNullableInt64, aNullableDouble: $aNullableDouble, aNullableByteArray: $aNullableByteArray, aNullable4ByteArray: $aNullable4ByteArray, aNullable8ByteArray: $aNullable8ByteArray, aNullableFloatArray: $aNullableFloatArray, aNullableEnum: $aNullableEnum, anotherNullableEnum: $anotherNullableEnum, aNullableString: $aNullableString, aNullableObject: $aNullableObject, allNullableTypes: $allNullableTypes, list: $list, stringList: $stringList, intList: $intList, doubleList: $doubleList, boolList: $boolList, enumList: $enumList, objectList: $objectList, listList: $listList, mapList: $mapList, recursiveClassList: $recursiveClassList, map: $map, stringMap: $stringMap, intMap: $intMap, enumMap: $enumMap, objectMap: $objectMap, listMap: $listMap, mapMap: $mapMap, recursiveClassMap: $recursiveClassMap)'; + } } sealed class PlatformEvent {} @@ -336,6 +341,11 @@ class IntEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'IntEvent(value: $value)'; + } } class StringEvent extends PlatformEvent { @@ -371,6 +381,11 @@ class StringEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'StringEvent(value: $value)'; + } } class BoolEvent extends PlatformEvent { @@ -406,6 +421,11 @@ class BoolEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'BoolEvent(value: $value)'; + } } class DoubleEvent extends PlatformEvent { @@ -441,6 +461,11 @@ class DoubleEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'DoubleEvent(value: $value)'; + } } class ObjectsEvent extends PlatformEvent { @@ -476,6 +501,11 @@ class ObjectsEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'ObjectsEvent(value: $value)'; + } } class EnumEvent extends PlatformEvent { @@ -511,6 +541,11 @@ class EnumEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'EnumEvent(value: $value)'; + } } class ClassEvent extends PlatformEvent { @@ -546,6 +581,11 @@ class ClassEvent extends PlatformEvent { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'ClassEvent(value: $value)'; + } } class _PigeonCodec extends StandardMessageCodec { diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart index 549ef4a503ed..9ce02d4a3b71 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart @@ -132,6 +132,11 @@ class FlutterSearchRequest { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'FlutterSearchRequest(query: $query)'; + } } class FlutterSearchReply { @@ -169,6 +174,11 @@ class FlutterSearchReply { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'FlutterSearchReply(result: $result, error: $error)'; + } } class FlutterSearchRequests { @@ -204,6 +214,11 @@ class FlutterSearchRequests { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'FlutterSearchRequests(requests: $requests)'; + } } class FlutterSearchReplies { @@ -239,6 +254,11 @@ class FlutterSearchReplies { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'FlutterSearchReplies(replies: $replies)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -283,8 +303,8 @@ class _PigeonCodec extends StandardMessageCodec { } class Api { - /// Constructor for [Api]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [Api]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. Api({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart index f83c1f684d96..bbe6644cda6b 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart @@ -167,6 +167,11 @@ class MessageSearchRequest { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'MessageSearchRequest(query: $query, anInt: $anInt, aBool: $aBool)'; + } } /// This comment is to test class documentation comments. @@ -218,6 +223,11 @@ class MessageSearchReply { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'MessageSearchReply(result: $result, error: $error, state: $state)'; + } } /// This comment is to test class documentation comments. @@ -255,6 +265,11 @@ class MessageNested { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'MessageNested(request: $request)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -303,8 +318,8 @@ class _PigeonCodec extends StandardMessageCodec { /// /// This comment also tests multiple line comments. class MessageApi { - /// Constructor for [MessageApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [MessageApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. MessageApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, @@ -357,8 +372,8 @@ class MessageApi { /// This comment is to test api documentation comments. class MessageNestedApi { - /// Constructor for [MessageNestedApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [MessageNestedApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. MessageNestedApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart index cfabf89d7f40..1e0649ef40fd 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart @@ -70,8 +70,8 @@ class _PigeonCodec extends StandardMessageCodec { } class MultipleArityHostApi { - /// Constructor for [MultipleArityHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [MultipleArityHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. MultipleArityHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart index 2f4a0fd15662..19a7ab097536 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart @@ -144,6 +144,11 @@ class NonNullFieldSearchRequest { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'NonNullFieldSearchRequest(query: $query)'; + } } class ExtraData { @@ -181,6 +186,11 @@ class ExtraData { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'ExtraData(detailA: $detailA, detailB: $detailB)'; + } } class NonNullFieldSearchReply { @@ -240,6 +250,11 @@ class NonNullFieldSearchReply { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'NonNullFieldSearchReply(result: $result, error: $error, indices: $indices, extraData: $extraData, type: $type)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -285,8 +300,8 @@ class _PigeonCodec extends StandardMessageCodec { } class NonNullFieldHostApi { - /// Constructor for [NonNullFieldHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [NonNullFieldHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. NonNullFieldHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart index 38affeab9b9c..e41b166e6e51 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart @@ -146,6 +146,11 @@ class NullFieldsSearchRequest { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'NullFieldsSearchRequest(query: $query, identifier: $identifier)'; + } } class NullFieldsSearchReply { @@ -199,6 +204,11 @@ class NullFieldsSearchReply { @override // ignore: avoid_equals_and_hash_code_on_mutable_classes int get hashCode => _deepHash([runtimeType, ..._toList()]); + + @override + String toString() { + return 'NullFieldsSearchReply(result: $result, error: $error, indices: $indices, request: $request, type: $type)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -239,8 +249,8 @@ class _PigeonCodec extends StandardMessageCodec { } class NullFieldsHostApi { - /// Constructor for [NullFieldsHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [NullFieldsHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. NullFieldsHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart index 9aa24097d442..32116f40bd58 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart @@ -70,8 +70,8 @@ class _PigeonCodec extends StandardMessageCodec { } class NullableReturnHostApi { - /// Constructor for [NullableReturnHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [NullableReturnHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. NullableReturnHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, @@ -142,8 +142,8 @@ abstract class NullableReturnFlutterApi { } class NullableArgHostApi { - /// Constructor for [NullableArgHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [NullableArgHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. NullableArgHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, @@ -216,8 +216,8 @@ abstract class NullableArgFlutterApi { } class NullableCollectionReturnHostApi { - /// Constructor for [NullableCollectionReturnHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [NullableCollectionReturnHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. NullableCollectionReturnHostApi({ BinaryMessenger? binaryMessenger, @@ -290,8 +290,8 @@ abstract class NullableCollectionReturnFlutterApi { } class NullableCollectionArgHostApi { - /// Constructor for [NullableCollectionArgHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [NullableCollectionArgHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. NullableCollectionArgHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart index c90f8204eb9a..41a1000e91e2 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart @@ -70,8 +70,8 @@ class _PigeonCodec extends StandardMessageCodec { } class PrimitiveHostApi { - /// Constructor for [PrimitiveHostApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default + /// Constructor for [PrimitiveHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. PrimitiveHostApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) : pigeonVar_binaryMessenger = binaryMessenger, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/equality_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/data_class_methods_test.dart similarity index 79% rename from packages/pigeon/platform_tests/shared_test_plugin_code/test/equality_test.dart rename to packages/pigeon/platform_tests/shared_test_plugin_code/test/data_class_methods_test.dart index b69641fd0e52..33407ef7fc89 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/equality_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/data_class_methods_test.dart @@ -192,5 +192,12 @@ void main() { expect(withMapInList, withDifferentMapInList); }, ); + + test('AllTypes toString full output', () { + expect( + genericAllTypes.toString(), + 'AllTypes(aBool: true, anInt: 42, anInt64: 3000000000, aDouble: 3.14159, aByteArray: [1, 2, 3], a4ByteArray: [4, 5, 6], a8ByteArray: [7, 8, 9], aFloatArray: [2.71828, 3.14159], anEnum: AnEnum.fortyTwo, anotherEnum: AnotherEnum.justInCase, aString: Hello host!, anObject: 1, list: [Thing 1, 2, true, 3.14, null], stringList: [Thing 1, 2, true, 3.14], intList: [1, 2, 3, 4], doubleList: [1.0, 2.99999, 3.0, 3.14], boolList: [true, false, true, false], enumList: [AnEnum.one, AnEnum.two, AnEnum.three, AnEnum.fortyTwo, AnEnum.fourHundredTwentyTwo], objectList: [Thing 1, 2, true, 3.14], listList: [[Thing 1, 2, true, 3.14], [Thing 1, 2, true, 3.14], [1, 2, 3, 4], [1.0, 2.99999, 3.0, 3.14], [true, false, true, false], [AnEnum.one, AnEnum.two, AnEnum.three, AnEnum.fortyTwo, AnEnum.fourHundredTwentyTwo]], mapList: [{a: 1, b: 2.0, c: three, d: false}, {a: 1, b: 2.0, c: three, d: false}, {0.0: 0.0, 1.1: 2.0, 3.0: 0.3, -0.4: -0.2}, {0: 0, 1: 1, 2: 3, 4: -1}, {0: true, 1: false, 2: true}, {AnEnum.one: AnEnum.one, AnEnum.two: AnEnum.two, AnEnum.three: AnEnum.three, AnEnum.fortyTwo: AnEnum.fortyTwo}], map: {a: 1, b: 2.0, c: three, d: false}, stringMap: {a: 1, b: 2.0, c: three, d: false}, intMap: {0: 0, 1: 1, 2: 3, 4: -1}, enumMap: {AnEnum.one: AnEnum.one, AnEnum.two: AnEnum.two, AnEnum.three: AnEnum.three, AnEnum.fortyTwo: AnEnum.fortyTwo}, objectMap: {a: 1, b: 2.0, c: three, d: false}, listMap: {0: [Thing 1, 2, true, 3.14], 1: [Thing 1, 2, true, 3.14], 2: [1.0, 2.99999, 3.0, 3.14], 4: [1, 2, 3, 4], 5: [true, false, true, false], 6: [AnEnum.one, AnEnum.two, AnEnum.three, AnEnum.fortyTwo, AnEnum.fourHundredTwentyTwo]}, mapMap: {0: {a: 1, b: 2.0, c: three, d: false}, 1: {a: 1, b: 2.0, c: three, d: false}, 2: {0.0: 0.0, 1.1: 2.0, 3.0: 0.3, -0.4: -0.2}, 4: {0: 0, 1: 1, 2: 3, 4: -1}, 5: {0: true, 1: false, 2: true}, 6: {AnEnum.one: AnEnum.one, AnEnum.two: AnEnum.two, AnEnum.three: AnEnum.three, AnEnum.fortyTwo: AnEnum.fortyTwo}})', + ); + }); }); } 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 938204b49782..a22c40a3c5f3 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 @@ -251,6 +251,10 @@ data class UnusedClass(val aField: Any? = null) { result = 31 * result + CoreTestsPigeonUtils.deepHash(this.aField) return result } + + override fun toString(): String { + return "UnusedClass(aField=$aField)" + } } /** @@ -453,6 +457,10 @@ data class AllTypes( result = 31 * result + CoreTestsPigeonUtils.deepHash(this.mapMap) return result } + + override fun toString(): String { + return "AllTypes(aBool=$aBool, anInt=$anInt, anInt64=$anInt64, aDouble=$aDouble, aByteArray=${aByteArray.contentToString()}, a4ByteArray=${a4ByteArray.contentToString()}, a8ByteArray=${a8ByteArray.contentToString()}, aFloatArray=${aFloatArray.contentToString()}, anEnum=$anEnum, anotherEnum=$anotherEnum, aString=$aString, anObject=$anObject, list=$list, stringList=$stringList, intList=$intList, doubleList=$doubleList, boolList=$boolList, enumList=$enumList, objectList=$objectList, listList=$listList, mapList=$mapList, map=$map, stringMap=$stringMap, intMap=$intMap, enumMap=$enumMap, objectMap=$objectMap, listMap=$listMap, mapMap=$mapMap)" + } } /** @@ -673,6 +681,10 @@ data class AllNullableTypes( result = 31 * result + CoreTestsPigeonUtils.deepHash(this.recursiveClassMap) return result } + + override fun toString(): String { + return "AllNullableTypes(aNullableBool=$aNullableBool, aNullableInt=$aNullableInt, aNullableInt64=$aNullableInt64, aNullableDouble=$aNullableDouble, aNullableByteArray=${aNullableByteArray?.contentToString()}, aNullable4ByteArray=${aNullable4ByteArray?.contentToString()}, aNullable8ByteArray=${aNullable8ByteArray?.contentToString()}, aNullableFloatArray=${aNullableFloatArray?.contentToString()}, aNullableEnum=$aNullableEnum, anotherNullableEnum=$anotherNullableEnum, aNullableString=$aNullableString, aNullableObject=$aNullableObject, allNullableTypes=$allNullableTypes, list=$list, stringList=$stringList, intList=$intList, doubleList=$doubleList, boolList=$boolList, enumList=$enumList, objectList=$objectList, listList=$listList, mapList=$mapList, recursiveClassList=$recursiveClassList, map=$map, stringMap=$stringMap, intMap=$intMap, enumMap=$enumMap, objectMap=$objectMap, listMap=$listMap, mapMap=$mapMap, recursiveClassMap=$recursiveClassMap)" + } } /** @@ -876,6 +888,10 @@ data class AllNullableTypesWithoutRecursion( result = 31 * result + CoreTestsPigeonUtils.deepHash(this.mapMap) return result } + + override fun toString(): String { + return "AllNullableTypesWithoutRecursion(aNullableBool=$aNullableBool, aNullableInt=$aNullableInt, aNullableInt64=$aNullableInt64, aNullableDouble=$aNullableDouble, aNullableByteArray=${aNullableByteArray?.contentToString()}, aNullable4ByteArray=${aNullable4ByteArray?.contentToString()}, aNullable8ByteArray=${aNullable8ByteArray?.contentToString()}, aNullableFloatArray=${aNullableFloatArray?.contentToString()}, aNullableEnum=$aNullableEnum, anotherNullableEnum=$anotherNullableEnum, aNullableString=$aNullableString, aNullableObject=$aNullableObject, list=$list, stringList=$stringList, intList=$intList, doubleList=$doubleList, boolList=$boolList, enumList=$enumList, objectList=$objectList, listList=$listList, mapList=$mapList, map=$map, stringMap=$stringMap, intMap=$intMap, enumMap=$enumMap, objectMap=$objectMap, listMap=$listMap, mapMap=$mapMap)" + } } /** @@ -957,6 +973,10 @@ data class AllClassesWrapper( result = 31 * result + CoreTestsPigeonUtils.deepHash(this.nullableClassMap) return result } + + override fun toString(): String { + return "AllClassesWrapper(allNullableTypes=$allNullableTypes, allNullableTypesWithoutRecursion=$allNullableTypesWithoutRecursion, allTypes=$allTypes, classList=$classList, nullableClassList=$nullableClassList, classMap=$classMap, nullableClassMap=$nullableClassMap)" + } } /** @@ -994,6 +1014,10 @@ data class TestMessage(val testList: List? = null) { result = 31 * result + CoreTestsPigeonUtils.deepHash(this.testList) return result } + + override fun toString(): String { + return "TestMessage(testList=$testList)" + } } private open class CoreTestsPigeonCodec : StandardMessageCodec() { @@ -1100,6 +1124,14 @@ interface HostIntegrationCoreApi { /** Returns the passed list, to test serialization and deserialization. */ fun echoList(list: List): List /** Returns the passed list, to test serialization and deserialization. */ + fun echoStringList(stringList: List): List + /** Returns the passed list, to test serialization and deserialization. */ + fun echoIntList(intList: List): List + /** Returns the passed list, to test serialization and deserialization. */ + fun echoDoubleList(doubleList: List): List + /** Returns the passed list, to test serialization and deserialization. */ + fun echoBoolList(boolList: List): List + /** Returns the passed list, to test serialization and deserialization. */ fun echoEnumList(enumList: List): List /** Returns the passed list, to test serialization and deserialization. */ fun echoClassList(classList: List): List @@ -1817,6 +1849,94 @@ interface HostIntegrationCoreApi { channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val stringListArg = args[0] as List + val wrapped: List = + try { + listOf(api.echoStringList(stringListArg)) + } catch (exception: Throwable) { + CoreTestsPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val intListArg = args[0] as List + val wrapped: List = + try { + listOf(api.echoIntList(intListArg)) + } catch (exception: Throwable) { + CoreTestsPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoDoubleList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val doubleListArg = args[0] as List + val wrapped: List = + try { + listOf(api.echoDoubleList(doubleListArg)) + } catch (exception: Throwable) { + CoreTestsPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoBoolList$separatedMessageChannelSuffix", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val boolListArg = args[0] as List + val wrapped: List = + try { + listOf(api.echoBoolList(boolListArg)) + } catch (exception: Throwable) { + CoreTestsPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel( 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 9e55d6984836..a9f3d6575308 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 @@ -422,6 +422,10 @@ data class EventAllNullableTypes( result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.recursiveClassMap) return result } + + override fun toString(): String { + return "EventAllNullableTypes(aNullableBool=$aNullableBool, aNullableInt=$aNullableInt, aNullableInt64=$aNullableInt64, aNullableDouble=$aNullableDouble, aNullableByteArray=${aNullableByteArray?.contentToString()}, aNullable4ByteArray=${aNullable4ByteArray?.contentToString()}, aNullable8ByteArray=${aNullable8ByteArray?.contentToString()}, aNullableFloatArray=${aNullableFloatArray?.contentToString()}, aNullableEnum=$aNullableEnum, anotherNullableEnum=$anotherNullableEnum, aNullableString=$aNullableString, aNullableObject=$aNullableObject, allNullableTypes=$allNullableTypes, list=$list, stringList=$stringList, intList=$intList, doubleList=$doubleList, boolList=$boolList, enumList=$enumList, objectList=$objectList, listList=$listList, mapList=$mapList, recursiveClassList=$recursiveClassList, map=$map, stringMap=$stringMap, intMap=$intMap, enumMap=$enumMap, objectMap=$objectMap, listMap=$listMap, mapMap=$mapMap, recursiveClassMap=$recursiveClassMap)" + } } /** @@ -460,6 +464,10 @@ data class IntEvent(val value: Long) : PlatformEvent() { result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.value) return result } + + override fun toString(): String { + return "IntEvent(value=$value)" + } } /** Generated class from Pigeon that represents data sent in messages. */ @@ -493,6 +501,10 @@ data class StringEvent(val value: String) : PlatformEvent() { result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.value) return result } + + override fun toString(): String { + return "StringEvent(value=$value)" + } } /** Generated class from Pigeon that represents data sent in messages. */ @@ -526,6 +538,10 @@ data class BoolEvent(val value: Boolean) : PlatformEvent() { result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.value) return result } + + override fun toString(): String { + return "BoolEvent(value=$value)" + } } /** Generated class from Pigeon that represents data sent in messages. */ @@ -559,6 +575,10 @@ data class DoubleEvent(val value: Double) : PlatformEvent() { result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.value) return result } + + override fun toString(): String { + return "DoubleEvent(value=$value)" + } } /** Generated class from Pigeon that represents data sent in messages. */ @@ -592,6 +612,10 @@ data class ObjectsEvent(val value: Any) : PlatformEvent() { result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.value) return result } + + override fun toString(): String { + return "ObjectsEvent(value=$value)" + } } /** Generated class from Pigeon that represents data sent in messages. */ @@ -625,6 +649,10 @@ data class EnumEvent(val value: EventEnum) : PlatformEvent() { result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.value) return result } + + override fun toString(): String { + return "EnumEvent(value=$value)" + } } /** Generated class from Pigeon that represents data sent in messages. */ @@ -658,6 +686,10 @@ data class ClassEvent(val value: EventAllNullableTypes) : PlatformEvent() { result = 31 * result + EventChannelTestsPigeonUtils.deepHash(this.value) return result } + + override fun toString(): String { + return "ClassEvent(value=$value)" + } } private open class EventChannelTestsPigeonCodec : StandardMessageCodec() { diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt index ea402e91d7a4..dd42cb4ddb90 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt @@ -113,6 +113,22 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { return list } + override fun echoStringList(stringList: List): List { + return stringList + } + + override fun echoIntList(intList: List): List { + return intList + } + + override fun echoDoubleList(doubleList: List): List { + return doubleList + } + + override fun echoBoolList(boolList: List): List { + return boolList + } + override fun echoEnumList(enumList: List): List { return enumList } 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/DataClassMethodsTest.kt similarity index 89% rename from packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt rename to packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/DataClassMethodsTest.kt index 28a27c985604..ab9a69d91208 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/DataClassMethodsTest.kt @@ -15,7 +15,7 @@ import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Test -internal class AllDatatypesTest { +internal class DataClassMethodsTest { @Test fun testNullValues() { @@ -292,4 +292,15 @@ internal class AllDatatypesTest { assertEquals(a, b) assertEquals(a.hashCode(), b.hashCode()) } + + @Test + fun `toString full output serialization`() { + // On the JVM/Android, LinkedHashMap and standard Collection string formatting + // are deterministic, preserving insertion order. Thus, exact string snapshotting + // provides safe, complete, and robust validation across all 31 fields. + val everything = getFullyPopulatedAllNullableTypes() + assertEquals( + "AllNullableTypes(aNullableBool=false, aNullableInt=1234, aNullableInt64=null, aNullableDouble=2.0, aNullableByteArray=[1, 2, 3, 4], aNullable4ByteArray=[1, 2, 3, 4], aNullable8ByteArray=[1, 2, 3, 4], aNullableFloatArray=[0.5, 0.25, 1.5, 1.25], aNullableEnum=TWO, anotherNullableEnum=JUST_IN_CASE, aNullableString=hello, aNullableObject=0, allNullableTypes=null, list=[1, 2, 3], stringList=[string, another one], intList=[1, 2], doubleList=[1.1, 2.2], boolList=[true, false], enumList=[ONE, TWO], objectList=[1, 2, 3], listList=[[string, another one], [string, another one]], mapList=[{hello=1234}, {hello=1234}], recursiveClassList=null, map={hello=1234}, stringMap={hello=you}, intMap={1=0}, enumMap={ONE=FORTY_TWO, TWO=FOUR_HUNDRED_TWENTY_TWO}, objectMap={hello=1234}, listMap={1=[string, another one]}, mapMap={1={}}, recursiveClassMap=null)", + everything.toString()) + } } diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/ListTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/ListTest.kt index f91c0b747d3c..71b49995d0ee 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/ListTest.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/ListTest.kt @@ -43,4 +43,13 @@ class ListTest { assertTrue(didCall) } + + @Test + fun testToStringSnapshot() { + val msg = TestMessage(listOf("hello", 42)) + val str = msg.toString() + assertTrue(str.startsWith("TestMessage(testList=")) + assertTrue(str.contains("hello")) + assertTrue(str.contains("42")) + } } diff --git a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/CoreTests.gen.swift index 606d58783837..a7392aa9686f 100644 --- a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/CoreTests.gen.swift @@ -65,122 +65,132 @@ private func createConnectionError(withChannelName channelName: String) -> Pigeo details: "") } -private func isNullish(_ value: Any?) -> Bool { - return value is NSNull || value == nil -} +enum CoreTestsPigeonInternal { + static func isNullish(_ value: Any?) -> Bool { + guard let innerValue = value else { + return true + } -private func nilOrValue(_ value: Any?) -> T? { - if value is NSNull { return nil } - return value as! T? -} + if case Optional.some(Optional.none) = value { + return true + } -private func doubleEqualsCoreTests(_ lhs: Double, _ rhs: Double) -> Bool { - return (lhs.isNaN && rhs.isNaN) || lhs == rhs -} + return innerValue is NSNull + } + static func doubleEquals(_ lhs: Double, _ rhs: Double) -> Bool { + return (lhs.isNaN && rhs.isNaN) || lhs == rhs + } -private func doubleHashCoreTests(_ value: Double, _ hasher: inout Hasher) { - if value.isNaN { - hasher.combine(0x7FF8_0000_0000_0000) - } else { - // Normalize -0.0 to 0.0 - hasher.combine(value == 0 ? 0 : value) + static func doubleHash(_ value: Double, _ hasher: inout Hasher) { + if value.isNaN { + hasher.combine(0x7FF8_0000_0000_0000) + } else { + // Normalize -0.0 to 0.0 + hasher.combine(value == 0 ? 0 : value) + } } -} -func deepEqualsCoreTests(_ lhs: Any?, _ rhs: Any?) -> Bool { - let cleanLhs = nilOrValue(lhs) as Any? - let cleanRhs = nilOrValue(rhs) as Any? - switch (cleanLhs, cleanRhs) { - case (nil, nil): - return true + static func deepEquals(_ lhs: Any?, _ rhs: Any?) -> Bool { + let cleanLhs = nilOrValue(lhs) as Any? + let cleanRhs = nilOrValue(rhs) as Any? + switch (cleanLhs, cleanRhs) { + case (nil, nil): + return true - case (nil, _), (_, nil): - return false + case (nil, _), (_, nil): + return false - case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: - return true + case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: + return true - case is (Void, Void): - return true + case is (Void, Void): + return true - case (let lhsArray, let rhsArray) as ([Any?], [Any?]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !deepEqualsCoreTests(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Any?], [Any?]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !deepEquals(element, rhsArray[index]) { + return false + } } - } - return true + return true - case (let lhsArray, let rhsArray) as ([Double], [Double]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !doubleEqualsCoreTests(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Double], [Double]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !doubleEquals(element, rhsArray[index]) { + return false + } } - } - return true + return true - case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): - guard lhsDictionary.count == rhsDictionary.count else { return false } - for (lhsKey, lhsValue) in lhsDictionary { - var found = false - for (rhsKey, rhsValue) in rhsDictionary { - if deepEqualsCoreTests(lhsKey, rhsKey) { - if deepEqualsCoreTests(lhsValue, rhsValue) { - found = true - break - } else { - return false + case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): + guard lhsDictionary.count == rhsDictionary.count else { return false } + for (lhsKey, lhsValue) in lhsDictionary { + var found = false + for (rhsKey, rhsValue) in rhsDictionary { + if deepEquals(lhsKey, rhsKey) { + if deepEquals(lhsValue, rhsValue) { + found = true + break + } else { + return false + } } } + if !found { return false } } - if !found { return false } - } - return true + return true + + case (let lhs as Double, let rhs as Double): + return doubleEquals(lhs, rhs) - case (let lhs as Double, let rhs as Double): - return doubleEqualsCoreTests(lhs, rhs) + case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): + return lhsHashable == rhsHashable - case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): - return lhsHashable == rhsHashable + default: + return false + } + } - default: - return false + static func deepHash(value: Any?, hasher: inout Hasher) { + let cleanValue = nilOrValue(value) as Any? + if let cleanValue = cleanValue { + if let doubleValue = cleanValue as? Double { + doubleHash(doubleValue, &hasher) + } else if let valueList = cleanValue as? [Any?] { + for item in valueList { + deepHash(value: item, hasher: &hasher) + } + } else if let valueList = cleanValue as? [Double] { + for item in valueList { + doubleHash(item, &hasher) + } + } else if let valueDict = cleanValue as? [AnyHashable: Any?] { + var result = 0 + for (key, value) in valueDict { + var entryKeyHasher = Hasher() + deepHash(value: key, hasher: &entryKeyHasher) + var entryValueHasher = Hasher() + deepHash(value: value, hasher: &entryValueHasher) + result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + } + hasher.combine(result) + } else if let hashableValue = cleanValue as? AnyHashable { + hasher.combine(hashableValue) + } else { + hasher.combine(String(describing: cleanValue)) + } + } else { + hasher.combine(0) + } } + } -func deepHashCoreTests(value: Any?, hasher: inout Hasher) { - let cleanValue = nilOrValue(value) as Any? - if let cleanValue = cleanValue { - if let doubleValue = cleanValue as? Double { - doubleHashCoreTests(doubleValue, &hasher) - } else if let valueList = cleanValue as? [Any?] { - for item in valueList { - deepHashCoreTests(value: item, hasher: &hasher) - } - } else if let valueList = cleanValue as? [Double] { - for item in valueList { - doubleHashCoreTests(item, &hasher) - } - } else if let valueDict = cleanValue as? [AnyHashable: Any?] { - var result = 0 - for (key, value) in valueDict { - var entryKeyHasher = Hasher() - deepHashCoreTests(value: key, hasher: &entryKeyHasher) - var entryValueHasher = Hasher() - deepHashCoreTests(value: value, hasher: &entryValueHasher) - result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) - } - hasher.combine(result) - } else if let hashableValue = cleanValue as? AnyHashable { - hasher.combine(hashableValue) - } else { - hasher.combine(String(describing: cleanValue)) - } - } else { - hasher.combine(0) - } +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? } enum AnEnum: Int { @@ -196,7 +206,7 @@ enum AnotherEnum: Int { } /// Generated class from Pigeon that represents data sent in messages. -struct UnusedClass: Hashable { +struct UnusedClass: Hashable, CustomStringConvertible { var aField: Any? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -216,19 +226,23 @@ struct UnusedClass: Hashable { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsCoreTests(lhs.aField, rhs.aField) + return CoreTestsPigeonInternal.deepEquals(lhs.aField, rhs.aField) } func hash(into hasher: inout Hasher) { hasher.combine("UnusedClass") - deepHashCoreTests(value: aField, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aField, hasher: &hasher) + } + + public var description: String { + return "UnusedClass(aField: \(String(describing: aField)))" } } /// A class containing all supported types. /// /// Generated class from Pigeon that represents data sent in messages. -struct AllTypes: Hashable { +struct AllTypes: Hashable, CustomStringConvertible { var aBool: Bool var anInt: Int64 var anInt64: Int64 @@ -356,70 +370,78 @@ struct AllTypes: Hashable { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsCoreTests(lhs.aBool, rhs.aBool) && deepEqualsCoreTests(lhs.anInt, rhs.anInt) - && deepEqualsCoreTests(lhs.anInt64, rhs.anInt64) - && deepEqualsCoreTests(lhs.aDouble, rhs.aDouble) - && deepEqualsCoreTests(lhs.aByteArray, rhs.aByteArray) - && deepEqualsCoreTests(lhs.a4ByteArray, rhs.a4ByteArray) - && deepEqualsCoreTests(lhs.a8ByteArray, rhs.a8ByteArray) - && deepEqualsCoreTests(lhs.aFloatArray, rhs.aFloatArray) - && deepEqualsCoreTests(lhs.anEnum, rhs.anEnum) - && deepEqualsCoreTests(lhs.anotherEnum, rhs.anotherEnum) - && deepEqualsCoreTests(lhs.aString, rhs.aString) - && deepEqualsCoreTests(lhs.anObject, rhs.anObject) && deepEqualsCoreTests(lhs.list, rhs.list) - && deepEqualsCoreTests(lhs.stringList, rhs.stringList) - && deepEqualsCoreTests(lhs.intList, rhs.intList) - && deepEqualsCoreTests(lhs.doubleList, rhs.doubleList) - && deepEqualsCoreTests(lhs.boolList, rhs.boolList) - && deepEqualsCoreTests(lhs.enumList, rhs.enumList) - && deepEqualsCoreTests(lhs.objectList, rhs.objectList) - && deepEqualsCoreTests(lhs.listList, rhs.listList) - && deepEqualsCoreTests(lhs.mapList, rhs.mapList) && deepEqualsCoreTests(lhs.map, rhs.map) - && deepEqualsCoreTests(lhs.stringMap, rhs.stringMap) - && deepEqualsCoreTests(lhs.intMap, rhs.intMap) - && deepEqualsCoreTests(lhs.enumMap, rhs.enumMap) - && deepEqualsCoreTests(lhs.objectMap, rhs.objectMap) - && deepEqualsCoreTests(lhs.listMap, rhs.listMap) - && deepEqualsCoreTests(lhs.mapMap, rhs.mapMap) + return CoreTestsPigeonInternal.deepEquals(lhs.aBool, rhs.aBool) + && CoreTestsPigeonInternal.deepEquals(lhs.anInt, rhs.anInt) + && CoreTestsPigeonInternal.deepEquals(lhs.anInt64, rhs.anInt64) + && CoreTestsPigeonInternal.deepEquals(lhs.aDouble, rhs.aDouble) + && CoreTestsPigeonInternal.deepEquals(lhs.aByteArray, rhs.aByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.a4ByteArray, rhs.a4ByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.a8ByteArray, rhs.a8ByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aFloatArray, rhs.aFloatArray) + && CoreTestsPigeonInternal.deepEquals(lhs.anEnum, rhs.anEnum) + && CoreTestsPigeonInternal.deepEquals(lhs.anotherEnum, rhs.anotherEnum) + && CoreTestsPigeonInternal.deepEquals(lhs.aString, rhs.aString) + && CoreTestsPigeonInternal.deepEquals(lhs.anObject, rhs.anObject) + && CoreTestsPigeonInternal.deepEquals(lhs.list, rhs.list) + && CoreTestsPigeonInternal.deepEquals(lhs.stringList, rhs.stringList) + && CoreTestsPigeonInternal.deepEquals(lhs.intList, rhs.intList) + && CoreTestsPigeonInternal.deepEquals(lhs.doubleList, rhs.doubleList) + && CoreTestsPigeonInternal.deepEquals(lhs.boolList, rhs.boolList) + && CoreTestsPigeonInternal.deepEquals(lhs.enumList, rhs.enumList) + && CoreTestsPigeonInternal.deepEquals(lhs.objectList, rhs.objectList) + && CoreTestsPigeonInternal.deepEquals(lhs.listList, rhs.listList) + && CoreTestsPigeonInternal.deepEquals(lhs.mapList, rhs.mapList) + && CoreTestsPigeonInternal.deepEquals(lhs.map, rhs.map) + && CoreTestsPigeonInternal.deepEquals(lhs.stringMap, rhs.stringMap) + && CoreTestsPigeonInternal.deepEquals(lhs.intMap, rhs.intMap) + && CoreTestsPigeonInternal.deepEquals(lhs.enumMap, rhs.enumMap) + && CoreTestsPigeonInternal.deepEquals(lhs.objectMap, rhs.objectMap) + && CoreTestsPigeonInternal.deepEquals(lhs.listMap, rhs.listMap) + && CoreTestsPigeonInternal.deepEquals(lhs.mapMap, rhs.mapMap) } func hash(into hasher: inout Hasher) { hasher.combine("AllTypes") - deepHashCoreTests(value: aBool, hasher: &hasher) - deepHashCoreTests(value: anInt, hasher: &hasher) - deepHashCoreTests(value: anInt64, hasher: &hasher) - deepHashCoreTests(value: aDouble, hasher: &hasher) - deepHashCoreTests(value: aByteArray, hasher: &hasher) - deepHashCoreTests(value: a4ByteArray, hasher: &hasher) - deepHashCoreTests(value: a8ByteArray, hasher: &hasher) - deepHashCoreTests(value: aFloatArray, hasher: &hasher) - deepHashCoreTests(value: anEnum, hasher: &hasher) - deepHashCoreTests(value: anotherEnum, hasher: &hasher) - deepHashCoreTests(value: aString, hasher: &hasher) - deepHashCoreTests(value: anObject, hasher: &hasher) - deepHashCoreTests(value: list, hasher: &hasher) - deepHashCoreTests(value: stringList, hasher: &hasher) - deepHashCoreTests(value: intList, hasher: &hasher) - deepHashCoreTests(value: doubleList, hasher: &hasher) - deepHashCoreTests(value: boolList, hasher: &hasher) - deepHashCoreTests(value: enumList, hasher: &hasher) - deepHashCoreTests(value: objectList, hasher: &hasher) - deepHashCoreTests(value: listList, hasher: &hasher) - deepHashCoreTests(value: mapList, hasher: &hasher) - deepHashCoreTests(value: map, hasher: &hasher) - deepHashCoreTests(value: stringMap, hasher: &hasher) - deepHashCoreTests(value: intMap, hasher: &hasher) - deepHashCoreTests(value: enumMap, hasher: &hasher) - deepHashCoreTests(value: objectMap, hasher: &hasher) - deepHashCoreTests(value: listMap, hasher: &hasher) - deepHashCoreTests(value: mapMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aBool, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: anInt, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: anInt64, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aDouble, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: a4ByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: a8ByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aFloatArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: anEnum, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: anotherEnum, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aString, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: anObject, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: list, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: stringList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: intList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: doubleList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: boolList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: enumList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: objectList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: listList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: mapList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: map, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: stringMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: intMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: enumMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: objectMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: listMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: mapMap, hasher: &hasher) + } + + public var description: String { + return + "AllTypes(aBool: \(String(describing: aBool)), anInt: \(String(describing: anInt)), anInt64: \(String(describing: anInt64)), aDouble: \(String(describing: aDouble)), aByteArray: \(String(describing: aByteArray)), a4ByteArray: \(String(describing: a4ByteArray)), a8ByteArray: \(String(describing: a8ByteArray)), aFloatArray: \(String(describing: aFloatArray)), anEnum: \(String(describing: anEnum)), anotherEnum: \(String(describing: anotherEnum)), aString: \(String(describing: aString)), anObject: \(String(describing: anObject)), list: \(String(describing: list)), stringList: \(String(describing: stringList)), intList: \(String(describing: intList)), doubleList: \(String(describing: doubleList)), boolList: \(String(describing: boolList)), enumList: \(String(describing: enumList)), objectList: \(String(describing: objectList)), listList: \(String(describing: listList)), mapList: \(String(describing: mapList)), map: \(String(describing: map)), stringMap: \(String(describing: stringMap)), intMap: \(String(describing: intMap)), enumMap: \(String(describing: enumMap)), objectMap: \(String(describing: objectMap)), listMap: \(String(describing: listMap)), mapMap: \(String(describing: mapMap)))" } } /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -class AllNullableTypes: Hashable { +class AllNullableTypes: Hashable, CustomStringConvertible { init( aNullableBool: Bool? = nil, aNullableInt: Int64? = nil, @@ -627,71 +649,77 @@ class AllNullableTypes: Hashable { if lhs === rhs { return true } - return deepEqualsCoreTests(lhs.aNullableBool, rhs.aNullableBool) - && deepEqualsCoreTests(lhs.aNullableInt, rhs.aNullableInt) - && deepEqualsCoreTests(lhs.aNullableInt64, rhs.aNullableInt64) - && deepEqualsCoreTests(lhs.aNullableDouble, rhs.aNullableDouble) - && deepEqualsCoreTests(lhs.aNullableByteArray, rhs.aNullableByteArray) - && deepEqualsCoreTests(lhs.aNullable4ByteArray, rhs.aNullable4ByteArray) - && deepEqualsCoreTests(lhs.aNullable8ByteArray, rhs.aNullable8ByteArray) - && deepEqualsCoreTests(lhs.aNullableFloatArray, rhs.aNullableFloatArray) - && deepEqualsCoreTests(lhs.aNullableEnum, rhs.aNullableEnum) - && deepEqualsCoreTests(lhs.anotherNullableEnum, rhs.anotherNullableEnum) - && deepEqualsCoreTests(lhs.aNullableString, rhs.aNullableString) - && deepEqualsCoreTests(lhs.aNullableObject, rhs.aNullableObject) - && deepEqualsCoreTests(lhs.allNullableTypes, rhs.allNullableTypes) - && deepEqualsCoreTests(lhs.list, rhs.list) - && deepEqualsCoreTests(lhs.stringList, rhs.stringList) - && deepEqualsCoreTests(lhs.intList, rhs.intList) - && deepEqualsCoreTests(lhs.doubleList, rhs.doubleList) - && deepEqualsCoreTests(lhs.boolList, rhs.boolList) - && deepEqualsCoreTests(lhs.enumList, rhs.enumList) - && deepEqualsCoreTests(lhs.objectList, rhs.objectList) - && deepEqualsCoreTests(lhs.listList, rhs.listList) - && deepEqualsCoreTests(lhs.mapList, rhs.mapList) - && deepEqualsCoreTests(lhs.recursiveClassList, rhs.recursiveClassList) - && deepEqualsCoreTests(lhs.map, rhs.map) && deepEqualsCoreTests(lhs.stringMap, rhs.stringMap) - && deepEqualsCoreTests(lhs.intMap, rhs.intMap) - && deepEqualsCoreTests(lhs.enumMap, rhs.enumMap) - && deepEqualsCoreTests(lhs.objectMap, rhs.objectMap) - && deepEqualsCoreTests(lhs.listMap, rhs.listMap) - && deepEqualsCoreTests(lhs.mapMap, rhs.mapMap) - && deepEqualsCoreTests(lhs.recursiveClassMap, rhs.recursiveClassMap) + return CoreTestsPigeonInternal.deepEquals(lhs.aNullableBool, rhs.aNullableBool) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableInt, rhs.aNullableInt) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableInt64, rhs.aNullableInt64) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableDouble, rhs.aNullableDouble) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableByteArray, rhs.aNullableByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullable4ByteArray, rhs.aNullable4ByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullable8ByteArray, rhs.aNullable8ByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableFloatArray, rhs.aNullableFloatArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableEnum, rhs.aNullableEnum) + && CoreTestsPigeonInternal.deepEquals(lhs.anotherNullableEnum, rhs.anotherNullableEnum) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableString, rhs.aNullableString) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableObject, rhs.aNullableObject) + && CoreTestsPigeonInternal.deepEquals(lhs.allNullableTypes, rhs.allNullableTypes) + && CoreTestsPigeonInternal.deepEquals(lhs.list, rhs.list) + && CoreTestsPigeonInternal.deepEquals(lhs.stringList, rhs.stringList) + && CoreTestsPigeonInternal.deepEquals(lhs.intList, rhs.intList) + && CoreTestsPigeonInternal.deepEquals(lhs.doubleList, rhs.doubleList) + && CoreTestsPigeonInternal.deepEquals(lhs.boolList, rhs.boolList) + && CoreTestsPigeonInternal.deepEquals(lhs.enumList, rhs.enumList) + && CoreTestsPigeonInternal.deepEquals(lhs.objectList, rhs.objectList) + && CoreTestsPigeonInternal.deepEquals(lhs.listList, rhs.listList) + && CoreTestsPigeonInternal.deepEquals(lhs.mapList, rhs.mapList) + && CoreTestsPigeonInternal.deepEquals(lhs.recursiveClassList, rhs.recursiveClassList) + && CoreTestsPigeonInternal.deepEquals(lhs.map, rhs.map) + && CoreTestsPigeonInternal.deepEquals(lhs.stringMap, rhs.stringMap) + && CoreTestsPigeonInternal.deepEquals(lhs.intMap, rhs.intMap) + && CoreTestsPigeonInternal.deepEquals(lhs.enumMap, rhs.enumMap) + && CoreTestsPigeonInternal.deepEquals(lhs.objectMap, rhs.objectMap) + && CoreTestsPigeonInternal.deepEquals(lhs.listMap, rhs.listMap) + && CoreTestsPigeonInternal.deepEquals(lhs.mapMap, rhs.mapMap) + && CoreTestsPigeonInternal.deepEquals(lhs.recursiveClassMap, rhs.recursiveClassMap) } func hash(into hasher: inout Hasher) { hasher.combine("AllNullableTypes") - deepHashCoreTests(value: aNullableBool, hasher: &hasher) - deepHashCoreTests(value: aNullableInt, hasher: &hasher) - deepHashCoreTests(value: aNullableInt64, hasher: &hasher) - deepHashCoreTests(value: aNullableDouble, hasher: &hasher) - deepHashCoreTests(value: aNullableByteArray, hasher: &hasher) - deepHashCoreTests(value: aNullable4ByteArray, hasher: &hasher) - deepHashCoreTests(value: aNullable8ByteArray, hasher: &hasher) - deepHashCoreTests(value: aNullableFloatArray, hasher: &hasher) - deepHashCoreTests(value: aNullableEnum, hasher: &hasher) - deepHashCoreTests(value: anotherNullableEnum, hasher: &hasher) - deepHashCoreTests(value: aNullableString, hasher: &hasher) - deepHashCoreTests(value: aNullableObject, hasher: &hasher) - deepHashCoreTests(value: allNullableTypes, hasher: &hasher) - deepHashCoreTests(value: list, hasher: &hasher) - deepHashCoreTests(value: stringList, hasher: &hasher) - deepHashCoreTests(value: intList, hasher: &hasher) - deepHashCoreTests(value: doubleList, hasher: &hasher) - deepHashCoreTests(value: boolList, hasher: &hasher) - deepHashCoreTests(value: enumList, hasher: &hasher) - deepHashCoreTests(value: objectList, hasher: &hasher) - deepHashCoreTests(value: listList, hasher: &hasher) - deepHashCoreTests(value: mapList, hasher: &hasher) - deepHashCoreTests(value: recursiveClassList, hasher: &hasher) - deepHashCoreTests(value: map, hasher: &hasher) - deepHashCoreTests(value: stringMap, hasher: &hasher) - deepHashCoreTests(value: intMap, hasher: &hasher) - deepHashCoreTests(value: enumMap, hasher: &hasher) - deepHashCoreTests(value: objectMap, hasher: &hasher) - deepHashCoreTests(value: listMap, hasher: &hasher) - deepHashCoreTests(value: mapMap, hasher: &hasher) - deepHashCoreTests(value: recursiveClassMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableBool, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableInt, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableInt64, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableDouble, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullable4ByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullable8ByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableFloatArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableEnum, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: anotherNullableEnum, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableString, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableObject, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: allNullableTypes, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: list, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: stringList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: intList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: doubleList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: boolList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: enumList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: objectList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: listList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: mapList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: recursiveClassList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: map, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: stringMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: intMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: enumMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: objectMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: listMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: mapMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: recursiveClassMap, hasher: &hasher) + } + + public var description: String { + return + "AllNullableTypes(aNullableBool: \(String(describing: aNullableBool)), aNullableInt: \(String(describing: aNullableInt)), aNullableInt64: \(String(describing: aNullableInt64)), aNullableDouble: \(String(describing: aNullableDouble)), aNullableByteArray: \(String(describing: aNullableByteArray)), aNullable4ByteArray: \(String(describing: aNullable4ByteArray)), aNullable8ByteArray: \(String(describing: aNullable8ByteArray)), aNullableFloatArray: \(String(describing: aNullableFloatArray)), aNullableEnum: \(String(describing: aNullableEnum)), anotherNullableEnum: \(String(describing: anotherNullableEnum)), aNullableString: \(String(describing: aNullableString)), aNullableObject: \(String(describing: aNullableObject)), allNullableTypes: \(String(describing: allNullableTypes)), list: \(String(describing: list)), stringList: \(String(describing: stringList)), intList: \(String(describing: intList)), doubleList: \(String(describing: doubleList)), boolList: \(String(describing: boolList)), enumList: \(String(describing: enumList)), objectList: \(String(describing: objectList)), listList: \(String(describing: listList)), mapList: \(String(describing: mapList)), recursiveClassList: \(String(describing: recursiveClassList)), map: \(String(describing: map)), stringMap: \(String(describing: stringMap)), intMap: \(String(describing: intMap)), enumMap: \(String(describing: enumMap)), objectMap: \(String(describing: objectMap)), listMap: \(String(describing: listMap)), mapMap: \(String(describing: mapMap)), recursiveClassMap: \(String(describing: recursiveClassMap)))" } } @@ -700,7 +728,7 @@ class AllNullableTypes: Hashable { /// test Swift classes. /// /// Generated class from Pigeon that represents data sent in messages. -struct AllNullableTypesWithoutRecursion: Hashable { +struct AllNullableTypesWithoutRecursion: Hashable, CustomStringConvertible { var aNullableBool: Bool? = nil var aNullableInt: Int64? = nil var aNullableInt64: Int64? = nil @@ -830,65 +858,71 @@ struct AllNullableTypesWithoutRecursion: Hashable { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsCoreTests(lhs.aNullableBool, rhs.aNullableBool) - && deepEqualsCoreTests(lhs.aNullableInt, rhs.aNullableInt) - && deepEqualsCoreTests(lhs.aNullableInt64, rhs.aNullableInt64) - && deepEqualsCoreTests(lhs.aNullableDouble, rhs.aNullableDouble) - && deepEqualsCoreTests(lhs.aNullableByteArray, rhs.aNullableByteArray) - && deepEqualsCoreTests(lhs.aNullable4ByteArray, rhs.aNullable4ByteArray) - && deepEqualsCoreTests(lhs.aNullable8ByteArray, rhs.aNullable8ByteArray) - && deepEqualsCoreTests(lhs.aNullableFloatArray, rhs.aNullableFloatArray) - && deepEqualsCoreTests(lhs.aNullableEnum, rhs.aNullableEnum) - && deepEqualsCoreTests(lhs.anotherNullableEnum, rhs.anotherNullableEnum) - && deepEqualsCoreTests(lhs.aNullableString, rhs.aNullableString) - && deepEqualsCoreTests(lhs.aNullableObject, rhs.aNullableObject) - && deepEqualsCoreTests(lhs.list, rhs.list) - && deepEqualsCoreTests(lhs.stringList, rhs.stringList) - && deepEqualsCoreTests(lhs.intList, rhs.intList) - && deepEqualsCoreTests(lhs.doubleList, rhs.doubleList) - && deepEqualsCoreTests(lhs.boolList, rhs.boolList) - && deepEqualsCoreTests(lhs.enumList, rhs.enumList) - && deepEqualsCoreTests(lhs.objectList, rhs.objectList) - && deepEqualsCoreTests(lhs.listList, rhs.listList) - && deepEqualsCoreTests(lhs.mapList, rhs.mapList) && deepEqualsCoreTests(lhs.map, rhs.map) - && deepEqualsCoreTests(lhs.stringMap, rhs.stringMap) - && deepEqualsCoreTests(lhs.intMap, rhs.intMap) - && deepEqualsCoreTests(lhs.enumMap, rhs.enumMap) - && deepEqualsCoreTests(lhs.objectMap, rhs.objectMap) - && deepEqualsCoreTests(lhs.listMap, rhs.listMap) - && deepEqualsCoreTests(lhs.mapMap, rhs.mapMap) + return CoreTestsPigeonInternal.deepEquals(lhs.aNullableBool, rhs.aNullableBool) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableInt, rhs.aNullableInt) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableInt64, rhs.aNullableInt64) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableDouble, rhs.aNullableDouble) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableByteArray, rhs.aNullableByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullable4ByteArray, rhs.aNullable4ByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullable8ByteArray, rhs.aNullable8ByteArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableFloatArray, rhs.aNullableFloatArray) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableEnum, rhs.aNullableEnum) + && CoreTestsPigeonInternal.deepEquals(lhs.anotherNullableEnum, rhs.anotherNullableEnum) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableString, rhs.aNullableString) + && CoreTestsPigeonInternal.deepEquals(lhs.aNullableObject, rhs.aNullableObject) + && CoreTestsPigeonInternal.deepEquals(lhs.list, rhs.list) + && CoreTestsPigeonInternal.deepEquals(lhs.stringList, rhs.stringList) + && CoreTestsPigeonInternal.deepEquals(lhs.intList, rhs.intList) + && CoreTestsPigeonInternal.deepEquals(lhs.doubleList, rhs.doubleList) + && CoreTestsPigeonInternal.deepEquals(lhs.boolList, rhs.boolList) + && CoreTestsPigeonInternal.deepEquals(lhs.enumList, rhs.enumList) + && CoreTestsPigeonInternal.deepEquals(lhs.objectList, rhs.objectList) + && CoreTestsPigeonInternal.deepEquals(lhs.listList, rhs.listList) + && CoreTestsPigeonInternal.deepEquals(lhs.mapList, rhs.mapList) + && CoreTestsPigeonInternal.deepEquals(lhs.map, rhs.map) + && CoreTestsPigeonInternal.deepEquals(lhs.stringMap, rhs.stringMap) + && CoreTestsPigeonInternal.deepEquals(lhs.intMap, rhs.intMap) + && CoreTestsPigeonInternal.deepEquals(lhs.enumMap, rhs.enumMap) + && CoreTestsPigeonInternal.deepEquals(lhs.objectMap, rhs.objectMap) + && CoreTestsPigeonInternal.deepEquals(lhs.listMap, rhs.listMap) + && CoreTestsPigeonInternal.deepEquals(lhs.mapMap, rhs.mapMap) } func hash(into hasher: inout Hasher) { hasher.combine("AllNullableTypesWithoutRecursion") - deepHashCoreTests(value: aNullableBool, hasher: &hasher) - deepHashCoreTests(value: aNullableInt, hasher: &hasher) - deepHashCoreTests(value: aNullableInt64, hasher: &hasher) - deepHashCoreTests(value: aNullableDouble, hasher: &hasher) - deepHashCoreTests(value: aNullableByteArray, hasher: &hasher) - deepHashCoreTests(value: aNullable4ByteArray, hasher: &hasher) - deepHashCoreTests(value: aNullable8ByteArray, hasher: &hasher) - deepHashCoreTests(value: aNullableFloatArray, hasher: &hasher) - deepHashCoreTests(value: aNullableEnum, hasher: &hasher) - deepHashCoreTests(value: anotherNullableEnum, hasher: &hasher) - deepHashCoreTests(value: aNullableString, hasher: &hasher) - deepHashCoreTests(value: aNullableObject, hasher: &hasher) - deepHashCoreTests(value: list, hasher: &hasher) - deepHashCoreTests(value: stringList, hasher: &hasher) - deepHashCoreTests(value: intList, hasher: &hasher) - deepHashCoreTests(value: doubleList, hasher: &hasher) - deepHashCoreTests(value: boolList, hasher: &hasher) - deepHashCoreTests(value: enumList, hasher: &hasher) - deepHashCoreTests(value: objectList, hasher: &hasher) - deepHashCoreTests(value: listList, hasher: &hasher) - deepHashCoreTests(value: mapList, hasher: &hasher) - deepHashCoreTests(value: map, hasher: &hasher) - deepHashCoreTests(value: stringMap, hasher: &hasher) - deepHashCoreTests(value: intMap, hasher: &hasher) - deepHashCoreTests(value: enumMap, hasher: &hasher) - deepHashCoreTests(value: objectMap, hasher: &hasher) - deepHashCoreTests(value: listMap, hasher: &hasher) - deepHashCoreTests(value: mapMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableBool, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableInt, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableInt64, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableDouble, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullable4ByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullable8ByteArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableFloatArray, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableEnum, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: anotherNullableEnum, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableString, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: aNullableObject, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: list, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: stringList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: intList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: doubleList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: boolList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: enumList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: objectList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: listList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: mapList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: map, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: stringMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: intMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: enumMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: objectMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: listMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: mapMap, hasher: &hasher) + } + + public var description: String { + return + "AllNullableTypesWithoutRecursion(aNullableBool: \(String(describing: aNullableBool)), aNullableInt: \(String(describing: aNullableInt)), aNullableInt64: \(String(describing: aNullableInt64)), aNullableDouble: \(String(describing: aNullableDouble)), aNullableByteArray: \(String(describing: aNullableByteArray)), aNullable4ByteArray: \(String(describing: aNullable4ByteArray)), aNullable8ByteArray: \(String(describing: aNullable8ByteArray)), aNullableFloatArray: \(String(describing: aNullableFloatArray)), aNullableEnum: \(String(describing: aNullableEnum)), anotherNullableEnum: \(String(describing: anotherNullableEnum)), aNullableString: \(String(describing: aNullableString)), aNullableObject: \(String(describing: aNullableObject)), list: \(String(describing: list)), stringList: \(String(describing: stringList)), intList: \(String(describing: intList)), doubleList: \(String(describing: doubleList)), boolList: \(String(describing: boolList)), enumList: \(String(describing: enumList)), objectList: \(String(describing: objectList)), listList: \(String(describing: listList)), mapList: \(String(describing: mapList)), map: \(String(describing: map)), stringMap: \(String(describing: stringMap)), intMap: \(String(describing: intMap)), enumMap: \(String(describing: enumMap)), objectMap: \(String(describing: objectMap)), listMap: \(String(describing: listMap)), mapMap: \(String(describing: mapMap)))" } } @@ -899,7 +933,7 @@ struct AllNullableTypesWithoutRecursion: Hashable { /// than `AllTypes` when testing doesn't require both (ie. testing null classes). /// /// Generated class from Pigeon that represents data sent in messages. -struct AllClassesWrapper: Hashable { +struct AllClassesWrapper: Hashable, CustomStringConvertible { var allNullableTypes: AllNullableTypes var allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nil var allTypes: AllTypes? = nil @@ -945,32 +979,37 @@ struct AllClassesWrapper: Hashable { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsCoreTests(lhs.allNullableTypes, rhs.allNullableTypes) - && deepEqualsCoreTests( + return CoreTestsPigeonInternal.deepEquals(lhs.allNullableTypes, rhs.allNullableTypes) + && CoreTestsPigeonInternal.deepEquals( lhs.allNullableTypesWithoutRecursion, rhs.allNullableTypesWithoutRecursion) - && deepEqualsCoreTests(lhs.allTypes, rhs.allTypes) - && deepEqualsCoreTests(lhs.classList, rhs.classList) - && deepEqualsCoreTests(lhs.nullableClassList, rhs.nullableClassList) - && deepEqualsCoreTests(lhs.classMap, rhs.classMap) - && deepEqualsCoreTests(lhs.nullableClassMap, rhs.nullableClassMap) + && CoreTestsPigeonInternal.deepEquals(lhs.allTypes, rhs.allTypes) + && CoreTestsPigeonInternal.deepEquals(lhs.classList, rhs.classList) + && CoreTestsPigeonInternal.deepEquals(lhs.nullableClassList, rhs.nullableClassList) + && CoreTestsPigeonInternal.deepEquals(lhs.classMap, rhs.classMap) + && CoreTestsPigeonInternal.deepEquals(lhs.nullableClassMap, rhs.nullableClassMap) } func hash(into hasher: inout Hasher) { hasher.combine("AllClassesWrapper") - deepHashCoreTests(value: allNullableTypes, hasher: &hasher) - deepHashCoreTests(value: allNullableTypesWithoutRecursion, hasher: &hasher) - deepHashCoreTests(value: allTypes, hasher: &hasher) - deepHashCoreTests(value: classList, hasher: &hasher) - deepHashCoreTests(value: nullableClassList, hasher: &hasher) - deepHashCoreTests(value: classMap, hasher: &hasher) - deepHashCoreTests(value: nullableClassMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: allNullableTypes, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: allNullableTypesWithoutRecursion, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: allTypes, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: classList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: nullableClassList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: classMap, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: nullableClassMap, hasher: &hasher) + } + + public var description: String { + return + "AllClassesWrapper(allNullableTypes: \(String(describing: allNullableTypes)), allNullableTypesWithoutRecursion: \(String(describing: allNullableTypesWithoutRecursion)), allTypes: \(String(describing: allTypes)), classList: \(String(describing: classList)), nullableClassList: \(String(describing: nullableClassList)), classMap: \(String(describing: classMap)), nullableClassMap: \(String(describing: nullableClassMap)))" } } /// A data class containing a List, used in unit tests. /// /// Generated class from Pigeon that represents data sent in messages. -struct TestMessage: Hashable { +struct TestMessage: Hashable, CustomStringConvertible { var testList: [Any?]? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -990,12 +1029,16 @@ struct TestMessage: Hashable { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsCoreTests(lhs.testList, rhs.testList) + return CoreTestsPigeonInternal.deepEquals(lhs.testList, rhs.testList) } func hash(into hasher: inout Hasher) { hasher.combine("TestMessage") - deepHashCoreTests(value: testList, hasher: &hasher) + CoreTestsPigeonInternal.deepHash(value: testList, hasher: &hasher) + } + + public var description: String { + return "TestMessage(testList: \(String(describing: testList)))" } } @@ -1109,6 +1152,14 @@ protocol HostIntegrationCoreApi { /// Returns the passed list, to test serialization and deserialization. func echo(_ list: [Any?]) throws -> [Any?] /// Returns the passed list, to test serialization and deserialization. + func echo(stringList: [String?]) throws -> [String?] + /// Returns the passed list, to test serialization and deserialization. + func echo(intList: [Int64?]) throws -> [Int64?] + /// Returns the passed list, to test serialization and deserialization. + func echo(doubleList: [Double?]) throws -> [Double?] + /// Returns the passed list, to test serialization and deserialization. + func echo(boolList: [Bool?]) throws -> [Bool?] + /// Returns the passed list, to test serialization and deserialization. func echo(enumList: [AnEnum?]) throws -> [AnEnum?] /// Returns the passed list, to test serialization and deserialization. func echo(classList: [AllNullableTypes?]) throws -> [AllNullableTypes?] @@ -1685,6 +1736,82 @@ class HostIntegrationCoreApiSetup { echoListChannel.setMessageHandler(nil) } /// Returns the passed list, to test serialization and deserialization. + let echoStringListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoStringList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoStringListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let stringListArg = args[0] as! [String?] + do { + let result = try api.echo(stringList: stringListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoStringListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test serialization and deserialization. + let echoIntListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoIntList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoIntListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let intListArg = args[0] as! [Int64?] + do { + let result = try api.echo(intList: intListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoIntListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test serialization and deserialization. + let echoDoubleListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoDoubleList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoDoubleListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let doubleListArg = args[0] as! [Double?] + do { + let result = try api.echo(doubleList: doubleListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoDoubleListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test serialization and deserialization. + let echoBoolListChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoBoolList\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoBoolListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let boolListArg = args[0] as! [Bool?] + do { + let result = try api.echo(boolList: boolListArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoBoolListChannel.setMessageHandler(nil) + } + /// Returns the passed list, to test serialization and deserialization. let echoEnumListChannel = FlutterBasicMessageChannel( name: "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoEnumList\(channelSuffix)", @@ -4558,6 +4685,7 @@ class HostIntegrationCoreApiSetup { } } } + /// The core interface that the Dart platform_test code implements for host /// integration tests to call into. /// @@ -6253,6 +6381,7 @@ class HostSmallApiSetup { } } } + /// A simple API called in some unit tests. /// /// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. diff --git a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/EventChannelTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/EventChannelTests.gen.swift index da3e19626382..a41edd2fb053 100644 --- a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/EventChannelTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/EventChannelTests.gen.swift @@ -33,122 +33,132 @@ final class EventChannelTestsError: Error { } } -private func isNullish(_ value: Any?) -> Bool { - return value is NSNull || value == nil -} +enum EventChannelTestsPigeonInternal { + static func isNullish(_ value: Any?) -> Bool { + guard let innerValue = value else { + return true + } -private func nilOrValue(_ value: Any?) -> T? { - if value is NSNull { return nil } - return value as! T? -} + if case Optional.some(Optional.none) = value { + return true + } -private func doubleEqualsEventChannelTests(_ lhs: Double, _ rhs: Double) -> Bool { - return (lhs.isNaN && rhs.isNaN) || lhs == rhs -} + return innerValue is NSNull + } + static func doubleEquals(_ lhs: Double, _ rhs: Double) -> Bool { + return (lhs.isNaN && rhs.isNaN) || lhs == rhs + } -private func doubleHashEventChannelTests(_ value: Double, _ hasher: inout Hasher) { - if value.isNaN { - hasher.combine(0x7FF8_0000_0000_0000) - } else { - // Normalize -0.0 to 0.0 - hasher.combine(value == 0 ? 0 : value) + static func doubleHash(_ value: Double, _ hasher: inout Hasher) { + if value.isNaN { + hasher.combine(0x7FF8_0000_0000_0000) + } else { + // Normalize -0.0 to 0.0 + hasher.combine(value == 0 ? 0 : value) + } } -} -func deepEqualsEventChannelTests(_ lhs: Any?, _ rhs: Any?) -> Bool { - let cleanLhs = nilOrValue(lhs) as Any? - let cleanRhs = nilOrValue(rhs) as Any? - switch (cleanLhs, cleanRhs) { - case (nil, nil): - return true + static func deepEquals(_ lhs: Any?, _ rhs: Any?) -> Bool { + let cleanLhs = nilOrValue(lhs) as Any? + let cleanRhs = nilOrValue(rhs) as Any? + switch (cleanLhs, cleanRhs) { + case (nil, nil): + return true - case (nil, _), (_, nil): - return false + case (nil, _), (_, nil): + return false - case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: - return true + case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: + return true - case is (Void, Void): - return true + case is (Void, Void): + return true - case (let lhsArray, let rhsArray) as ([Any?], [Any?]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !deepEqualsEventChannelTests(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Any?], [Any?]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !deepEquals(element, rhsArray[index]) { + return false + } } - } - return true + return true - case (let lhsArray, let rhsArray) as ([Double], [Double]): - guard lhsArray.count == rhsArray.count else { return false } - for (index, element) in lhsArray.enumerated() { - if !doubleEqualsEventChannelTests(element, rhsArray[index]) { - return false + case (let lhsArray, let rhsArray) as ([Double], [Double]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !doubleEquals(element, rhsArray[index]) { + return false + } } - } - return true - - case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): - guard lhsDictionary.count == rhsDictionary.count else { return false } - for (lhsKey, lhsValue) in lhsDictionary { - var found = false - for (rhsKey, rhsValue) in rhsDictionary { - if deepEqualsEventChannelTests(lhsKey, rhsKey) { - if deepEqualsEventChannelTests(lhsValue, rhsValue) { - found = true - break - } else { - return false + return true + + case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): + guard lhsDictionary.count == rhsDictionary.count else { return false } + for (lhsKey, lhsValue) in lhsDictionary { + var found = false + for (rhsKey, rhsValue) in rhsDictionary { + if deepEquals(lhsKey, rhsKey) { + if deepEquals(lhsValue, rhsValue) { + found = true + break + } else { + return false + } } } + if !found { return false } } - if !found { return false } - } - return true + return true - case (let lhs as Double, let rhs as Double): - return doubleEqualsEventChannelTests(lhs, rhs) + case (let lhs as Double, let rhs as Double): + return doubleEquals(lhs, rhs) - case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): - return lhsHashable == rhsHashable + case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): + return lhsHashable == rhsHashable - default: - return false + default: + return false + } } -} -func deepHashEventChannelTests(value: Any?, hasher: inout Hasher) { - let cleanValue = nilOrValue(value) as Any? - if let cleanValue = cleanValue { - if let doubleValue = cleanValue as? Double { - doubleHashEventChannelTests(doubleValue, &hasher) - } else if let valueList = cleanValue as? [Any?] { - for item in valueList { - deepHashEventChannelTests(value: item, hasher: &hasher) - } - } else if let valueList = cleanValue as? [Double] { - for item in valueList { - doubleHashEventChannelTests(item, &hasher) - } - } else if let valueDict = cleanValue as? [AnyHashable: Any?] { - var result = 0 - for (key, value) in valueDict { - var entryKeyHasher = Hasher() - deepHashEventChannelTests(value: key, hasher: &entryKeyHasher) - var entryValueHasher = Hasher() - deepHashEventChannelTests(value: value, hasher: &entryValueHasher) - result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + static func deepHash(value: Any?, hasher: inout Hasher) { + let cleanValue = nilOrValue(value) as Any? + if let cleanValue = cleanValue { + if let doubleValue = cleanValue as? Double { + doubleHash(doubleValue, &hasher) + } else if let valueList = cleanValue as? [Any?] { + for item in valueList { + deepHash(value: item, hasher: &hasher) + } + } else if let valueList = cleanValue as? [Double] { + for item in valueList { + doubleHash(item, &hasher) + } + } else if let valueDict = cleanValue as? [AnyHashable: Any?] { + var result = 0 + for (key, value) in valueDict { + var entryKeyHasher = Hasher() + deepHash(value: key, hasher: &entryKeyHasher) + var entryValueHasher = Hasher() + deepHash(value: value, hasher: &entryValueHasher) + result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + } + hasher.combine(result) + } else if let hashableValue = cleanValue as? AnyHashable { + hasher.combine(hashableValue) + } else { + hasher.combine(String(describing: cleanValue)) } - hasher.combine(result) - } else if let hashableValue = cleanValue as? AnyHashable { - hasher.combine(hashableValue) } else { - hasher.combine(String(describing: cleanValue)) + hasher.combine(0) } - } else { - hasher.combine(0) } + +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? } enum EventEnum: Int { @@ -166,7 +176,7 @@ enum AnotherEventEnum: Int { /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -class EventAllNullableTypes: Hashable { +class EventAllNullableTypes: Hashable, CustomStringConvertible { init( aNullableBool: Bool? = nil, aNullableInt: Int64? = nil, @@ -374,72 +384,81 @@ class EventAllNullableTypes: Hashable { if lhs === rhs { return true } - return deepEqualsEventChannelTests(lhs.aNullableBool, rhs.aNullableBool) - && deepEqualsEventChannelTests(lhs.aNullableInt, rhs.aNullableInt) - && deepEqualsEventChannelTests(lhs.aNullableInt64, rhs.aNullableInt64) - && deepEqualsEventChannelTests(lhs.aNullableDouble, rhs.aNullableDouble) - && deepEqualsEventChannelTests(lhs.aNullableByteArray, rhs.aNullableByteArray) - && deepEqualsEventChannelTests(lhs.aNullable4ByteArray, rhs.aNullable4ByteArray) - && deepEqualsEventChannelTests(lhs.aNullable8ByteArray, rhs.aNullable8ByteArray) - && deepEqualsEventChannelTests(lhs.aNullableFloatArray, rhs.aNullableFloatArray) - && deepEqualsEventChannelTests(lhs.aNullableEnum, rhs.aNullableEnum) - && deepEqualsEventChannelTests(lhs.anotherNullableEnum, rhs.anotherNullableEnum) - && deepEqualsEventChannelTests(lhs.aNullableString, rhs.aNullableString) - && deepEqualsEventChannelTests(lhs.aNullableObject, rhs.aNullableObject) - && deepEqualsEventChannelTests(lhs.allNullableTypes, rhs.allNullableTypes) - && deepEqualsEventChannelTests(lhs.list, rhs.list) - && deepEqualsEventChannelTests(lhs.stringList, rhs.stringList) - && deepEqualsEventChannelTests(lhs.intList, rhs.intList) - && deepEqualsEventChannelTests(lhs.doubleList, rhs.doubleList) - && deepEqualsEventChannelTests(lhs.boolList, rhs.boolList) - && deepEqualsEventChannelTests(lhs.enumList, rhs.enumList) - && deepEqualsEventChannelTests(lhs.objectList, rhs.objectList) - && deepEqualsEventChannelTests(lhs.listList, rhs.listList) - && deepEqualsEventChannelTests(lhs.mapList, rhs.mapList) - && deepEqualsEventChannelTests(lhs.recursiveClassList, rhs.recursiveClassList) - && deepEqualsEventChannelTests(lhs.map, rhs.map) - && deepEqualsEventChannelTests(lhs.stringMap, rhs.stringMap) - && deepEqualsEventChannelTests(lhs.intMap, rhs.intMap) - && deepEqualsEventChannelTests(lhs.enumMap, rhs.enumMap) - && deepEqualsEventChannelTests(lhs.objectMap, rhs.objectMap) - && deepEqualsEventChannelTests(lhs.listMap, rhs.listMap) - && deepEqualsEventChannelTests(lhs.mapMap, rhs.mapMap) - && deepEqualsEventChannelTests(lhs.recursiveClassMap, rhs.recursiveClassMap) + return EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableBool, rhs.aNullableBool) + && EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableInt, rhs.aNullableInt) + && EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableInt64, rhs.aNullableInt64) + && EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableDouble, rhs.aNullableDouble) + && EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableByteArray, rhs.aNullableByteArray) + && EventChannelTestsPigeonInternal.deepEquals( + lhs.aNullable4ByteArray, rhs.aNullable4ByteArray) + && EventChannelTestsPigeonInternal.deepEquals( + lhs.aNullable8ByteArray, rhs.aNullable8ByteArray) + && EventChannelTestsPigeonInternal.deepEquals( + lhs.aNullableFloatArray, rhs.aNullableFloatArray) + && EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableEnum, rhs.aNullableEnum) + && EventChannelTestsPigeonInternal.deepEquals( + lhs.anotherNullableEnum, rhs.anotherNullableEnum) + && EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableString, rhs.aNullableString) + && EventChannelTestsPigeonInternal.deepEquals(lhs.aNullableObject, rhs.aNullableObject) + && EventChannelTestsPigeonInternal.deepEquals(lhs.allNullableTypes, rhs.allNullableTypes) + && EventChannelTestsPigeonInternal.deepEquals(lhs.list, rhs.list) + && EventChannelTestsPigeonInternal.deepEquals(lhs.stringList, rhs.stringList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.intList, rhs.intList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.doubleList, rhs.doubleList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.boolList, rhs.boolList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.enumList, rhs.enumList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.objectList, rhs.objectList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.listList, rhs.listList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.mapList, rhs.mapList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.recursiveClassList, rhs.recursiveClassList) + && EventChannelTestsPigeonInternal.deepEquals(lhs.map, rhs.map) + && EventChannelTestsPigeonInternal.deepEquals(lhs.stringMap, rhs.stringMap) + && EventChannelTestsPigeonInternal.deepEquals(lhs.intMap, rhs.intMap) + && EventChannelTestsPigeonInternal.deepEquals(lhs.enumMap, rhs.enumMap) + && EventChannelTestsPigeonInternal.deepEquals(lhs.objectMap, rhs.objectMap) + && EventChannelTestsPigeonInternal.deepEquals(lhs.listMap, rhs.listMap) + && EventChannelTestsPigeonInternal.deepEquals(lhs.mapMap, rhs.mapMap) + && EventChannelTestsPigeonInternal.deepEquals(lhs.recursiveClassMap, rhs.recursiveClassMap) } func hash(into hasher: inout Hasher) { hasher.combine("EventAllNullableTypes") - deepHashEventChannelTests(value: aNullableBool, hasher: &hasher) - deepHashEventChannelTests(value: aNullableInt, hasher: &hasher) - deepHashEventChannelTests(value: aNullableInt64, hasher: &hasher) - deepHashEventChannelTests(value: aNullableDouble, hasher: &hasher) - deepHashEventChannelTests(value: aNullableByteArray, hasher: &hasher) - deepHashEventChannelTests(value: aNullable4ByteArray, hasher: &hasher) - deepHashEventChannelTests(value: aNullable8ByteArray, hasher: &hasher) - deepHashEventChannelTests(value: aNullableFloatArray, hasher: &hasher) - deepHashEventChannelTests(value: aNullableEnum, hasher: &hasher) - deepHashEventChannelTests(value: anotherNullableEnum, hasher: &hasher) - deepHashEventChannelTests(value: aNullableString, hasher: &hasher) - deepHashEventChannelTests(value: aNullableObject, hasher: &hasher) - deepHashEventChannelTests(value: allNullableTypes, hasher: &hasher) - deepHashEventChannelTests(value: list, hasher: &hasher) - deepHashEventChannelTests(value: stringList, hasher: &hasher) - deepHashEventChannelTests(value: intList, hasher: &hasher) - deepHashEventChannelTests(value: doubleList, hasher: &hasher) - deepHashEventChannelTests(value: boolList, hasher: &hasher) - deepHashEventChannelTests(value: enumList, hasher: &hasher) - deepHashEventChannelTests(value: objectList, hasher: &hasher) - deepHashEventChannelTests(value: listList, hasher: &hasher) - deepHashEventChannelTests(value: mapList, hasher: &hasher) - deepHashEventChannelTests(value: recursiveClassList, hasher: &hasher) - deepHashEventChannelTests(value: map, hasher: &hasher) - deepHashEventChannelTests(value: stringMap, hasher: &hasher) - deepHashEventChannelTests(value: intMap, hasher: &hasher) - deepHashEventChannelTests(value: enumMap, hasher: &hasher) - deepHashEventChannelTests(value: objectMap, hasher: &hasher) - deepHashEventChannelTests(value: listMap, hasher: &hasher) - deepHashEventChannelTests(value: mapMap, hasher: &hasher) - deepHashEventChannelTests(value: recursiveClassMap, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableBool, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableInt, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableInt64, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableDouble, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableByteArray, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullable4ByteArray, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullable8ByteArray, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableFloatArray, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableEnum, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: anotherNullableEnum, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableString, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: aNullableObject, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: allNullableTypes, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: list, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: stringList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: intList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: doubleList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: boolList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: enumList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: objectList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: listList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: mapList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: recursiveClassList, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: map, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: stringMap, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: intMap, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: enumMap, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: objectMap, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: listMap, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: mapMap, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: recursiveClassMap, hasher: &hasher) + } + + public var description: String { + return + "EventAllNullableTypes(aNullableBool: \(String(describing: aNullableBool)), aNullableInt: \(String(describing: aNullableInt)), aNullableInt64: \(String(describing: aNullableInt64)), aNullableDouble: \(String(describing: aNullableDouble)), aNullableByteArray: \(String(describing: aNullableByteArray)), aNullable4ByteArray: \(String(describing: aNullable4ByteArray)), aNullable8ByteArray: \(String(describing: aNullable8ByteArray)), aNullableFloatArray: \(String(describing: aNullableFloatArray)), aNullableEnum: \(String(describing: aNullableEnum)), anotherNullableEnum: \(String(describing: anotherNullableEnum)), aNullableString: \(String(describing: aNullableString)), aNullableObject: \(String(describing: aNullableObject)), allNullableTypes: \(String(describing: allNullableTypes)), list: \(String(describing: list)), stringList: \(String(describing: stringList)), intList: \(String(describing: intList)), doubleList: \(String(describing: doubleList)), boolList: \(String(describing: boolList)), enumList: \(String(describing: enumList)), objectList: \(String(describing: objectList)), listList: \(String(describing: listList)), mapList: \(String(describing: mapList)), recursiveClassList: \(String(describing: recursiveClassList)), map: \(String(describing: map)), stringMap: \(String(describing: stringMap)), intMap: \(String(describing: intMap)), enumMap: \(String(describing: enumMap)), objectMap: \(String(describing: objectMap)), listMap: \(String(describing: listMap)), mapMap: \(String(describing: mapMap)), recursiveClassMap: \(String(describing: recursiveClassMap)))" } } @@ -470,12 +489,16 @@ struct IntEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelTests(lhs.value, rhs.value) + return EventChannelTestsPigeonInternal.deepEquals(lhs.value, rhs.value) } func hash(into hasher: inout Hasher) { hasher.combine("IntEvent") - deepHashEventChannelTests(value: value, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: value, hasher: &hasher) + } + + public var description: String { + return "IntEvent(value: \(String(describing: value)))" } } @@ -500,12 +523,16 @@ struct StringEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelTests(lhs.value, rhs.value) + return EventChannelTestsPigeonInternal.deepEquals(lhs.value, rhs.value) } func hash(into hasher: inout Hasher) { hasher.combine("StringEvent") - deepHashEventChannelTests(value: value, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: value, hasher: &hasher) + } + + public var description: String { + return "StringEvent(value: \(String(describing: value)))" } } @@ -530,12 +557,16 @@ struct BoolEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelTests(lhs.value, rhs.value) + return EventChannelTestsPigeonInternal.deepEquals(lhs.value, rhs.value) } func hash(into hasher: inout Hasher) { hasher.combine("BoolEvent") - deepHashEventChannelTests(value: value, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: value, hasher: &hasher) + } + + public var description: String { + return "BoolEvent(value: \(String(describing: value)))" } } @@ -560,12 +591,16 @@ struct DoubleEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelTests(lhs.value, rhs.value) + return EventChannelTestsPigeonInternal.deepEquals(lhs.value, rhs.value) } func hash(into hasher: inout Hasher) { hasher.combine("DoubleEvent") - deepHashEventChannelTests(value: value, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: value, hasher: &hasher) + } + + public var description: String { + return "DoubleEvent(value: \(String(describing: value)))" } } @@ -590,12 +625,16 @@ struct ObjectsEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelTests(lhs.value, rhs.value) + return EventChannelTestsPigeonInternal.deepEquals(lhs.value, rhs.value) } func hash(into hasher: inout Hasher) { hasher.combine("ObjectsEvent") - deepHashEventChannelTests(value: value, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: value, hasher: &hasher) + } + + public var description: String { + return "ObjectsEvent(value: \(String(describing: value)))" } } @@ -620,12 +659,16 @@ struct EnumEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelTests(lhs.value, rhs.value) + return EventChannelTestsPigeonInternal.deepEquals(lhs.value, rhs.value) } func hash(into hasher: inout Hasher) { hasher.combine("EnumEvent") - deepHashEventChannelTests(value: value, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: value, hasher: &hasher) + } + + public var description: String { + return "EnumEvent(value: \(String(describing: value)))" } } @@ -650,12 +693,16 @@ struct ClassEvent: PlatformEvent { if Swift.type(of: lhs) != Swift.type(of: rhs) { return false } - return deepEqualsEventChannelTests(lhs.value, rhs.value) + return EventChannelTestsPigeonInternal.deepEquals(lhs.value, rhs.value) } func hash(into hasher: inout Hasher) { hasher.combine("ClassEvent") - deepHashEventChannelTests(value: value, hasher: &hasher) + EventChannelTestsPigeonInternal.deepHash(value: value, hasher: &hasher) + } + + public var description: String { + return "ClassEvent(value: \(String(describing: value)))" } } diff --git a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/ProxyApiTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/ProxyApiTests.gen.swift index 5eb4b81803ad..c77dc71f58b3 100644 --- a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/ProxyApiTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/ProxyApiTests.gen.swift @@ -65,8 +65,18 @@ private func createConnectionError(withChannelName channelName: String) -> Proxy details: "") } -private func isNullish(_ value: Any?) -> Bool { - return value is NSNull || value == nil +enum ProxyApiTestsPigeonInternal { + static func isNullish(_ value: Any?) -> Bool { + guard let innerValue = value else { + return true + } + + if case Optional.some(Optional.none) = value { + return true + } + + return innerValue is NSNull + } } private func nilOrValue(_ value: Any?) -> T? { diff --git a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/TestPlugin.swift index 89d25d32f58e..95d63024e972 100644 --- a/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/darwin/test_plugin/Sources/test_plugin/TestPlugin.swift @@ -132,6 +132,22 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return list } + func echo(stringList: [String?]) throws -> [String?] { + return stringList + } + + func echo(intList: [Int64?]) throws -> [Int64?] { + return intList + } + + func echo(doubleList: [Double?]) throws -> [Double?] { + return doubleList + } + + func echo(boolList: [Bool?]) throws -> [Bool?] { + return boolList + } + func echo(enumList: [AnEnum?]) throws -> [AnEnum?] { return enumList } diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj b/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj index 1c93e5bc05f0..8f0aca3b9a14 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 33A341B8291ECCA100D34E0F /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341B7291ECCA100D34E0F /* RunnerTests.swift */; }; 33A341CB291ECDFD00D34E0F /* MultipleArityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341BF291ECDFD00D34E0F /* MultipleArityTests.swift */; }; - 33A341CC291ECDFD00D34E0F /* AllDatatypesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341C0291ECDFD00D34E0F /* AllDatatypesTests.swift */; }; + 33A341CC291ECDFD00D34E0F /* DataClassMethodsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341C0291ECDFD00D34E0F /* DataClassMethodsTests.swift */; }; 33A341CD291ECDFD00D34E0F /* ListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341C1291ECDFD00D34E0F /* ListTests.swift */; }; 33A341CE291ECDFD00D34E0F /* EnumTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341C2291ECDFD00D34E0F /* EnumTests.swift */; }; 33A341CF291ECDFD00D34E0F /* NonNullFieldsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A341C3291ECDFD00D34E0F /* NonNullFieldsTest.swift */; }; @@ -61,7 +61,7 @@ 33A341B5291ECCA100D34E0F /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 33A341B7291ECCA100D34E0F /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 33A341BF291ECDFD00D34E0F /* MultipleArityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipleArityTests.swift; sourceTree = ""; }; - 33A341C0291ECDFD00D34E0F /* AllDatatypesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AllDatatypesTests.swift; sourceTree = ""; }; + 33A341C0291ECDFD00D34E0F /* DataClassMethodsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataClassMethodsTests.swift; sourceTree = ""; }; 33A341C1291ECDFD00D34E0F /* ListTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTests.swift; sourceTree = ""; }; 33A341C2291ECDFD00D34E0F /* EnumTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnumTests.swift; sourceTree = ""; }; 33A341C3291ECDFD00D34E0F /* NonNullFieldsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonNullFieldsTest.swift; sourceTree = ""; }; @@ -113,7 +113,7 @@ 33A341B6291ECCA100D34E0F /* RunnerTests */ = { isa = PBXGroup; children = ( - 33A341C0291ECDFD00D34E0F /* AllDatatypesTests.swift */, + 33A341C0291ECDFD00D34E0F /* DataClassMethodsTests.swift */, 33A341C9291ECDFD00D34E0F /* AsyncHandlersTest.swift */, 33A341C4291ECDFD00D34E0F /* EchoBinaryMessenger.swift */, 33A341C2291ECDFD00D34E0F /* EnumTests.swift */, @@ -350,7 +350,7 @@ 33A341CF291ECDFD00D34E0F /* NonNullFieldsTest.swift in Sources */, F750BDEE2F28844900E3DB39 /* ProxyApiTests.swift in Sources */, 33A341CB291ECDFD00D34E0F /* MultipleArityTests.swift in Sources */, - 33A341CC291ECDFD00D34E0F /* AllDatatypesTests.swift in Sources */, + 33A341CC291ECDFD00D34E0F /* DataClassMethodsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/DataClassMethodsTests.swift similarity index 78% rename from packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift rename to packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/DataClassMethodsTests.swift index e855f673fd29..69360f095190 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/DataClassMethodsTests.swift @@ -8,7 +8,32 @@ import Testing @testable import test_plugin @MainActor -struct AllDatatypesTests { +struct DataClassMethodsTests { + + private let everythingFull = AllNullableTypes( + aNullableBool: true, + aNullableInt: 1, + aNullableDouble: 2.0, + aNullableByteArray: FlutterStandardTypedData(bytes: "1234".data(using: .utf8)!), + aNullable4ByteArray: FlutterStandardTypedData(int32: "1234".data(using: .utf8)!), + aNullable8ByteArray: FlutterStandardTypedData(int64: "12345678".data(using: .utf8)!), + aNullableFloatArray: FlutterStandardTypedData(float64: "12345678".data(using: .utf8)!), + aNullableString: "123", + list: ["string", 2], + stringList: ["string", "another one", nil], + intList: [1, 2], + doubleList: [1.1, 2.2], + boolList: [true, false], + objectList: ["string", 2], + listList: [[true], [false]], + mapList: [["hello": 1234], ["hello": 1234]], + map: ["hello": 1234, "null": nil], + stringMap: ["hello": "you"], + intMap: [1: 0], + objectMap: ["hello": 1234], + listMap: [1234: ["string", 2]], + mapMap: [1234: ["hello": 1234]] + ) @Test func allNull() async throws { @@ -31,30 +56,7 @@ struct AllDatatypesTests { @Test func allEquals() async throws { - let everything = AllNullableTypes( - aNullableBool: true, - aNullableInt: 1, - aNullableDouble: 2.0, - aNullableByteArray: FlutterStandardTypedData(bytes: "1234".data(using: .utf8)!), - aNullable4ByteArray: FlutterStandardTypedData(int32: "1234".data(using: .utf8)!), - aNullable8ByteArray: FlutterStandardTypedData(int64: "12345678".data(using: .utf8)!), - aNullableFloatArray: FlutterStandardTypedData(float64: "12345678".data(using: .utf8)!), - aNullableString: "123", - list: ["string", 2], - stringList: ["string", "another one", nil], - intList: [1, 2], - doubleList: [1.1, 2.2], - boolList: [true, false], - objectList: ["string", 2], - listList: [[true], [false]], - mapList: [["hello": 1234], ["hello": 1234]], - map: ["hello": 1234, "null": nil], - stringMap: ["hello": "you"], - intMap: [1: 0], - objectMap: ["hello": 1234], - listMap: [1234: ["string", 2]], - mapMap: [1234: ["hello": 1234]] - ) + let everything = everythingFull let binaryMessenger = EchoBinaryMessenger(codec: CoreTestsPigeonCodec.shared) let api = FlutterIntegrationCoreApi(binaryMessenger: binaryMessenger) @@ -72,6 +74,63 @@ struct AllDatatypesTests { } } + // We validate individual field outputs rather than asserting against a single exact expected string + // because `AllNullableTypes` contains Swift `Dictionary` properties. Swift hash maps serialize + // key-value pairs in a non-deterministic order across test executions, which would cause + // flaky CI failures if compared to a fixed canonical string. + @Test + func descriptionFullOutput() { + let desc = everythingFull.description + #expect(desc.hasPrefix("AllNullableTypes(")) + #expect(desc.hasSuffix(")")) + + let expectedFields = [ + "aNullableBool:", + "aNullableInt:", + "aNullableInt64:", + "aNullableDouble:", + "aNullableByteArray:", + "aNullable4ByteArray:", + "aNullable8ByteArray:", + "aNullableFloatArray:", + "aNullableEnum:", + "anotherNullableEnum:", + "aNullableString:", + "aNullableObject:", + "allNullableTypes:", + "list:", + "stringList:", + "intList:", + "doubleList:", + "boolList:", + "enumList:", + "objectList:", + "listList:", + "mapList:", + "recursiveClassList:", + "map:", + "stringMap:", + "intMap:", + "enumMap:", + "objectMap:", + "listMap:", + "mapMap:", + "recursiveClassMap:", + ] + + for field in expectedFields { + #expect(desc.contains(field)) + } + + #expect(desc.contains("aNullableBool: Optional(true)")) + #expect(desc.contains("aNullableInt: Optional(1)")) + #expect(desc.contains("aNullableDouble: Optional(2.0)")) + #expect(desc.contains("aNullableString: Optional(\"123\")")) + #expect(desc.contains("list: Optional([")) + #expect(desc.contains("stringList: Optional([")) + #expect(desc.contains("stringMap: Optional([")) + } + private let correctList: [Any?] = ["a", 2, "three"] private let matchingList: [Any?] = ["a", 2, "three"] private let differentList: [Any?] = ["a", 2, "three", 4.0] diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/IsNullishTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/IsNullishTests.swift new file mode 100644 index 000000000000..fc797a060480 --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/IsNullishTests.swift @@ -0,0 +1,58 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Foundation +import Testing + +@testable import test_plugin + +struct IsNullishTests { + + @Test + func testNil() { + let value: Any? = nil + #expect(CoreTestsPigeonInternal.isNullish(value) == true) + } + + @Test + func testNSNull() { + let value: Any? = NSNull() + #expect(CoreTestsPigeonInternal.isNullish(value) == true) + } + + @Test + func testNestedNil() { + let inner: Any? = nil + let value: Any? = inner + #expect(CoreTestsPigeonInternal.isNullish(value) == true) + } + + @Test + func testDoubleNestedNil() { + let innerMost: Any? = nil + let inner: Any?? = innerMost + let value: Any? = inner + #expect(CoreTestsPigeonInternal.isNullish(value) == true) + } + + @Test + func testTypedNil() { + let typedNil: String? = nil + let value: Any? = typedNil + #expect(CoreTestsPigeonInternal.isNullish(value) == true) + } + + @Test + func testNestedNSNull() { + let inner: Any? = NSNull() + let value: Any? = inner + #expect(CoreTestsPigeonInternal.isNullish(value) == true) + } + + @Test + func testNonNullValue() { + let value: Any? = "Hello" + #expect(CoreTestsPigeonInternal.isNullish(value) == false) + } +} diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/ListTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/ListTests.swift index a681304291b2..b4c0119c6128 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/ListTests.swift +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/ListTests.swift @@ -31,4 +31,13 @@ struct ListTests { } } + @Test + func descriptionSnapshot() { + let msg = TestMessage(testList: ["hello", 42]) + let desc = msg.description + #expect(desc.hasPrefix("TestMessage(testList: ")) + #expect(desc.contains("hello")) + #expect(desc.contains("42")) + } + } diff --git a/packages/pigeon/platform_tests/test_plugin/linux/CMakeLists.txt b/packages/pigeon/platform_tests/test_plugin/linux/CMakeLists.txt index df18c7756f36..00b9a970f1e7 100644 --- a/packages/pigeon/platform_tests/test_plugin/linux/CMakeLists.txt +++ b/packages/pigeon/platform_tests/test_plugin/linux/CMakeLists.txt @@ -100,7 +100,7 @@ add_executable(${TEST_RUNNER} test/nullable_returns_test.cc test/null_fields_test.cc test/primitive_test.cc - test/equality_test.cc + test/data_class_methods_test.cc # Test utilities. test/utils/fake_host_messenger.cc test/utils/fake_host_messenger.h diff --git a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc index 023cd1ed85db..d099ee1b7fb6 100644 --- a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc +++ b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc @@ -197,6 +197,108 @@ static guint G_GNUC_UNUSED flpigeon_deep_hash(FlValue* value) { } return 0; } +static gchar* G_GNUC_UNUSED flpigeon_to_string(FlValue* value) { + if (value == nullptr) { + return g_strdup("null"); + } + switch (fl_value_get_type(value)) { + case FL_VALUE_TYPE_NULL: + return g_strdup("null"); + case FL_VALUE_TYPE_BOOL: + return g_strdup(fl_value_get_bool(value) ? "true" : "false"); + case FL_VALUE_TYPE_INT: + return g_strdup_printf("%" G_GINT64_FORMAT, fl_value_get_int(value)); + case FL_VALUE_TYPE_FLOAT: + return g_strdup_printf("%g", fl_value_get_float(value)); + case FL_VALUE_TYPE_STRING: + return g_strdup_printf("\"%s\"", fl_value_get_string(value)); + case FL_VALUE_TYPE_UINT8_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const uint8_t* data = fl_value_get_uint8_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_INT32_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const int32_t* data = fl_value_get_int32_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_INT64_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const int64_t* data = fl_value_get_int64_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%" G_GINT64_FORMAT, data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_FLOAT_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + const double* data = fl_value_get_float_list(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%g", data[i]); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_LIST: { + GString* str = g_string_new("["); + size_t len = fl_value_get_length(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + gchar* item_str = flpigeon_to_string(fl_value_get_list_value(value, i)); + g_string_append(str, item_str); + g_free(item_str); + } + g_string_append(str, "]"); + return g_string_free(str, FALSE); + } + case FL_VALUE_TYPE_MAP: { + GString* str = g_string_new("{"); + size_t len = fl_value_get_length(value); + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + gchar* key_str = flpigeon_to_string(fl_value_get_map_key(value, i)); + gchar* val_str = flpigeon_to_string(fl_value_get_map_value(value, i)); + g_string_append_printf(str, "%s: %s", key_str, val_str); + g_free(key_str); + g_free(val_str); + } + g_string_append(str, "}"); + return g_string_free(str, FALSE); + } + default: + return g_strdup("[custom]"); + } + return g_strdup("null"); +} struct _CoreTestsPigeonTestUnusedClass { GObject parent_instance; @@ -282,6 +384,22 @@ guint core_tests_pigeon_test_unused_class_hash( return result; } +gchar* core_tests_pigeon_test_unused_class_to_string( + CoreTestsPigeonTestUnusedClass* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_UNUSED_CLASS(self), NULL); + GString* str = g_string_new("UnusedClass("); + g_string_append(str, "a_field: "); + if (self->a_field != nullptr) { + gchar* val_str = flpigeon_to_string(self->a_field); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestAllTypes { GObject parent_instance; @@ -909,6 +1027,228 @@ guint core_tests_pigeon_test_all_types_hash(CoreTestsPigeonTestAllTypes* self) { return result; } +gchar* core_tests_pigeon_test_all_types_to_string( + CoreTestsPigeonTestAllTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_TYPES(self), NULL); + GString* str = g_string_new("AllTypes("); + g_string_append(str, "a_bool: "); + g_string_append(str, self->a_bool ? "true" : "false"); + g_string_append(str, ", an_int: "); + g_string_append_printf(str, "%" G_GINT64_FORMAT, self->an_int); + g_string_append(str, ", an_int64: "); + g_string_append_printf(str, "%" G_GINT64_FORMAT, self->an_int64); + g_string_append(str, ", a_double: "); + g_string_append_printf(str, "%g", self->a_double); + g_string_append(str, ", a_byte_array: "); + if (self->a_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_byte_array_length; + const uint8_t* data = self->a_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", static_cast(data[i])); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a4_byte_array: "); + if (self->a4_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a4_byte_array_length; + const int32_t* data = self->a4_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", static_cast(data[i])); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a8_byte_array: "); + if (self->a8_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a8_byte_array_length; + const int64_t* data = self->a8_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%" G_GINT64_FORMAT, data[i]); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_float_array: "); + if (self->a_float_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_float_array_length; + const double* data = self->a_float_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%g", data[i]); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", an_enum: "); + g_string_append_printf(str, "%d", static_cast(self->an_enum)); + g_string_append(str, ", another_enum: "); + g_string_append_printf(str, "%d", static_cast(self->another_enum)); + g_string_append(str, ", a_string: "); + if (self->a_string != nullptr) { + g_string_append_printf(str, "\"%s\"", self->a_string); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", an_object: "); + if (self->an_object != nullptr) { + gchar* val_str = flpigeon_to_string(self->an_object); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list: "); + if (self->list != nullptr) { + gchar* val_str = flpigeon_to_string(self->list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", string_list: "); + if (self->string_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->string_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", int_list: "); + if (self->int_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->int_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", double_list: "); + if (self->double_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->double_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", bool_list: "); + if (self->bool_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->bool_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", enum_list: "); + if (self->enum_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->enum_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", object_list: "); + if (self->object_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->object_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list_list: "); + if (self->list_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->list_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map_list: "); + if (self->map_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->map_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map: "); + if (self->map != nullptr) { + gchar* val_str = flpigeon_to_string(self->map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", string_map: "); + if (self->string_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->string_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", int_map: "); + if (self->int_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->int_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", enum_map: "); + if (self->enum_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->enum_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", object_map: "); + if (self->object_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->object_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list_map: "); + if (self->list_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->list_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map_map: "); + if (self->map_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->map_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestAllNullableTypes { GObject parent_instance; @@ -2001,6 +2341,279 @@ guint core_tests_pigeon_test_all_nullable_types_hash( return result; } +gchar* core_tests_pigeon_test_all_nullable_types_to_string( + CoreTestsPigeonTestAllNullableTypes* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES(self), + NULL); + GString* str = g_string_new("AllNullableTypes("); + g_string_append(str, "a_nullable_bool: "); + if (self->a_nullable_bool != nullptr) { + g_string_append(str, *self->a_nullable_bool ? "true" : "false"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_int: "); + if (self->a_nullable_int != nullptr) { + g_string_append_printf(str, "%" G_GINT64_FORMAT, *self->a_nullable_int); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_int64: "); + if (self->a_nullable_int64 != nullptr) { + g_string_append_printf(str, "%" G_GINT64_FORMAT, *self->a_nullable_int64); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_double: "); + if (self->a_nullable_double != nullptr) { + g_string_append_printf(str, "%g", *self->a_nullable_double); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_byte_array: "); + if (self->a_nullable_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable_byte_array_length; + const uint8_t* data = self->a_nullable_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", static_cast(data[i])); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable4_byte_array: "); + if (self->a_nullable4_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable4_byte_array_length; + const int32_t* data = self->a_nullable4_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", static_cast(data[i])); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable8_byte_array: "); + if (self->a_nullable8_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable8_byte_array_length; + const int64_t* data = self->a_nullable8_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%" G_GINT64_FORMAT, data[i]); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_float_array: "); + if (self->a_nullable_float_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable_float_array_length; + const double* data = self->a_nullable_float_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%g", data[i]); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_enum: "); + if (self->a_nullable_enum != nullptr) { + g_string_append_printf(str, "%d", static_cast(*self->a_nullable_enum)); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", another_nullable_enum: "); + if (self->another_nullable_enum != nullptr) { + g_string_append_printf(str, "%d", + static_cast(*self->another_nullable_enum)); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_string: "); + if (self->a_nullable_string != nullptr) { + g_string_append_printf(str, "\"%s\"", self->a_nullable_string); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_object: "); + if (self->a_nullable_object != nullptr) { + gchar* val_str = flpigeon_to_string(self->a_nullable_object); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", all_nullable_types: "); + if (self->all_nullable_types != nullptr) { + gchar* field_str = core_tests_pigeon_test_all_nullable_types_to_string( + self->all_nullable_types); + g_string_append(str, field_str); + g_free(field_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list: "); + if (self->list != nullptr) { + gchar* val_str = flpigeon_to_string(self->list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", string_list: "); + if (self->string_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->string_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", int_list: "); + if (self->int_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->int_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", double_list: "); + if (self->double_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->double_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", bool_list: "); + if (self->bool_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->bool_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", enum_list: "); + if (self->enum_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->enum_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", object_list: "); + if (self->object_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->object_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list_list: "); + if (self->list_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->list_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map_list: "); + if (self->map_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->map_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", recursive_class_list: "); + if (self->recursive_class_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->recursive_class_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map: "); + if (self->map != nullptr) { + gchar* val_str = flpigeon_to_string(self->map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", string_map: "); + if (self->string_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->string_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", int_map: "); + if (self->int_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->int_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", enum_map: "); + if (self->enum_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->enum_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", object_map: "); + if (self->object_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->object_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list_map: "); + if (self->list_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->list_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map_map: "); + if (self->map_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->map_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", recursive_class_map: "); + if (self->recursive_class_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->recursive_class_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestAllNullableTypesWithoutRecursion { GObject parent_instance; @@ -3060,63 +3673,312 @@ guint core_tests_pigeon_test_all_nullable_types_without_recursion_hash( return result; } -struct _CoreTestsPigeonTestAllClassesWrapper { - GObject parent_instance; - - CoreTestsPigeonTestAllNullableTypes* all_nullable_types; - CoreTestsPigeonTestAllNullableTypesWithoutRecursion* - all_nullable_types_without_recursion; - CoreTestsPigeonTestAllTypes* all_types; - FlValue* class_list; - FlValue* nullable_class_list; - FlValue* class_map; - FlValue* nullable_class_map; -}; - -G_DEFINE_TYPE(CoreTestsPigeonTestAllClassesWrapper, - core_tests_pigeon_test_all_classes_wrapper, G_TYPE_OBJECT) - -static void core_tests_pigeon_test_all_classes_wrapper_dispose( - GObject* object) { - CoreTestsPigeonTestAllClassesWrapper* self = - CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER(object); - g_clear_object(&self->all_nullable_types); - g_clear_object(&self->all_nullable_types_without_recursion); - g_clear_object(&self->all_types); - g_clear_pointer(&self->class_list, fl_value_unref); - g_clear_pointer(&self->nullable_class_list, fl_value_unref); - g_clear_pointer(&self->class_map, fl_value_unref); - g_clear_pointer(&self->nullable_class_map, fl_value_unref); - G_OBJECT_CLASS(core_tests_pigeon_test_all_classes_wrapper_parent_class) - ->dispose(object); -} - -static void core_tests_pigeon_test_all_classes_wrapper_init( - CoreTestsPigeonTestAllClassesWrapper* self) {} - -static void core_tests_pigeon_test_all_classes_wrapper_class_init( - CoreTestsPigeonTestAllClassesWrapperClass* klass) { - G_OBJECT_CLASS(klass)->dispose = - core_tests_pigeon_test_all_classes_wrapper_dispose; -} - -CoreTestsPigeonTestAllClassesWrapper* -core_tests_pigeon_test_all_classes_wrapper_new( - CoreTestsPigeonTestAllNullableTypes* all_nullable_types, - CoreTestsPigeonTestAllNullableTypesWithoutRecursion* - all_nullable_types_without_recursion, - CoreTestsPigeonTestAllTypes* all_types, FlValue* class_list, - FlValue* nullable_class_list, FlValue* class_map, - FlValue* nullable_class_map) { - CoreTestsPigeonTestAllClassesWrapper* self = - CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER(g_object_new( - core_tests_pigeon_test_all_classes_wrapper_get_type(), nullptr)); - self->all_nullable_types = CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( - g_object_ref(all_nullable_types)); - if (all_nullable_types_without_recursion != nullptr) { - self->all_nullable_types_without_recursion = - CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( - g_object_ref(all_nullable_types_without_recursion)); +gchar* core_tests_pigeon_test_all_nullable_types_without_recursion_to_string( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* self) { + g_return_val_if_fail( + CORE_TESTS_PIGEON_TEST_IS_ALL_NULLABLE_TYPES_WITHOUT_RECURSION(self), + NULL); + GString* str = g_string_new("AllNullableTypesWithoutRecursion("); + g_string_append(str, "a_nullable_bool: "); + if (self->a_nullable_bool != nullptr) { + g_string_append(str, *self->a_nullable_bool ? "true" : "false"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_int: "); + if (self->a_nullable_int != nullptr) { + g_string_append_printf(str, "%" G_GINT64_FORMAT, *self->a_nullable_int); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_int64: "); + if (self->a_nullable_int64 != nullptr) { + g_string_append_printf(str, "%" G_GINT64_FORMAT, *self->a_nullable_int64); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_double: "); + if (self->a_nullable_double != nullptr) { + g_string_append_printf(str, "%g", *self->a_nullable_double); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_byte_array: "); + if (self->a_nullable_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable_byte_array_length; + const uint8_t* data = self->a_nullable_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", static_cast(data[i])); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable4_byte_array: "); + if (self->a_nullable4_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable4_byte_array_length; + const int32_t* data = self->a_nullable4_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%d", static_cast(data[i])); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable8_byte_array: "); + if (self->a_nullable8_byte_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable8_byte_array_length; + const int64_t* data = self->a_nullable8_byte_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%" G_GINT64_FORMAT, data[i]); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_float_array: "); + if (self->a_nullable_float_array != nullptr) { + g_string_append(str, "["); + size_t len = self->a_nullable_float_array_length; + const double* data = self->a_nullable_float_array; + for (size_t i = 0; i < len; i++) { + if (i > 0) { + g_string_append(str, ", "); + } + g_string_append_printf(str, "%g", data[i]); + } + g_string_append(str, "]"); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_enum: "); + if (self->a_nullable_enum != nullptr) { + g_string_append_printf(str, "%d", static_cast(*self->a_nullable_enum)); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", another_nullable_enum: "); + if (self->another_nullable_enum != nullptr) { + g_string_append_printf(str, "%d", + static_cast(*self->another_nullable_enum)); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_string: "); + if (self->a_nullable_string != nullptr) { + g_string_append_printf(str, "\"%s\"", self->a_nullable_string); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", a_nullable_object: "); + if (self->a_nullable_object != nullptr) { + gchar* val_str = flpigeon_to_string(self->a_nullable_object); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list: "); + if (self->list != nullptr) { + gchar* val_str = flpigeon_to_string(self->list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", string_list: "); + if (self->string_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->string_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", int_list: "); + if (self->int_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->int_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", double_list: "); + if (self->double_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->double_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", bool_list: "); + if (self->bool_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->bool_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", enum_list: "); + if (self->enum_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->enum_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", object_list: "); + if (self->object_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->object_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list_list: "); + if (self->list_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->list_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map_list: "); + if (self->map_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->map_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map: "); + if (self->map != nullptr) { + gchar* val_str = flpigeon_to_string(self->map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", string_map: "); + if (self->string_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->string_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", int_map: "); + if (self->int_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->int_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", enum_map: "); + if (self->enum_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->enum_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", object_map: "); + if (self->object_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->object_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", list_map: "); + if (self->list_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->list_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", map_map: "); + if (self->map_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->map_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + +struct _CoreTestsPigeonTestAllClassesWrapper { + GObject parent_instance; + + CoreTestsPigeonTestAllNullableTypes* all_nullable_types; + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion; + CoreTestsPigeonTestAllTypes* all_types; + FlValue* class_list; + FlValue* nullable_class_list; + FlValue* class_map; + FlValue* nullable_class_map; +}; + +G_DEFINE_TYPE(CoreTestsPigeonTestAllClassesWrapper, + core_tests_pigeon_test_all_classes_wrapper, G_TYPE_OBJECT) + +static void core_tests_pigeon_test_all_classes_wrapper_dispose( + GObject* object) { + CoreTestsPigeonTestAllClassesWrapper* self = + CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER(object); + g_clear_object(&self->all_nullable_types); + g_clear_object(&self->all_nullable_types_without_recursion); + g_clear_object(&self->all_types); + g_clear_pointer(&self->class_list, fl_value_unref); + g_clear_pointer(&self->nullable_class_list, fl_value_unref); + g_clear_pointer(&self->class_map, fl_value_unref); + g_clear_pointer(&self->nullable_class_map, fl_value_unref); + G_OBJECT_CLASS(core_tests_pigeon_test_all_classes_wrapper_parent_class) + ->dispose(object); +} + +static void core_tests_pigeon_test_all_classes_wrapper_init( + CoreTestsPigeonTestAllClassesWrapper* self) {} + +static void core_tests_pigeon_test_all_classes_wrapper_class_init( + CoreTestsPigeonTestAllClassesWrapperClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_all_classes_wrapper_dispose; +} + +CoreTestsPigeonTestAllClassesWrapper* +core_tests_pigeon_test_all_classes_wrapper_new( + CoreTestsPigeonTestAllNullableTypes* all_nullable_types, + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion, + CoreTestsPigeonTestAllTypes* all_types, FlValue* class_list, + FlValue* nullable_class_list, FlValue* class_map, + FlValue* nullable_class_map) { + CoreTestsPigeonTestAllClassesWrapper* self = + CORE_TESTS_PIGEON_TEST_ALL_CLASSES_WRAPPER(g_object_new( + core_tests_pigeon_test_all_classes_wrapper_get_type(), nullptr)); + self->all_nullable_types = CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES( + g_object_ref(all_nullable_types)); + if (all_nullable_types_without_recursion != nullptr) { + self->all_nullable_types_without_recursion = + CORE_TESTS_PIGEON_TEST_ALL_NULLABLE_TYPES_WITHOUT_RECURSION( + g_object_ref(all_nullable_types_without_recursion)); } else { self->all_nullable_types_without_recursion = nullptr; } @@ -3315,6 +4177,75 @@ guint core_tests_pigeon_test_all_classes_wrapper_hash( return result; } +gchar* core_tests_pigeon_test_all_classes_wrapper_to_string( + CoreTestsPigeonTestAllClassesWrapper* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_ALL_CLASSES_WRAPPER(self), + NULL); + GString* str = g_string_new("AllClassesWrapper("); + g_string_append(str, "all_nullable_types: "); + if (self->all_nullable_types != nullptr) { + gchar* field_str = core_tests_pigeon_test_all_nullable_types_to_string( + self->all_nullable_types); + g_string_append(str, field_str); + g_free(field_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", all_nullable_types_without_recursion: "); + if (self->all_nullable_types_without_recursion != nullptr) { + gchar* field_str = + core_tests_pigeon_test_all_nullable_types_without_recursion_to_string( + self->all_nullable_types_without_recursion); + g_string_append(str, field_str); + g_free(field_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", all_types: "); + if (self->all_types != nullptr) { + gchar* field_str = + core_tests_pigeon_test_all_types_to_string(self->all_types); + g_string_append(str, field_str); + g_free(field_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", class_list: "); + if (self->class_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->class_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", nullable_class_list: "); + if (self->nullable_class_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->nullable_class_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", class_map: "); + if (self->class_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->class_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", nullable_class_map: "); + if (self->nullable_class_map != nullptr) { + gchar* val_str = flpigeon_to_string(self->nullable_class_map); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestTestMessage { GObject parent_instance; @@ -3399,6 +4330,22 @@ guint core_tests_pigeon_test_test_message_hash( return result; } +gchar* core_tests_pigeon_test_test_message_to_string( + CoreTestsPigeonTestTestMessage* self) { + g_return_val_if_fail(CORE_TESTS_PIGEON_TEST_IS_TEST_MESSAGE(self), NULL); + GString* str = g_string_new("TestMessage("); + g_string_append(str, "test_list: "); + if (self->test_list != nullptr) { + gchar* val_str = flpigeon_to_string(self->test_list); + g_string_append(str, val_str); + g_free(val_str); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestMessageCodec { FlStandardMessageCodec parent_instance; }; @@ -4299,27 +5246,283 @@ static void core_tests_pigeon_test_host_integration_core_api_echo_bool_response_class_init( CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponseClass* klass) { G_OBJECT_CLASS(klass)->dispose = - core_tests_pigeon_test_host_integration_core_api_echo_bool_response_dispose; + core_tests_pigeon_test_host_integration_core_api_echo_bool_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new( + gboolean return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_bool(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_bool_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse, + core_tests_pigeon_test_host_integration_core_api_echo_string_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_string_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_string_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_response_new( + const gchar* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_string_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponseClass* + klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new( + const uint8_t* return_value, size_t return_value_length) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take( + self->value, fl_value_new_uint8_list(return_value, return_value_length)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse, + core_tests_pigeon_test_host_integration_core_api_echo_object_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_object_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_object_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_object_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_object_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_object_response_dispose; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_object_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_ref(return_value)); + return self; +} + +CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* +core_tests_pigeon_test_host_integration_core_api_echo_object_response_new_error( + const gchar* code, const gchar* message, FlValue* details) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_object_response_get_type(), + nullptr)); + self->value = fl_value_new_list(); + fl_value_append_take(self->value, fl_value_new_string(code)); + fl_value_append_take(self->value, + fl_value_new_string(message != nullptr ? message : "")); + fl_value_append_take(self->value, details != nullptr ? fl_value_ref(details) + : fl_value_new_null()); + return self; +} + +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse { + GObject parent_instance; + + FlValue* value; +}; + +G_DEFINE_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_list_response, + G_TYPE_OBJECT) + +static void +core_tests_pigeon_test_host_integration_core_api_echo_list_response_dispose( + GObject* object) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + object); + g_clear_pointer(&self->value, fl_value_unref); + G_OBJECT_CLASS( + core_tests_pigeon_test_host_integration_core_api_echo_list_response_parent_class) + ->dispose(object); +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self) {} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponseClass* klass) { + G_OBJECT_CLASS(klass)->dispose = + core_tests_pigeon_test_host_integration_core_api_echo_list_response_dispose; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* -core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new( - gboolean return_value) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE(g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_bool_response_get_type(), +CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); - fl_value_append_take(self->value, fl_value_new_bool(return_value)); + fl_value_append_take(self->value, fl_value_ref(return_value)); return self; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* -core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new_error( +CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_list_response_new_error( const gchar* code, const gchar* message, FlValue* details) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_RESPONSE(g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_bool_response_get_type(), + CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE(g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); fl_value_append_take(self->value, fl_value_new_string(code)); @@ -4330,60 +5533,61 @@ core_tests_pigeon_test_host_integration_core_api_echo_bool_response_new_error( return self; } -struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse { +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse { GObject parent_instance; FlValue* value; }; G_DEFINE_TYPE( - CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse, - core_tests_pigeon_test_host_integration_core_api_echo_string_response, + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_string_list_response, G_TYPE_OBJECT) static void -core_tests_pigeon_test_host_integration_core_api_echo_string_response_dispose( +core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_dispose( GObject* object) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_LIST_RESPONSE( object); g_clear_pointer(&self->value, fl_value_unref); G_OBJECT_CLASS( - core_tests_pigeon_test_host_integration_core_api_echo_string_response_parent_class) + core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_parent_class) ->dispose(object); } static void -core_tests_pigeon_test_host_integration_core_api_echo_string_response_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self) {} +core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* self) {} static void -core_tests_pigeon_test_host_integration_core_api_echo_string_response_class_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponseClass* klass) { +core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponseClass* + klass) { G_OBJECT_CLASS(klass)->dispose = - core_tests_pigeon_test_host_integration_core_api_echo_string_response_dispose; + core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_dispose; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* -core_tests_pigeon_test_host_integration_core_api_echo_string_response_new( - const gchar* return_value) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_LIST_RESPONSE( g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_string_response_get_type(), + core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); - fl_value_append_take(self->value, fl_value_new_string(return_value)); + fl_value_append_take(self->value, fl_value_ref(return_value)); return self; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* -core_tests_pigeon_test_host_integration_core_api_echo_string_response_new_error( +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_new_error( const gchar* code, const gchar* message, FlValue* details) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoStringResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_STRING_LIST_RESPONSE( g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_string_response_get_type(), + core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); fl_value_append_take(self->value, fl_value_new_string(code)); @@ -4394,62 +5598,60 @@ core_tests_pigeon_test_host_integration_core_api_echo_string_response_new_error( return self; } -struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse { +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse { GObject parent_instance; FlValue* value; }; G_DEFINE_TYPE( - CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse, - core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response, + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_int_list_response, G_TYPE_OBJECT) static void -core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_dispose( +core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_dispose( GObject* object) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_LIST_RESPONSE( object); g_clear_pointer(&self->value, fl_value_unref); G_OBJECT_CLASS( - core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_parent_class) + core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_parent_class) ->dispose(object); } static void -core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self) {} +core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* self) {} static void -core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_class_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponseClass* - klass) { +core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponseClass* klass) { G_OBJECT_CLASS(klass)->dispose = - core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_dispose; + core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_dispose; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* -core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new( - const uint8_t* return_value, size_t return_value_length) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_new( + FlValue* return_value) { + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_LIST_RESPONSE( g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_get_type(), + core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); - fl_value_append_take( - self->value, fl_value_new_uint8_list(return_value, return_value_length)); + fl_value_append_take(self->value, fl_value_ref(return_value)); return self; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* -core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new_error( +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_new_error( const gchar* code, const gchar* message, FlValue* details) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoUint8ListResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_UINT8_LIST_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_INT_LIST_RESPONSE( g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_get_type(), + core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); fl_value_append_take(self->value, fl_value_new_string(code)); @@ -4460,60 +5662,61 @@ core_tests_pigeon_test_host_integration_core_api_echo_uint8_list_response_new_er return self; } -struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse { +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse { GObject parent_instance; FlValue* value; }; G_DEFINE_TYPE( - CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse, - core_tests_pigeon_test_host_integration_core_api_echo_object_response, + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_double_list_response, G_TYPE_OBJECT) static void -core_tests_pigeon_test_host_integration_core_api_echo_object_response_dispose( +core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_dispose( GObject* object) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_LIST_RESPONSE( object); g_clear_pointer(&self->value, fl_value_unref); G_OBJECT_CLASS( - core_tests_pigeon_test_host_integration_core_api_echo_object_response_parent_class) + core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_parent_class) ->dispose(object); } static void -core_tests_pigeon_test_host_integration_core_api_echo_object_response_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self) {} +core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* self) {} static void -core_tests_pigeon_test_host_integration_core_api_echo_object_response_class_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponseClass* klass) { +core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponseClass* + klass) { G_OBJECT_CLASS(klass)->dispose = - core_tests_pigeon_test_host_integration_core_api_echo_object_response_dispose; + core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_dispose; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* -core_tests_pigeon_test_host_integration_core_api_echo_object_response_new( +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_new( FlValue* return_value) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_LIST_RESPONSE( g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_object_response_get_type(), + core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); fl_value_append_take(self->value, fl_value_ref(return_value)); return self; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* -core_tests_pigeon_test_host_integration_core_api_echo_object_response_new_error( +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_new_error( const gchar* code, const gchar* message, FlValue* details) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoObjectResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_OBJECT_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_LIST_RESPONSE( g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_object_response_get_type(), + core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_get_type(), nullptr)); self->value = fl_value_new_list(); fl_value_append_take(self->value, fl_value_new_string(code)); @@ -4524,59 +5727,61 @@ core_tests_pigeon_test_host_integration_core_api_echo_object_response_new_error( return self; } -struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse { +struct _CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse { GObject parent_instance; FlValue* value; }; G_DEFINE_TYPE( - CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse, - core_tests_pigeon_test_host_integration_core_api_echo_list_response, + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response, G_TYPE_OBJECT) static void -core_tests_pigeon_test_host_integration_core_api_echo_list_response_dispose( +core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_dispose( GObject* object) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_LIST_RESPONSE( object); g_clear_pointer(&self->value, fl_value_unref); G_OBJECT_CLASS( - core_tests_pigeon_test_host_integration_core_api_echo_list_response_parent_class) + core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_parent_class) ->dispose(object); } static void -core_tests_pigeon_test_host_integration_core_api_echo_list_response_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self) {} +core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* self) {} static void -core_tests_pigeon_test_host_integration_core_api_echo_list_response_class_init( - CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponseClass* klass) { +core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_class_init( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponseClass* klass) { G_OBJECT_CLASS(klass)->dispose = - core_tests_pigeon_test_host_integration_core_api_echo_list_response_dispose; + core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_dispose; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* -core_tests_pigeon_test_host_integration_core_api_echo_list_response_new( +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_new( FlValue* return_value) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE(g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_list_response_get_type(), - nullptr)); + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_get_type(), + nullptr)); self->value = fl_value_new_list(); fl_value_append_take(self->value, fl_value_ref(return_value)); return self; } -CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* -core_tests_pigeon_test_host_integration_core_api_echo_list_response_new_error( +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_new_error( const gchar* code, const gchar* message, FlValue* details) { - CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* self = - CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_LIST_RESPONSE(g_object_new( - core_tests_pigeon_test_host_integration_core_api_echo_list_response_get_type(), - nullptr)); + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API_ECHO_BOOL_LIST_RESPONSE( + g_object_new( + core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_get_type(), + nullptr)); self->value = fl_value_new_list(); fl_value_append_take(self->value, fl_value_new_string(code)); fl_value_append_take(self->value, @@ -15347,6 +16552,120 @@ static void core_tests_pigeon_test_host_integration_core_api_echo_list_cb( } } +static void +core_tests_pigeon_test_host_integration_core_api_echo_string_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_string_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* string_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse) + response = self->vtable->echo_string_list(string_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoStringList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoStringList", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_int_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_int_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* int_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse) + response = self->vtable->echo_int_list(int_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoIntList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoIntList", error->message); + } +} + +static void +core_tests_pigeon_test_host_integration_core_api_echo_double_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_double_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* double_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse) + response = self->vtable->echo_double_list(double_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoDoubleList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoDoubleList", error->message); + } +} + +static void core_tests_pigeon_test_host_integration_core_api_echo_bool_list_cb( + FlBasicMessageChannel* channel, FlValue* message_, + FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { + CoreTestsPigeonTestHostIntegrationCoreApi* self = + CORE_TESTS_PIGEON_TEST_HOST_INTEGRATION_CORE_API(user_data); + + if (self->vtable == nullptr || self->vtable->echo_bool_list == nullptr) { + return; + } + + FlValue* value0 = fl_value_get_list_value(message_, 0); + FlValue* bool_list = value0; + g_autoptr(CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse) + response = self->vtable->echo_bool_list(bool_list, self->user_data); + if (response == nullptr) { + g_warning("No response returned to %s.%s", "HostIntegrationCoreApi", + "echoBoolList"); + return; + } + + g_autoptr(GError) error = NULL; + if (!fl_basic_message_channel_respond(channel, response_handle, + response->value, &error)) { + g_warning("Failed to send response to %s.%s: %s", "HostIntegrationCoreApi", + "echoBoolList", error->message); + } +} + static void core_tests_pigeon_test_host_integration_core_api_echo_enum_list_cb( FlBasicMessageChannel* channel, FlValue* message_, FlBasicMessageChannelResponseHandle* response_handle, gpointer user_data) { @@ -19163,6 +20482,50 @@ void core_tests_pigeon_test_host_integration_core_api_set_method_handlers( echo_list_channel, core_tests_pigeon_test_host_integration_core_api_echo_list_cb, g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_string_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoStringList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_string_list_channel = + fl_basic_message_channel_new(messenger, echo_string_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_string_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_string_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_int_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoIntList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_int_list_channel = + fl_basic_message_channel_new(messenger, echo_int_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_int_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_int_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_double_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoDoubleList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_double_list_channel = + fl_basic_message_channel_new(messenger, echo_double_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_double_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_double_list_cb, + g_object_ref(api_data), g_object_unref); + g_autofree gchar* echo_bool_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoBoolList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_bool_list_channel = + fl_basic_message_channel_new(messenger, echo_bool_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler( + echo_bool_list_channel, + core_tests_pigeon_test_host_integration_core_api_echo_bool_list_cb, + g_object_ref(api_data), g_object_unref); g_autofree gchar* echo_enum_list_channel_name = g_strdup_printf( "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." "echoEnumList%s", @@ -21075,6 +22438,42 @@ void core_tests_pigeon_test_host_integration_core_api_clear_method_handlers( FL_MESSAGE_CODEC(codec)); fl_basic_message_channel_set_message_handler(echo_list_channel, nullptr, nullptr, nullptr); + g_autofree gchar* echo_string_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoStringList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_string_list_channel = + fl_basic_message_channel_new(messenger, echo_string_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_string_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_int_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoIntList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_int_list_channel = + fl_basic_message_channel_new(messenger, echo_int_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_int_list_channel, nullptr, + nullptr, nullptr); + g_autofree gchar* echo_double_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoDoubleList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_double_list_channel = + fl_basic_message_channel_new(messenger, echo_double_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_double_list_channel, + nullptr, nullptr, nullptr); + g_autofree gchar* echo_bool_list_channel_name = g_strdup_printf( + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoBoolList%s", + dot_suffix); + g_autoptr(FlBasicMessageChannel) echo_bool_list_channel = + fl_basic_message_channel_new(messenger, echo_bool_list_channel_name, + FL_MESSAGE_CODEC(codec)); + fl_basic_message_channel_set_message_handler(echo_bool_list_channel, nullptr, + nullptr, nullptr); g_autofree gchar* echo_enum_list_channel_name = g_strdup_printf( "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." "echoEnumList%s", diff --git a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h index 322b9bc8a6b5..e5d97e289756 100644 --- a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h @@ -92,6 +92,17 @@ gboolean core_tests_pigeon_test_unused_class_equals( guint core_tests_pigeon_test_unused_class_hash( CoreTestsPigeonTestUnusedClass* object); +/** + * core_tests_pigeon_test_unused_class_to_string: + * @object: a #CoreTestsPigeonTestUnusedClass. + * + * Returns a string representation of a #CoreTestsPigeonTestUnusedClass object. + * + * Returns: (transfer full): a new string, free with g_free(). + */ +gchar* core_tests_pigeon_test_unused_class_to_string( + CoreTestsPigeonTestUnusedClass* object); + /** * CoreTestsPigeonTestAllTypes: * @@ -491,6 +502,17 @@ gboolean core_tests_pigeon_test_all_types_equals( guint core_tests_pigeon_test_all_types_hash( CoreTestsPigeonTestAllTypes* object); +/** + * core_tests_pigeon_test_all_types_to_string: + * @object: a #CoreTestsPigeonTestAllTypes. + * + * Returns a string representation of a #CoreTestsPigeonTestAllTypes object. + * + * Returns: (transfer full): a new string, free with g_free(). + */ +gchar* core_tests_pigeon_test_all_types_to_string( + CoreTestsPigeonTestAllTypes* object); + /** * CoreTestsPigeonTestAllNullableTypes: * @@ -938,6 +960,18 @@ gboolean core_tests_pigeon_test_all_nullable_types_equals( guint core_tests_pigeon_test_all_nullable_types_hash( CoreTestsPigeonTestAllNullableTypes* object); +/** + * core_tests_pigeon_test_all_nullable_types_to_string: + * @object: a #CoreTestsPigeonTestAllNullableTypes. + * + * Returns a string representation of a #CoreTestsPigeonTestAllNullableTypes + * object. + * + * Returns: (transfer full): a new string, free with g_free(). + */ +gchar* core_tests_pigeon_test_all_nullable_types_to_string( + CoreTestsPigeonTestAllNullableTypes* object); + /** * CoreTestsPigeonTestAllNullableTypesWithoutRecursion: * @@ -1375,6 +1409,18 @@ gboolean core_tests_pigeon_test_all_nullable_types_without_recursion_equals( guint core_tests_pigeon_test_all_nullable_types_without_recursion_hash( CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); +/** + * core_tests_pigeon_test_all_nullable_types_without_recursion_to_string: + * @object: a #CoreTestsPigeonTestAllNullableTypesWithoutRecursion. + * + * Returns a string representation of a + * #CoreTestsPigeonTestAllNullableTypesWithoutRecursion object. + * + * Returns: (transfer full): a new string, free with g_free(). + */ +gchar* core_tests_pigeon_test_all_nullable_types_without_recursion_to_string( + CoreTestsPigeonTestAllNullableTypesWithoutRecursion* object); + /** * CoreTestsPigeonTestAllClassesWrapper: * @@ -1516,6 +1562,18 @@ gboolean core_tests_pigeon_test_all_classes_wrapper_equals( guint core_tests_pigeon_test_all_classes_wrapper_hash( CoreTestsPigeonTestAllClassesWrapper* object); +/** + * core_tests_pigeon_test_all_classes_wrapper_to_string: + * @object: a #CoreTestsPigeonTestAllClassesWrapper. + * + * Returns a string representation of a #CoreTestsPigeonTestAllClassesWrapper + * object. + * + * Returns: (transfer full): a new string, free with g_free(). + */ +gchar* core_tests_pigeon_test_all_classes_wrapper_to_string( + CoreTestsPigeonTestAllClassesWrapper* object); + /** * CoreTestsPigeonTestTestMessage: * @@ -1571,6 +1629,17 @@ gboolean core_tests_pigeon_test_test_message_equals( guint core_tests_pigeon_test_test_message_hash( CoreTestsPigeonTestTestMessage* object); +/** + * core_tests_pigeon_test_test_message_to_string: + * @object: a #CoreTestsPigeonTestTestMessage. + * + * Returns a string representation of a #CoreTestsPigeonTestTestMessage object. + * + * Returns: (transfer full): a new string, free with g_free(). + */ +gchar* core_tests_pigeon_test_test_message_to_string( + CoreTestsPigeonTestTestMessage* object); + G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestMessageCodec, core_tests_pigeon_test_message_codec, CORE_TESTS_PIGEON_TEST, MESSAGE_CODEC, @@ -1977,6 +2046,134 @@ CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* core_tests_pigeon_test_host_integration_core_api_echo_list_response_new_error( const gchar* code, const gchar* message, FlValue* details); +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_string_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_STRING_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoStringList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoStringList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_int_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_INT_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoIntList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoIntList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_double_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_DOUBLE_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoDoubleList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoDoubleList. + * + * Returns: a new + * #CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + +G_DECLARE_FINAL_TYPE( + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse, + core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response, + CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API_ECHO_BOOL_LIST_RESPONSE, + GObject) + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_new: + * + * Creates a new response to HostIntegrationCoreApi.echoBoolList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_new( + FlValue* return_value); + +/** + * core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_new_error: + * @code: error code. + * @message: error message. + * @details: (allow-none): error details or %NULL. + * + * Creates a new error response to HostIntegrationCoreApi.echoBoolList. + * + * Returns: a new #CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse + */ +CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* +core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_new_error( + const gchar* code, const gchar* message, FlValue* details); + G_DECLARE_FINAL_TYPE( CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse, core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response, @@ -3812,6 +4009,14 @@ typedef struct { FlValue* an_object, gpointer user_data); CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* (*echo_list)( FlValue* list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* ( + *echo_string_list)(FlValue* string_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* ( + *echo_int_list)(FlValue* int_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* ( + *echo_double_list)(FlValue* double_list, gpointer user_data); + CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* ( + *echo_bool_list)(FlValue* bool_list, gpointer user_data); CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* ( *echo_enum_list)(FlValue* enum_list, gpointer user_data); CoreTestsPigeonTestHostIntegrationCoreApiEchoClassListResponse* ( diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test/equality_test.cc b/packages/pigeon/platform_tests/test_plugin/linux/test/data_class_methods_test.cc similarity index 78% rename from packages/pigeon/platform_tests/test_plugin/linux/test/equality_test.cc rename to packages/pigeon/platform_tests/test_plugin/linux/test/data_class_methods_test.cc index 349c4bdd34cb..0346da708dec 100644 --- a/packages/pigeon/platform_tests/test_plugin/linux/test/equality_test.cc +++ b/packages/pigeon/platform_tests/test_plugin/linux/test/data_class_methods_test.cc @@ -236,3 +236,70 @@ TEST(Equality, SignedZeroMapValue) { EXPECT_EQ(core_tests_pigeon_test_all_nullable_types_hash(all1), core_tests_pigeon_test_all_nullable_types_hash(all2)); } + +TEST(Equality, ToStringSnapshot) { + g_autoptr(CoreTestsPigeonTestAllNullableTypes) empty_obj = + create_empty_all_nullable_types(); + + gchar* str = core_tests_pigeon_test_all_nullable_types_to_string(empty_obj); + ASSERT_NE(str, nullptr); + + // Verify structural validation across all 31 serialized fields. + const char* expected_fields[] = {"AllNullableTypes(", + "a_nullable_bool: null", + "a_nullable_int: null", + "a_nullable_int64: null", + "a_nullable_double: null", + "a_nullable_byte_array: null", + "a_nullable4_byte_array: null", + "a_nullable8_byte_array: null", + "a_nullable_float_array: null", + "a_nullable_enum: null", + "another_nullable_enum: null", + "a_nullable_string: null", + "a_nullable_object: null", + "all_nullable_types: null", + "list: null", + "string_list: null", + "int_list: null", + "double_list: null", + "bool_list: null", + "enum_list: null", + "object_list: null", + "list_list: null", + "map_list: null", + "recursive_class_list: null", + "map: null", + "string_map: null", + "int_map: null", + "enum_map: null", + "object_map: null", + "list_map: null", + "map_map: null", + "recursive_class_map: null"}; + + for (const char* field : expected_fields) { + EXPECT_TRUE(strstr(str, field) != nullptr) + << "Missing expected serialized field content: " << field; + } + + // Also verify exact expected canonical string layout for empty + // initialization. + const char* exact_expected = + "AllNullableTypes(a_nullable_bool: null, a_nullable_int: null, " + "a_nullable_int64: null, a_nullable_double: null, a_nullable_byte_array: " + "null, " + "a_nullable4_byte_array: null, a_nullable8_byte_array: null, " + "a_nullable_float_array: null, a_nullable_enum: null, " + "another_nullable_enum: null, a_nullable_string: null, " + "a_nullable_object: null, " + "all_nullable_types: null, list: null, string_list: null, int_list: " + "null, " + "double_list: null, bool_list: null, enum_list: null, object_list: null, " + "list_list: null, map_list: null, recursive_class_list: null, map: null, " + "string_map: null, int_map: null, enum_map: null, object_map: null, " + "list_map: null, map_map: null, recursive_class_map: null)"; + EXPECT_STREQ(str, exact_expected); + + g_free(str); +} diff --git a/packages/pigeon/platform_tests/test_plugin/linux/test_plugin.cc b/packages/pigeon/platform_tests/test_plugin/linux/test_plugin.cc index 693bb17eefee..1c4af93747d1 100644 --- a/packages/pigeon/platform_tests/test_plugin/linux/test_plugin.cc +++ b/packages/pigeon/platform_tests/test_plugin/linux/test_plugin.cc @@ -128,6 +128,30 @@ static CoreTestsPigeonTestHostIntegrationCoreApiEchoListResponse* echo_list( a_list); } +static CoreTestsPigeonTestHostIntegrationCoreApiEchoStringListResponse* +echo_string_list(FlValue* string_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_string_list_response_new( + string_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoIntListResponse* +echo_int_list(FlValue* int_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_int_list_response_new( + int_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoDoubleListResponse* +echo_double_list(FlValue* double_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_double_list_response_new( + double_list); +} + +static CoreTestsPigeonTestHostIntegrationCoreApiEchoBoolListResponse* +echo_bool_list(FlValue* bool_list, gpointer user_data) { + return core_tests_pigeon_test_host_integration_core_api_echo_bool_list_response_new( + bool_list); +} + static CoreTestsPigeonTestHostIntegrationCoreApiEchoEnumListResponse* echo_enum_list(FlValue* enum_list, gpointer user_data) { return core_tests_pigeon_test_host_integration_core_api_echo_enum_list_response_new( @@ -3228,6 +3252,10 @@ static CoreTestsPigeonTestHostIntegrationCoreApiVTable host_core_api_vtable = { .echo_uint8_list = echo_uint8_list, .echo_object = echo_object, .echo_list = echo_list, + .echo_string_list = echo_string_list, + .echo_int_list = echo_int_list, + .echo_double_list = echo_double_list, + .echo_bool_list = echo_bool_list, .echo_enum_list = echo_enum_list, .echo_class_list = echo_class_list, .echo_non_null_enum_list = echo_non_null_enum_list, diff --git a/packages/pigeon/platform_tests/test_plugin/windows/CMakeLists.txt b/packages/pigeon/platform_tests/test_plugin/windows/CMakeLists.txt index 71fe7b878b29..582c49537f7d 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/CMakeLists.txt +++ b/packages/pigeon/platform_tests/test_plugin/windows/CMakeLists.txt @@ -102,6 +102,7 @@ FetchContent_MakeAvailable(googletest) # directly into the test binary rather than using the DLL. add_executable(${TEST_RUNNER} # Tests. + test/data_class_methods_test.cpp test/multiple_arity_test.cpp test/non_null_fields_test.cpp test/nullable_returns_test.cpp diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp index f50c8eff918c..d78f843d1892 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace core_tests_pigeontest { @@ -239,6 +240,101 @@ size_t PigeonInternalDeepHash(const ::flutter::EncodableValue& v) { return result; } +template +std::string PigeonInternalToString(const T& v); + +std::string PigeonInternalToString(const bool& v); + +template +std::string PigeonInternalToString(const std::vector& v); + +template +std::string PigeonInternalToString(const std::map& v); + +template +std::string PigeonInternalToString(const std::optional& v); + +template +std::string PigeonInternalToString(const std::unique_ptr& v); + +std::string PigeonInternalToString(const ::flutter::EncodableValue& v); + +template +std::string PigeonInternalToString(const T& v) { + std::stringstream ss; + if constexpr (std::is_enum_v) { + ss << static_cast(v); + } else { + ss << v; + } + return ss.str(); +} + +std::string PigeonInternalToString(const bool& v) { + return v ? "true" : "false"; +} + +template +std::string PigeonInternalToString(const std::vector& v) { + std::stringstream ss; + ss << "["; + for (size_t i = 0; i < v.size(); ++i) { + if (i > 0) { + ss << ", "; + } + ss << PigeonInternalToString(v[i]); + } + ss << "]"; + return ss.str(); +} + +template +std::string PigeonInternalToString(const std::map& v) { + std::stringstream ss; + ss << "{"; + bool first = true; + for (const auto& kv : v) { + if (!first) { + ss << ", "; + } + first = false; + ss << PigeonInternalToString(kv.first) << ": " + << PigeonInternalToString(kv.second); + } + ss << "}"; + return ss.str(); +} + +template +std::string PigeonInternalToString(const std::optional& v) { + return v ? PigeonInternalToString(*v) : "null"; +} + +template +std::string PigeonInternalToString(const std::unique_ptr& v) { + return v ? PigeonInternalToString(*v) : "null"; +} + +std::string PigeonInternalToString(const ::flutter::EncodableValue& v) { + return std::visit( + [](const auto& val) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return std::string("null"); + } else if constexpr (std::is_same_v) { + return val ? std::string("true") : std::string("false"); + } else if constexpr (std::is_same_v) { + return "\"" + val + "\""; + } else if constexpr (std::is_same_v) { + return std::string("[custom]"); + } else { + return PigeonInternalToString(val); + } + }, + v); +} + } // namespace // UnusedClass @@ -291,6 +387,18 @@ size_t UnusedClass::Hash() const { return result; } +std::ostream& operator<<(std::ostream& os, const UnusedClass& obj) { + os << "UnusedClass("; + os << "a_field: "; + if (obj.a_field_) { + os << PigeonInternalToString(*obj.a_field_); + } else { + os << "null"; + } + os << ")"; + return os; +} + size_t PigeonInternalDeepHash(const UnusedClass& v) { return v.Hash(); } // AllTypes @@ -629,6 +737,68 @@ size_t AllTypes::Hash() const { return result; } +std::ostream& operator<<(std::ostream& os, const AllTypes& obj) { + os << "AllTypes("; + os << "a_bool: "; + os << PigeonInternalToString(obj.a_bool_); + os << ", an_int: "; + os << PigeonInternalToString(obj.an_int_); + os << ", an_int64: "; + os << PigeonInternalToString(obj.an_int64_); + os << ", a_double: "; + os << PigeonInternalToString(obj.a_double_); + os << ", a_byte_array: "; + os << PigeonInternalToString(obj.a_byte_array_); + os << ", a4_byte_array: "; + os << PigeonInternalToString(obj.a4_byte_array_); + os << ", a8_byte_array: "; + os << PigeonInternalToString(obj.a8_byte_array_); + os << ", a_float_array: "; + os << PigeonInternalToString(obj.a_float_array_); + os << ", an_enum: "; + os << PigeonInternalToString(obj.an_enum_); + os << ", another_enum: "; + os << PigeonInternalToString(obj.another_enum_); + os << ", a_string: "; + os << PigeonInternalToString(obj.a_string_); + os << ", an_object: "; + os << PigeonInternalToString(obj.an_object_); + os << ", list: "; + os << PigeonInternalToString(obj.list_); + os << ", string_list: "; + os << PigeonInternalToString(obj.string_list_); + os << ", int_list: "; + os << PigeonInternalToString(obj.int_list_); + os << ", double_list: "; + os << PigeonInternalToString(obj.double_list_); + os << ", bool_list: "; + os << PigeonInternalToString(obj.bool_list_); + os << ", enum_list: "; + os << PigeonInternalToString(obj.enum_list_); + os << ", object_list: "; + os << PigeonInternalToString(obj.object_list_); + os << ", list_list: "; + os << PigeonInternalToString(obj.list_list_); + os << ", map_list: "; + os << PigeonInternalToString(obj.map_list_); + os << ", map: "; + os << PigeonInternalToString(obj.map_); + os << ", string_map: "; + os << PigeonInternalToString(obj.string_map_); + os << ", int_map: "; + os << PigeonInternalToString(obj.int_map_); + os << ", enum_map: "; + os << PigeonInternalToString(obj.enum_map_); + os << ", object_map: "; + os << PigeonInternalToString(obj.object_map_); + os << ", list_map: "; + os << PigeonInternalToString(obj.list_map_); + os << ", map_map: "; + os << PigeonInternalToString(obj.map_map_); + os << ")"; + return os; +} + size_t PigeonInternalDeepHash(const AllTypes& v) { return v.Hash(); } // AllNullableTypes @@ -1566,6 +1736,198 @@ size_t AllNullableTypes::Hash() const { return result; } +std::ostream& operator<<(std::ostream& os, const AllNullableTypes& obj) { + os << "AllNullableTypes("; + os << "a_nullable_bool: "; + if (obj.a_nullable_bool_) { + os << PigeonInternalToString(*obj.a_nullable_bool_); + } else { + os << "null"; + } + os << ", a_nullable_int: "; + if (obj.a_nullable_int_) { + os << PigeonInternalToString(*obj.a_nullable_int_); + } else { + os << "null"; + } + os << ", a_nullable_int64: "; + if (obj.a_nullable_int64_) { + os << PigeonInternalToString(*obj.a_nullable_int64_); + } else { + os << "null"; + } + os << ", a_nullable_double: "; + if (obj.a_nullable_double_) { + os << PigeonInternalToString(*obj.a_nullable_double_); + } else { + os << "null"; + } + os << ", a_nullable_byte_array: "; + if (obj.a_nullable_byte_array_) { + os << PigeonInternalToString(*obj.a_nullable_byte_array_); + } else { + os << "null"; + } + os << ", a_nullable4_byte_array: "; + if (obj.a_nullable4_byte_array_) { + os << PigeonInternalToString(*obj.a_nullable4_byte_array_); + } else { + os << "null"; + } + os << ", a_nullable8_byte_array: "; + if (obj.a_nullable8_byte_array_) { + os << PigeonInternalToString(*obj.a_nullable8_byte_array_); + } else { + os << "null"; + } + os << ", a_nullable_float_array: "; + if (obj.a_nullable_float_array_) { + os << PigeonInternalToString(*obj.a_nullable_float_array_); + } else { + os << "null"; + } + os << ", a_nullable_enum: "; + if (obj.a_nullable_enum_) { + os << PigeonInternalToString(*obj.a_nullable_enum_); + } else { + os << "null"; + } + os << ", another_nullable_enum: "; + if (obj.another_nullable_enum_) { + os << PigeonInternalToString(*obj.another_nullable_enum_); + } else { + os << "null"; + } + os << ", a_nullable_string: "; + if (obj.a_nullable_string_) { + os << PigeonInternalToString(*obj.a_nullable_string_); + } else { + os << "null"; + } + os << ", a_nullable_object: "; + if (obj.a_nullable_object_) { + os << PigeonInternalToString(*obj.a_nullable_object_); + } else { + os << "null"; + } + os << ", all_nullable_types: "; + if (obj.all_nullable_types_) { + os << *obj.all_nullable_types_; + } else { + os << "null"; + } + os << ", list: "; + if (obj.list_) { + os << PigeonInternalToString(*obj.list_); + } else { + os << "null"; + } + os << ", string_list: "; + if (obj.string_list_) { + os << PigeonInternalToString(*obj.string_list_); + } else { + os << "null"; + } + os << ", int_list: "; + if (obj.int_list_) { + os << PigeonInternalToString(*obj.int_list_); + } else { + os << "null"; + } + os << ", double_list: "; + if (obj.double_list_) { + os << PigeonInternalToString(*obj.double_list_); + } else { + os << "null"; + } + os << ", bool_list: "; + if (obj.bool_list_) { + os << PigeonInternalToString(*obj.bool_list_); + } else { + os << "null"; + } + os << ", enum_list: "; + if (obj.enum_list_) { + os << PigeonInternalToString(*obj.enum_list_); + } else { + os << "null"; + } + os << ", object_list: "; + if (obj.object_list_) { + os << PigeonInternalToString(*obj.object_list_); + } else { + os << "null"; + } + os << ", list_list: "; + if (obj.list_list_) { + os << PigeonInternalToString(*obj.list_list_); + } else { + os << "null"; + } + os << ", map_list: "; + if (obj.map_list_) { + os << PigeonInternalToString(*obj.map_list_); + } else { + os << "null"; + } + os << ", recursive_class_list: "; + if (obj.recursive_class_list_) { + os << PigeonInternalToString(*obj.recursive_class_list_); + } else { + os << "null"; + } + os << ", map: "; + if (obj.map_) { + os << PigeonInternalToString(*obj.map_); + } else { + os << "null"; + } + os << ", string_map: "; + if (obj.string_map_) { + os << PigeonInternalToString(*obj.string_map_); + } else { + os << "null"; + } + os << ", int_map: "; + if (obj.int_map_) { + os << PigeonInternalToString(*obj.int_map_); + } else { + os << "null"; + } + os << ", enum_map: "; + if (obj.enum_map_) { + os << PigeonInternalToString(*obj.enum_map_); + } else { + os << "null"; + } + os << ", object_map: "; + if (obj.object_map_) { + os << PigeonInternalToString(*obj.object_map_); + } else { + os << "null"; + } + os << ", list_map: "; + if (obj.list_map_) { + os << PigeonInternalToString(*obj.list_map_); + } else { + os << "null"; + } + os << ", map_map: "; + if (obj.map_map_) { + os << PigeonInternalToString(*obj.map_map_); + } else { + os << "null"; + } + os << ", recursive_class_map: "; + if (obj.recursive_class_map_) { + os << PigeonInternalToString(*obj.recursive_class_map_); + } else { + os << "null"; + } + os << ")"; + return os; +} + size_t PigeonInternalDeepHash(const AllNullableTypes& v) { return v.Hash(); } // AllNullableTypesWithoutRecursion @@ -2332,6 +2694,181 @@ size_t AllNullableTypesWithoutRecursion::Hash() const { return result; } +std::ostream& operator<<(std::ostream& os, + const AllNullableTypesWithoutRecursion& obj) { + os << "AllNullableTypesWithoutRecursion("; + os << "a_nullable_bool: "; + if (obj.a_nullable_bool_) { + os << PigeonInternalToString(*obj.a_nullable_bool_); + } else { + os << "null"; + } + os << ", a_nullable_int: "; + if (obj.a_nullable_int_) { + os << PigeonInternalToString(*obj.a_nullable_int_); + } else { + os << "null"; + } + os << ", a_nullable_int64: "; + if (obj.a_nullable_int64_) { + os << PigeonInternalToString(*obj.a_nullable_int64_); + } else { + os << "null"; + } + os << ", a_nullable_double: "; + if (obj.a_nullable_double_) { + os << PigeonInternalToString(*obj.a_nullable_double_); + } else { + os << "null"; + } + os << ", a_nullable_byte_array: "; + if (obj.a_nullable_byte_array_) { + os << PigeonInternalToString(*obj.a_nullable_byte_array_); + } else { + os << "null"; + } + os << ", a_nullable4_byte_array: "; + if (obj.a_nullable4_byte_array_) { + os << PigeonInternalToString(*obj.a_nullable4_byte_array_); + } else { + os << "null"; + } + os << ", a_nullable8_byte_array: "; + if (obj.a_nullable8_byte_array_) { + os << PigeonInternalToString(*obj.a_nullable8_byte_array_); + } else { + os << "null"; + } + os << ", a_nullable_float_array: "; + if (obj.a_nullable_float_array_) { + os << PigeonInternalToString(*obj.a_nullable_float_array_); + } else { + os << "null"; + } + os << ", a_nullable_enum: "; + if (obj.a_nullable_enum_) { + os << PigeonInternalToString(*obj.a_nullable_enum_); + } else { + os << "null"; + } + os << ", another_nullable_enum: "; + if (obj.another_nullable_enum_) { + os << PigeonInternalToString(*obj.another_nullable_enum_); + } else { + os << "null"; + } + os << ", a_nullable_string: "; + if (obj.a_nullable_string_) { + os << PigeonInternalToString(*obj.a_nullable_string_); + } else { + os << "null"; + } + os << ", a_nullable_object: "; + if (obj.a_nullable_object_) { + os << PigeonInternalToString(*obj.a_nullable_object_); + } else { + os << "null"; + } + os << ", list: "; + if (obj.list_) { + os << PigeonInternalToString(*obj.list_); + } else { + os << "null"; + } + os << ", string_list: "; + if (obj.string_list_) { + os << PigeonInternalToString(*obj.string_list_); + } else { + os << "null"; + } + os << ", int_list: "; + if (obj.int_list_) { + os << PigeonInternalToString(*obj.int_list_); + } else { + os << "null"; + } + os << ", double_list: "; + if (obj.double_list_) { + os << PigeonInternalToString(*obj.double_list_); + } else { + os << "null"; + } + os << ", bool_list: "; + if (obj.bool_list_) { + os << PigeonInternalToString(*obj.bool_list_); + } else { + os << "null"; + } + os << ", enum_list: "; + if (obj.enum_list_) { + os << PigeonInternalToString(*obj.enum_list_); + } else { + os << "null"; + } + os << ", object_list: "; + if (obj.object_list_) { + os << PigeonInternalToString(*obj.object_list_); + } else { + os << "null"; + } + os << ", list_list: "; + if (obj.list_list_) { + os << PigeonInternalToString(*obj.list_list_); + } else { + os << "null"; + } + os << ", map_list: "; + if (obj.map_list_) { + os << PigeonInternalToString(*obj.map_list_); + } else { + os << "null"; + } + os << ", map: "; + if (obj.map_) { + os << PigeonInternalToString(*obj.map_); + } else { + os << "null"; + } + os << ", string_map: "; + if (obj.string_map_) { + os << PigeonInternalToString(*obj.string_map_); + } else { + os << "null"; + } + os << ", int_map: "; + if (obj.int_map_) { + os << PigeonInternalToString(*obj.int_map_); + } else { + os << "null"; + } + os << ", enum_map: "; + if (obj.enum_map_) { + os << PigeonInternalToString(*obj.enum_map_); + } else { + os << "null"; + } + os << ", object_map: "; + if (obj.object_map_) { + os << PigeonInternalToString(*obj.object_map_); + } else { + os << "null"; + } + os << ", list_map: "; + if (obj.list_map_) { + os << PigeonInternalToString(*obj.list_map_); + } else { + os << "null"; + } + os << ", map_map: "; + if (obj.map_map_) { + os << PigeonInternalToString(*obj.map_map_); + } else { + os << "null"; + } + os << ")"; + return os; +} + size_t PigeonInternalDeepHash(const AllNullableTypesWithoutRecursion& v) { return v.Hash(); } @@ -2574,6 +3111,42 @@ size_t AllClassesWrapper::Hash() const { return result; } +std::ostream& operator<<(std::ostream& os, const AllClassesWrapper& obj) { + os << "AllClassesWrapper("; + os << "all_nullable_types: "; + os << obj.all_nullable_types_; + os << ", all_nullable_types_without_recursion: "; + if (obj.all_nullable_types_without_recursion_) { + os << *obj.all_nullable_types_without_recursion_; + } else { + os << "null"; + } + os << ", all_types: "; + if (obj.all_types_) { + os << *obj.all_types_; + } else { + os << "null"; + } + os << ", class_list: "; + os << PigeonInternalToString(obj.class_list_); + os << ", nullable_class_list: "; + if (obj.nullable_class_list_) { + os << PigeonInternalToString(*obj.nullable_class_list_); + } else { + os << "null"; + } + os << ", class_map: "; + os << PigeonInternalToString(obj.class_map_); + os << ", nullable_class_map: "; + if (obj.nullable_class_map_) { + os << PigeonInternalToString(*obj.nullable_class_map_); + } else { + os << "null"; + } + os << ")"; + return os; +} + size_t PigeonInternalDeepHash(const AllClassesWrapper& v) { return v.Hash(); } // TestMessage @@ -2627,6 +3200,18 @@ size_t TestMessage::Hash() const { return result; } +std::ostream& operator<<(std::ostream& os, const TestMessage& obj) { + os << "TestMessage("; + os << "test_list: "; + if (obj.test_list_) { + os << PigeonInternalToString(*obj.test_list_); + } else { + os << "null"; + } + os << ")"; + return os; +} + size_t PigeonInternalDeepHash(const TestMessage& v) { return v.Hash(); } PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} @@ -3169,6 +3754,148 @@ void HostIntegrationCoreApi::SetUp(::flutter::BinaryMessenger* binary_messenger, channel.SetMessageHandler(nullptr); } } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoStringList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const ::flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_string_list_arg = args.at(0); + if (encodable_string_list_arg.IsNull()) { + reply(WrapError("string_list_arg unexpectedly null.")); + return; + } + const auto& string_list_arg = + std::get(encodable_string_list_arg); + ErrorOr output = + api->EchoStringList(string_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoIntList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const ::flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_int_list_arg = args.at(0); + if (encodable_int_list_arg.IsNull()) { + reply(WrapError("int_list_arg unexpectedly null.")); + return; + } + const auto& int_list_arg = + std::get(encodable_int_list_arg); + ErrorOr output = api->EchoIntList(int_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoDoubleList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const ::flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_double_list_arg = args.at(0); + if (encodable_double_list_arg.IsNull()) { + reply(WrapError("double_list_arg unexpectedly null.")); + return; + } + const auto& double_list_arg = + std::get(encodable_double_list_arg); + ErrorOr output = + api->EchoDoubleList(double_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel(binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests." + "HostIntegrationCoreApi.echoBoolList" + + prepended_suffix, + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const ::flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_bool_list_arg = args.at(0); + if (encodable_bool_list_arg.IsNull()) { + reply(WrapError("bool_list_arg unexpectedly null.")); + return; + } + const auto& bool_list_arg = + std::get(encodable_bool_list_arg); + ErrorOr output = api->EchoBoolList(bool_list_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index 24ca4540d6a8..6778e1943213 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -14,6 +14,7 @@ #include #include +#include #include namespace core_tests_pigeontest { @@ -93,6 +94,8 @@ class UnusedClass { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + /// Stream output operator for formatted string representation. + friend std::ostream& operator<<(std::ostream& os, const UnusedClass& obj); private: static UnusedClass FromEncodableList(const ::flutter::EncodableList& list); @@ -227,6 +230,8 @@ class AllTypes { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + /// Stream output operator for formatted string representation. + friend std::ostream& operator<<(std::ostream& os, const AllTypes& obj); private: static AllTypes FromEncodableList(const ::flutter::EncodableList& list); @@ -442,6 +447,9 @@ class AllNullableTypes { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + /// Stream output operator for formatted string representation. + friend std::ostream& operator<<(std::ostream& os, + const AllNullableTypes& obj); private: static AllNullableTypes FromEncodableList( @@ -643,6 +651,9 @@ class AllNullableTypesWithoutRecursion { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + /// Stream output operator for formatted string representation. + friend std::ostream& operator<<(std::ostream& os, + const AllNullableTypesWithoutRecursion& obj); private: static AllNullableTypesWithoutRecursion FromEncodableList( @@ -748,6 +759,9 @@ class AllClassesWrapper { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + /// Stream output operator for formatted string representation. + friend std::ostream& operator<<(std::ostream& os, + const AllClassesWrapper& obj); private: static AllClassesWrapper FromEncodableList( @@ -790,6 +804,8 @@ class TestMessage { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + /// Stream output operator for formatted string representation. + friend std::ostream& operator<<(std::ostream& os, const TestMessage& obj); private: static TestMessage FromEncodableList(const ::flutter::EncodableList& list); @@ -861,6 +877,18 @@ class HostIntegrationCoreApi { virtual ErrorOr<::flutter::EncodableList> EchoList( const ::flutter::EncodableList& list) = 0; // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr<::flutter::EncodableList> EchoStringList( + const ::flutter::EncodableList& string_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr<::flutter::EncodableList> EchoIntList( + const ::flutter::EncodableList& int_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr<::flutter::EncodableList> EchoDoubleList( + const ::flutter::EncodableList& double_list) = 0; + // Returns the passed list, to test serialization and deserialization. + virtual ErrorOr<::flutter::EncodableList> EchoBoolList( + const ::flutter::EncodableList& bool_list) = 0; + // Returns the passed list, to test serialization and deserialization. virtual ErrorOr<::flutter::EncodableList> EchoEnumList( const ::flutter::EncodableList& enum_list) = 0; // Returns the passed list, to test serialization and deserialization. diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test/equality_test.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test/data_class_methods_test.cpp similarity index 51% rename from packages/pigeon/platform_tests/test_plugin/windows/test/equality_test.cpp rename to packages/pigeon/platform_tests/test_plugin/windows/test/data_class_methods_test.cpp index 79cfe24f9cb8..dc1f6ad3f809 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test/equality_test.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test/data_class_methods_test.cpp @@ -5,6 +5,7 @@ #include #include +#include #include "pigeon/core_tests.gen.h" @@ -40,7 +41,7 @@ TEST(EqualityTests, OptionalNaNEquality) { } TEST(EqualityTests, NestedNaNEquality) { - std::vector list = {NAN}; + flutter::EncodableList list = {flutter::EncodableValue(NAN)}; AllNullableTypes all1; all1.set_double_list(list); @@ -61,11 +62,11 @@ TEST(EqualityTests, SignedZeroEquality) { } TEST(EqualityTests, NestedZeroListEquality) { - std::vector list1 = {0.0}; + flutter::EncodableList list1 = {flutter::EncodableValue(0.0)}; AllNullableTypes all1; all1.set_double_list(list1); - std::vector list2 = {-0.0}; + flutter::EncodableList list2 = {flutter::EncodableValue(-0.0)}; AllNullableTypes all2; all2.set_double_list(list2); @@ -100,5 +101,57 @@ TEST(EqualityTests, ZeroMapValueEquality) { EXPECT_EQ(all1, all2); } +TEST(SerializationTests, StreamOutputSnapshot) { + flutter::EncodableList list; + list.push_back(flutter::EncodableValue("hello")); + list.push_back(flutter::EncodableValue(42)); + + TestMessage msg; + msg.set_test_list(list); + + std::stringstream ss; + ss << msg; + + EXPECT_EQ(ss.str(), "TestMessage(test_list: [\"hello\", 42])"); +} + +// On Windows, C++ stream serialization and std::map key traversal are +// completely deterministic and stable, allowing us to validate the entire +// output with a single exact string. +TEST(SerializationTests, StreamOutputFullSnapshot) { + AllNullableTypes everything; + everything.set_a_nullable_bool(true); + everything.set_a_nullable_int(1); + everything.set_a_nullable_double(2.0); + everything.set_a_nullable_string("123"); + + flutter::EncodableList list; + list.push_back(flutter::EncodableValue("string")); + list.push_back(flutter::EncodableValue(1)); + everything.set_list(list); + + flutter::EncodableMap map; + map[flutter::EncodableValue("hello")] = flutter::EncodableValue("you"); + everything.set_string_map(map); + + std::stringstream ss; + ss << everything; + + EXPECT_EQ( + ss.str(), + "AllNullableTypes(a_nullable_bool: true, a_nullable_int: 1, " + "a_nullable_int64: null, a_nullable_double: 2, a_nullable_byte_array: " + "null, a_nullable4_byte_array: null, a_nullable8_byte_array: null, " + "a_nullable_float_array: null, a_nullable_enum: null, " + "another_nullable_enum: null, a_nullable_string: 123, a_nullable_object: " + "null, all_nullable_types: null, list: [\"string\", 1], string_list: " + "null, int_list: null, double_list: null, bool_list: null, enum_list: " + "null, object_list: null, list_list: null, map_list: null, " + "recursive_class_list: null, map: null, string_map: {\"hello\": " + "\"you\"}, " + "int_map: null, enum_map: null, object_map: null, list_map: null, " + "map_map: null, recursive_class_map: null)"); +} + } // namespace test } // namespace test_plugin diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp index 212e1866fa83..298b52cc278f 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp @@ -158,6 +158,25 @@ ErrorOr TestPlugin::EchoList(const EncodableList& a_list) { return a_list; } +ErrorOr TestPlugin::EchoStringList( + const EncodableList& string_list) { + return string_list; +} + +ErrorOr TestPlugin::EchoIntList(const EncodableList& int_list) { + return int_list; +} + +ErrorOr TestPlugin::EchoDoubleList( + const EncodableList& double_list) { + return double_list; +} + +ErrorOr TestPlugin::EchoBoolList( + const EncodableList& bool_list) { + return bool_list; +} + ErrorOr TestPlugin::EchoEnumList( const EncodableList& enum_list) { return enum_list; diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h index a52bd83f03a2..066231295f95 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h @@ -91,6 +91,14 @@ class TestPlugin : public flutter::Plugin, const flutter::EncodableValue& an_object) override; core_tests_pigeontest::ErrorOr EchoList( const flutter::EncodableList& a_list) override; + core_tests_pigeontest::ErrorOr EchoStringList( + const flutter::EncodableList& string_list) override; + core_tests_pigeontest::ErrorOr EchoIntList( + const flutter::EncodableList& int_list) override; + core_tests_pigeontest::ErrorOr EchoDoubleList( + const flutter::EncodableList& double_list) override; + core_tests_pigeontest::ErrorOr EchoBoolList( + const flutter::EncodableList& bool_list) override; core_tests_pigeontest::ErrorOr EchoEnumList( const flutter::EncodableList& enum_list) override; core_tests_pigeontest::ErrorOr EchoClassList( diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 7ac94252e537..0472d4c5fe8d 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.3.4 # This must match the version in lib/src/generator_tools.dart +version: 27.0.0 # This must match the version in lib/src/generator_tools.dart environment: sdk: ^3.10.0 diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index aec1b205c3d9..fa65936598ca 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -470,6 +470,7 @@ void main() { #include #include +#include #include '''), ); @@ -501,6 +502,7 @@ void main() { #include #include #include +#include #include '''), ); @@ -2263,6 +2265,82 @@ void main() { expect(code, contains('bool Foo::operator==(const Foo& other) const {')); }); + test('data class operator<<', () { + final root = Root( + apis: [], + classes: [ + Class( + name: 'Foo', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: false), + name: 'bar', + ), + ], + ), + ], + enums: [], + ); + final sink = StringBuffer(); + const generator = CppGenerator(); + final generatorOptions = OutputFileOptions( + fileType: FileType.source, + languageOptions: const InternalCppOptions( + cppHeaderOut: '', + cppSourceOut: '', + headerIncludePath: '', + ), + ); + generator.generate(generatorOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('std::ostream& operator<<(')); + expect(code, contains('os << "bar: ";')); + expect(code, contains('os << PigeonInternalToString(obj.bar_);')); + }); + + test('data class operator<< with nullable pointer', () { + final nested = Class( + name: 'Nested', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: false), + name: 'data', + ), + ], + ); + final root = Root( + apis: [], + classes: [ + Class( + name: 'Foo', + fields: [ + NamedType( + type: TypeDeclaration(baseName: 'Nested', isNullable: true, associatedClass: nested), + name: 'nested', + ), + ], + ), + nested, + ], + enums: [], + ); + final sink = StringBuffer(); + const generator = CppGenerator(); + final generatorOptions = OutputFileOptions( + fileType: FileType.source, + languageOptions: const InternalCppOptions( + cppHeaderOut: '', + cppSourceOut: '', + headerIncludePath: '', + ), + ); + generator.generate(generatorOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('std::ostream& operator<<(')); + expect(code, contains('if (obj.nested_) {')); + expect(code, contains('os << *obj.nested_;')); + }); + test('data classes implement Hash', () { final root = Root( apis: [], diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index d6e0553341a4..695b9a97c8c5 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -2003,4 +2003,28 @@ name: foobar expect(code, contains('bool operator ==(Object other) {')); expect(code, contains('int get hashCode =>')); }); + + test('data class toString', () { + final classDefinition = Class( + name: 'Foobar', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: true), + name: 'field1', + ), + ], + ); + final root = Root(apis: [], classes: [classDefinition], enums: []); + final sink = StringBuffer(); + const generator = DartGenerator(); + generator.generate( + const InternalDartOptions(ignoreLints: false), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final code = sink.toString(); + expect(code, contains('String toString() {')); + expect(code, contains(r"return 'Foobar(field1: $field1)';")); + }); } diff --git a/packages/pigeon/test/gobject_generator_test.dart b/packages/pigeon/test/gobject_generator_test.dart index ebf6bda6a04b..23e4f77f1244 100644 --- a/packages/pigeon/test/gobject_generator_test.dart +++ b/packages/pigeon/test/gobject_generator_test.dart @@ -909,4 +909,31 @@ void main() { expect(code, contains('guint test_package_input_hash(')); } }); + + test('data classes handle to_string', () { + final inputClass = Class( + name: 'Input', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'String', isNullable: true), + name: 'input', + ), + ], + ); + final root = Root(apis: [], classes: [inputClass], enums: []); + final sink = StringBuffer(); + const generator = GObjectGenerator(); + final generatorOptions = OutputFileOptions( + fileType: FileType.source, + languageOptions: const InternalGObjectOptions( + headerIncludePath: '', + gobjectHeaderOut: '', + gobjectSourceOut: '', + ), + ); + generator.generate(generatorOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('gchar* test_package_input_to_string(')); + expect(code, contains('g_string_new("Input(");')); + }); } diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index 3fb422410190..6a93704be7a5 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -1562,4 +1562,24 @@ void main() { expect(code, contains('public boolean equals(Object o) {')); expect(code, contains('public int hashCode() {')); }); + + test('data class toString', () { + final classDefinition = Class( + name: 'Foobar', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: true), + name: 'field1', + ), + ], + ); + final root = Root(apis: [], classes: [classDefinition], enums: []); + final sink = StringBuffer(); + const javaOptions = InternalJavaOptions(className: 'Messages', javaOut: ''); + const generator = JavaGenerator(); + generator.generate(javaOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('public String toString() {')); + expect(code, contains('return "Foobar{" + "field1=" + field1 + "}";')); + }); } diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 726f6e69dc03..5164c203860e 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -1783,4 +1783,48 @@ void main() { expect(code, contains('override fun equals(other: Any?): Boolean {')); expect(code, contains('override fun hashCode(): Int {')); }); + + test('data class toString', () { + final classDefinition = Class( + name: 'Foobar', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: true), + name: 'field1', + ), + ], + ); + final root = Root(apis: [], classes: [classDefinition], enums: []); + final sink = StringBuffer(); + const kotlinOptions = InternalKotlinOptions(kotlinOut: ''); + const generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('override fun toString(): String {')); + expect(code, contains(r'return "Foobar(field1=$field1)"')); + }); + + test('data class toString multi-field', () { + final classDefinition = Class( + name: 'Foobar', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: true), + name: 'field1', + ), + NamedType( + type: const TypeDeclaration(baseName: 'String', isNullable: true), + name: 'field2', + ), + ], + ); + final root = Root(apis: [], classes: [classDefinition], enums: []); + final sink = StringBuffer(); + const kotlinOptions = InternalKotlinOptions(kotlinOut: ''); + const generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('override fun toString(): String {')); + expect(code, contains(r'return "Foobar(field1=$field1, field2=$field2)"')); + }); } diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index 19e916230681..a5f8179fe84c 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -3489,4 +3489,63 @@ void main() { expect(code, contains('- (NSUInteger)hash {')); } }); + + test('data class description', () { + final root = Root( + apis: [], + classes: [ + Class( + name: 'Foo', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: false), + name: 'bar', + ), + ], + ), + ], + enums: [], + ); + final sink = StringBuffer(); + const generator = ObjcGenerator(); + final generatorOptions = OutputFileOptions( + fileType: FileType.source, + languageOptions: const InternalObjcOptions( + prefix: 'ABC', + objcHeaderOut: '', + objcSourceOut: '', + headerIncludePath: '', + ), + ); + generator.generate(generatorOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('- (NSString *)description {')); + expect( + code, + contains('return [NSString stringWithFormat:@"ABCFoo(bar: %ld)", (long)self.bar];'), + ); + }); + + test('data class description empty', () { + final root = Root( + apis: [], + classes: [Class(name: 'Foo', fields: [])], + enums: [], + ); + final sink = StringBuffer(); + const generator = ObjcGenerator(); + final generatorOptions = OutputFileOptions( + fileType: FileType.source, + languageOptions: const InternalObjcOptions( + prefix: 'ABC', + objcHeaderOut: '', + objcSourceOut: '', + headerIncludePath: '', + ), + ); + generator.generate(generatorOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains('- (NSString *)description {')); + expect(code, contains('return [NSString stringWithFormat:@"ABCFoo()"];')); + }); } diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index e318fe5d8f7f..7c319672e81d 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -36,7 +36,7 @@ class _ValidatorGeneratorAdapter implements GeneratorAdapter { void main() { /// Creates a temporary file named [filename] then calls [callback] with a - /// [File] representing that temporary directory. The file will be deleted + /// [File] representing that temporary directory. The file will be deleted /// after the [callback] is executed. void withTempFile(String filename, void Function(File) callback) { final Directory dir = Directory.systemTemp.createTempSync(); @@ -1745,5 +1745,28 @@ abstract class events { contains('Sealed class: "DataClass" must not contain fields.'), ); }); + + test('swift description field error', () async { + final completer = Completer(); + const code = ''' +class Foo { + String? description; +} + +@HostApi() +abstract class Api { + void method(Foo foo); +} +'''; + withTempFile('foo.dart', (File input) async { + input.writeAsStringSync(code); + final int result = await Pigeon.runWithOptions( + PigeonOptions(input: input.path, swiftOut: 'Foo.swift', dartOut: 'foo.dart'), + ); + expect(result, isNot(0)); + completer.complete(); + }); + await completer.future; + }); }); } diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 8b665eeea8da..548895978b2d 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -1516,4 +1516,25 @@ void main() { expect(code, contains('static func == (lhs: Foobar, rhs: Foobar) -> Bool {')); expect(code, contains('func hash(into hasher: inout Hasher) {')); }); + + test('data class toString', () { + final classDefinition = Class( + name: 'Foobar', + fields: [ + NamedType( + type: const TypeDeclaration(baseName: 'int', isNullable: true), + name: 'field1', + ), + ], + ); + final root = Root(apis: [], classes: [classDefinition], enums: []); + final sink = StringBuffer(); + const swiftOptions = InternalSwiftOptions(swiftOut: ''); + const generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink, dartPackageName: DEFAULT_PACKAGE_NAME); + final code = sink.toString(); + expect(code, contains(': Hashable, CustomStringConvertible')); + expect(code, contains('public var description: String {')); + expect(code, contains(r'return "Foobar(field1: \(String(describing: field1)))"')); + }); }