diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 1d8884d3e71c..b1e2b6f2ff62 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,8 @@ +## 26.4.0 + +* Overrides `toString` (or equivalent) methods on generated data classes. +* [swift] Updates `isNullish` to handle double nested `Any?` values. + ## 26.3.4 * [kotlin] Updates generated error class to inherit from `RuntimeException` @@ -915,7 +920,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 @@ -1078,11 +1083,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 @@ -1104,10 +1109,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 @@ -1123,7 +1128,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. @@ -1209,7 +1214,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/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..03e0ada8b642 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 @@ -311,6 +311,23 @@ public int hashCode() { return pigeonDeepHashCode(fields); } + @Override + public String toString() { + return "MessageData{" + + "name=" + + name + + ", " + + "description=" + + description + + ", " + + "code=" + + code + + ", " + + "data=" + + data + + "}"; + } + public static final class Builder { private @Nullable String name; 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..cb82bcddc884 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 @@ -252,6 +252,10 @@ data class MessageData( result = 31 * result + MessagesPigeonUtils.deepHash(this.data) return result } + + override fun toString(): String { + return "MessageData(name=$name, description=$description, 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..9670f9f4ec8f 100644 --- a/packages/pigeon/example/app/ios/Runner/EventChannelMessages.g.swift +++ b/packages/pigeon/example/app/ios/Runner/EventChannelMessages.g.swift @@ -14,8 +14,18 @@ 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 + } + + if case Optional.some(Optional.none) = value { + return true + } + + return innerValue is NSNull + } } private func nilOrValue(_ value: Any?) -> T? { @@ -166,6 +176,10 @@ struct IntEvent: PlatformEvent { hasher.combine("IntEvent") deepHashEventChannelMessages(value: data, hasher: &hasher) } + + public var description: String { + return "IntEvent(data: \(String(describing: data)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -196,6 +210,10 @@ struct StringEvent: PlatformEvent { hasher.combine("StringEvent") deepHashEventChannelMessages(value: data, hasher: &hasher) } + + public var description: String { + return "StringEvent(data: \(String(describing: data)))" + } } private class EventChannelMessagesPigeonCodecReader: FlutterStandardReader { diff --git a/packages/pigeon/example/app/ios/Runner/Messages.g.swift b/packages/pigeon/example/app/ios/Runner/Messages.g.swift index f8b12f846c22..00fe1d967477 100644 --- a/packages/pigeon/example/app/ios/Runner/Messages.g.swift +++ b/packages/pigeon/example/app/ios/Runner/Messages.g.swift @@ -64,8 +64,18 @@ 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 + } + + if case Optional.some(Optional.none) = value { + return true + } + + return innerValue is NSNull + } } private func nilOrValue(_ value: Any?) -> T? { @@ -188,7 +198,7 @@ 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 code: Code @@ -232,6 +242,11 @@ struct MessageData: Hashable { deepHashMessages(value: code, hasher: &hasher) deepHashMessages(value: data, hasher: &hasher) } + + public var description: String { + return + "MessageData(name: \(String(describing: name)), description: \(String(describing: description)), code: \(String(describing: code)), data: \(String(describing: data)))" + } } private class MessagesPigeonCodecReader: FlutterStandardReader { @@ -349,6 +364,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/src/event_channel_messages.g.dart b/packages/pigeon/example/app/lib/src/event_channel_messages.g.dart index 8fdd1c22e5c5..abc02462ac60 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 @@ -110,6 +110,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 { @@ -145,6 +150,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 699368ba5b3d..5af45ca6db96 100644 --- a/packages/pigeon/example/app/lib/src/messages.g.dart +++ b/packages/pigeon/example/app/lib/src/messages.g.dart @@ -168,6 +168,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, description: $description, code: $code, data: $data)'; + } } class _PigeonCodec extends StandardMessageCodec { @@ -203,8 +208,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, diff --git a/packages/pigeon/example/app/linux/messages.g.cc b/packages/pigeon/example/app/linux/messages.g.cc index f1b0e818d11f..81da50ca9d31 100644 --- a/packages/pigeon/example/app/linux/messages.g.cc +++ b/packages/pigeon/example/app/linux/messages.g.cc @@ -345,6 +345,30 @@ guint pigeon_example_package_message_data_hash( 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, ", description: "); + if (self->description != nullptr) { + g_string_append_printf(str, "\"%s\"", self->description); + } else { + g_string_append(str, "null"); + } + g_string_append(str, ", code: "); + g_string_append(str, "..."); + g_string_append(str, ", data: "); + g_string_append(str, "..."); + 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..ac57669f71ba 100644 --- a/packages/pigeon/example/app/linux/messages.g.h +++ b/packages/pigeon/example/app/linux/messages.g.h @@ -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.m b/packages/pigeon/example/app/macos/Runner/messages.g.m index ed7655039d25..0b7f8b3a9ce1 100644 --- a/packages/pigeon/example/app/macos/Runner/messages.g.m +++ b/packages/pigeon/example/app/macos/Runner/messages.g.m @@ -195,6 +195,11 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.data); return result; } +- (NSString *)description { + return + [NSString stringWithFormat:@"PGNMessageData(name: %@, description: %@, code: %@, data: %@)", + self.name, self.description, @(self.code), self.data]; +} @end @interface PGNMessagesPigeonCodecReader : FlutterStandardReader diff --git a/packages/pigeon/example/app/windows/runner/messages.g.cpp b/packages/pigeon/example/app/windows/runner/messages.g.cpp index 11453da4e053..e3f744ac1b34 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 { @@ -330,6 +331,29 @@ size_t MessageData::Hash() const { return result; } +std::string MessageData::ToString() const { + std::stringstream ss; + ss << "MessageData("; + ss << "name: "; + if (name_.has_value()) { + ss << *name_; + } else { + ss << "null"; + } + ss << ", description: "; + if (description_.has_value()) { + ss << *description_; + } else { + ss << "null"; + } + ss << ", code: "; + ss << code_; + ss << ", data: "; + ss << data_; + ss << ")"; + return ss.str(); +} + 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..681e53c2d73e 100644 --- a/packages/pigeon/example/app/windows/runner/messages.g.h +++ b/packages/pigeon/example/app/windows/runner/messages.g.h @@ -90,6 +90,7 @@ class MessageData { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + std::string ToString() const; private: static MessageData FromEncodableList(const ::flutter::EncodableList& list); diff --git a/packages/pigeon/lib/src/cpp/cpp_generator.dart b/packages/pigeon/lib/src/cpp/cpp_generator.dart index ffaf56787d66..938019f3aa43 100644 --- a/packages/pigeon/lib/src/cpp/cpp_generator.dart +++ b/packages/pigeon/lib/src/cpp/cpp_generator.dart @@ -483,6 +483,12 @@ class CppHeaderGenerator extends StructuredGenerator { returnType: 'size_t', isConst: true, ); + _writeFunctionDeclaration( + indent, + 'ToString', + returnType: 'std::string', + isConst: true, + ); }); _writeAccessBlock(indent, _ClassAccess.private, () { @@ -966,6 +972,7 @@ class CppSourceGenerator extends StructuredGenerator { 'map', 'string', 'optional', + 'sstream', ]); indent.newln(); } @@ -1133,6 +1140,43 @@ class CppSourceGenerator extends StructuredGenerator { }, ); + _writeFunctionDefinition( + indent, + 'ToString', + scope: classDefinition.name, + returnType: 'std::string', + isConst: true, + body: () { + indent.writeln('std::stringstream ss;'); + indent.writeln('ss << "${classDefinition.name}(";'); + enumerate(orderedFields, (int index, final NamedType field) { + final String name = _makeInstanceVariableName(field); + final comma = index == 0 ? '' : ', '; + indent.writeln('ss << "$comma${field.name}: ";'); + if (field.type.isNullable) { + indent.writeScoped('if ($name.has_value()) {', '}', () { + if (field.type.isClass) { + indent.writeln('ss << $name->ToString();'); + } else { + indent.writeln('ss << *$name;'); + } + }); + indent.writeScoped('else {', '}', () { + indent.writeln('ss << "null";'); + }); + } else { + if (field.type.isClass) { + indent.writeln('ss << $name.ToString();'); + } else { + indent.writeln('ss << $name;'); + } + } + }); + indent.writeln('ss << ")";'); + indent.writeln('return ss.str();'); + }, + ); + _writeFunctionDefinition( indent, 'PigeonInternalDeepHash', diff --git a/packages/pigeon/lib/src/dart/dart_generator.dart b/packages/pigeon/lib/src/dart/dart_generator.dart index 435df247c0c2..68ede69b0dd6 100644 --- a/packages/pigeon/lib/src/dart/dart_generator.dart +++ b/packages/pigeon/lib/src/dart/dart_generator.dart @@ -398,6 +398,19 @@ class DartGenerator extends StructuredGenerator { 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}'; + }); + final String fieldsConcat = fieldStrings.join(', '); + indent.writeln("return '${classDefinition.name}($fieldsConcat)';"); + }); } @override @@ -645,8 +658,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, @@ -1272,7 +1285,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 01a9cf8b30a0..7ef3bf0da6dc 100644 --- a/packages/pigeon/lib/src/functional.dart +++ b/packages/pigeon/lib/src/functional.dart @@ -24,7 +24,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, @@ -41,7 +41,7 @@ Iterable map2( } } -/// 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 55874a95684a..0902718890dc 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 = '26.4.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 0906c005d78a..328118de6733 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'; @@ -352,6 +353,17 @@ class GObjectHeaderGenerator '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 @@ -1346,6 +1358,89 @@ class GObjectSourceGenerator } 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, final NamedType field) { + final String fieldName = _getFieldName(field.name); + final comma = index == 0 ? '' : ', '; + indent.writeln('g_string_append(str, "$comma$fieldName: ");'); + + if (field.type.isClass) { + final String fieldMethodPrefix = _getMethodPrefix( + module, + field.type.baseName, + ); + indent.writeScoped('if (self->$fieldName != nullptr) {', '}', () { + indent.writeln( + 'gchar* field_str = ${fieldMethodPrefix}_to_string(self->$fieldName);', + ); + indent.writeln('g_string_append(str, field_str);'); + indent.writeln('g_free(field_str);'); + }); + indent.writeScoped('else {', '}', () { + indent.writeln('g_string_append(str, "null");'); + }); + } else if (field.type.baseName == 'String') { + indent.writeScoped('if (self->$fieldName != nullptr) {', '}', () { + indent.writeln( + 'g_string_append_printf(str, "\\"%s\\"", self->$fieldName);', + ); + }); + indent.writeScoped('else {', '}', () { + indent.writeln('g_string_append(str, "null");'); + }); + } else if (_isNumericListType(field.type)) { + indent.writeln( + 'g_string_append_printf(str, "[...], length: %zu", self->${fieldName}_length);', + ); + } else if (field.type.baseName == 'bool') { + indent.writeln( + 'g_string_append(str, self->$fieldName ? "true" : "false");', + ); + } else if (field.type.baseName == 'int') { + if (field.type.isNullable) { + indent.writeScoped('if (self->$fieldName != nullptr) {', '}', () { + indent.writeln( + 'g_string_append_printf(str, "%" G_GINT64_FORMAT, *self->$fieldName);', + ); + }); + indent.writeScoped('else {', '}', () { + indent.writeln('g_string_append(str, "null");'); + }); + } else { + indent.writeln( + 'g_string_append_printf(str, "%" G_GINT64_FORMAT, self->$fieldName);', + ); + } + } else if (field.type.baseName == 'double') { + if (field.type.isNullable) { + indent.writeScoped('if (self->$fieldName != nullptr) {', '}', () { + indent.writeln( + 'g_string_append_printf(str, "%g", *self->$fieldName);', + ); + }); + indent.writeScoped('else {', '}', () { + indent.writeln('g_string_append(str, "null");'); + }); + } else { + indent.writeln( + 'g_string_append_printf(str, "%g", self->$fieldName);', + ); + } + } else { + indent.writeln('g_string_append(str, "...");'); + } + }); + + indent.writeln('g_string_append(str, ")");'); + indent.writeln('return g_string_free(str, FALSE);'); + }); } @override diff --git a/packages/pigeon/lib/src/java/java_generator.dart b/packages/pigeon/lib/src/java/java_generator.dart index 4b7f792dc1c3..e9485e17db93 100644 --- a/packages/pigeon/lib/src/java/java_generator.dart +++ b/packages/pigeon/lib/src/java/java_generator.dart @@ -289,6 +289,7 @@ class JavaGenerator extends StructuredGenerator { indent.newln(); } _writeEquality(indent, classDefinition); + _writeToString(indent, classDefinition); _writeClassBuilder(generatorOptions, root, indent, classDefinition); writeClassEncode( @@ -410,6 +411,33 @@ 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'; + }); + final String fieldsConcat = fieldStrings.join(' + ", " + '); + if (fieldsConcat.isEmpty) { + indent.writeln('return "${classDefinition.name}{}";'); + } else { + indent.writeln( + 'return "${classDefinition.name}{" + $fieldsConcat + "}";', + ); + } + }); + indent.newln(); + } + void _writeDeepEquals(Indent indent) { indent.writeScoped( 'static boolean pigeonDeepEquals(Object a, Object b) {', diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 41e6a880f0a2..c04639aa2f5f 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -333,6 +333,13 @@ class KotlinGenerator extends StructuredGenerator { classDefinition, dartPackageName: dartPackageName, ); + writeClassToString( + generatorOptions, + root, + indent, + classDefinition, + dartPackageName: dartPackageName, + ); }); } @@ -390,6 +397,37 @@ 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'; + }); + final String fieldsConcat = fieldStrings.join(', '); + if (fieldsConcat.isEmpty) { + indent.writeln('return "${classDefinition.name}()"'); + } else { + indent.writeln('return "${classDefinition.name}($fieldsConcat)"'); + } + }); + } + void _writeDataClassSignature( Indent indent, Class classDefinition, { diff --git a/packages/pigeon/lib/src/kotlin/templates.dart b/packages/pigeon/lib/src/kotlin/templates.dart index f8afe99fe980..ad9b752c175f 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 af0ad6d1ea2a..0cec49bdfebe 100644 --- a/packages/pigeon/lib/src/objc/objc_generator.dart +++ b/packages/pigeon/lib/src/objc/objc_generator.dart @@ -617,6 +617,7 @@ class ObjcSourceGenerator extends StructuredGenerator { dartPackageName: dartPackageName, ); _writeObjcEquality(generatorOptions, indent, classDefinition); + _writeObjcDescription(generatorOptions, indent, classDefinition); indent.writeln('@end'); indent.newln(); } @@ -686,6 +687,39 @@ 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, + ) { + return '${field.name}: %@'; + }); + final formatString = '$className(${fieldLabels.join(', ')})'; + + final Iterable fieldValues = classDefinition.fields.map(( + NamedType field, + ) { + if (_usesPrimitive(field.type)) { + return '@(self.${field.name})'; + } + return 'self.${field.name}'; + }); + + final args = fieldValues.isEmpty ? '' : ', ${fieldValues.join(', ')}'; + indent.writeln( + 'return [NSString stringWithFormat:@"$formatString"$args];', + ); + }); + } + @override void writeClassEncode( InternalObjcOptions generatorOptions, @@ -1913,7 +1947,7 @@ 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: @@ -1945,13 +1979,13 @@ Iterable _getSelectorComponents( } } -/// 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 75504154bfcd..78e39f672d73 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 fd6b6c827b2b..9c38d8068d3c 100644 --- a/packages/pigeon/lib/src/pigeon_lib.dart +++ b/packages/pigeon/lib/src/pigeon_lib.dart @@ -110,7 +110,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. @@ -629,7 +629,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); @@ -691,8 +691,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( @@ -704,8 +704,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/swift/swift_generator.dart b/packages/pigeon/lib/src/swift/swift_generator.dart index 45b968ed4d10..2ed53a95b376 100644 --- a/packages/pigeon/lib/src/swift/swift_generator.dart +++ b/packages/pigeon/lib/src/swift/swift_generator.dart @@ -423,8 +423,8 @@ class SwiftGenerator extends StructuredGenerator { final extendsString = classDefinition.superClass != null ? ': ${classDefinition.superClass!.name}' : hashable - ? ': Hashable' - : ''; + ? ': Hashable, CustomStringConvertible' + : ': CustomStringConvertible'; if (classDefinition.isSwiftClass) { indent.write( '${privateString}class ${classDefinition.name}$extendsString ', @@ -593,6 +593,14 @@ if (wrapped == nil) { classDefinition, dartPackageName: dartPackageName, ); + indent.newln(); + writeClassToString( + generatorOptions, + root, + indent, + classDefinition, + dartPackageName: dartPackageName, + ); }); } @@ -704,6 +712,33 @@ if (wrapped == nil) { }); } + /// 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}))'; + }); + final String fieldsConcat = fieldStrings.join(', '); + indent.writeln('return "${classDefinition.name}($fieldsConcat)"'); + }, + ); + } + @override void writeClassDecode( InternalSwiftOptions generatorOptions, @@ -799,6 +834,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.', ]; @@ -1431,12 +1467,24 @@ if (wrapped == nil) { } } - void _writeIsNullish(Indent indent) { + void _writeIsNullish(InternalSwiftOptions generatorOptions, Indent indent) { indent.newln(); - indent.write('private func isNullish(_ value: Any?) -> Bool '); - indent.addScoped('{', '}', () { - indent.writeln('return value is NSNull || value == nil'); - }); + final String uniqueComponent = + generatorOptions.fileSpecificClassNameComponent ?? ''; + indent.format(''' +enum ${uniqueComponent}PigeonInternal { + 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) { @@ -1646,7 +1694,7 @@ func $deepHashName(value: Any?, hasher: inout Hasher) { _writeCreateConnectionError(generatorOptions, indent); } - _writeIsNullish(indent); + _writeIsNullish(generatorOptions, indent); _writeNilOrValue(indent); if (root.classes.isNotEmpty) { _writeDeepEquals(generatorOptions, indent); 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..1412c1fa1d6e 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; 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..f999a0fb6d53 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,20 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.mapMap); return result; } +- (NSString *)description { + return [NSString + stringWithFormat: + @"FLTAllTypes(aBool: %@, anInt: %@, anInt64: %@, aDouble: %@, aByteArray: %@, " + @"a4ByteArray: %@, a8ByteArray: %@, aFloatArray: %@, anEnum: %@, anotherEnum: %@, " + @"aString: %@, anObject: %@, list: %@, stringList: %@, intList: %@, doubleList: %@, " + @"boolList: %@, enumList: %@, objectList: %@, listList: %@, mapList: %@, map: %@, " + @"stringMap: %@, intMap: %@, enumMap: %@, objectMap: %@, listMap: %@, mapMap: %@)", + @(self.aBool), @(self.anInt), @(self.anInt64), @(self.aDouble), self.aByteArray, + self.a4ByteArray, self.a8ByteArray, self.aFloatArray, @(self.anEnum), @(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 +653,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 +875,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 +972,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 +1018,9 @@ - (NSUInteger)hash { result = result * 31 + FLTPigeonDeepHash(self.testList); return result; } +- (NSString *)description { + return [NSString stringWithFormat:@"FLTTestMessage(testList: %@)", self.testList]; +} @end @interface FLTCoreTestsPigeonCodecReader : FlutterStandardReader 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 d6e49a4b33b3..1ba37b3eae22 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, 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 482368add83b..3178b27fd494 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 @@ -152,6 +152,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. @@ -358,6 +363,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. @@ -585,6 +595,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 @@ -795,6 +810,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. @@ -883,6 +903,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. @@ -919,6 +944,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 { @@ -987,8 +1017,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, @@ -6123,8 +6153,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, @@ -6160,8 +6190,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, 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 202b98268626..3e577db1832f 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 @@ -165,6 +165,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 { @@ -201,8 +206,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, 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 4734c4b0cdb0..41bbc7ef8351 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 @@ -306,6 +306,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 {} @@ -343,6 +348,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 { @@ -378,6 +388,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 { @@ -413,6 +428,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 { @@ -448,6 +468,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 { @@ -483,6 +508,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 { @@ -518,6 +548,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 { @@ -553,6 +588,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 3fe4b498ee2d..940a8df6993f 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 @@ -134,6 +134,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 { @@ -174,6 +179,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 { @@ -209,6 +219,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 { @@ -244,6 +259,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 { @@ -288,8 +308,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 9013d5973196..08b51cf0867d 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 @@ -173,6 +173,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. @@ -224,6 +229,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. @@ -261,6 +271,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 { @@ -309,8 +324,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, @@ -371,8 +386,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, 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 7b2ebf15d84e..f431295f9022 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 @@ -74,8 +74,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, 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 476917a52f9f..0af20b35e5cb 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 @@ -151,6 +151,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 { @@ -192,6 +197,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 { @@ -251,6 +261,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 { @@ -296,8 +311,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, 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 e861dbaa62ed..a24a07771761 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 @@ -156,6 +156,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 { @@ -215,6 +220,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 { @@ -255,8 +265,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, 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 2c9c03a02426..a55bcf80b0a2 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 @@ -74,8 +74,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, @@ -150,8 +150,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, @@ -230,8 +230,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, @@ -306,8 +306,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, 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 b86058696a44..618b132d5047 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 @@ -74,8 +74,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, 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..c2a4db44242e 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() { 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/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..ccbc467b7344 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,8 +65,18 @@ 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 + } + + if case Optional.some(Optional.none) = value { + return true + } + + return innerValue is NSNull + } } private func nilOrValue(_ value: Any?) -> T? { @@ -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 @@ -223,12 +233,16 @@ struct UnusedClass: Hashable { hasher.combine("UnusedClass") deepHashCoreTests(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 @@ -414,12 +428,17 @@ struct AllTypes: Hashable { deepHashCoreTests(value: listMap, hasher: &hasher) deepHashCoreTests(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, @@ -693,6 +712,11 @@ class AllNullableTypes: Hashable { deepHashCoreTests(value: mapMap, hasher: &hasher) deepHashCoreTests(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)))" + } } /// The primary purpose for this class is to ensure coverage of Swift structs @@ -700,7 +724,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 @@ -890,6 +914,11 @@ struct AllNullableTypesWithoutRecursion: Hashable { deepHashCoreTests(value: listMap, hasher: &hasher) deepHashCoreTests(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)))" + } } /// A class for testing nested class handling. @@ -899,7 +928,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 @@ -965,12 +994,17 @@ struct AllClassesWrapper: Hashable { deepHashCoreTests(value: classMap, hasher: &hasher) deepHashCoreTests(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 @@ -997,6 +1031,10 @@ struct TestMessage: Hashable { hasher.combine("TestMessage") deepHashCoreTests(value: testList, hasher: &hasher) } + + public var description: String { + return "TestMessage(testList: \(String(describing: testList)))" + } } private class CoreTestsPigeonCodecReader: FlutterStandardReader { @@ -4558,6 +4596,7 @@ class HostIntegrationCoreApiSetup { } } } + /// The core interface that the Dart platform_test code implements for host /// integration tests to call into. /// @@ -6253,6 +6292,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..0d9f5514911d 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,8 +33,18 @@ 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 + } + + if case Optional.some(Optional.none) = value { + return true + } + + return innerValue is NSNull + } } private func nilOrValue(_ value: Any?) -> T? { @@ -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, @@ -441,6 +451,11 @@ class EventAllNullableTypes: Hashable { deepHashEventChannelTests(value: mapMap, hasher: &hasher) deepHashEventChannelTests(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)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -477,6 +492,10 @@ struct IntEvent: PlatformEvent { hasher.combine("IntEvent") deepHashEventChannelTests(value: value, hasher: &hasher) } + + public var description: String { + return "IntEvent(value: \(String(describing: value)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -507,6 +526,10 @@ struct StringEvent: PlatformEvent { hasher.combine("StringEvent") deepHashEventChannelTests(value: value, hasher: &hasher) } + + public var description: String { + return "StringEvent(value: \(String(describing: value)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -537,6 +560,10 @@ struct BoolEvent: PlatformEvent { hasher.combine("BoolEvent") deepHashEventChannelTests(value: value, hasher: &hasher) } + + public var description: String { + return "BoolEvent(value: \(String(describing: value)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -567,6 +594,10 @@ struct DoubleEvent: PlatformEvent { hasher.combine("DoubleEvent") deepHashEventChannelTests(value: value, hasher: &hasher) } + + public var description: String { + return "DoubleEvent(value: \(String(describing: value)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -597,6 +628,10 @@ struct ObjectsEvent: PlatformEvent { hasher.combine("ObjectsEvent") deepHashEventChannelTests(value: value, hasher: &hasher) } + + public var description: String { + return "ObjectsEvent(value: \(String(describing: value)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -627,6 +662,10 @@ struct EnumEvent: PlatformEvent { hasher.combine("EnumEvent") deepHashEventChannelTests(value: value, hasher: &hasher) } + + public var description: String { + return "EnumEvent(value: \(String(describing: value)))" + } } /// Generated class from Pigeon that represents data sent in messages. @@ -657,6 +696,10 @@ struct ClassEvent: PlatformEvent { hasher.combine("ClassEvent") deepHashEventChannelTests(value: value, hasher: &hasher) } + + public var description: String { + return "ClassEvent(value: \(String(describing: value)))" + } } private class EventChannelTestsPigeonCodecReader: FlutterStandardReader { 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/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/linux/pigeon/core_tests.gen.cc b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc index 023cd1ed85db..4c1866684d3e 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 @@ -282,6 +282,16 @@ 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: "); + g_string_append(str, "..."); + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestAllTypes { GObject parent_instance; @@ -909,6 +919,74 @@ 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: "); + g_string_append_printf(str, "[...], length: %zu", self->a_byte_array_length); + g_string_append(str, ", a4_byte_array: "); + g_string_append_printf(str, "[...], length: %zu", self->a4_byte_array_length); + g_string_append(str, ", a8_byte_array: "); + g_string_append_printf(str, "[...], length: %zu", self->a8_byte_array_length); + g_string_append(str, ", a_float_array: "); + g_string_append_printf(str, "[...], length: %zu", self->a_float_array_length); + g_string_append(str, ", an_enum: "); + g_string_append(str, "..."); + g_string_append(str, ", another_enum: "); + g_string_append(str, "..."); + 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: "); + g_string_append(str, "..."); + g_string_append(str, ", list: "); + g_string_append(str, "..."); + g_string_append(str, ", string_list: "); + g_string_append(str, "..."); + g_string_append(str, ", int_list: "); + g_string_append(str, "..."); + g_string_append(str, ", double_list: "); + g_string_append(str, "..."); + g_string_append(str, ", bool_list: "); + g_string_append(str, "..."); + g_string_append(str, ", enum_list: "); + g_string_append(str, "..."); + g_string_append(str, ", object_list: "); + g_string_append(str, "..."); + g_string_append(str, ", list_list: "); + g_string_append(str, "..."); + g_string_append(str, ", map_list: "); + g_string_append(str, "..."); + g_string_append(str, ", map: "); + g_string_append(str, "..."); + g_string_append(str, ", string_map: "); + g_string_append(str, "..."); + g_string_append(str, ", int_map: "); + g_string_append(str, "..."); + g_string_append(str, ", enum_map: "); + g_string_append(str, "..."); + g_string_append(str, ", object_map: "); + g_string_append(str, "..."); + g_string_append(str, ", list_map: "); + g_string_append(str, "..."); + g_string_append(str, ", map_map: "); + g_string_append(str, "..."); + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestAllNullableTypes { GObject parent_instance; @@ -2001,6 +2079,104 @@ 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: "); + g_string_append(str, self->a_nullable_bool ? "true" : "false"); + 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: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable_byte_array_length); + g_string_append(str, ", a_nullable4_byte_array: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable4_byte_array_length); + g_string_append(str, ", a_nullable8_byte_array: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable8_byte_array_length); + g_string_append(str, ", a_nullable_float_array: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable_float_array_length); + g_string_append(str, ", a_nullable_enum: "); + g_string_append(str, "..."); + g_string_append(str, ", another_nullable_enum: "); + g_string_append(str, "..."); + 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: "); + g_string_append(str, "..."); + 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: "); + g_string_append(str, "..."); + g_string_append(str, ", string_list: "); + g_string_append(str, "..."); + g_string_append(str, ", int_list: "); + g_string_append(str, "..."); + g_string_append(str, ", double_list: "); + g_string_append(str, "..."); + g_string_append(str, ", bool_list: "); + g_string_append(str, "..."); + g_string_append(str, ", enum_list: "); + g_string_append(str, "..."); + g_string_append(str, ", object_list: "); + g_string_append(str, "..."); + g_string_append(str, ", list_list: "); + g_string_append(str, "..."); + g_string_append(str, ", map_list: "); + g_string_append(str, "..."); + g_string_append(str, ", recursive_class_list: "); + g_string_append(str, "..."); + g_string_append(str, ", map: "); + g_string_append(str, "..."); + g_string_append(str, ", string_map: "); + g_string_append(str, "..."); + g_string_append(str, ", int_map: "); + g_string_append(str, "..."); + g_string_append(str, ", enum_map: "); + g_string_append(str, "..."); + g_string_append(str, ", object_map: "); + g_string_append(str, "..."); + g_string_append(str, ", list_map: "); + g_string_append(str, "..."); + g_string_append(str, ", map_map: "); + g_string_append(str, "..."); + g_string_append(str, ", recursive_class_map: "); + g_string_append(str, "..."); + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestAllNullableTypesWithoutRecursion { GObject parent_instance; @@ -3060,6 +3236,92 @@ guint core_tests_pigeon_test_all_nullable_types_without_recursion_hash( return result; } +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: "); + g_string_append(str, self->a_nullable_bool ? "true" : "false"); + 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: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable_byte_array_length); + g_string_append(str, ", a_nullable4_byte_array: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable4_byte_array_length); + g_string_append(str, ", a_nullable8_byte_array: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable8_byte_array_length); + g_string_append(str, ", a_nullable_float_array: "); + g_string_append_printf(str, "[...], length: %zu", + self->a_nullable_float_array_length); + g_string_append(str, ", a_nullable_enum: "); + g_string_append(str, "..."); + g_string_append(str, ", another_nullable_enum: "); + g_string_append(str, "..."); + 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: "); + g_string_append(str, "..."); + g_string_append(str, ", list: "); + g_string_append(str, "..."); + g_string_append(str, ", string_list: "); + g_string_append(str, "..."); + g_string_append(str, ", int_list: "); + g_string_append(str, "..."); + g_string_append(str, ", double_list: "); + g_string_append(str, "..."); + g_string_append(str, ", bool_list: "); + g_string_append(str, "..."); + g_string_append(str, ", enum_list: "); + g_string_append(str, "..."); + g_string_append(str, ", object_list: "); + g_string_append(str, "..."); + g_string_append(str, ", list_list: "); + g_string_append(str, "..."); + g_string_append(str, ", map_list: "); + g_string_append(str, "..."); + g_string_append(str, ", map: "); + g_string_append(str, "..."); + g_string_append(str, ", string_map: "); + g_string_append(str, "..."); + g_string_append(str, ", int_map: "); + g_string_append(str, "..."); + g_string_append(str, ", enum_map: "); + g_string_append(str, "..."); + g_string_append(str, ", object_map: "); + g_string_append(str, "..."); + g_string_append(str, ", list_map: "); + g_string_append(str, "..."); + g_string_append(str, ", map_map: "); + g_string_append(str, "..."); + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestAllClassesWrapper { GObject parent_instance; @@ -3315,6 +3577,51 @@ 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: "); + g_string_append(str, "..."); + g_string_append(str, ", nullable_class_list: "); + g_string_append(str, "..."); + g_string_append(str, ", class_map: "); + g_string_append(str, "..."); + g_string_append(str, ", nullable_class_map: "); + g_string_append(str, "..."); + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestTestMessage { GObject parent_instance; @@ -3399,6 +3706,16 @@ 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: "); + g_string_append(str, "..."); + g_string_append(str, ")"); + return g_string_free(str, FALSE); +} + struct _CoreTestsPigeonTestMessageCodec { FlStandardMessageCodec parent_instance; }; 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..455c0d95fae3 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, 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..6302c3ad6234 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 { @@ -291,6 +292,19 @@ size_t UnusedClass::Hash() const { return result; } +std::string UnusedClass::ToString() const { + std::stringstream ss; + ss << "UnusedClass("; + ss << "aField: "; + if (a_field_.has_value()) { + ss << *a_field_; + } else { + ss << "null"; + } + ss << ")"; + return ss.str(); +} + size_t PigeonInternalDeepHash(const UnusedClass& v) { return v.Hash(); } // AllTypes @@ -629,6 +643,69 @@ size_t AllTypes::Hash() const { return result; } +std::string AllTypes::ToString() const { + std::stringstream ss; + ss << "AllTypes("; + ss << "aBool: "; + ss << a_bool_; + ss << ", anInt: "; + ss << an_int_; + ss << ", anInt64: "; + ss << an_int64_; + ss << ", aDouble: "; + ss << a_double_; + ss << ", aByteArray: "; + ss << a_byte_array_; + ss << ", a4ByteArray: "; + ss << a4_byte_array_; + ss << ", a8ByteArray: "; + ss << a8_byte_array_; + ss << ", aFloatArray: "; + ss << a_float_array_; + ss << ", anEnum: "; + ss << an_enum_; + ss << ", anotherEnum: "; + ss << another_enum_; + ss << ", aString: "; + ss << a_string_; + ss << ", anObject: "; + ss << an_object_; + ss << ", list: "; + ss << list_; + ss << ", stringList: "; + ss << string_list_; + ss << ", intList: "; + ss << int_list_; + ss << ", doubleList: "; + ss << double_list_; + ss << ", boolList: "; + ss << bool_list_; + ss << ", enumList: "; + ss << enum_list_; + ss << ", objectList: "; + ss << object_list_; + ss << ", listList: "; + ss << list_list_; + ss << ", mapList: "; + ss << map_list_; + ss << ", map: "; + ss << map_; + ss << ", stringMap: "; + ss << string_map_; + ss << ", intMap: "; + ss << int_map_; + ss << ", enumMap: "; + ss << enum_map_; + ss << ", objectMap: "; + ss << object_map_; + ss << ", listMap: "; + ss << list_map_; + ss << ", mapMap: "; + ss << map_map_; + ss << ")"; + return ss.str(); +} + size_t PigeonInternalDeepHash(const AllTypes& v) { return v.Hash(); } // AllNullableTypes @@ -1566,6 +1643,199 @@ size_t AllNullableTypes::Hash() const { return result; } +std::string AllNullableTypes::ToString() const { + std::stringstream ss; + ss << "AllNullableTypes("; + ss << "aNullableBool: "; + if (a_nullable_bool_.has_value()) { + ss << *a_nullable_bool_; + } else { + ss << "null"; + } + ss << ", aNullableInt: "; + if (a_nullable_int_.has_value()) { + ss << *a_nullable_int_; + } else { + ss << "null"; + } + ss << ", aNullableInt64: "; + if (a_nullable_int64_.has_value()) { + ss << *a_nullable_int64_; + } else { + ss << "null"; + } + ss << ", aNullableDouble: "; + if (a_nullable_double_.has_value()) { + ss << *a_nullable_double_; + } else { + ss << "null"; + } + ss << ", aNullableByteArray: "; + if (a_nullable_byte_array_.has_value()) { + ss << *a_nullable_byte_array_; + } else { + ss << "null"; + } + ss << ", aNullable4ByteArray: "; + if (a_nullable4_byte_array_.has_value()) { + ss << *a_nullable4_byte_array_; + } else { + ss << "null"; + } + ss << ", aNullable8ByteArray: "; + if (a_nullable8_byte_array_.has_value()) { + ss << *a_nullable8_byte_array_; + } else { + ss << "null"; + } + ss << ", aNullableFloatArray: "; + if (a_nullable_float_array_.has_value()) { + ss << *a_nullable_float_array_; + } else { + ss << "null"; + } + ss << ", aNullableEnum: "; + if (a_nullable_enum_.has_value()) { + ss << *a_nullable_enum_; + } else { + ss << "null"; + } + ss << ", anotherNullableEnum: "; + if (another_nullable_enum_.has_value()) { + ss << *another_nullable_enum_; + } else { + ss << "null"; + } + ss << ", aNullableString: "; + if (a_nullable_string_.has_value()) { + ss << *a_nullable_string_; + } else { + ss << "null"; + } + ss << ", aNullableObject: "; + if (a_nullable_object_.has_value()) { + ss << *a_nullable_object_; + } else { + ss << "null"; + } + ss << ", allNullableTypes: "; + if (all_nullable_types_.has_value()) { + ss << all_nullable_types_->ToString(); + } else { + ss << "null"; + } + ss << ", list: "; + if (list_.has_value()) { + ss << *list_; + } else { + ss << "null"; + } + ss << ", stringList: "; + if (string_list_.has_value()) { + ss << *string_list_; + } else { + ss << "null"; + } + ss << ", intList: "; + if (int_list_.has_value()) { + ss << *int_list_; + } else { + ss << "null"; + } + ss << ", doubleList: "; + if (double_list_.has_value()) { + ss << *double_list_; + } else { + ss << "null"; + } + ss << ", boolList: "; + if (bool_list_.has_value()) { + ss << *bool_list_; + } else { + ss << "null"; + } + ss << ", enumList: "; + if (enum_list_.has_value()) { + ss << *enum_list_; + } else { + ss << "null"; + } + ss << ", objectList: "; + if (object_list_.has_value()) { + ss << *object_list_; + } else { + ss << "null"; + } + ss << ", listList: "; + if (list_list_.has_value()) { + ss << *list_list_; + } else { + ss << "null"; + } + ss << ", mapList: "; + if (map_list_.has_value()) { + ss << *map_list_; + } else { + ss << "null"; + } + ss << ", recursiveClassList: "; + if (recursive_class_list_.has_value()) { + ss << *recursive_class_list_; + } else { + ss << "null"; + } + ss << ", map: "; + if (map_.has_value()) { + ss << *map_; + } else { + ss << "null"; + } + ss << ", stringMap: "; + if (string_map_.has_value()) { + ss << *string_map_; + } else { + ss << "null"; + } + ss << ", intMap: "; + if (int_map_.has_value()) { + ss << *int_map_; + } else { + ss << "null"; + } + ss << ", enumMap: "; + if (enum_map_.has_value()) { + ss << *enum_map_; + } else { + ss << "null"; + } + ss << ", objectMap: "; + if (object_map_.has_value()) { + ss << *object_map_; + } else { + ss << "null"; + } + ss << ", listMap: "; + if (list_map_.has_value()) { + ss << *list_map_; + } else { + ss << "null"; + } + ss << ", mapMap: "; + if (map_map_.has_value()) { + ss << *map_map_; + } else { + ss << "null"; + } + ss << ", recursiveClassMap: "; + if (recursive_class_map_.has_value()) { + ss << *recursive_class_map_; + } else { + ss << "null"; + } + ss << ")"; + return ss.str(); +} + size_t PigeonInternalDeepHash(const AllNullableTypes& v) { return v.Hash(); } // AllNullableTypesWithoutRecursion @@ -2332,6 +2602,181 @@ size_t AllNullableTypesWithoutRecursion::Hash() const { return result; } +std::string AllNullableTypesWithoutRecursion::ToString() const { + std::stringstream ss; + ss << "AllNullableTypesWithoutRecursion("; + ss << "aNullableBool: "; + if (a_nullable_bool_.has_value()) { + ss << *a_nullable_bool_; + } else { + ss << "null"; + } + ss << ", aNullableInt: "; + if (a_nullable_int_.has_value()) { + ss << *a_nullable_int_; + } else { + ss << "null"; + } + ss << ", aNullableInt64: "; + if (a_nullable_int64_.has_value()) { + ss << *a_nullable_int64_; + } else { + ss << "null"; + } + ss << ", aNullableDouble: "; + if (a_nullable_double_.has_value()) { + ss << *a_nullable_double_; + } else { + ss << "null"; + } + ss << ", aNullableByteArray: "; + if (a_nullable_byte_array_.has_value()) { + ss << *a_nullable_byte_array_; + } else { + ss << "null"; + } + ss << ", aNullable4ByteArray: "; + if (a_nullable4_byte_array_.has_value()) { + ss << *a_nullable4_byte_array_; + } else { + ss << "null"; + } + ss << ", aNullable8ByteArray: "; + if (a_nullable8_byte_array_.has_value()) { + ss << *a_nullable8_byte_array_; + } else { + ss << "null"; + } + ss << ", aNullableFloatArray: "; + if (a_nullable_float_array_.has_value()) { + ss << *a_nullable_float_array_; + } else { + ss << "null"; + } + ss << ", aNullableEnum: "; + if (a_nullable_enum_.has_value()) { + ss << *a_nullable_enum_; + } else { + ss << "null"; + } + ss << ", anotherNullableEnum: "; + if (another_nullable_enum_.has_value()) { + ss << *another_nullable_enum_; + } else { + ss << "null"; + } + ss << ", aNullableString: "; + if (a_nullable_string_.has_value()) { + ss << *a_nullable_string_; + } else { + ss << "null"; + } + ss << ", aNullableObject: "; + if (a_nullable_object_.has_value()) { + ss << *a_nullable_object_; + } else { + ss << "null"; + } + ss << ", list: "; + if (list_.has_value()) { + ss << *list_; + } else { + ss << "null"; + } + ss << ", stringList: "; + if (string_list_.has_value()) { + ss << *string_list_; + } else { + ss << "null"; + } + ss << ", intList: "; + if (int_list_.has_value()) { + ss << *int_list_; + } else { + ss << "null"; + } + ss << ", doubleList: "; + if (double_list_.has_value()) { + ss << *double_list_; + } else { + ss << "null"; + } + ss << ", boolList: "; + if (bool_list_.has_value()) { + ss << *bool_list_; + } else { + ss << "null"; + } + ss << ", enumList: "; + if (enum_list_.has_value()) { + ss << *enum_list_; + } else { + ss << "null"; + } + ss << ", objectList: "; + if (object_list_.has_value()) { + ss << *object_list_; + } else { + ss << "null"; + } + ss << ", listList: "; + if (list_list_.has_value()) { + ss << *list_list_; + } else { + ss << "null"; + } + ss << ", mapList: "; + if (map_list_.has_value()) { + ss << *map_list_; + } else { + ss << "null"; + } + ss << ", map: "; + if (map_.has_value()) { + ss << *map_; + } else { + ss << "null"; + } + ss << ", stringMap: "; + if (string_map_.has_value()) { + ss << *string_map_; + } else { + ss << "null"; + } + ss << ", intMap: "; + if (int_map_.has_value()) { + ss << *int_map_; + } else { + ss << "null"; + } + ss << ", enumMap: "; + if (enum_map_.has_value()) { + ss << *enum_map_; + } else { + ss << "null"; + } + ss << ", objectMap: "; + if (object_map_.has_value()) { + ss << *object_map_; + } else { + ss << "null"; + } + ss << ", listMap: "; + if (list_map_.has_value()) { + ss << *list_map_; + } else { + ss << "null"; + } + ss << ", mapMap: "; + if (map_map_.has_value()) { + ss << *map_map_; + } else { + ss << "null"; + } + ss << ")"; + return ss.str(); +} + size_t PigeonInternalDeepHash(const AllNullableTypesWithoutRecursion& v) { return v.Hash(); } @@ -2574,6 +3019,43 @@ size_t AllClassesWrapper::Hash() const { return result; } +std::string AllClassesWrapper::ToString() const { + std::stringstream ss; + ss << "AllClassesWrapper("; + ss << "allNullableTypes: "; + ss << all_nullable_types_.ToString(); + ss << ", allNullableTypesWithoutRecursion: "; + if (all_nullable_types_without_recursion_.has_value()) { + ss << all_nullable_types_without_recursion_->ToString(); + } else { + ss << "null"; + } + ss << ", allTypes: "; + if (all_types_.has_value()) { + ss << all_types_->ToString(); + } else { + ss << "null"; + } + ss << ", classList: "; + ss << class_list_; + ss << ", nullableClassList: "; + if (nullable_class_list_.has_value()) { + ss << *nullable_class_list_; + } else { + ss << "null"; + } + ss << ", classMap: "; + ss << class_map_; + ss << ", nullableClassMap: "; + if (nullable_class_map_.has_value()) { + ss << *nullable_class_map_; + } else { + ss << "null"; + } + ss << ")"; + return ss.str(); +} + size_t PigeonInternalDeepHash(const AllClassesWrapper& v) { return v.Hash(); } // TestMessage @@ -2627,6 +3109,19 @@ size_t TestMessage::Hash() const { return result; } +std::string TestMessage::ToString() const { + std::stringstream ss; + ss << "TestMessage("; + ss << "testList: "; + if (test_list_.has_value()) { + ss << *test_list_; + } else { + ss << "null"; + } + ss << ")"; + return ss.str(); +} + size_t PigeonInternalDeepHash(const TestMessage& v) { return v.Hash(); } PigeonInternalCodecSerializer::PigeonInternalCodecSerializer() {} 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..e3e62dd62b9e 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 @@ -93,6 +93,7 @@ class UnusedClass { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + std::string ToString() const; private: static UnusedClass FromEncodableList(const ::flutter::EncodableList& list); @@ -227,6 +228,7 @@ class AllTypes { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + std::string ToString() const; private: static AllTypes FromEncodableList(const ::flutter::EncodableList& list); @@ -442,6 +444,7 @@ class AllNullableTypes { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + std::string ToString() const; private: static AllNullableTypes FromEncodableList( @@ -643,6 +646,7 @@ class AllNullableTypesWithoutRecursion { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + std::string ToString() const; private: static AllNullableTypesWithoutRecursion FromEncodableList( @@ -748,6 +752,7 @@ class AllClassesWrapper { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + std::string ToString() const; private: static AllClassesWrapper FromEncodableList( @@ -790,6 +795,7 @@ class TestMessage { /// Returns a hash code value for the object. This method is supported for the /// benefit of hash tables. size_t Hash() const; + std::string ToString() const; private: static TestMessage FromEncodableList(const ::flutter::EncodableList& list); diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 804181258e69..3cf419595efb 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: 26.4.0 # This must match the version in lib/src/generator_tools.dart environment: sdk: ^3.9.0 diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index 0c77bed2b1de..acfe6513caa2 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -571,6 +571,7 @@ void main() { #include #include #include +#include #include '''), ); @@ -2725,6 +2726,44 @@ void main() { expect(code, contains('bool Foo::operator==(const Foo& other) const {')); }); + test('data class ToString', () { + 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::string Foo::ToString() const {')); + expect(code, contains('ss << "bar: ";')); + expect(code, contains('ss << bar_;')); + }); + 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 f3774fc75c92..01dd129b06b3 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -2151,4 +2151,32 @@ 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 8f44885a4617..1cb5c94728e3 100644 --- a/packages/pigeon/test/gobject_generator_test.dart +++ b/packages/pigeon/test/gobject_generator_test.dart @@ -1081,4 +1081,40 @@ 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 a5f0708abf58..0ca4fed593ca 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -1920,4 +1920,33 @@ 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 fe9600e81bc1..ff58fb181e56 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -2171,4 +2171,33 @@ 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)"')); + }); } diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index fb18833f77bc..4f8507ca3be2 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -4099,4 +4099,47 @@ 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: %@)", @(self.bar)];', + ), + ); + }); } diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 7b2d3b78a1c7..ca0fe431d772 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -41,7 +41,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(); diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index fa567e2b02c8..101fbb4a2688 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -1853,4 +1853,37 @@ void main() { ); 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)))"'), + ); + }); }