From b20727b67a84d72cee61a98aedb3a3a6f20bf4ff Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 12:01:09 -0700 Subject: [PATCH 01/16] add integration test and ast changes --- packages/pigeon/lib/ast.dart | 7 ++++ packages/pigeon/lib/pigeon_lib.dart | 7 ++++ packages/pigeon/lib/swift_generator.dart | 4 +++ packages/pigeon/pigeons/core_tests.dart | 3 ++ .../CoreTests.java | 27 ++++++++++++++- .../ios/Classes/CoreTests.gen.h | 4 ++- .../ios/Classes/CoreTests.gen.m | 7 +++- .../macos/Classes/CoreTests.gen.h | 4 ++- .../macos/Classes/CoreTests.gen.m | 7 +++- .../lib/src/generated/core_tests.gen.dart | 7 ++++ .../com/example/test_plugin/CoreTests.gen.kt | 9 +++-- .../ios/Classes/CoreTests.gen.swift | 9 ++++- .../macos/Classes/CoreTests.gen.swift | 9 ++++- .../windows/pigeon/core_tests.gen.cpp | 33 +++++++++++++++++-- .../windows/pigeon/core_tests.gen.h | 8 ++++- 15 files changed, 132 insertions(+), 13 deletions(-) diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index bc4ec8c4477..8bf1ba1fe34 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -639,6 +639,7 @@ class Class extends Node { Class({ required this.name, required this.fields, + this.swiftClass = false, this.documentationComments = const [], }); @@ -648,6 +649,12 @@ class Class extends Node { /// All the fields contained in the class. List fields; + /// Determines whether the defined class should be represented as a struct or + /// a class in Swift generation. + /// + /// Defaults to false, which would represent a struct. + bool swiftClass; + /// List of documentation comments, separated by line. /// /// Lines should not include the comment marker itself, but should include any diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 8f418d04259..f5fb3c58e96 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -177,6 +177,12 @@ class SwiftFunction { final String value; } +/// Metadata to annotate data classes to be defined as class in Swift output. +class SwiftClass { + /// Constructor. + const SwiftClass(); +} + /// Type of TaskQueue which determines how handlers are dispatched for /// HostApi's. enum TaskQueueType { @@ -1550,6 +1556,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { _currentClass = Class( name: node.name.lexeme, fields: [], + swiftClass: _hasMetadata(node.metadata, 'SwiftClass'), documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 1004a4f38d5..78720dd5c73 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -125,7 +125,11 @@ class SwiftGenerator extends StructuredGenerator { indent, classDefinition.documentationComments, _docCommentSpec, generatorComments: generatedComments); + // if (classDefinition.swiftClass) { + // indent.write('class ${classDefinition.name} '); + // } else { indent.write('struct ${classDefinition.name} '); + // } indent.addScoped('{', '}', () { getFieldsInSerializationOrder(classDefinition).forEach((NamedType field) { _writeClassField(indent, field); diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index 9d571688a09..a98f3c8ca24 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -48,6 +48,7 @@ class AllTypes { } /// A class containing all supported nullable types. +@SwiftClass() class AllNullableTypes { AllNullableTypes( this.aNullableBool, @@ -66,6 +67,7 @@ class AllNullableTypes { this.aNullableEnum, this.aNullableString, this.aNullableObject, + this.allNullableTypes, ); bool? aNullableBool; @@ -86,6 +88,7 @@ class AllNullableTypes { AnEnum? aNullableEnum; String? aNullableString; Object? aNullableObject; + AllNullableTypes? allNullableTypes; } /// A class for testing nested class handling. 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 0917a8cfa79..ecfdff1136d 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 @@ -612,6 +612,16 @@ public void setANullableObject(@Nullable Object setterArg) { this.aNullableObject = setterArg; } + private @Nullable AllNullableTypes allNullableTypes; + + public @Nullable AllNullableTypes getAllNullableTypes() { + return allNullableTypes; + } + + public void setAllNullableTypes(@Nullable AllNullableTypes setterArg) { + this.allNullableTypes = setterArg; + } + public static final class Builder { private @Nullable Boolean aNullableBool; @@ -743,6 +753,14 @@ public static final class Builder { return this; } + private @Nullable AllNullableTypes allNullableTypes; + + @CanIgnoreReturnValue + public @NonNull Builder setAllNullableTypes(@Nullable AllNullableTypes setterArg) { + this.allNullableTypes = setterArg; + return this; + } + public @NonNull AllNullableTypes build() { AllNullableTypes pigeonReturn = new AllNullableTypes(); pigeonReturn.setANullableBool(aNullableBool); @@ -761,13 +779,14 @@ public static final class Builder { pigeonReturn.setANullableEnum(aNullableEnum); pigeonReturn.setANullableString(aNullableString); pigeonReturn.setANullableObject(aNullableObject); + pigeonReturn.setAllNullableTypes(allNullableTypes); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(16); + ArrayList toListResult = new ArrayList(17); toListResult.add(aNullableBool); toListResult.add(aNullableInt); toListResult.add(aNullableInt64); @@ -784,6 +803,7 @@ ArrayList toList() { toListResult.add(aNullableEnum == null ? null : aNullableEnum.index); toListResult.add(aNullableString); toListResult.add(aNullableObject); + toListResult.add((allNullableTypes == null) ? null : allNullableTypes.toList()); return toListResult; } @@ -830,6 +850,11 @@ ArrayList toList() { pigeonResult.setANullableString((String) aNullableString); Object aNullableObject = list.get(15); pigeonResult.setANullableObject(aNullableObject); + Object allNullableTypes = list.get(16); + pigeonResult.setAllNullableTypes( + (allNullableTypes == null) + ? null + : AllNullableTypes.fromList((ArrayList) allNullableTypes)); return pigeonResult; } } diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index d3506f9d3e9..71e98de8037 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -83,7 +83,8 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject; + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes; @property(nonatomic, strong, nullable) NSNumber *aNullableBool; @property(nonatomic, strong, nullable) NSNumber *aNullableInt; @property(nonatomic, strong, nullable) NSNumber *aNullableInt64; @@ -101,6 +102,7 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, strong, nullable) FLTAnEnumBox *aNullableEnum; @property(nonatomic, copy, nullable) NSString *aNullableString; @property(nonatomic, strong, nullable) id aNullableObject; +@property(nonatomic, strong, nullable) FLTAllNullableTypes *allNullableTypes; @end /// A class for testing nested class handling. diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index d69afc01e13..b3648a7d3a3 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -160,7 +160,8 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject { + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable FLTAllNullableTypes *)allNullableTypes { FLTAllNullableTypes *pigeonResult = [[FLTAllNullableTypes alloc] init]; pigeonResult.aNullableBool = aNullableBool; pigeonResult.aNullableInt = aNullableInt; @@ -178,6 +179,7 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.aNullableEnum = aNullableEnum; pigeonResult.aNullableString = aNullableString; pigeonResult.aNullableObject = aNullableObject; + pigeonResult.allNullableTypes = allNullableTypes; return pigeonResult; } + (FLTAllNullableTypes *)fromList:(NSArray *)list { @@ -203,6 +205,8 @@ + (FLTAllNullableTypes *)fromList:(NSArray *)list { pigeonResult.aNullableEnum = aNullableEnum; pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 14); pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 15); + pigeonResult.allNullableTypes = + [FLTAllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 16))]; return pigeonResult; } + (nullable FLTAllNullableTypes *)nullableFromList:(NSArray *)list { @@ -227,6 +231,7 @@ - (NSArray *)toList { : [NSNumber numberWithInteger:self.aNullableEnum.value]), self.aNullableString ?: [NSNull null], self.aNullableObject ?: [NSNull null], + (self.allNullableTypes ? [self.allNullableTypes toList] : [NSNull null]), ]; } @end diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h index e7022baa940..1777c506820 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h @@ -83,7 +83,8 @@ typedef NS_ENUM(NSUInteger, AnEnum) { nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject aNullableEnum:(nullable AnEnumBox *)aNullableEnum aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject; + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable AllNullableTypes *)allNullableTypes; @property(nonatomic, strong, nullable) NSNumber *aNullableBool; @property(nonatomic, strong, nullable) NSNumber *aNullableInt; @property(nonatomic, strong, nullable) NSNumber *aNullableInt64; @@ -101,6 +102,7 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, strong, nullable) AnEnumBox *aNullableEnum; @property(nonatomic, copy, nullable) NSString *aNullableString; @property(nonatomic, strong, nullable) id aNullableObject; +@property(nonatomic, strong, nullable) AllNullableTypes *allNullableTypes; @end /// A class for testing nested class handling. diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m index 0cc5b059c04..1fe478cdbb5 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m @@ -160,7 +160,8 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject aNullableEnum:(nullable AnEnumBox *)aNullableEnum aNullableString:(nullable NSString *)aNullableString - aNullableObject:(nullable id)aNullableObject { + aNullableObject:(nullable id)aNullableObject + allNullableTypes:(nullable AllNullableTypes *)allNullableTypes { AllNullableTypes *pigeonResult = [[AllNullableTypes alloc] init]; pigeonResult.aNullableBool = aNullableBool; pigeonResult.aNullableInt = aNullableInt; @@ -178,6 +179,7 @@ + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool pigeonResult.aNullableEnum = aNullableEnum; pigeonResult.aNullableString = aNullableString; pigeonResult.aNullableObject = aNullableObject; + pigeonResult.allNullableTypes = allNullableTypes; return pigeonResult; } + (AllNullableTypes *)fromList:(NSArray *)list { @@ -203,6 +205,8 @@ + (AllNullableTypes *)fromList:(NSArray *)list { pigeonResult.aNullableEnum = aNullableEnum; pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 14); pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 15); + pigeonResult.allNullableTypes = + [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 16))]; return pigeonResult; } + (nullable AllNullableTypes *)nullableFromList:(NSArray *)list { @@ -227,6 +231,7 @@ - (NSArray *)toList { : [NSNumber numberWithInteger:self.aNullableEnum.value]), self.aNullableString ?: [NSNull null], self.aNullableObject ?: [NSNull null], + (self.allNullableTypes ? [self.allNullableTypes toList] : [NSNull null]), ]; } @end 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 98c1aea5c08..5f9695a4015 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 @@ -139,6 +139,7 @@ class AllNullableTypes { this.aNullableEnum, this.aNullableString, this.aNullableObject, + this.allNullableTypes, }); bool? aNullableBool; @@ -173,6 +174,8 @@ class AllNullableTypes { Object? aNullableObject; + AllNullableTypes? allNullableTypes; + Object encode() { return [ aNullableBool, @@ -191,6 +194,7 @@ class AllNullableTypes { aNullableEnum?.index, aNullableString, aNullableObject, + allNullableTypes?.encode(), ]; } @@ -216,6 +220,9 @@ class AllNullableTypes { result[13] != null ? AnEnum.values[result[13]! as int] : null, aNullableString: result[14] as String?, aNullableObject: result[15], + allNullableTypes: result[16] != null + ? AllNullableTypes.decode(result[16]! as List) + : null, ); } } 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 b97e72c0146..3499266d35c 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 @@ -142,7 +142,8 @@ data class AllNullableTypes( val nullableMapWithObject: Map? = null, val aNullableEnum: AnEnum? = null, val aNullableString: String? = null, - val aNullableObject: Any? = null + val aNullableObject: Any? = null, + val allNullableTypes: AllNullableTypes? = null ) { companion object { @Suppress("UNCHECKED_CAST") @@ -163,6 +164,8 @@ data class AllNullableTypes( val aNullableEnum: AnEnum? = (list[13] as Int?)?.let { AnEnum.ofRaw(it) } val aNullableString = list[14] as String? val aNullableObject = list[15] + val allNullableTypes: AllNullableTypes? = + (list[16] as List?)?.let { AllNullableTypes.fromList(it) } return AllNullableTypes( aNullableBool, aNullableInt, @@ -179,7 +182,8 @@ data class AllNullableTypes( nullableMapWithObject, aNullableEnum, aNullableString, - aNullableObject) + aNullableObject, + allNullableTypes) } } @@ -201,6 +205,7 @@ data class AllNullableTypes( aNullableEnum?.raw, aNullableString, aNullableObject, + allNullableTypes?.toList(), ) } } diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 62682b44c2c..edf01e930ba 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -145,6 +145,7 @@ struct AllNullableTypes { var aNullableEnum: AnEnum? = nil var aNullableString: String? = nil var aNullableObject: Any? = nil + var allNullableTypes: AllNullableTypes? = nil static func fromList(_ list: [Any?]) -> AllNullableTypes? { let aNullableBool: Bool? = nilOrValue(list[0]) @@ -169,6 +170,10 @@ struct AllNullableTypes { } let aNullableString: String? = nilOrValue(list[14]) let aNullableObject: Any? = list[15] + var allNullableTypes: AllNullableTypes? = nil + if let allNullableTypesList: [Any?] = nilOrValue(list[16]) { + allNullableTypes = AllNullableTypes.fromList(allNullableTypesList) + } return AllNullableTypes( aNullableBool: aNullableBool, @@ -186,7 +191,8 @@ struct AllNullableTypes { nullableMapWithObject: nullableMapWithObject, aNullableEnum: aNullableEnum, aNullableString: aNullableString, - aNullableObject: aNullableObject + aNullableObject: aNullableObject, + allNullableTypes: allNullableTypes ) } func toList() -> [Any?] { @@ -207,6 +213,7 @@ struct AllNullableTypes { aNullableEnum?.rawValue, aNullableString, aNullableObject, + allNullableTypes?.toList(), ] } } diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 62682b44c2c..edf01e930ba 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -145,6 +145,7 @@ struct AllNullableTypes { var aNullableEnum: AnEnum? = nil var aNullableString: String? = nil var aNullableObject: Any? = nil + var allNullableTypes: AllNullableTypes? = nil static func fromList(_ list: [Any?]) -> AllNullableTypes? { let aNullableBool: Bool? = nilOrValue(list[0]) @@ -169,6 +170,10 @@ struct AllNullableTypes { } let aNullableString: String? = nilOrValue(list[14]) let aNullableObject: Any? = list[15] + var allNullableTypes: AllNullableTypes? = nil + if let allNullableTypesList: [Any?] = nilOrValue(list[16]) { + allNullableTypes = AllNullableTypes.fromList(allNullableTypesList) + } return AllNullableTypes( aNullableBool: aNullableBool, @@ -186,7 +191,8 @@ struct AllNullableTypes { nullableMapWithObject: nullableMapWithObject, aNullableEnum: aNullableEnum, aNullableString: aNullableString, - aNullableObject: aNullableObject + aNullableObject: aNullableObject, + allNullableTypes: allNullableTypes ) } func toList() -> [Any?] { @@ -207,6 +213,7 @@ struct AllNullableTypes { aNullableEnum?.rawValue, aNullableString, aNullableObject, + allNullableTypes?.toList(), ] } } 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 eee8003a744..9ec333bc885 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 @@ -177,7 +177,8 @@ AllNullableTypes::AllNullableTypes( const EncodableMap* nullable_map_with_annotations, const EncodableMap* nullable_map_with_object, const AnEnum* a_nullable_enum, const std::string* a_nullable_string, - const EncodableValue* a_nullable_object) + const EncodableValue* a_nullable_object, + const AllNullableTypes* all_nullable_types) : a_nullable_bool_(a_nullable_bool ? std::optional(*a_nullable_bool) : std::nullopt), a_nullable_int_(a_nullable_int ? std::optional(*a_nullable_int) @@ -228,7 +229,10 @@ AllNullableTypes::AllNullableTypes( : std::nullopt), a_nullable_object_(a_nullable_object ? std::optional(*a_nullable_object) - : std::nullopt) {} + : std::nullopt), + all_nullable_types_(all_nullable_types ? std::optional( + *all_nullable_types) + : std::nullopt) {} const bool* AllNullableTypes::a_nullable_bool() const { return a_nullable_bool_ ? &(*a_nullable_bool_) : nullptr; @@ -456,9 +460,24 @@ void AllNullableTypes::set_a_nullable_object(const EncodableValue& value_arg) { a_nullable_object_ = value_arg; } +const AllNullableTypes* AllNullableTypes::all_nullable_types() const { + return all_nullable_types_ ? &(*all_nullable_types_) : nullptr; +} + +void AllNullableTypes::set_all_nullable_types( + const AllNullableTypes* value_arg) { + all_nullable_types_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypes::set_all_nullable_types( + const AllNullableTypes& value_arg) { + all_nullable_types_ = value_arg; +} + EncodableList AllNullableTypes::ToEncodableList() const { EncodableList list; - list.reserve(16); + list.reserve(17); list.push_back(a_nullable_bool_ ? EncodableValue(*a_nullable_bool_) : EncodableValue()); list.push_back(a_nullable_int_ ? EncodableValue(*a_nullable_int_) @@ -496,6 +515,9 @@ EncodableList AllNullableTypes::ToEncodableList() const { list.push_back(a_nullable_string_ ? EncodableValue(*a_nullable_string_) : EncodableValue()); list.push_back(a_nullable_object_ ? *a_nullable_object_ : EncodableValue()); + list.push_back(all_nullable_types_ + ? EncodableValue(all_nullable_types_->ToEncodableList()) + : EncodableValue()); return list; } @@ -578,6 +600,11 @@ AllNullableTypes AllNullableTypes::FromEncodableList( if (!encodable_a_nullable_object.IsNull()) { decoded.set_a_nullable_object(encodable_a_nullable_object); } + auto& encodable_all_nullable_types = list[16]; + if (!encodable_all_nullable_types.IsNull()) { + decoded.set_all_nullable_types(AllNullableTypes::FromEncodableList( + std::get(encodable_all_nullable_types))); + } return decoded; } 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 484d5e349bc..0140bbd68e5 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 @@ -180,7 +180,8 @@ class AllNullableTypes { const flutter::EncodableMap* nullable_map_with_annotations, const flutter::EncodableMap* nullable_map_with_object, const AnEnum* a_nullable_enum, const std::string* a_nullable_string, - const flutter::EncodableValue* a_nullable_object); + const flutter::EncodableValue* a_nullable_object, + const AllNullableTypes* all_nullable_types); const bool* a_nullable_bool() const; void set_a_nullable_bool(const bool* value_arg); @@ -248,6 +249,10 @@ class AllNullableTypes { void set_a_nullable_object(const flutter::EncodableValue* value_arg); void set_a_nullable_object(const flutter::EncodableValue& value_arg); + const AllNullableTypes* all_nullable_types() const; + void set_all_nullable_types(const AllNullableTypes* value_arg); + void set_all_nullable_types(const AllNullableTypes& value_arg); + private: static AllNullableTypes FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; @@ -279,6 +284,7 @@ class AllNullableTypes { std::optional a_nullable_enum_; std::optional a_nullable_string_; std::optional a_nullable_object_; + std::optional all_nullable_types_; }; // A class for testing nested class handling. From f5303513a6c3f6750985cdcf6d226eca867252d3 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 14:03:00 -0700 Subject: [PATCH 02/16] update swift to use classes --- packages/pigeon/lib/swift_generator.dart | 64 ++++++++++++++----- .../ios/Classes/CoreTests.gen.swift | 39 ++++++++++- .../macos/Classes/CoreTests.gen.swift | 39 ++++++++++- 3 files changed, 123 insertions(+), 19 deletions(-) diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 78720dd5c73..f1e84ffd23d 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -125,15 +125,26 @@ class SwiftGenerator extends StructuredGenerator { indent, classDefinition.documentationComments, _docCommentSpec, generatorComments: generatedComments); - // if (classDefinition.swiftClass) { - // indent.write('class ${classDefinition.name} '); - // } else { - indent.write('struct ${classDefinition.name} '); - // } + if (classDefinition.swiftClass) { + indent.write('class ${classDefinition.name} '); + } else { + indent.write('struct ${classDefinition.name} '); + } indent.addScoped('{', '}', () { - getFieldsInSerializationOrder(classDefinition).forEach((NamedType field) { + final Iterable fields = + getFieldsInSerializationOrder(classDefinition); + + if (classDefinition.swiftClass) { + _writeClassInit(indent, fields.toList()); + } + + for (final NamedType field in fields) { + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + indent.write('var '); _writeClassField(indent, field); - }); + indent.newln(); + } indent.newln(); writeClassDecode( @@ -153,6 +164,35 @@ class SwiftGenerator extends StructuredGenerator { }); } + void _writeClassInit(Indent indent, List fields) { + indent.writeScoped('init(', ')', () { + for (int i = 0; i < fields.length; i++) { + indent.write(''); + _writeClassField(indent, fields[i]); + if (i == fields.length - 1) { + indent.newln(); + } else { + indent.addln(','); + } + } + }, addTrailingNewline: false); + indent.addScoped(' {', '}', () { + for (final NamedType field in fields) { + _writeClassFieldInit(indent, field); + } + }); + } + + void _writeClassField(Indent indent, NamedType field) { + indent.add('${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); + final String defaultNil = field.type.isNullable ? ' = nil' : ''; + indent.add(defaultNil); + } + + void _writeClassFieldInit(Indent indent, NamedType field) { + indent.writeln('self.${field.name} = ${field.name}'); + } + @override void writeClassEncode( SwiftOptions generatorOptions, @@ -226,16 +266,6 @@ class SwiftGenerator extends StructuredGenerator { }); } - void _writeClassField(Indent indent, NamedType field) { - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - - indent.write( - 'var ${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); - final String defaultNil = field.type.isNullable ? ' = nil' : ''; - indent.addln(defaultNil); - } - @override void writeApis( SwiftOptions generatorOptions, diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index edf01e930ba..88b39e155af 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -128,7 +128,44 @@ struct AllTypes { /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -struct AllNullableTypes { +class AllNullableTypes { + init( + aNullableBool: Bool? = nil, + aNullableInt: Int64? = nil, + aNullableInt64: Int64? = nil, + aNullableDouble: Double? = nil, + aNullableByteArray: FlutterStandardTypedData? = nil, + aNullable4ByteArray: FlutterStandardTypedData? = nil, + aNullable8ByteArray: FlutterStandardTypedData? = nil, + aNullableFloatArray: FlutterStandardTypedData? = nil, + aNullableList: [Any?]? = nil, + aNullableMap: [AnyHashable: Any?]? = nil, + nullableNestedList: [[Bool?]?]? = nil, + nullableMapWithAnnotations: [String?: String?]? = nil, + nullableMapWithObject: [String?: Any?]? = nil, + aNullableEnum: AnEnum? = nil, + aNullableString: String? = nil, + aNullableObject: Any? = nil, + allNullableTypes: AllNullableTypes? = nil + ) { + self.aNullableBool = aNullableBool + self.aNullableInt = aNullableInt + self.aNullableInt64 = aNullableInt64 + self.aNullableDouble = aNullableDouble + self.aNullableByteArray = aNullableByteArray + self.aNullable4ByteArray = aNullable4ByteArray + self.aNullable8ByteArray = aNullable8ByteArray + self.aNullableFloatArray = aNullableFloatArray + self.aNullableList = aNullableList + self.aNullableMap = aNullableMap + self.nullableNestedList = nullableNestedList + self.nullableMapWithAnnotations = nullableMapWithAnnotations + self.nullableMapWithObject = nullableMapWithObject + self.aNullableEnum = aNullableEnum + self.aNullableString = aNullableString + self.aNullableObject = aNullableObject + self.allNullableTypes = allNullableTypes + } var aNullableBool: Bool? = nil var aNullableInt: Int64? = nil var aNullableInt64: Int64? = nil diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index edf01e930ba..88b39e155af 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -128,7 +128,44 @@ struct AllTypes { /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -struct AllNullableTypes { +class AllNullableTypes { + init( + aNullableBool: Bool? = nil, + aNullableInt: Int64? = nil, + aNullableInt64: Int64? = nil, + aNullableDouble: Double? = nil, + aNullableByteArray: FlutterStandardTypedData? = nil, + aNullable4ByteArray: FlutterStandardTypedData? = nil, + aNullable8ByteArray: FlutterStandardTypedData? = nil, + aNullableFloatArray: FlutterStandardTypedData? = nil, + aNullableList: [Any?]? = nil, + aNullableMap: [AnyHashable: Any?]? = nil, + nullableNestedList: [[Bool?]?]? = nil, + nullableMapWithAnnotations: [String?: String?]? = nil, + nullableMapWithObject: [String?: Any?]? = nil, + aNullableEnum: AnEnum? = nil, + aNullableString: String? = nil, + aNullableObject: Any? = nil, + allNullableTypes: AllNullableTypes? = nil + ) { + self.aNullableBool = aNullableBool + self.aNullableInt = aNullableInt + self.aNullableInt64 = aNullableInt64 + self.aNullableDouble = aNullableDouble + self.aNullableByteArray = aNullableByteArray + self.aNullable4ByteArray = aNullable4ByteArray + self.aNullable8ByteArray = aNullable8ByteArray + self.aNullableFloatArray = aNullableFloatArray + self.aNullableList = aNullableList + self.aNullableMap = aNullableMap + self.nullableNestedList = nullableNestedList + self.nullableMapWithAnnotations = nullableMapWithAnnotations + self.nullableMapWithObject = nullableMapWithObject + self.aNullableEnum = aNullableEnum + self.aNullableString = aNullableString + self.aNullableObject = aNullableObject + self.allNullableTypes = allNullableTypes + } var aNullableBool: Bool? = nil var aNullableInt: Int64? = nil var aNullableInt64: Int64? = nil From b6ab323d3fd46c8a1942de9389b5b737244502c5 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 15:08:57 -0700 Subject: [PATCH 03/16] changelog --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index ea6cd9df5b5..1245668dd43 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 17.3.0 + +* [swift] Adds `@SwiftClass` annotation to allow choice between `struct` and `class` for data classes. + ## 17.2.0 * [dart] Adds implementation for `@ProxyApi`. diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 66dd99750f3..4540b5d04d8 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -13,7 +13,7 @@ import 'ast.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '17.2.0'; +const String pigeonVersion = '17.3.0'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index d5b579405d4..b4912fd3262 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: 17.2.0 # This must match the version in lib/generator_tools.dart +version: 17.3.0 # This must match the version in lib/generator_tools.dart environment: sdk: ^3.1.0 From 5a8dfc7202c59f8ba1c780b1c47fd21a095de6b7 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 15:25:23 -0700 Subject: [PATCH 04/16] clean up code, improve tests --- packages/pigeon/lib/ast.dart | 4 +- packages/pigeon/lib/pigeon_lib.dart | 8 +--- packages/pigeon/lib/swift_generator.dart | 4 +- .../lib/integration_tests.dart | 44 ++++++++++++++++--- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index 8bf1ba1fe34..08eef8cc6c7 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -639,7 +639,7 @@ class Class extends Node { Class({ required this.name, required this.fields, - this.swiftClass = false, + this.isSwiftClass = false, this.documentationComments = const [], }); @@ -653,7 +653,7 @@ class Class extends Node { /// a class in Swift generation. /// /// Defaults to false, which would represent a struct. - bool swiftClass; + bool isSwiftClass; /// List of documentation comments, separated by line. /// diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index f5fb3c58e96..71c1983e091 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -177,12 +177,6 @@ class SwiftFunction { final String value; } -/// Metadata to annotate data classes to be defined as class in Swift output. -class SwiftClass { - /// Constructor. - const SwiftClass(); -} - /// Type of TaskQueue which determines how handlers are dispatched for /// HostApi's. enum TaskQueueType { @@ -1556,7 +1550,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { _currentClass = Class( name: node.name.lexeme, fields: [], - swiftClass: _hasMetadata(node.metadata, 'SwiftClass'), + isSwiftClass: _hasMetadata(node.metadata, 'SwiftClass'), documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index f1e84ffd23d..f9857b99194 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -125,7 +125,7 @@ class SwiftGenerator extends StructuredGenerator { indent, classDefinition.documentationComments, _docCommentSpec, generatorComments: generatedComments); - if (classDefinition.swiftClass) { + if (classDefinition.isSwiftClass) { indent.write('class ${classDefinition.name} '); } else { indent.write('struct ${classDefinition.name} '); @@ -134,7 +134,7 @@ class SwiftGenerator extends StructuredGenerator { final Iterable fields = getFieldsInSerializationOrder(classDefinition); - if (classDefinition.swiftClass) { + if (classDefinition.isSwiftClass) { _writeClassInit(indent, fields.toList()); } diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart index 4ebee6b740a..071eefe2a1c 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart @@ -106,6 +106,8 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { allNullableTypesTwo.aNullableObject); expect( allNullableTypesOne.aNullableEnum, allNullableTypesTwo.aNullableEnum); + compareAllNullableTypes(allNullableTypesOne.allNullableTypes, + allNullableTypesTwo.allNullableTypes); } void compareAllClassesWrapper( @@ -170,6 +172,35 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { aNullableObject: 0, ); + final AllNullableTypes recursiveAllNullableTypes = AllNullableTypes( + aNullableBool: true, + aNullableInt: _regularInt, + aNullableInt64: _biggerThanBigInt, + aNullableDouble: _doublePi, + aNullableString: 'Hello host!', + aNullableByteArray: Uint8List.fromList([1, 2, 3]), + aNullable4ByteArray: Int32List.fromList([4, 5, 6]), + aNullable8ByteArray: Int64List.fromList([7, 8, 9]), + aNullableFloatArray: Float64List.fromList([2.71828, _doublePi]), + aNullableList: ['Thing 1', 2, true, 3.14, null], + aNullableMap: { + 'a': 1, + 'b': 2.0, + 'c': 'three', + 'd': false, + 'e': null + }, + nullableNestedList: >[ + [true, false], + [false, true] + ], + nullableMapWithAnnotations: {}, + nullableMapWithObject: {}, + aNullableEnum: AnEnum.fourHundredTwentyTwo, + aNullableObject: 0, + allNullableTypes: genericAllNullableTypes, + ); + group('Host sync API tests', () { testWidgets('basic void->void call works', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -190,9 +221,9 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); final AllNullableTypes? echoObject = - await api.echoAllNullableTypes(genericAllNullableTypes); + await api.echoAllNullableTypes(recursiveAllNullableTypes); - compareAllNullableTypes(echoObject, genericAllNullableTypes); + compareAllNullableTypes(echoObject, recursiveAllNullableTypes); }); testWidgets('all null datatypes serialize and deserialize correctly', @@ -266,7 +297,8 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); final AllClassesWrapper sentObject = AllClassesWrapper( - allNullableTypes: genericAllNullableTypes, allTypes: genericAllTypes); + allNullableTypes: recursiveAllNullableTypes, + allTypes: genericAllTypes); final String? receivedString = await api.extractNestedNullableString(sentObject); @@ -775,10 +807,10 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllNullableTypes? echoObject = - await api.echoAsyncNullableAllNullableTypes(genericAllNullableTypes); + final AllNullableTypes? echoObject = await api + .echoAsyncNullableAllNullableTypes(recursiveAllNullableTypes); - compareAllNullableTypes(echoObject, genericAllNullableTypes); + compareAllNullableTypes(echoObject, recursiveAllNullableTypes); }); testWidgets('all null datatypes async serialize and deserialize correctly', From 7ce8b6e0aeef2dd1a7a6fe142a2651039b65baa0 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 15:29:53 -0700 Subject: [PATCH 05/16] readme --- packages/pigeon/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/pigeon/README.md b/packages/pigeon/README.md index 213e650c632..b8614e4647d 100644 --- a/packages/pigeon/README.md +++ b/packages/pigeon/README.md @@ -27,6 +27,10 @@ Custom classes, nested datatypes, and enums are also supported. Nullable enums in Objective-C generated code will be wrapped in a class to allow for nullability. +By default, custom classes in Swift are defined as structs. +If you need classes instead - for recursive data, or objc interop - +use the @SwiftClass annotation when defining the class. + ### Synchronous and Asynchronous methods While all calls across platform channel APIs (such as pigeon methods) are asynchronous, From ca02c4227e905990498f924d2cf4ad94d9da1b43 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 16:09:27 -0700 Subject: [PATCH 06/16] add back annotation class --- packages/pigeon/lib/pigeon_lib.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 71c1983e091..addce55d54a 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -177,6 +177,12 @@ class SwiftFunction { final String value; } +/// Metadata to annotate data classes to be defined as class in Swift output. +class SwiftClass { + /// Constructor. + const SwiftClass(); +} + /// Type of TaskQueue which determines how handlers are dispatched for /// HostApi's. enum TaskQueueType { From 1ed419fee2ffa4725ccf71f12edb61cb6237d8f8 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 17:10:38 -0700 Subject: [PATCH 07/16] add integration tests for with/without recursion classes --- packages/pigeon/pigeons/core_tests.dart | 96 +- .../AlternateLanguageTestPlugin.java | 45 + .../CoreTests.java | 698 ++++++++++++++- .../ios/Classes/AlternateLanguageTestPlugin.m | 68 +- .../ios/Classes/CoreTests.gen.h | 91 ++ .../ios/Classes/CoreTests.gen.m | 329 ++++++- .../Classes/AlternateLanguageTestPlugin.m | 66 +- .../macos/Classes/CoreTests.gen.h | 90 ++ .../macos/Classes/CoreTests.gen.m | 326 ++++++- .../lib/integration_tests.dart | 261 +++++- .../lib/src/generated/core_tests.gen.dart | 345 +++++++- .../com/example/test_plugin/CoreTests.gen.kt | 327 ++++++- .../com/example/test_plugin/TestPlugin.kt | 52 +- .../ios/Classes/CoreTests.gen.swift | 315 ++++++- .../test_plugin/ios/Classes/TestPlugin.swift | 53 ++ .../macos/Classes/CoreTests.gen.swift | 315 ++++++- .../macos/Classes/TestPlugin.swift | 76 +- .../windows/pigeon/core_tests.gen.cpp | 830 +++++++++++++++++- .../windows/pigeon/core_tests.gen.h | 171 ++++ .../test_plugin/windows/test_plugin.cpp | 63 ++ .../test_plugin/windows/test_plugin.h | 32 + 21 files changed, 4563 insertions(+), 86 deletions(-) diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index a98f3c8ca24..3fd036f9c96 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -91,14 +91,56 @@ class AllNullableTypes { AllNullableTypes? allNullableTypes; } +class AllNullableTypesWithoutRecursion { + AllNullableTypesWithoutRecursion( + this.aNullableBool, + this.aNullableInt, + this.aNullableInt64, + this.aNullableDouble, + this.aNullableByteArray, + this.aNullable4ByteArray, + this.aNullable8ByteArray, + this.aNullableFloatArray, + this.aNullableList, + this.aNullableMap, + this.nullableNestedList, + this.nullableMapWithAnnotations, + this.nullableMapWithObject, + this.aNullableEnum, + this.aNullableString, + this.aNullableObject, + ); + + bool? aNullableBool; + int? aNullableInt; + int? aNullableInt64; + double? aNullableDouble; + Uint8List? aNullableByteArray; + Int32List? aNullable4ByteArray; + Int64List? aNullable8ByteArray; + Float64List? aNullableFloatArray; + // ignore: always_specify_types, strict_raw_type + List? aNullableList; + // ignore: always_specify_types, strict_raw_type + Map? aNullableMap; + List?>? nullableNestedList; + Map? nullableMapWithAnnotations; + Map? nullableMapWithObject; + AnEnum? aNullableEnum; + String? aNullableString; + Object? aNullableObject; +} + /// A class for testing nested class handling. /// /// This is needed to test nested nullable and non-nullable classes, /// `AllNullableTypes` is non-nullable here as it is easier to instantiate /// than `AllTypes` when testing doesn't require both (ie. testing null classes). class AllClassesWrapper { - AllClassesWrapper(this.allNullableTypes, this.allTypes); + AllClassesWrapper(this.allNullableTypes, + this.allNullableTypesWithoutRecursion, this.allTypes); AllNullableTypes allNullableTypes; + AllNullableTypesWithoutRecursion? allNullableTypesWithoutRecursion; AllTypes? allTypes; } @@ -198,6 +240,12 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echo(_:)') AllNullableTypes? echoAllNullableTypes(AllNullableTypes? everything); + /// Returns the passed object, to test serialization and deserialization. + @ObjCSelector('echoAllNullableTypesWithoutRecursion:') + @SwiftFunction('echo(_:)') + AllNullableTypesWithoutRecursion? echoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything); + /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. @ObjCSelector('extractNestedNullableStringFrom:') @@ -216,6 +264,13 @@ abstract class HostIntegrationCoreApi { AllNullableTypes sendMultipleNullableTypes( bool? aNullableBool, int? aNullableInt, String? aNullableString); + /// Returns passed in arguments of multiple types. + @ObjCSelector('sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:') + @SwiftFunction( + 'sendMultipleNullableTypesWithoutRecursion(aBool:anInt:aString:)') + AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( + bool? aNullableBool, int? aNullableInt, String? aNullableString); + /// Returns passed in int. @ObjCSelector('echoNullableInt:') @SwiftFunction('echo(_:)') @@ -356,6 +411,14 @@ abstract class HostIntegrationCoreApi { AllNullableTypes? echoAsyncNullableAllNullableTypes( AllNullableTypes? everything); + /// Returns the passed object, to test serialization and deserialization. + @async + @ObjCSelector('echoAsyncNullableAllNullableTypesWithoutRecursion:') + @SwiftFunction('echoAsync(_:)') + AllNullableTypesWithoutRecursion? + echoAsyncNullableAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything); + /// Returns passed in int asynchronously. @async @ObjCSelector('echoAsyncNullableInt:') @@ -438,6 +501,22 @@ abstract class HostIntegrationCoreApi { AllNullableTypes callFlutterSendMultipleNullableTypes( bool? aNullableBool, int? aNullableInt, String? aNullableString); + @async + @ObjCSelector('callFlutterEchoAllNullableTypesWithoutRecursion:') + @SwiftFunction('callFlutterEcho(_:)') + AllNullableTypesWithoutRecursion? + callFlutterEchoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything); + + @async + @ObjCSelector( + 'callFlutterSendMultipleNullableTypesWithoutRecursionABool:anInt:aString:') + @SwiftFunction( + 'callFlutterSendMultipleNullableTypesWithoutRecursion(aBool:anInt:aString:)') + AllNullableTypesWithoutRecursion + callFlutterSendMultipleNullableTypesWithoutRecursion( + bool? aNullableBool, int? aNullableInt, String? aNullableString); + @async @ObjCSelector('callFlutterEchoBool:') @SwiftFunction('callFlutterEcho(_:)') @@ -552,6 +631,21 @@ abstract class FlutterIntegrationCoreApi { AllNullableTypes sendMultipleNullableTypes( bool? aNullableBool, int? aNullableInt, String? aNullableString); + /// Returns the passed object, to test serialization and deserialization. + @ObjCSelector('echoAllNullableTypesWithoutRecursion:') + @SwiftFunction('echoNullable(_:)') + AllNullableTypesWithoutRecursion? echoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything); + + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + @ObjCSelector('sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:') + @SwiftFunction( + 'sendMultipleNullableTypesWithoutRecursion(aBool:anInt:aString:)') + AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( + bool? aNullableBool, int? aNullableInt, String? aNullableString); + // ========== Non-nullable argument/return type tests ========== /// Returns the passed boolean, to test serialization and deserialization. diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java index a99aa2ef913..7a44f6a8883 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import com.example.alternate_language_test_plugin.CoreTests.AllClassesWrapper; import com.example.alternate_language_test_plugin.CoreTests.AllNullableTypes; +import com.example.alternate_language_test_plugin.CoreTests.AllNullableTypesWithoutRecursion; import com.example.alternate_language_test_plugin.CoreTests.AllTypes; import com.example.alternate_language_test_plugin.CoreTests.AnEnum; import com.example.alternate_language_test_plugin.CoreTests.FlutterIntegrationCoreApi; @@ -47,6 +48,12 @@ public void noop() {} return everything; } + @Override + public @Nullable AllNullableTypesWithoutRecursion echoAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everything) { + return everything; + } + @Override public @Nullable Object throwError() { throw new RuntimeException("An error"); @@ -153,6 +160,20 @@ public void throwErrorFromVoid() { return someThings; } + @Override + public @NonNull AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( + @Nullable Boolean aNullableBool, + @Nullable Long aNullableInt, + @Nullable String aNullableString) { + AllNullableTypesWithoutRecursion someThings = + new AllNullableTypesWithoutRecursion.Builder() + .setANullableBool(aNullableBool) + .setANullableInt(aNullableInt) + .setANullableString(aNullableString) + .build(); + return someThings; + } + @Override public @Nullable Long echoNullableInt(@Nullable Long aNullableInt) { return aNullableInt; @@ -239,6 +260,13 @@ public void echoAsyncNullableAllNullableTypes( result.success(everything); } + @Override + public void echoAsyncNullableAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everything, + @NonNull NullableResult result) { + result.success(everything); + } + @Override public void echoAsyncInt(@NonNull Long anInt, @NonNull Result result) { result.success(anInt); @@ -374,6 +402,23 @@ public void callFlutterSendMultipleNullableTypes( flutterApi.sendMultipleNullableTypes(aNullableBool, aNullableInt, aNullableString, result); } + @Override + public void callFlutterEchoAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everything, + @NonNull NullableResult result) { + flutterApi.echoAllNullableTypesWithoutRecursion(everything, result); + } + + @Override + public void callFlutterSendMultipleNullableTypesWithoutRecursion( + @Nullable Boolean aNullableBool, + @Nullable Long aNullableInt, + @Nullable String aNullableString, + @NonNull Result result) { + flutterApi.sendMultipleNullableTypesWithoutRecursion( + aNullableBool, aNullableInt, aNullableString, result); + } + @Override public void callFlutterEchoBool(@NonNull Boolean aBool, @NonNull Result result) { flutterApi.echoBool(aBool, result); 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 ecfdff1136d..e2f52c0954f 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 @@ -859,6 +859,390 @@ ArrayList toList() { } } + /** Generated class from Pigeon that represents data sent in messages. */ + public static final class AllNullableTypesWithoutRecursion { + private @Nullable Boolean aNullableBool; + + public @Nullable Boolean getANullableBool() { + return aNullableBool; + } + + public void setANullableBool(@Nullable Boolean setterArg) { + this.aNullableBool = setterArg; + } + + private @Nullable Long aNullableInt; + + public @Nullable Long getANullableInt() { + return aNullableInt; + } + + public void setANullableInt(@Nullable Long setterArg) { + this.aNullableInt = setterArg; + } + + private @Nullable Long aNullableInt64; + + public @Nullable Long getANullableInt64() { + return aNullableInt64; + } + + public void setANullableInt64(@Nullable Long setterArg) { + this.aNullableInt64 = setterArg; + } + + private @Nullable Double aNullableDouble; + + public @Nullable Double getANullableDouble() { + return aNullableDouble; + } + + public void setANullableDouble(@Nullable Double setterArg) { + this.aNullableDouble = setterArg; + } + + private @Nullable byte[] aNullableByteArray; + + public @Nullable byte[] getANullableByteArray() { + return aNullableByteArray; + } + + public void setANullableByteArray(@Nullable byte[] setterArg) { + this.aNullableByteArray = setterArg; + } + + private @Nullable int[] aNullable4ByteArray; + + public @Nullable int[] getANullable4ByteArray() { + return aNullable4ByteArray; + } + + public void setANullable4ByteArray(@Nullable int[] setterArg) { + this.aNullable4ByteArray = setterArg; + } + + private @Nullable long[] aNullable8ByteArray; + + public @Nullable long[] getANullable8ByteArray() { + return aNullable8ByteArray; + } + + public void setANullable8ByteArray(@Nullable long[] setterArg) { + this.aNullable8ByteArray = setterArg; + } + + private @Nullable double[] aNullableFloatArray; + + public @Nullable double[] getANullableFloatArray() { + return aNullableFloatArray; + } + + public void setANullableFloatArray(@Nullable double[] setterArg) { + this.aNullableFloatArray = setterArg; + } + + private @Nullable List aNullableList; + + public @Nullable List getANullableList() { + return aNullableList; + } + + public void setANullableList(@Nullable List setterArg) { + this.aNullableList = setterArg; + } + + private @Nullable Map aNullableMap; + + public @Nullable Map getANullableMap() { + return aNullableMap; + } + + public void setANullableMap(@Nullable Map setterArg) { + this.aNullableMap = setterArg; + } + + private @Nullable List> nullableNestedList; + + public @Nullable List> getNullableNestedList() { + return nullableNestedList; + } + + public void setNullableNestedList(@Nullable List> setterArg) { + this.nullableNestedList = setterArg; + } + + private @Nullable Map nullableMapWithAnnotations; + + public @Nullable Map getNullableMapWithAnnotations() { + return nullableMapWithAnnotations; + } + + public void setNullableMapWithAnnotations(@Nullable Map setterArg) { + this.nullableMapWithAnnotations = setterArg; + } + + private @Nullable Map nullableMapWithObject; + + public @Nullable Map getNullableMapWithObject() { + return nullableMapWithObject; + } + + public void setNullableMapWithObject(@Nullable Map setterArg) { + this.nullableMapWithObject = setterArg; + } + + private @Nullable AnEnum aNullableEnum; + + public @Nullable AnEnum getANullableEnum() { + return aNullableEnum; + } + + public void setANullableEnum(@Nullable AnEnum setterArg) { + this.aNullableEnum = setterArg; + } + + private @Nullable String aNullableString; + + public @Nullable String getANullableString() { + return aNullableString; + } + + public void setANullableString(@Nullable String setterArg) { + this.aNullableString = setterArg; + } + + private @Nullable Object aNullableObject; + + public @Nullable Object getANullableObject() { + return aNullableObject; + } + + public void setANullableObject(@Nullable Object setterArg) { + this.aNullableObject = setterArg; + } + + public static final class Builder { + + private @Nullable Boolean aNullableBool; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableBool(@Nullable Boolean setterArg) { + this.aNullableBool = setterArg; + return this; + } + + private @Nullable Long aNullableInt; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableInt(@Nullable Long setterArg) { + this.aNullableInt = setterArg; + return this; + } + + private @Nullable Long aNullableInt64; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableInt64(@Nullable Long setterArg) { + this.aNullableInt64 = setterArg; + return this; + } + + private @Nullable Double aNullableDouble; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableDouble(@Nullable Double setterArg) { + this.aNullableDouble = setterArg; + return this; + } + + private @Nullable byte[] aNullableByteArray; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableByteArray(@Nullable byte[] setterArg) { + this.aNullableByteArray = setterArg; + return this; + } + + private @Nullable int[] aNullable4ByteArray; + + @CanIgnoreReturnValue + public @NonNull Builder setANullable4ByteArray(@Nullable int[] setterArg) { + this.aNullable4ByteArray = setterArg; + return this; + } + + private @Nullable long[] aNullable8ByteArray; + + @CanIgnoreReturnValue + public @NonNull Builder setANullable8ByteArray(@Nullable long[] setterArg) { + this.aNullable8ByteArray = setterArg; + return this; + } + + private @Nullable double[] aNullableFloatArray; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableFloatArray(@Nullable double[] setterArg) { + this.aNullableFloatArray = setterArg; + return this; + } + + private @Nullable List aNullableList; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableList(@Nullable List setterArg) { + this.aNullableList = setterArg; + return this; + } + + private @Nullable Map aNullableMap; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableMap(@Nullable Map setterArg) { + this.aNullableMap = setterArg; + return this; + } + + private @Nullable List> nullableNestedList; + + @CanIgnoreReturnValue + public @NonNull Builder setNullableNestedList(@Nullable List> setterArg) { + this.nullableNestedList = setterArg; + return this; + } + + private @Nullable Map nullableMapWithAnnotations; + + @CanIgnoreReturnValue + public @NonNull Builder setNullableMapWithAnnotations( + @Nullable Map setterArg) { + this.nullableMapWithAnnotations = setterArg; + return this; + } + + private @Nullable Map nullableMapWithObject; + + @CanIgnoreReturnValue + public @NonNull Builder setNullableMapWithObject(@Nullable Map setterArg) { + this.nullableMapWithObject = setterArg; + return this; + } + + private @Nullable AnEnum aNullableEnum; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableEnum(@Nullable AnEnum setterArg) { + this.aNullableEnum = setterArg; + return this; + } + + private @Nullable String aNullableString; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableString(@Nullable String setterArg) { + this.aNullableString = setterArg; + return this; + } + + private @Nullable Object aNullableObject; + + @CanIgnoreReturnValue + public @NonNull Builder setANullableObject(@Nullable Object setterArg) { + this.aNullableObject = setterArg; + return this; + } + + public @NonNull AllNullableTypesWithoutRecursion build() { + AllNullableTypesWithoutRecursion pigeonReturn = new AllNullableTypesWithoutRecursion(); + pigeonReturn.setANullableBool(aNullableBool); + pigeonReturn.setANullableInt(aNullableInt); + pigeonReturn.setANullableInt64(aNullableInt64); + pigeonReturn.setANullableDouble(aNullableDouble); + pigeonReturn.setANullableByteArray(aNullableByteArray); + pigeonReturn.setANullable4ByteArray(aNullable4ByteArray); + pigeonReturn.setANullable8ByteArray(aNullable8ByteArray); + pigeonReturn.setANullableFloatArray(aNullableFloatArray); + pigeonReturn.setANullableList(aNullableList); + pigeonReturn.setANullableMap(aNullableMap); + pigeonReturn.setNullableNestedList(nullableNestedList); + pigeonReturn.setNullableMapWithAnnotations(nullableMapWithAnnotations); + pigeonReturn.setNullableMapWithObject(nullableMapWithObject); + pigeonReturn.setANullableEnum(aNullableEnum); + pigeonReturn.setANullableString(aNullableString); + pigeonReturn.setANullableObject(aNullableObject); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList(16); + toListResult.add(aNullableBool); + toListResult.add(aNullableInt); + toListResult.add(aNullableInt64); + toListResult.add(aNullableDouble); + toListResult.add(aNullableByteArray); + toListResult.add(aNullable4ByteArray); + toListResult.add(aNullable8ByteArray); + toListResult.add(aNullableFloatArray); + toListResult.add(aNullableList); + toListResult.add(aNullableMap); + toListResult.add(nullableNestedList); + toListResult.add(nullableMapWithAnnotations); + toListResult.add(nullableMapWithObject); + toListResult.add(aNullableEnum == null ? null : aNullableEnum.index); + toListResult.add(aNullableString); + toListResult.add(aNullableObject); + return toListResult; + } + + static @NonNull AllNullableTypesWithoutRecursion fromList(@NonNull ArrayList list) { + AllNullableTypesWithoutRecursion pigeonResult = new AllNullableTypesWithoutRecursion(); + Object aNullableBool = list.get(0); + pigeonResult.setANullableBool((Boolean) aNullableBool); + Object aNullableInt = list.get(1); + pigeonResult.setANullableInt( + (aNullableInt == null) + ? null + : ((aNullableInt instanceof Integer) ? (Integer) aNullableInt : (Long) aNullableInt)); + Object aNullableInt64 = list.get(2); + pigeonResult.setANullableInt64( + (aNullableInt64 == null) + ? null + : ((aNullableInt64 instanceof Integer) + ? (Integer) aNullableInt64 + : (Long) aNullableInt64)); + Object aNullableDouble = list.get(3); + pigeonResult.setANullableDouble((Double) aNullableDouble); + Object aNullableByteArray = list.get(4); + pigeonResult.setANullableByteArray((byte[]) aNullableByteArray); + Object aNullable4ByteArray = list.get(5); + pigeonResult.setANullable4ByteArray((int[]) aNullable4ByteArray); + Object aNullable8ByteArray = list.get(6); + pigeonResult.setANullable8ByteArray((long[]) aNullable8ByteArray); + Object aNullableFloatArray = list.get(7); + pigeonResult.setANullableFloatArray((double[]) aNullableFloatArray); + Object aNullableList = list.get(8); + pigeonResult.setANullableList((List) aNullableList); + Object aNullableMap = list.get(9); + pigeonResult.setANullableMap((Map) aNullableMap); + Object nullableNestedList = list.get(10); + pigeonResult.setNullableNestedList((List>) nullableNestedList); + Object nullableMapWithAnnotations = list.get(11); + pigeonResult.setNullableMapWithAnnotations((Map) nullableMapWithAnnotations); + Object nullableMapWithObject = list.get(12); + pigeonResult.setNullableMapWithObject((Map) nullableMapWithObject); + Object aNullableEnum = list.get(13); + pigeonResult.setANullableEnum( + aNullableEnum == null ? null : AnEnum.values()[(int) aNullableEnum]); + Object aNullableString = list.get(14); + pigeonResult.setANullableString((String) aNullableString); + Object aNullableObject = list.get(15); + pigeonResult.setANullableObject(aNullableObject); + return pigeonResult; + } + } + /** * A class for testing nested class handling. * @@ -882,6 +1266,17 @@ public void setAllNullableTypes(@NonNull AllNullableTypes setterArg) { this.allNullableTypes = setterArg; } + private @Nullable AllNullableTypesWithoutRecursion allNullableTypesWithoutRecursion; + + public @Nullable AllNullableTypesWithoutRecursion getAllNullableTypesWithoutRecursion() { + return allNullableTypesWithoutRecursion; + } + + public void setAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion setterArg) { + this.allNullableTypesWithoutRecursion = setterArg; + } + private @Nullable AllTypes allTypes; public @Nullable AllTypes getAllTypes() { @@ -905,6 +1300,15 @@ public static final class Builder { return this; } + private @Nullable AllNullableTypesWithoutRecursion allNullableTypesWithoutRecursion; + + @CanIgnoreReturnValue + public @NonNull Builder setAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion setterArg) { + this.allNullableTypesWithoutRecursion = setterArg; + return this; + } + private @Nullable AllTypes allTypes; @CanIgnoreReturnValue @@ -916,6 +1320,7 @@ public static final class Builder { public @NonNull AllClassesWrapper build() { AllClassesWrapper pigeonReturn = new AllClassesWrapper(); pigeonReturn.setAllNullableTypes(allNullableTypes); + pigeonReturn.setAllNullableTypesWithoutRecursion(allNullableTypesWithoutRecursion); pigeonReturn.setAllTypes(allTypes); return pigeonReturn; } @@ -923,8 +1328,12 @@ public static final class Builder { @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(2); + ArrayList toListResult = new ArrayList(3); toListResult.add((allNullableTypes == null) ? null : allNullableTypes.toList()); + toListResult.add( + (allNullableTypesWithoutRecursion == null) + ? null + : allNullableTypesWithoutRecursion.toList()); toListResult.add((allTypes == null) ? null : allTypes.toList()); return toListResult; } @@ -936,7 +1345,13 @@ ArrayList toList() { (allNullableTypes == null) ? null : AllNullableTypes.fromList((ArrayList) allNullableTypes)); - Object allTypes = list.get(1); + Object allNullableTypesWithoutRecursion = list.get(1); + pigeonResult.setAllNullableTypesWithoutRecursion( + (allNullableTypesWithoutRecursion == null) + ? null + : AllNullableTypesWithoutRecursion.fromList( + (ArrayList) allNullableTypesWithoutRecursion)); + Object allTypes = list.get(2); pigeonResult.setAllTypes( (allTypes == null) ? null : AllTypes.fromList((ArrayList) allTypes)); return pigeonResult; @@ -1029,8 +1444,10 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { case (byte) 129: return AllNullableTypes.fromList((ArrayList) readValue(buffer)); case (byte) 130: - return AllTypes.fromList((ArrayList) readValue(buffer)); + return AllNullableTypesWithoutRecursion.fromList((ArrayList) readValue(buffer)); case (byte) 131: + return AllTypes.fromList((ArrayList) readValue(buffer)); + case (byte) 132: return TestMessage.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); @@ -1045,11 +1462,14 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { } else if (value instanceof AllNullableTypes) { stream.write(129); writeValue(stream, ((AllNullableTypes) value).toList()); - } else if (value instanceof AllTypes) { + } else if (value instanceof AllNullableTypesWithoutRecursion) { stream.write(130); + writeValue(stream, ((AllNullableTypesWithoutRecursion) value).toList()); + } else if (value instanceof AllTypes) { + stream.write(131); writeValue(stream, ((AllTypes) value).toList()); } else if (value instanceof TestMessage) { - stream.write(131); + stream.write(132); writeValue(stream, ((TestMessage) value).toList()); } else { super.writeValue(stream, value); @@ -1121,6 +1541,10 @@ public interface HostIntegrationCoreApi { /** Returns the passed object, to test serialization and deserialization. */ @Nullable AllNullableTypes echoAllNullableTypes(@Nullable AllNullableTypes everything); + /** Returns the passed object, to test serialization and deserialization. */ + @Nullable + AllNullableTypesWithoutRecursion echoAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everything); /** * Returns the inner `aString` value from the wrapped object, to test sending of nested objects. */ @@ -1137,6 +1561,12 @@ AllNullableTypes sendMultipleNullableTypes( @Nullable Boolean aNullableBool, @Nullable Long aNullableInt, @Nullable String aNullableString); + /** Returns passed in arguments of multiple types. */ + @NonNull + AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( + @Nullable Boolean aNullableBool, + @Nullable Long aNullableInt, + @Nullable String aNullableString); /** Returns passed in int. */ @Nullable Long echoNullableInt(@Nullable Long aNullableInt); @@ -1205,6 +1635,10 @@ void echoAsyncMap( /** Returns the passed object, to test serialization and deserialization. */ void echoAsyncNullableAllNullableTypes( @Nullable AllNullableTypes everything, @NonNull NullableResult result); + /** Returns the passed object, to test serialization and deserialization. */ + void echoAsyncNullableAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everything, + @NonNull NullableResult result); /** Returns passed in int asynchronously. */ void echoAsyncNullableInt(@Nullable Long anInt, @NonNull NullableResult result); /** Returns passed in double asynchronously. */ @@ -1244,6 +1678,16 @@ void callFlutterSendMultipleNullableTypes( @Nullable String aNullableString, @NonNull Result result); + void callFlutterEchoAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everything, + @NonNull NullableResult result); + + void callFlutterSendMultipleNullableTypesWithoutRecursion( + @Nullable Boolean aNullableBool, + @Nullable Long aNullableInt, + @Nullable String aNullableString, + @NonNull Result result); + void callFlutterEchoBool(@NonNull Boolean aBool, @NonNull Result result); void callFlutterEchoInt(@NonNull Long anInt, @NonNull Result result); @@ -1762,6 +2206,33 @@ static void setUp( channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + AllNullableTypesWithoutRecursion everythingArg = + (AllNullableTypesWithoutRecursion) args.get(0); + try { + AllNullableTypesWithoutRecursion output = + api.echoAllNullableTypesWithoutRecursion(everythingArg); + wrapped.add(0, output); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -1843,6 +2314,37 @@ static void setUp( channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Boolean aNullableBoolArg = (Boolean) args.get(0); + Number aNullableIntArg = (Number) args.get(1); + String aNullableStringArg = (String) args.get(2); + try { + AllNullableTypesWithoutRecursion output = + api.sendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, + (aNullableIntArg == null) ? null : aNullableIntArg.longValue(), + aNullableStringArg); + wrapped.add(0, output); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -2579,6 +3081,39 @@ public void error(Throwable error) { channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + AllNullableTypesWithoutRecursion everythingArg = + (AllNullableTypesWithoutRecursion) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AllNullableTypesWithoutRecursion result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.echoAsyncNullableAllNullableTypesWithoutRecursion( + everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -3045,6 +3580,75 @@ public void error(Throwable error) { channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + AllNullableTypesWithoutRecursion everythingArg = + (AllNullableTypesWithoutRecursion) args.get(0); + NullableResult resultCallback = + new NullableResult() { + public void success(AllNullableTypesWithoutRecursion result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterEchoAllNullableTypesWithoutRecursion(everythingArg, resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Boolean aNullableBoolArg = (Boolean) args.get(0); + Number aNullableIntArg = (Number) args.get(1); + String aNullableStringArg = (String) args.get(2); + Result resultCallback = + new Result() { + public void success(AllNullableTypesWithoutRecursion result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, + (aNullableIntArg == null) ? null : aNullableIntArg.longValue(), + aNullableStringArg, + resultCallback); + }); + } else { + channel.setMessageHandler(null); + } + } { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -3560,8 +4164,10 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { case (byte) 129: return AllNullableTypes.fromList((ArrayList) readValue(buffer)); case (byte) 130: - return AllTypes.fromList((ArrayList) readValue(buffer)); + return AllNullableTypesWithoutRecursion.fromList((ArrayList) readValue(buffer)); case (byte) 131: + return AllTypes.fromList((ArrayList) readValue(buffer)); + case (byte) 132: return TestMessage.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); @@ -3576,11 +4182,14 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { } else if (value instanceof AllNullableTypes) { stream.write(129); writeValue(stream, ((AllNullableTypes) value).toList()); - } else if (value instanceof AllTypes) { + } else if (value instanceof AllNullableTypesWithoutRecursion) { stream.write(130); + writeValue(stream, ((AllNullableTypesWithoutRecursion) value).toList()); + } else if (value instanceof AllTypes) { + stream.write(131); writeValue(stream, ((AllTypes) value).toList()); } else if (value instanceof TestMessage) { - stream.write(131); + stream.write(132); writeValue(stream, ((TestMessage) value).toList()); } else { super.writeValue(stream, value); @@ -3789,6 +4398,79 @@ public void sendMultipleNullableTypes( } }); } + /** Returns the passed object, to test serialization and deserialization. */ + public void echoAllNullableTypesWithoutRecursion( + @Nullable AllNullableTypesWithoutRecursion everythingArg, + @NonNull NullableResult result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion"; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList(Collections.singletonList(everythingArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), + (String) listReply.get(1), + (String) listReply.get(2))); + } else { + @SuppressWarnings("ConstantConditions") + AllNullableTypesWithoutRecursion output = + (AllNullableTypesWithoutRecursion) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } + /** + * Returns passed in arguments of multiple types. + * + *

Tests multiple-arity FlutterApi handling. + */ + public void sendMultipleNullableTypesWithoutRecursion( + @Nullable Boolean aNullableBoolArg, + @Nullable Long aNullableIntArg, + @Nullable String aNullableStringArg, + @NonNull Result result) { + final String channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion"; + BasicMessageChannel channel = + new BasicMessageChannel<>(binaryMessenger, channelName, getCodec()); + channel.send( + new ArrayList( + Arrays.asList(aNullableBoolArg, aNullableIntArg, aNullableStringArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), + (String) listReply.get(1), + (String) listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + AllNullableTypesWithoutRecursion output = + (AllNullableTypesWithoutRecursion) listReply.get(0); + result.success(output); + } + } else { + result.error(createConnectionError(channelName)); + } + }); + } /** Returns the passed boolean, to test serialization and deserialization. */ public void echoBool(@NonNull Boolean aBoolArg, @NonNull Result result) { final String channelName = diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m index b10d8d99bcc..c3501d5ce7a 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m @@ -34,6 +34,12 @@ - (nullable FLTAllNullableTypes *)echoAllNullableTypes:(nullable FLTAllNullableT return everything; } +- (nullable FLTAllNullableTypesWithoutRecursion *) + echoAllNullableTypesWithoutRecursion:(nullable FLTAllNullableTypesWithoutRecursion *)everything + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return everything; +} + - (nullable id)throwErrorWithError:(FlutterError *_Nullable *_Nonnull)error { *error = [FlutterError errorWithCode:@"An error" message:nil details:nil]; return nil; @@ -119,7 +125,9 @@ - (nullable NSString *)extractNestedNullableStringFrom:(FLTAllClassesWrapper *)w error:(FlutterError *_Nullable *_Nonnull)error { FLTAllNullableTypes *innerObject = [[FLTAllNullableTypes alloc] init]; innerObject.aNullableString = nullableString; - return [FLTAllClassesWrapper makeWithAllNullableTypes:innerObject allTypes:nil]; + return [FLTAllClassesWrapper makeWithAllNullableTypes:innerObject + allNullableTypesWithoutRecursion:nil + allTypes:nil]; } - (nullable FLTAllNullableTypes *) @@ -134,6 +142,21 @@ - (nullable NSString *)extractNestedNullableStringFrom:(FLTAllClassesWrapper *)w return someTypes; } +- (nullable FLTAllNullableTypesWithoutRecursion *) + sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + error: + (FlutterError *_Nullable __autoreleasing *_Nonnull) + error { + FLTAllNullableTypesWithoutRecursion *someTypes = + [[FLTAllNullableTypesWithoutRecursion alloc] init]; + someTypes.aNullableBool = aNullableBool; + someTypes.aNullableInt = aNullableInt; + someTypes.aNullableString = aNullableString; + return someTypes; +} + - (nullable NSNumber *)echoNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error { return aNullableInt; @@ -219,6 +242,16 @@ - (void)echoAsyncNullableAllNullableTypes:(nullable FLTAllNullableTypes *)everyt completion(everything, nil); } +- (void) + echoAsyncNullableAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)everything + completion: + (nonnull void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + completion(everything, nil); +} + - (void)echoAsyncInt:(NSInteger)anInt completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { completion(@(anInt), nil); @@ -357,6 +390,25 @@ - (void)callFlutterSendMultipleNullableTypesABool:(nullable NSNumber *)aNullable }]; } +- (void)callFlutterSendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString: + (nullable NSString *)aNullableString + completion: + (nonnull void (^)( + FLTAllNullableTypesWithoutRecursion + *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + sendMultipleNullableTypesWithoutRecursionABool:aNullableBool + anInt:aNullableInt + aString:aNullableString + completion:^(FLTAllNullableTypesWithoutRecursion *value, + FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterEchoBool:(BOOL)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { [self.flutterAPI echoBool:aBool @@ -432,6 +484,20 @@ - (void)callFlutterEchoAllNullableTypes:(nullable FLTAllNullableTypes *)everythi }]; } +- (void)callFlutterEchoAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)everything + completion: + (nonnull void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + echoAllNullableTypesWithoutRecursion:everything + completion:^(FLTAllNullableTypesWithoutRecursion *value, + FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterEchoNullableBool:(nullable NSNumber *)aBool completion: (void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 71e98de8037..7c7bfe42c15 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -30,6 +30,7 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @class FLTAllTypes; @class FLTAllNullableTypes; +@class FLTAllNullableTypesWithoutRecursion; @class FLTAllClassesWrapper; @class FLTTestMessage; @@ -105,6 +106,43 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, strong, nullable) FLTAllNullableTypes *allNullableTypes; @end +@interface FLTAllNullableTypesWithoutRecursion : NSObject ++ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableList:(nullable NSArray *)aNullableList + aNullableMap:(nullable NSDictionary *)aNullableMap + nullableNestedList:(nullable NSArray *> *)nullableNestedList + nullableMapWithAnnotations: + (nullable NSDictionary *)nullableMapWithAnnotations + nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject; +@property(nonatomic, strong, nullable) NSNumber *aNullableBool; +@property(nonatomic, strong, nullable) NSNumber *aNullableInt; +@property(nonatomic, strong, nullable) NSNumber *aNullableInt64; +@property(nonatomic, strong, nullable) NSNumber *aNullableDouble; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableByteArray; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable4ByteArray; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable8ByteArray; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableFloatArray; +@property(nonatomic, copy, nullable) NSArray *aNullableList; +@property(nonatomic, copy, nullable) NSDictionary *aNullableMap; +@property(nonatomic, copy, nullable) NSArray *> *nullableNestedList; +@property(nonatomic, copy, nullable) + NSDictionary *nullableMapWithAnnotations; +@property(nonatomic, copy, nullable) NSDictionary *nullableMapWithObject; +@property(nonatomic, strong, nullable) FLTAnEnumBox *aNullableEnum; +@property(nonatomic, copy, nullable) NSString *aNullableString; +@property(nonatomic, strong, nullable) id aNullableObject; +@end + /// A class for testing nested class handling. /// /// This is needed to test nested nullable and non-nullable classes, @@ -114,8 +152,12 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion allTypes:(nullable FLTAllTypes *)allTypes; @property(nonatomic, strong) FLTAllNullableTypes *allNullableTypes; +@property(nonatomic, strong, nullable) + FLTAllNullableTypesWithoutRecursion *allNullableTypesWithoutRecursion; @property(nonatomic, strong, nullable) FLTAllTypes *allTypes; @end @@ -209,6 +251,10 @@ NSObject *FLTHostIntegrationCoreApiGetCodec(void); /// Returns the passed object, to test serialization and deserialization. - (nullable FLTAllNullableTypes *)echoAllNullableTypes:(nullable FLTAllNullableTypes *)everything error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed object, to test serialization and deserialization. +- (nullable FLTAllNullableTypesWithoutRecursion *) + echoAllNullableTypesWithoutRecursion:(nullable FLTAllNullableTypesWithoutRecursion *)everything + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - (nullable NSString *)extractNestedNullableStringFrom:(FLTAllClassesWrapper *)wrapper @@ -228,6 +274,14 @@ NSObject *FLTHostIntegrationCoreApiGetCodec(void); anInt:(nullable NSNumber *)aNullableInt aString:(nullable NSString *)aNullableString error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns passed in arguments of multiple types. +/// +/// @return `nil` only when `error != nil`. +- (nullable FLTAllNullableTypesWithoutRecursion *) + sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in int. - (nullable NSNumber *)echoNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error; @@ -308,6 +362,13 @@ NSObject *FLTHostIntegrationCoreApiGetCodec(void); - (void)echoAsyncNullableAllNullableTypes:(nullable FLTAllNullableTypes *)everything completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed object, to test serialization and deserialization. +- (void)echoAsyncNullableAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)everything + completion: + (void (^)(FLTAllNullableTypesWithoutRecursion + *_Nullable, + FlutterError *_Nullable))completion; /// Returns passed in int asynchronously. - (void)echoAsyncNullableInt:(nullable NSNumber *)anInt completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -353,6 +414,21 @@ NSObject *FLTHostIntegrationCoreApiGetCodec(void); aString:(nullable NSString *)aNullableString completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; +- (void)callFlutterEchoAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)everything + completion: + (void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; +- (void) + callFlutterSendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + completion: + (void (^)(FLTAllNullableTypesWithoutRecursion + *_Nullable, + FlutterError *_Nullable)) + completion; - (void)callFlutterEchoBool:(BOOL)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; - (void)callFlutterEchoInt:(NSInteger)anInt @@ -429,6 +505,21 @@ NSObject *FLTFlutterIntegrationCoreApiGetCodec(void); aString:(nullable NSString *)aNullableString completion:(void (^)(FLTAllNullableTypes *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed object, to test serialization and deserialization. +- (void) + echoAllNullableTypesWithoutRecursion:(nullable FLTAllNullableTypesWithoutRecursion *)everything + completion:(void (^)(FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; +/// Returns passed in arguments of multiple types. +/// +/// Tests multiple-arity FlutterApi handling. +- (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + completion: + (void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed boolean, to test serialization and deserialization. - (void)echoBool:(BOOL)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index b3648a7d3a3..2861a888048 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -62,6 +62,12 @@ + (nullable FLTAllNullableTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end +@interface FLTAllNullableTypesWithoutRecursion () ++ (FLTAllNullableTypesWithoutRecursion *)fromList:(NSArray *)list; ++ (nullable FLTAllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + @interface FLTAllClassesWrapper () + (FLTAllClassesWrapper *)fromList:(NSArray *)list; + (nullable FLTAllClassesWrapper *)nullableFromList:(NSArray *)list; @@ -236,11 +242,104 @@ - (NSArray *)toList { } @end +@implementation FLTAllNullableTypesWithoutRecursion ++ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableList:(nullable NSArray *)aNullableList + aNullableMap:(nullable NSDictionary *)aNullableMap + nullableNestedList:(nullable NSArray *> *)nullableNestedList + nullableMapWithAnnotations: + (nullable NSDictionary *)nullableMapWithAnnotations + nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject + aNullableEnum:(nullable FLTAnEnumBox *)aNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject { + FLTAllNullableTypesWithoutRecursion *pigeonResult = + [[FLTAllNullableTypesWithoutRecursion alloc] init]; + pigeonResult.aNullableBool = aNullableBool; + pigeonResult.aNullableInt = aNullableInt; + pigeonResult.aNullableInt64 = aNullableInt64; + pigeonResult.aNullableDouble = aNullableDouble; + pigeonResult.aNullableByteArray = aNullableByteArray; + pigeonResult.aNullable4ByteArray = aNullable4ByteArray; + pigeonResult.aNullable8ByteArray = aNullable8ByteArray; + pigeonResult.aNullableFloatArray = aNullableFloatArray; + pigeonResult.aNullableList = aNullableList; + pigeonResult.aNullableMap = aNullableMap; + pigeonResult.nullableNestedList = nullableNestedList; + pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations; + pigeonResult.nullableMapWithObject = nullableMapWithObject; + pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.aNullableString = aNullableString; + pigeonResult.aNullableObject = aNullableObject; + return pigeonResult; +} ++ (FLTAllNullableTypesWithoutRecursion *)fromList:(NSArray *)list { + FLTAllNullableTypesWithoutRecursion *pigeonResult = + [[FLTAllNullableTypesWithoutRecursion alloc] init]; + pigeonResult.aNullableBool = GetNullableObjectAtIndex(list, 0); + pigeonResult.aNullableInt = GetNullableObjectAtIndex(list, 1); + pigeonResult.aNullableInt64 = GetNullableObjectAtIndex(list, 2); + pigeonResult.aNullableDouble = GetNullableObjectAtIndex(list, 3); + pigeonResult.aNullableByteArray = GetNullableObjectAtIndex(list, 4); + pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 5); + pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 6); + pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 7); + pigeonResult.aNullableList = GetNullableObjectAtIndex(list, 8); + pigeonResult.aNullableMap = GetNullableObjectAtIndex(list, 9); + pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 10); + pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 11); + pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 12); + NSNumber *aNullableEnumAsNumber = GetNullableObjectAtIndex(list, 13); + FLTAnEnumBox *aNullableEnum = + aNullableEnumAsNumber == nil + ? nil + : [[FLTAnEnumBox alloc] initWithValue:[aNullableEnumAsNumber integerValue]]; + pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 14); + pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 15); + return pigeonResult; +} ++ (nullable FLTAllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list { + return (list) ? [FLTAllNullableTypesWithoutRecursion fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.aNullableBool ?: [NSNull null], + self.aNullableInt ?: [NSNull null], + self.aNullableInt64 ?: [NSNull null], + self.aNullableDouble ?: [NSNull null], + self.aNullableByteArray ?: [NSNull null], + self.aNullable4ByteArray ?: [NSNull null], + self.aNullable8ByteArray ?: [NSNull null], + self.aNullableFloatArray ?: [NSNull null], + self.aNullableList ?: [NSNull null], + self.aNullableMap ?: [NSNull null], + self.nullableNestedList ?: [NSNull null], + self.nullableMapWithAnnotations ?: [NSNull null], + self.nullableMapWithObject ?: [NSNull null], + (self.aNullableEnum == nil ? [NSNull null] + : [NSNumber numberWithInteger:self.aNullableEnum.value]), + self.aNullableString ?: [NSNull null], + self.aNullableObject ?: [NSNull null], + ]; +} +@end + @implementation FLTAllClassesWrapper + (instancetype)makeWithAllNullableTypes:(FLTAllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion allTypes:(nullable FLTAllTypes *)allTypes { FLTAllClassesWrapper *pigeonResult = [[FLTAllClassesWrapper alloc] init]; pigeonResult.allNullableTypes = allNullableTypes; + pigeonResult.allNullableTypesWithoutRecursion = allNullableTypesWithoutRecursion; pigeonResult.allTypes = allTypes; return pigeonResult; } @@ -248,7 +347,9 @@ + (FLTAllClassesWrapper *)fromList:(NSArray *)list { FLTAllClassesWrapper *pigeonResult = [[FLTAllClassesWrapper alloc] init]; pigeonResult.allNullableTypes = [FLTAllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))]; - pigeonResult.allTypes = [FLTAllTypes nullableFromList:(GetNullableObjectAtIndex(list, 1))]; + pigeonResult.allNullableTypesWithoutRecursion = + [FLTAllNullableTypesWithoutRecursion nullableFromList:(GetNullableObjectAtIndex(list, 1))]; + pigeonResult.allTypes = [FLTAllTypes nullableFromList:(GetNullableObjectAtIndex(list, 2))]; return pigeonResult; } + (nullable FLTAllClassesWrapper *)nullableFromList:(NSArray *)list { @@ -257,6 +358,8 @@ + (nullable FLTAllClassesWrapper *)nullableFromList:(NSArray *)list { - (NSArray *)toList { return @[ (self.allNullableTypes ? [self.allNullableTypes toList] : [NSNull null]), + (self.allNullableTypesWithoutRecursion ? [self.allNullableTypesWithoutRecursion toList] + : [NSNull null]), (self.allTypes ? [self.allTypes toList] : [NSNull null]), ]; } @@ -293,8 +396,10 @@ - (nullable id)readValueOfType:(UInt8)type { case 129: return [FLTAllNullableTypes fromList:[self readValue]]; case 130: - return [FLTAllTypes fromList:[self readValue]]; + return [FLTAllNullableTypesWithoutRecursion fromList:[self readValue]]; case 131: + return [FLTAllTypes fromList:[self readValue]]; + case 132: return [FLTTestMessage fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -312,12 +417,15 @@ - (void)writeValue:(id)value { } else if ([value isKindOfClass:[FLTAllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FLTAllTypes class]]) { + } else if ([value isKindOfClass:[FLTAllNullableTypesWithoutRecursion class]]) { [self writeByte:130]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FLTTestMessage class]]) { + } else if ([value isKindOfClass:[FLTAllTypes class]]) { [self writeByte:131]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FLTTestMessage class]]) { + [self writeByte:132]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } @@ -772,6 +880,30 @@ void SetUpFLTHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"echoAllNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:FLTHostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAllNullableTypesWithoutRecursion:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAllNullableTypesWithoutRecursion:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FLTAllNullableTypesWithoutRecursion *output = + [api echoAllNullableTypesWithoutRecursion:arg_everything error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. { @@ -850,6 +982,36 @@ void SetUpFLTHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns passed in arguments of multiple types. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"sendMultipleNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:FLTHostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + FLTAllNullableTypesWithoutRecursion *output = + [api sendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] @@ -1463,6 +1625,33 @@ void SetUpFLTHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"echoAsyncNullableAllNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:FLTHostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableAllNullableTypesWithoutRecursion:arg_everything + completion:^(FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns passed in int asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] @@ -1826,6 +2015,66 @@ void SetUpFLTHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"callFlutterEchoAllNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:FLTHostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (callFlutterEchoAllNullableTypesWithoutRecursion:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllNullableTypesWithoutRecursion:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + FLTAllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllNullableTypesWithoutRecursion:arg_everything + completion:^(FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"callFlutterSendMultipleNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:FLTHostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector + (callFlutterSendMultipleNullableTypesWithoutRecursionABool: + anInt:aString:completion:)], + @"FLTHostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSendMultipleNullableTypesWithoutRecursionABool:anInt:aString:" + @"completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + [api callFlutterSendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + completion:^( + FLTAllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." @@ -2225,8 +2474,10 @@ - (nullable id)readValueOfType:(UInt8)type { case 129: return [FLTAllNullableTypes fromList:[self readValue]]; case 130: - return [FLTAllTypes fromList:[self readValue]]; + return [FLTAllNullableTypesWithoutRecursion fromList:[self readValue]]; case 131: + return [FLTAllTypes fromList:[self readValue]]; + case 132: return [FLTTestMessage fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -2244,12 +2495,15 @@ - (void)writeValue:(id)value { } else if ([value isKindOfClass:[FLTAllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FLTAllTypes class]]) { + } else if ([value isKindOfClass:[FLTAllNullableTypesWithoutRecursion class]]) { [self writeByte:130]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FLTTestMessage class]]) { + } else if ([value isKindOfClass:[FLTAllTypes class]]) { [self writeByte:131]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FLTTestMessage class]]) { + [self writeByte:132]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } @@ -2437,6 +2691,67 @@ - (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool } }]; } +- (void)echoAllNullableTypesWithoutRecursion: + (nullable FLTAllNullableTypesWithoutRecursion *)arg_everything + completion: + (void (^)(FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + @"echoAllNullableTypesWithoutRecursion"; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTFlutterIntegrationCoreApiGetCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void)sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_aNullableBool + anInt:(nullable NSNumber *)arg_aNullableInt + aString:(nullable NSString *)arg_aNullableString + completion: + (void (^)( + FLTAllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + @"sendMultipleNullableTypesWithoutRecursion"; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FLTFlutterIntegrationCoreApiGetCodec()]; + [channel sendMessage:@[ + arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], + arg_aNullableString ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + FLTAllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} - (void)echoBool:(BOOL)arg_aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m index 671116aacae..ea91a7eaa1b 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/AlternateLanguageTestPlugin.m @@ -34,6 +34,12 @@ - (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes * return everything; } +- (nullable AllNullableTypesWithoutRecursion *) + echoAllNullableTypesWithoutRecursion:(nullable AllNullableTypesWithoutRecursion *)everything + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return everything; +} + - (nullable id)throwErrorWithError:(FlutterError *_Nullable *_Nonnull)error { *error = [FlutterError errorWithCode:@"An error" message:nil details:nil]; return nil; @@ -92,6 +98,7 @@ - (nullable AllClassesWrapper *)echoClassWrapper:(AllClassesWrapper *)wrapper - (AnEnumBox *_Nullable)echoEnum:(AnEnum)anEnum error:(FlutterError *_Nullable *_Nonnull)error { return [[AnEnumBox alloc] initWithValue:anEnum]; } + - (nullable NSString *)echoNamedDefaultString:(NSString *)aString error:(FlutterError *_Nullable *_Nonnull)error { return aString; @@ -117,7 +124,9 @@ - (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrap error:(FlutterError *_Nullable *_Nonnull)error { AllNullableTypes *innerObject = [[AllNullableTypes alloc] init]; innerObject.aNullableString = nullableString; - return [AllClassesWrapper makeWithAllNullableTypes:innerObject allTypes:nil]; + return [AllClassesWrapper makeWithAllNullableTypes:innerObject + allNullableTypesWithoutRecursion:nil + allTypes:nil]; } - (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool @@ -132,6 +141,20 @@ - (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber return someTypes; } +- (nullable AllNullableTypesWithoutRecursion *) + sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + error: + (FlutterError *_Nullable __autoreleasing *_Nonnull) + error { + AllNullableTypesWithoutRecursion *someTypes = [[AllNullableTypesWithoutRecursion alloc] init]; + someTypes.aNullableBool = aNullableBool; + someTypes.aNullableInt = aNullableInt; + someTypes.aNullableString = aNullableString; + return someTypes; +} + - (nullable NSNumber *)echoNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error { return aNullableInt; @@ -217,6 +240,15 @@ - (void)echoAsyncNullableAllNullableTypes:(nullable AllNullableTypes *)everythin completion(everything, nil); } +- (void)echoAsyncNullableAllNullableTypesWithoutRecursion: + (nullable AllNullableTypesWithoutRecursion *)everything + completion: + (nonnull void (^)( + AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + completion(everything, nil); +} + - (void)echoAsyncInt:(NSInteger)anInt completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { completion(@(anInt), nil); @@ -352,6 +384,25 @@ - (void)callFlutterSendMultipleNullableTypesABool:(nullable NSNumber *)aNullable }]; } +- (void)callFlutterSendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString: + (nullable NSString *)aNullableString + completion: + (nonnull void (^)( + AllNullableTypesWithoutRecursion + *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI + sendMultipleNullableTypesWithoutRecursionABool:aNullableBool + anInt:aNullableInt + aString:aNullableString + completion:^(AllNullableTypesWithoutRecursion *value, + FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterEchoBool:(BOOL)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { [self.flutterAPI echoBool:aBool @@ -427,6 +478,19 @@ - (void)callFlutterEchoAllNullableTypes:(nullable AllNullableTypes *)everything }]; } +- (void)callFlutterEchoAllNullableTypesWithoutRecursion: + (nullable AllNullableTypesWithoutRecursion *)everything + completion: + (nonnull void (^)( + AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + [self.flutterAPI echoAllNullableTypesWithoutRecursion:everything + completion:^(AllNullableTypesWithoutRecursion *value, + FlutterError *error) { + completion(value, error); + }]; +} + - (void)callFlutterEchoNullableBool:(nullable NSNumber *)aBool completion: (void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h index 1777c506820..78ca94e00f0 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h @@ -30,6 +30,7 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @class AllTypes; @class AllNullableTypes; +@class AllNullableTypesWithoutRecursion; @class AllClassesWrapper; @class TestMessage; @@ -105,6 +106,43 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, strong, nullable) AllNullableTypes *allNullableTypes; @end +@interface AllNullableTypesWithoutRecursion : NSObject ++ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableList:(nullable NSArray *)aNullableList + aNullableMap:(nullable NSDictionary *)aNullableMap + nullableNestedList:(nullable NSArray *> *)nullableNestedList + nullableMapWithAnnotations: + (nullable NSDictionary *)nullableMapWithAnnotations + nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject + aNullableEnum:(nullable AnEnumBox *)aNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject; +@property(nonatomic, strong, nullable) NSNumber *aNullableBool; +@property(nonatomic, strong, nullable) NSNumber *aNullableInt; +@property(nonatomic, strong, nullable) NSNumber *aNullableInt64; +@property(nonatomic, strong, nullable) NSNumber *aNullableDouble; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableByteArray; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable4ByteArray; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullable8ByteArray; +@property(nonatomic, strong, nullable) FlutterStandardTypedData *aNullableFloatArray; +@property(nonatomic, copy, nullable) NSArray *aNullableList; +@property(nonatomic, copy, nullable) NSDictionary *aNullableMap; +@property(nonatomic, copy, nullable) NSArray *> *nullableNestedList; +@property(nonatomic, copy, nullable) + NSDictionary *nullableMapWithAnnotations; +@property(nonatomic, copy, nullable) NSDictionary *nullableMapWithObject; +@property(nonatomic, strong, nullable) AnEnumBox *aNullableEnum; +@property(nonatomic, copy, nullable) NSString *aNullableString; +@property(nonatomic, strong, nullable) id aNullableObject; +@end + /// A class for testing nested class handling. /// /// This is needed to test nested nullable and non-nullable classes, @@ -114,8 +152,12 @@ typedef NS_ENUM(NSUInteger, AnEnum) { /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; + (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable AllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion allTypes:(nullable AllTypes *)allTypes; @property(nonatomic, strong) AllNullableTypes *allNullableTypes; +@property(nonatomic, strong, nullable) + AllNullableTypesWithoutRecursion *allNullableTypesWithoutRecursion; @property(nonatomic, strong, nullable) AllTypes *allTypes; @end @@ -208,6 +250,10 @@ NSObject *HostIntegrationCoreApiGetCodec(void); /// Returns the passed object, to test serialization and deserialization. - (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes *)everything error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed object, to test serialization and deserialization. +- (nullable AllNullableTypesWithoutRecursion *) + echoAllNullableTypesWithoutRecursion:(nullable AllNullableTypesWithoutRecursion *)everything + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrapper @@ -227,6 +273,14 @@ NSObject *HostIntegrationCoreApiGetCodec(void); aString:(nullable NSString *)aNullableString error:(FlutterError *_Nullable *_Nonnull) error; +/// Returns passed in arguments of multiple types. +/// +/// @return `nil` only when `error != nil`. +- (nullable AllNullableTypesWithoutRecursion *) + sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in int. - (nullable NSNumber *)echoNullableInt:(nullable NSNumber *)aNullableInt error:(FlutterError *_Nullable *_Nonnull)error; @@ -307,6 +361,13 @@ NSObject *HostIntegrationCoreApiGetCodec(void); - (void)echoAsyncNullableAllNullableTypes:(nullable AllNullableTypes *)everything completion:(void (^)(AllNullableTypes *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed object, to test serialization and deserialization. +- (void)echoAsyncNullableAllNullableTypesWithoutRecursion: + (nullable AllNullableTypesWithoutRecursion *)everything + completion: + (void (^)( + AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; /// Returns passed in int asynchronously. - (void)echoAsyncNullableInt:(nullable NSNumber *)anInt completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; @@ -350,6 +411,21 @@ NSObject *HostIntegrationCoreApiGetCodec(void); aString:(nullable NSString *)aNullableString completion:(void (^)(AllNullableTypes *_Nullable, FlutterError *_Nullable))completion; +- (void) + callFlutterEchoAllNullableTypesWithoutRecursion: + (nullable AllNullableTypesWithoutRecursion *)everything + completion: + (void (^)(AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; +- (void) + callFlutterSendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + completion: + (void (^)(AllNullableTypesWithoutRecursion + *_Nullable, + FlutterError *_Nullable)) + completion; - (void)callFlutterEchoBool:(BOOL)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; - (void)callFlutterEchoInt:(NSInteger)anInt @@ -426,6 +502,20 @@ NSObject *FlutterIntegrationCoreApiGetCodec(void); aString:(nullable NSString *)aNullableString completion:(void (^)(AllNullableTypes *_Nullable, FlutterError *_Nullable))completion; +/// Returns the passed object, to test serialization and deserialization. +- (void)echoAllNullableTypesWithoutRecursion:(nullable AllNullableTypesWithoutRecursion *)everything + completion:(void (^)(AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; +/// Returns passed in arguments of multiple types. +/// +/// Tests multiple-arity FlutterApi handling. +- (void) + sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + completion: + (void (^)(AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion; /// Returns the passed boolean, to test serialization and deserialization. - (void)echoBool:(BOOL)aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m index 1fe478cdbb5..b90345836c5 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m @@ -62,6 +62,12 @@ + (nullable AllNullableTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end +@interface AllNullableTypesWithoutRecursion () ++ (AllNullableTypesWithoutRecursion *)fromList:(NSArray *)list; ++ (nullable AllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + @interface AllClassesWrapper () + (AllClassesWrapper *)fromList:(NSArray *)list; + (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list; @@ -236,11 +242,102 @@ - (NSArray *)toList { } @end +@implementation AllNullableTypesWithoutRecursion ++ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool + aNullableInt:(nullable NSNumber *)aNullableInt + aNullableInt64:(nullable NSNumber *)aNullableInt64 + aNullableDouble:(nullable NSNumber *)aNullableDouble + aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray + aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray + aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray + aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray + aNullableList:(nullable NSArray *)aNullableList + aNullableMap:(nullable NSDictionary *)aNullableMap + nullableNestedList:(nullable NSArray *> *)nullableNestedList + nullableMapWithAnnotations: + (nullable NSDictionary *)nullableMapWithAnnotations + nullableMapWithObject:(nullable NSDictionary *)nullableMapWithObject + aNullableEnum:(nullable AnEnumBox *)aNullableEnum + aNullableString:(nullable NSString *)aNullableString + aNullableObject:(nullable id)aNullableObject { + AllNullableTypesWithoutRecursion *pigeonResult = [[AllNullableTypesWithoutRecursion alloc] init]; + pigeonResult.aNullableBool = aNullableBool; + pigeonResult.aNullableInt = aNullableInt; + pigeonResult.aNullableInt64 = aNullableInt64; + pigeonResult.aNullableDouble = aNullableDouble; + pigeonResult.aNullableByteArray = aNullableByteArray; + pigeonResult.aNullable4ByteArray = aNullable4ByteArray; + pigeonResult.aNullable8ByteArray = aNullable8ByteArray; + pigeonResult.aNullableFloatArray = aNullableFloatArray; + pigeonResult.aNullableList = aNullableList; + pigeonResult.aNullableMap = aNullableMap; + pigeonResult.nullableNestedList = nullableNestedList; + pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations; + pigeonResult.nullableMapWithObject = nullableMapWithObject; + pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.aNullableString = aNullableString; + pigeonResult.aNullableObject = aNullableObject; + return pigeonResult; +} ++ (AllNullableTypesWithoutRecursion *)fromList:(NSArray *)list { + AllNullableTypesWithoutRecursion *pigeonResult = [[AllNullableTypesWithoutRecursion alloc] init]; + pigeonResult.aNullableBool = GetNullableObjectAtIndex(list, 0); + pigeonResult.aNullableInt = GetNullableObjectAtIndex(list, 1); + pigeonResult.aNullableInt64 = GetNullableObjectAtIndex(list, 2); + pigeonResult.aNullableDouble = GetNullableObjectAtIndex(list, 3); + pigeonResult.aNullableByteArray = GetNullableObjectAtIndex(list, 4); + pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 5); + pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 6); + pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 7); + pigeonResult.aNullableList = GetNullableObjectAtIndex(list, 8); + pigeonResult.aNullableMap = GetNullableObjectAtIndex(list, 9); + pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 10); + pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 11); + pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 12); + NSNumber *aNullableEnumAsNumber = GetNullableObjectAtIndex(list, 13); + AnEnumBox *aNullableEnum = + aNullableEnumAsNumber == nil + ? nil + : [[AnEnumBox alloc] initWithValue:[aNullableEnumAsNumber integerValue]]; + pigeonResult.aNullableEnum = aNullableEnum; + pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 14); + pigeonResult.aNullableObject = GetNullableObjectAtIndex(list, 15); + return pigeonResult; +} ++ (nullable AllNullableTypesWithoutRecursion *)nullableFromList:(NSArray *)list { + return (list) ? [AllNullableTypesWithoutRecursion fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + self.aNullableBool ?: [NSNull null], + self.aNullableInt ?: [NSNull null], + self.aNullableInt64 ?: [NSNull null], + self.aNullableDouble ?: [NSNull null], + self.aNullableByteArray ?: [NSNull null], + self.aNullable4ByteArray ?: [NSNull null], + self.aNullable8ByteArray ?: [NSNull null], + self.aNullableFloatArray ?: [NSNull null], + self.aNullableList ?: [NSNull null], + self.aNullableMap ?: [NSNull null], + self.nullableNestedList ?: [NSNull null], + self.nullableMapWithAnnotations ?: [NSNull null], + self.nullableMapWithObject ?: [NSNull null], + (self.aNullableEnum == nil ? [NSNull null] + : [NSNumber numberWithInteger:self.aNullableEnum.value]), + self.aNullableString ?: [NSNull null], + self.aNullableObject ?: [NSNull null], + ]; +} +@end + @implementation AllClassesWrapper + (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes + allNullableTypesWithoutRecursion: + (nullable AllNullableTypesWithoutRecursion *)allNullableTypesWithoutRecursion allTypes:(nullable AllTypes *)allTypes { AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; pigeonResult.allNullableTypes = allNullableTypes; + pigeonResult.allNullableTypesWithoutRecursion = allNullableTypesWithoutRecursion; pigeonResult.allTypes = allTypes; return pigeonResult; } @@ -248,7 +345,9 @@ + (AllClassesWrapper *)fromList:(NSArray *)list { AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; pigeonResult.allNullableTypes = [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))]; - pigeonResult.allTypes = [AllTypes nullableFromList:(GetNullableObjectAtIndex(list, 1))]; + pigeonResult.allNullableTypesWithoutRecursion = + [AllNullableTypesWithoutRecursion nullableFromList:(GetNullableObjectAtIndex(list, 1))]; + pigeonResult.allTypes = [AllTypes nullableFromList:(GetNullableObjectAtIndex(list, 2))]; return pigeonResult; } + (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list { @@ -257,6 +356,8 @@ + (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list { - (NSArray *)toList { return @[ (self.allNullableTypes ? [self.allNullableTypes toList] : [NSNull null]), + (self.allNullableTypesWithoutRecursion ? [self.allNullableTypesWithoutRecursion toList] + : [NSNull null]), (self.allTypes ? [self.allTypes toList] : [NSNull null]), ]; } @@ -293,8 +394,10 @@ - (nullable id)readValueOfType:(UInt8)type { case 129: return [AllNullableTypes fromList:[self readValue]]; case 130: - return [AllTypes fromList:[self readValue]]; + return [AllNullableTypesWithoutRecursion fromList:[self readValue]]; case 131: + return [AllTypes fromList:[self readValue]]; + case 132: return [TestMessage fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -312,12 +415,15 @@ - (void)writeValue:(id)value { } else if ([value isKindOfClass:[AllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllTypes class]]) { + } else if ([value isKindOfClass:[AllNullableTypesWithoutRecursion class]]) { [self writeByte:130]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[TestMessage class]]) { + } else if ([value isKindOfClass:[AllTypes class]]) { [self writeByte:131]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[TestMessage class]]) { + [self writeByte:132]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } @@ -769,6 +875,30 @@ void SetUpHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"echoAllNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:HostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(echoAllNullableTypesWithoutRecursion:error:)], + @"HostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAllNullableTypesWithoutRecursion:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + AllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + AllNullableTypesWithoutRecursion *output = + [api echoAllNullableTypesWithoutRecursion:arg_everything error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. { @@ -847,6 +977,36 @@ void SetUpHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns passed in arguments of multiple types. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"sendMultipleNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:HostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)], + @"HostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(sendMultipleNullableTypesWithoutRecursionABool:anInt:aString:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + FlutterError *error; + AllNullableTypesWithoutRecursion *output = + [api sendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns passed in int. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] @@ -1460,6 +1620,33 @@ void SetUpHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns the passed object, to test serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"echoAsyncNullableAllNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:HostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)], + @"HostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(echoAsyncNullableAllNullableTypesWithoutRecursion:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + AllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api echoAsyncNullableAllNullableTypesWithoutRecursion:arg_everything + completion:^(AllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns passed in int asynchronously. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] @@ -1822,6 +2009,66 @@ void SetUpHostIntegrationCoreApi(id binaryMessenger, [channel setMessageHandler:nil]; } } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"callFlutterEchoAllNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:HostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (callFlutterEchoAllNullableTypesWithoutRecursion:completion:)], + @"HostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterEchoAllNullableTypesWithoutRecursion:completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + AllNullableTypesWithoutRecursion *arg_everything = GetNullableObjectAtIndex(args, 0); + [api callFlutterEchoAllNullableTypesWithoutRecursion:arg_everything + completion:^(AllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + @"callFlutterSendMultipleNullableTypesWithoutRecursion" + binaryMessenger:binaryMessenger + codec:HostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector + (callFlutterSendMultipleNullableTypesWithoutRecursionABool: + anInt:aString:completion:)], + @"HostIntegrationCoreApi api (%@) doesn't respond to " + @"@selector(callFlutterSendMultipleNullableTypesWithoutRecursionABool:anInt:aString:" + @"completion:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0); + NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1); + NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2); + [api callFlutterSendMultipleNullableTypesWithoutRecursionABool:arg_aNullableBool + anInt:arg_aNullableInt + aString:arg_aNullableString + completion:^( + AllNullableTypesWithoutRecursion + *_Nullable output, + FlutterError *_Nullable error) { + callback(wrapResult(output, error)); + }]; + }]; + } else { + [channel setMessageHandler:nil]; + } + } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:@"dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." @@ -2220,8 +2467,10 @@ - (nullable id)readValueOfType:(UInt8)type { case 129: return [AllNullableTypes fromList:[self readValue]]; case 130: - return [AllTypes fromList:[self readValue]]; + return [AllNullableTypesWithoutRecursion fromList:[self readValue]]; case 131: + return [AllTypes fromList:[self readValue]]; + case 132: return [TestMessage fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -2239,12 +2488,15 @@ - (void)writeValue:(id)value { } else if ([value isKindOfClass:[AllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllTypes class]]) { + } else if ([value isKindOfClass:[AllNullableTypesWithoutRecursion class]]) { [self writeByte:130]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[TestMessage class]]) { + } else if ([value isKindOfClass:[AllTypes class]]) { [self writeByte:131]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[TestMessage class]]) { + [self writeByte:132]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } @@ -2432,6 +2684,66 @@ - (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool } }]; } +- (void)echoAllNullableTypesWithoutRecursion: + (nullable AllNullableTypesWithoutRecursion *)arg_everything + completion:(void (^)(AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + @"echoAllNullableTypesWithoutRecursion"; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FlutterIntegrationCoreApiGetCodec()]; + [channel sendMessage:@[ arg_everything ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + AllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} +- (void) + sendMultipleNullableTypesWithoutRecursionABool:(nullable NSNumber *)arg_aNullableBool + anInt:(nullable NSNumber *)arg_aNullableInt + aString:(nullable NSString *)arg_aNullableString + completion: + (void (^)(AllNullableTypesWithoutRecursion *_Nullable, + FlutterError *_Nullable))completion { + NSString *channelName = @"dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + @"sendMultipleNullableTypesWithoutRecursion"; + FlutterBasicMessageChannel *channel = + [FlutterBasicMessageChannel messageChannelWithName:channelName + binaryMessenger:self.binaryMessenger + codec:FlutterIntegrationCoreApiGetCodec()]; + [channel sendMessage:@[ + arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null], + arg_aNullableString ?: [NSNull null] + ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + AllNullableTypesWithoutRecursion *output = + reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, createConnectionError(channelName)); + } + }]; +} - (void)echoBool:(BOOL)arg_aBool completion:(void (^)(NSNumber *_Nullable, FlutterError *_Nullable))completion { NSString *channelName = diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart index 071eefe2a1c..876c3b149d7 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart @@ -110,6 +110,60 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { allNullableTypesTwo.allNullableTypes); } + void compareAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? allNullableTypesOne, + AllNullableTypesWithoutRecursion? allNullableTypesTwo) { + expect(allNullableTypesOne == null, allNullableTypesTwo == null); + if (allNullableTypesOne == null || allNullableTypesTwo == null) { + return; + } + expect( + allNullableTypesOne.aNullableBool, allNullableTypesTwo.aNullableBool); + expect(allNullableTypesOne.aNullableInt, allNullableTypesTwo.aNullableInt); + expect( + allNullableTypesOne.aNullableInt64, allNullableTypesTwo.aNullableInt64); + expect(allNullableTypesOne.aNullableDouble, + allNullableTypesTwo.aNullableDouble); + expect(allNullableTypesOne.aNullableString, + allNullableTypesTwo.aNullableString); + expect(allNullableTypesOne.aNullableByteArray, + allNullableTypesTwo.aNullableByteArray); + expect(allNullableTypesOne.aNullable4ByteArray, + allNullableTypesTwo.aNullable4ByteArray); + expect(allNullableTypesOne.aNullable8ByteArray, + allNullableTypesTwo.aNullable8ByteArray); + expect(allNullableTypesOne.aNullableFloatArray, + allNullableTypesTwo.aNullableFloatArray); + expect( + listEquals(allNullableTypesOne.aNullableList, + allNullableTypesTwo.aNullableList), + true); + expect( + mapEquals( + allNullableTypesOne.aNullableMap, allNullableTypesTwo.aNullableMap), + true); + expect(allNullableTypesOne.nullableNestedList?.length, + allNullableTypesTwo.nullableNestedList?.length); + // TODO(stuartmorgan): Enable this once the Dart types are fixed; see + // https://github.com/flutter/flutter/issues/116117 + //for (int i = 0; i < allNullableTypesOne.nullableNestedList!.length; i++) { + // expect(listEquals(allNullableTypesOne.nullableNestedList![i], allNullableTypesTwo.nullableNestedList![i]), + // true); + //} + expect( + mapEquals(allNullableTypesOne.nullableMapWithAnnotations, + allNullableTypesTwo.nullableMapWithAnnotations), + true); + expect( + mapEquals(allNullableTypesOne.nullableMapWithObject, + allNullableTypesTwo.nullableMapWithObject), + true); + expect(allNullableTypesOne.aNullableObject, + allNullableTypesTwo.aNullableObject); + expect( + allNullableTypesOne.aNullableEnum, allNullableTypesTwo.aNullableEnum); + } + void compareAllClassesWrapper( AllClassesWrapper? wrapperOne, AllClassesWrapper? wrapperTwo) { expect(wrapperOne == null, wrapperTwo == null); @@ -119,6 +173,10 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { compareAllNullableTypes( wrapperOne.allNullableTypes, wrapperTwo.allNullableTypes); + compareAllNullableTypesWithoutRecursion( + wrapperOne.allNullableTypesWithoutRecursion, + wrapperTwo.allNullableTypesWithoutRecursion, + ); compareAllTypes(wrapperOne.allTypes, wrapperTwo.allTypes); } @@ -201,6 +259,36 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { allNullableTypes: genericAllNullableTypes, ); + final AllNullableTypesWithoutRecursion + genericAllNullableTypesWithoutRecursion = + AllNullableTypesWithoutRecursion( + aNullableBool: true, + aNullableInt: _regularInt, + aNullableInt64: _biggerThanBigInt, + aNullableDouble: _doublePi, + aNullableString: 'Hello host!', + aNullableByteArray: Uint8List.fromList([1, 2, 3]), + aNullable4ByteArray: Int32List.fromList([4, 5, 6]), + aNullable8ByteArray: Int64List.fromList([7, 8, 9]), + aNullableFloatArray: Float64List.fromList([2.71828, _doublePi]), + aNullableList: ['Thing 1', 2, true, 3.14, null], + aNullableMap: { + 'a': 1, + 'b': 2.0, + 'c': 'three', + 'd': false, + 'e': null + }, + nullableNestedList: >[ + [true, false], + [false, true] + ], + nullableMapWithAnnotations: {}, + nullableMapWithObject: {}, + aNullableEnum: AnEnum.fourHundredTwentyTwo, + aNullableObject: 0, + ); + group('Host sync API tests', () { testWidgets('basic void->void call works', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -263,6 +351,67 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { compareAllNullableTypes(nullableListTypes, echoNullFilledClass); }); + testWidgets( + 'all nullable datatypes without recursion serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion? echoObject = + await api.echoAllNullableTypesWithoutRecursion( + genericAllNullableTypesWithoutRecursion); + + compareAllNullableTypesWithoutRecursion( + echoObject, genericAllNullableTypesWithoutRecursion); + }); + + testWidgets( + 'all null datatypes without recursion serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion allTypesNull = + AllNullableTypesWithoutRecursion(); + + final AllNullableTypesWithoutRecursion? echoNullFilledClass = + await api.echoAllNullableTypesWithoutRecursion(allTypesNull); + compareAllNullableTypesWithoutRecursion( + allTypesNull, echoNullFilledClass); + }); + + testWidgets( + 'Classes without recursion with list of null serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion nullableListTypes = + AllNullableTypesWithoutRecursion( + aNullableList: ['String', null]); + + final AllNullableTypesWithoutRecursion? echoNullFilledClass = + await api.echoAllNullableTypesWithoutRecursion(nullableListTypes); + + compareAllNullableTypesWithoutRecursion( + nullableListTypes, echoNullFilledClass); + }); + + testWidgets( + 'Classes without recursion with map of null serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion nullableListTypes = + AllNullableTypesWithoutRecursion(aNullableMap: { + 'String': 'string', + 'null': null + }); + + final AllNullableTypesWithoutRecursion? echoNullFilledClass = + await api.echoAllNullableTypesWithoutRecursion(nullableListTypes); + + compareAllNullableTypesWithoutRecursion( + nullableListTypes, echoNullFilledClass); + }); + testWidgets('errors are returned correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -298,6 +447,8 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AllClassesWrapper sentObject = AllClassesWrapper( allNullableTypes: recursiveAllNullableTypes, + allNullableTypesWithoutRecursion: + genericAllNullableTypesWithoutRecursion, allTypes: genericAllTypes); final String? receivedString = @@ -320,7 +471,10 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); final AllClassesWrapper sentWrapper = AllClassesWrapper( - allNullableTypes: AllNullableTypes(), allTypes: genericAllTypes); + allNullableTypes: AllNullableTypes(), + allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion(), + allTypes: genericAllTypes, + ); final AllClassesWrapper receivedClassWrapper = await api.echoClassWrapper(sentWrapper); @@ -331,8 +485,10 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllClassesWrapper sentWrapper = - AllClassesWrapper(allNullableTypes: AllNullableTypes()); + final AllClassesWrapper sentWrapper = AllClassesWrapper( + allNullableTypes: AllNullableTypes(), + allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion(), + ); final AllClassesWrapper receivedClassWrapper = await api.echoClassWrapper(sentWrapper); @@ -366,6 +522,34 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(echoNullFilledClass.aNullableString, null); }); + testWidgets( + 'Arguments of multiple types serialize and deserialize correctly (WithoutRecursion)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + const String aNullableString = 'this is a String'; + const bool aNullableBool = false; + const int aNullableInt = _regularInt; + + final AllNullableTypesWithoutRecursion echoObject = + await api.sendMultipleNullableTypesWithoutRecursion( + aNullableBool, aNullableInt, aNullableString); + expect(echoObject.aNullableInt, aNullableInt); + expect(echoObject.aNullableBool, aNullableBool); + expect(echoObject.aNullableString, aNullableString); + }); + + testWidgets( + 'Arguments of multiple null types serialize and deserialize correctly (WithoutRecursion)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion echoNullFilledClass = + await api.sendMultipleNullableTypesWithoutRecursion(null, null, null); + expect(echoNullFilledClass.aNullableInt, null); + expect(echoNullFilledClass.aNullableBool, null); + expect(echoNullFilledClass.aNullableString, null); + }); + testWidgets('Int serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -824,6 +1008,33 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { compareAllNullableTypes(echoNullFilledClass, allTypesNull); }); + testWidgets( + 'all nullable async datatypes without recursion serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion? echoObject = + await api.echoAsyncNullableAllNullableTypesWithoutRecursion( + genericAllNullableTypesWithoutRecursion); + + compareAllNullableTypesWithoutRecursion( + echoObject, genericAllNullableTypesWithoutRecursion); + }); + + testWidgets( + 'all null datatypes without recursion async serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion allTypesNull = + AllNullableTypesWithoutRecursion(); + + final AllNullableTypesWithoutRecursion? echoNullFilledClass = await api + .echoAsyncNullableAllNullableTypesWithoutRecursion(allTypesNull); + compareAllNullableTypesWithoutRecursion( + echoNullFilledClass, allTypesNull); + }); + testWidgets('Int async serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -1219,6 +1430,35 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { expect(compositeObject.aNullableString, null); }); + testWidgets( + 'Arguments of multiple types serialize and deserialize correctly (WithoutRecursion)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + const String aNullableString = 'this is a String'; + const bool aNullableBool = false; + const int aNullableInt = _regularInt; + + final AllNullableTypesWithoutRecursion compositeObject = + await api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aNullableBool, aNullableInt, aNullableString); + expect(compositeObject.aNullableInt, aNullableInt); + expect(compositeObject.aNullableBool, aNullableBool); + expect(compositeObject.aNullableString, aNullableString); + }); + + testWidgets( + 'Arguments of multiple null types serialize and deserialize correctly (WithoutRecursion)', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypesWithoutRecursion compositeObject = + await api.callFlutterSendMultipleNullableTypesWithoutRecursion( + null, null, null); + expect(compositeObject.aNullableInt, null); + expect(compositeObject.aNullableBool, null); + expect(compositeObject.aNullableString, null); + }); + testWidgets('booleans serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -1515,6 +1755,12 @@ class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { return everything; } + @override + AllNullableTypesWithoutRecursion? echoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything) { + return everything; + } + @override void noop() {} @@ -1537,6 +1783,15 @@ class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { aNullableString: aNullableString); } + @override + AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( + bool? aNullableBool, int? aNullableInt, String? aNullableString) { + return AllNullableTypesWithoutRecursion( + aNullableBool: aNullableBool, + aNullableInt: aNullableInt, + aNullableString: aNullableString); + } + @override bool echoBool(bool aBool) => aBool; 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 5f9695a4015..d0ffaf17932 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 @@ -227,6 +227,105 @@ class AllNullableTypes { } } +class AllNullableTypesWithoutRecursion { + AllNullableTypesWithoutRecursion({ + this.aNullableBool, + this.aNullableInt, + this.aNullableInt64, + this.aNullableDouble, + this.aNullableByteArray, + this.aNullable4ByteArray, + this.aNullable8ByteArray, + this.aNullableFloatArray, + this.aNullableList, + this.aNullableMap, + this.nullableNestedList, + this.nullableMapWithAnnotations, + this.nullableMapWithObject, + this.aNullableEnum, + this.aNullableString, + this.aNullableObject, + }); + + bool? aNullableBool; + + int? aNullableInt; + + int? aNullableInt64; + + double? aNullableDouble; + + Uint8List? aNullableByteArray; + + Int32List? aNullable4ByteArray; + + Int64List? aNullable8ByteArray; + + Float64List? aNullableFloatArray; + + List? aNullableList; + + Map? aNullableMap; + + List?>? nullableNestedList; + + Map? nullableMapWithAnnotations; + + Map? nullableMapWithObject; + + AnEnum? aNullableEnum; + + String? aNullableString; + + Object? aNullableObject; + + Object encode() { + return [ + aNullableBool, + aNullableInt, + aNullableInt64, + aNullableDouble, + aNullableByteArray, + aNullable4ByteArray, + aNullable8ByteArray, + aNullableFloatArray, + aNullableList, + aNullableMap, + nullableNestedList, + nullableMapWithAnnotations, + nullableMapWithObject, + aNullableEnum?.index, + aNullableString, + aNullableObject, + ]; + } + + static AllNullableTypesWithoutRecursion decode(Object result) { + result as List; + return AllNullableTypesWithoutRecursion( + aNullableBool: result[0] as bool?, + aNullableInt: result[1] as int?, + aNullableInt64: result[2] as int?, + aNullableDouble: result[3] as double?, + aNullableByteArray: result[4] as Uint8List?, + aNullable4ByteArray: result[5] as Int32List?, + aNullable8ByteArray: result[6] as Int64List?, + aNullableFloatArray: result[7] as Float64List?, + aNullableList: result[8] as List?, + aNullableMap: result[9] as Map?, + nullableNestedList: (result[10] as List?)?.cast?>(), + nullableMapWithAnnotations: + (result[11] as Map?)?.cast(), + nullableMapWithObject: + (result[12] as Map?)?.cast(), + aNullableEnum: + result[13] != null ? AnEnum.values[result[13]! as int] : null, + aNullableString: result[14] as String?, + aNullableObject: result[15], + ); + } +} + /// A class for testing nested class handling. /// /// This is needed to test nested nullable and non-nullable classes, @@ -235,16 +334,20 @@ class AllNullableTypes { class AllClassesWrapper { AllClassesWrapper({ required this.allNullableTypes, + this.allNullableTypesWithoutRecursion, this.allTypes, }); AllNullableTypes allNullableTypes; + AllNullableTypesWithoutRecursion? allNullableTypesWithoutRecursion; + AllTypes? allTypes; Object encode() { return [ allNullableTypes.encode(), + allNullableTypesWithoutRecursion?.encode(), allTypes?.encode(), ]; } @@ -253,8 +356,11 @@ class AllClassesWrapper { result as List; return AllClassesWrapper( allNullableTypes: AllNullableTypes.decode(result[0]! as List), - allTypes: result[1] != null - ? AllTypes.decode(result[1]! as List) + allNullableTypesWithoutRecursion: result[1] != null + ? AllNullableTypesWithoutRecursion.decode(result[1]! as List) + : null, + allTypes: result[2] != null + ? AllTypes.decode(result[2]! as List) : null, ); } @@ -292,12 +398,15 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is AllTypes) { + } else if (value is AllNullableTypesWithoutRecursion) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is TestMessage) { + } else if (value is AllTypes) { buffer.putUint8(131); writeValue(buffer, value.encode()); + } else if (value is TestMessage) { + buffer.putUint8(132); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -311,8 +420,10 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { case 129: return AllNullableTypes.decode(readValue(buffer)!); case 130: - return AllTypes.decode(readValue(buffer)!); + return AllNullableTypesWithoutRecursion.decode(readValue(buffer)!); case 131: + return AllTypes.decode(readValue(buffer)!); + case 132: return TestMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -881,6 +992,33 @@ class HostIntegrationCoreApi { } } + /// Returns the passed object, to test serialization and deserialization. + Future + echoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([everything]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as AllNullableTypesWithoutRecursion?); + } + } + /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. Future extractNestedNullableString(AllClassesWrapper wrapper) async { @@ -971,6 +1109,39 @@ class HostIntegrationCoreApi { } } + /// Returns passed in arguments of multiple types. + Future + sendMultipleNullableTypesWithoutRecursion(bool? aNullableBool, + int? aNullableInt, String? aNullableString) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([aNullableBool, aNullableInt, aNullableString]) + as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as AllNullableTypesWithoutRecursion?)!; + } + } + /// Returns passed in int. Future echoNullableInt(int? aNullableInt) async { const String __pigeon_channelName = @@ -1678,6 +1849,33 @@ class HostIntegrationCoreApi { } } + /// Returns the passed object, to test serialization and deserialization. + Future + echoAsyncNullableAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([everything]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as AllNullableTypesWithoutRecursion?); + } + } + /// Returns passed in int asynchronously. Future echoAsyncNullableInt(int? anInt) async { const String __pigeon_channelName = @@ -2064,6 +2262,64 @@ class HostIntegrationCoreApi { } } + Future + callFlutterEchoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([everything]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as AllNullableTypesWithoutRecursion?); + } + } + + Future + callFlutterSendMultipleNullableTypesWithoutRecursion(bool? aNullableBool, + int? aNullableInt, String? aNullableString) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([aNullableBool, aNullableInt, aNullableString]) + as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as AllNullableTypesWithoutRecursion?)!; + } + } + Future callFlutterEchoBool(bool aBool) async { const String __pigeon_channelName = 'dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool'; @@ -2506,12 +2762,15 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is AllTypes) { + } else if (value is AllNullableTypesWithoutRecursion) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is TestMessage) { + } else if (value is AllTypes) { buffer.putUint8(131); writeValue(buffer, value.encode()); + } else if (value is TestMessage) { + buffer.putUint8(132); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -2525,8 +2784,10 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { case 129: return AllNullableTypes.decode(readValue(buffer)!); case 130: - return AllTypes.decode(readValue(buffer)!); + return AllNullableTypesWithoutRecursion.decode(readValue(buffer)!); case 131: + return AllTypes.decode(readValue(buffer)!); + case 132: return TestMessage.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -2562,6 +2823,16 @@ abstract class FlutterIntegrationCoreApi { AllNullableTypes sendMultipleNullableTypes( bool? aNullableBool, int? aNullableInt, String? aNullableString); + /// Returns the passed object, to test serialization and deserialization. + AllNullableTypesWithoutRecursion? echoAllNullableTypesWithoutRecursion( + AllNullableTypesWithoutRecursion? everything); + + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + AllNullableTypesWithoutRecursion sendMultipleNullableTypesWithoutRecursion( + bool? aNullableBool, int? aNullableInt, String? aNullableString); + /// Returns the passed boolean, to test serialization and deserialization. bool echoBool(bool aBool); @@ -2770,6 +3041,64 @@ abstract class FlutterIntegrationCoreApi { }); } } + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion was null.'); + final List args = (message as List?)!; + final AllNullableTypesWithoutRecursion? arg_everything = + (args[0] as AllNullableTypesWithoutRecursion?); + try { + final AllNullableTypesWithoutRecursion? output = + api.echoAllNullableTypesWithoutRecursion(arg_everything); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion was null.'); + final List args = (message as List?)!; + final bool? arg_aNullableBool = (args[0] as bool?); + final int? arg_aNullableInt = (args[1] as int?); + final String? arg_aNullableString = (args[2] as String?); + try { + final AllNullableTypesWithoutRecursion output = + api.sendMultipleNullableTypesWithoutRecursion( + arg_aNullableBool, arg_aNullableInt, arg_aNullableString); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } { final BasicMessageChannel __pigeon_channel = BasicMessageChannel< Object?>( 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 3499266d35c..5dbb8e50af7 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 @@ -210,6 +210,86 @@ data class AllNullableTypes( } } +/** Generated class from Pigeon that represents data sent in messages. */ +data class AllNullableTypesWithoutRecursion( + val aNullableBool: Boolean? = null, + val aNullableInt: Long? = null, + val aNullableInt64: Long? = null, + val aNullableDouble: Double? = null, + val aNullableByteArray: ByteArray? = null, + val aNullable4ByteArray: IntArray? = null, + val aNullable8ByteArray: LongArray? = null, + val aNullableFloatArray: DoubleArray? = null, + val aNullableList: List? = null, + val aNullableMap: Map? = null, + val nullableNestedList: List?>? = null, + val nullableMapWithAnnotations: Map? = null, + val nullableMapWithObject: Map? = null, + val aNullableEnum: AnEnum? = null, + val aNullableString: String? = null, + val aNullableObject: Any? = null +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): AllNullableTypesWithoutRecursion { + val aNullableBool = list[0] as Boolean? + val aNullableInt = list[1].let { if (it is Int) it.toLong() else it as Long? } + val aNullableInt64 = list[2].let { if (it is Int) it.toLong() else it as Long? } + val aNullableDouble = list[3] as Double? + val aNullableByteArray = list[4] as ByteArray? + val aNullable4ByteArray = list[5] as IntArray? + val aNullable8ByteArray = list[6] as LongArray? + val aNullableFloatArray = list[7] as DoubleArray? + val aNullableList = list[8] as List? + val aNullableMap = list[9] as Map? + val nullableNestedList = list[10] as List?>? + val nullableMapWithAnnotations = list[11] as Map? + val nullableMapWithObject = list[12] as Map? + val aNullableEnum: AnEnum? = (list[13] as Int?)?.let { AnEnum.ofRaw(it) } + val aNullableString = list[14] as String? + val aNullableObject = list[15] + return AllNullableTypesWithoutRecursion( + aNullableBool, + aNullableInt, + aNullableInt64, + aNullableDouble, + aNullableByteArray, + aNullable4ByteArray, + aNullable8ByteArray, + aNullableFloatArray, + aNullableList, + aNullableMap, + nullableNestedList, + nullableMapWithAnnotations, + nullableMapWithObject, + aNullableEnum, + aNullableString, + aNullableObject) + } + } + + fun toList(): List { + return listOf( + aNullableBool, + aNullableInt, + aNullableInt64, + aNullableDouble, + aNullableByteArray, + aNullable4ByteArray, + aNullable8ByteArray, + aNullableFloatArray, + aNullableList, + aNullableMap, + nullableNestedList, + nullableMapWithAnnotations, + nullableMapWithObject, + aNullableEnum?.raw, + aNullableString, + aNullableObject, + ) + } +} + /** * A class for testing nested class handling. * @@ -221,20 +301,24 @@ data class AllNullableTypes( */ data class AllClassesWrapper( val allNullableTypes: AllNullableTypes, + val allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = null, val allTypes: AllTypes? = null ) { companion object { @Suppress("UNCHECKED_CAST") fun fromList(list: List): AllClassesWrapper { val allNullableTypes = AllNullableTypes.fromList(list[0] as List) - val allTypes: AllTypes? = (list[1] as List?)?.let { AllTypes.fromList(it) } - return AllClassesWrapper(allNullableTypes, allTypes) + val allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = + (list[1] as List?)?.let { AllNullableTypesWithoutRecursion.fromList(it) } + val allTypes: AllTypes? = (list[2] as List?)?.let { AllTypes.fromList(it) } + return AllClassesWrapper(allNullableTypes, allNullableTypesWithoutRecursion, allTypes) } } fun toList(): List { return listOf( allNullableTypes.toList(), + allNullableTypesWithoutRecursion?.toList(), allTypes?.toList(), ) } @@ -273,9 +357,14 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() { return (readValue(buffer) as? List)?.let { AllNullableTypes.fromList(it) } } 130.toByte() -> { - return (readValue(buffer) as? List)?.let { AllTypes.fromList(it) } + return (readValue(buffer) as? List)?.let { + AllNullableTypesWithoutRecursion.fromList(it) + } } 131.toByte() -> { + return (readValue(buffer) as? List)?.let { AllTypes.fromList(it) } + } + 132.toByte() -> { return (readValue(buffer) as? List)?.let { TestMessage.fromList(it) } } else -> super.readValueOfType(type, buffer) @@ -292,14 +381,18 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() { stream.write(129) writeValue(stream, value.toList()) } - is AllTypes -> { + is AllNullableTypesWithoutRecursion -> { stream.write(130) writeValue(stream, value.toList()) } - is TestMessage -> { + is AllTypes -> { stream.write(131) writeValue(stream, value.toList()) } + is TestMessage -> { + stream.write(132) + writeValue(stream, value.toList()) + } else -> super.writeValue(stream, value) } } @@ -350,6 +443,10 @@ interface HostIntegrationCoreApi { fun echoRequiredInt(anInt: Long): Long /** Returns the passed object, to test serialization and deserialization. */ fun echoAllNullableTypes(everything: AllNullableTypes?): AllNullableTypes? + /** Returns the passed object, to test serialization and deserialization. */ + fun echoAllNullableTypesWithoutRecursion( + everything: AllNullableTypesWithoutRecursion? + ): AllNullableTypesWithoutRecursion? /** * Returns the inner `aString` value from the wrapped object, to test sending of nested objects. */ @@ -364,6 +461,12 @@ interface HostIntegrationCoreApi { aNullableInt: Long?, aNullableString: String? ): AllNullableTypes + /** Returns passed in arguments of multiple types. */ + fun sendMultipleNullableTypesWithoutRecursion( + aNullableBool: Boolean?, + aNullableInt: Long?, + aNullableString: String? + ): AllNullableTypesWithoutRecursion /** Returns passed in int. */ fun echoNullableInt(aNullableInt: Long?): Long? /** Returns passed in double. */ @@ -422,6 +525,11 @@ interface HostIntegrationCoreApi { everything: AllNullableTypes?, callback: (Result) -> Unit ) + /** Returns the passed object, to test serialization and deserialization. */ + fun echoAsyncNullableAllNullableTypesWithoutRecursion( + everything: AllNullableTypesWithoutRecursion?, + callback: (Result) -> Unit + ) /** Returns passed in int asynchronously. */ fun echoAsyncNullableInt(anInt: Long?, callback: (Result) -> Unit) /** Returns passed in double asynchronously. */ @@ -464,6 +572,18 @@ interface HostIntegrationCoreApi { callback: (Result) -> Unit ) + fun callFlutterEchoAllNullableTypesWithoutRecursion( + everything: AllNullableTypesWithoutRecursion?, + callback: (Result) -> Unit + ) + + fun callFlutterSendMultipleNullableTypesWithoutRecursion( + aNullableBool: Boolean?, + aNullableInt: Long?, + aNullableString: String?, + callback: (Result) -> Unit + ) + fun callFlutterEchoBool(aBool: Boolean, callback: (Result) -> Unit) fun callFlutterEchoInt(anInt: Long, callback: (Result) -> Unit) @@ -920,6 +1040,28 @@ interface HostIntegrationCoreApi { channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val everythingArg = args[0] as AllNullableTypesWithoutRecursion? + var wrapped: List + try { + wrapped = listOf(api.echoAllNullableTypesWithoutRecursion(everythingArg)) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel( @@ -991,6 +1133,33 @@ interface HostIntegrationCoreApi { channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aNullableBoolArg = args[0] as Boolean? + val aNullableIntArg = args[1].let { if (it is Int) it.toLong() else it as Long? } + val aNullableStringArg = args[2] as String? + var wrapped: List + try { + wrapped = + listOf( + api.sendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, aNullableIntArg, aNullableStringArg)) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel( @@ -1584,6 +1753,31 @@ interface HostIntegrationCoreApi { channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val everythingArg = args[0] as AllNullableTypesWithoutRecursion? + api.echoAsyncNullableAllNullableTypesWithoutRecursion(everythingArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel( @@ -1941,6 +2135,59 @@ interface HostIntegrationCoreApi { channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val everythingArg = args[0] as AllNullableTypesWithoutRecursion? + api.callFlutterEchoAllNullableTypesWithoutRecursion(everythingArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val aNullableBoolArg = args[0] as Boolean? + val aNullableIntArg = args[1].let { if (it is Int) it.toLong() else it as Long? } + val aNullableStringArg = args[2] as String? + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg, aNullableIntArg, aNullableStringArg) { + result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel( @@ -2340,9 +2587,14 @@ private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() { return (readValue(buffer) as? List)?.let { AllNullableTypes.fromList(it) } } 130.toByte() -> { - return (readValue(buffer) as? List)?.let { AllTypes.fromList(it) } + return (readValue(buffer) as? List)?.let { + AllNullableTypesWithoutRecursion.fromList(it) + } } 131.toByte() -> { + return (readValue(buffer) as? List)?.let { AllTypes.fromList(it) } + } + 132.toByte() -> { return (readValue(buffer) as? List)?.let { TestMessage.fromList(it) } } else -> super.readValueOfType(type, buffer) @@ -2359,14 +2611,18 @@ private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() { stream.write(129) writeValue(stream, value.toList()) } - is AllTypes -> { + is AllNullableTypesWithoutRecursion -> { stream.write(130) writeValue(stream, value.toList()) } - is TestMessage -> { + is AllTypes -> { stream.write(131) writeValue(stream, value.toList()) } + is TestMessage -> { + stream.write(132) + writeValue(stream, value.toList()) + } else -> super.writeValue(stream, value) } } @@ -2515,6 +2771,61 @@ class FlutterIntegrationCoreApi(private val binaryMessenger: BinaryMessenger) { } } } + /** Returns the passed object, to test serialization and deserialization. */ + fun echoAllNullableTypesWithoutRecursion( + everythingArg: AllNullableTypesWithoutRecursion?, + callback: (Result) -> Unit + ) { + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(everythingArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + val output = it[0] as AllNullableTypesWithoutRecursion? + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + /** + * Returns passed in arguments of multiple types. + * + * Tests multiple-arity FlutterApi handling. + */ + fun sendMultipleNullableTypesWithoutRecursion( + aNullableBoolArg: Boolean?, + aNullableIntArg: Long?, + aNullableStringArg: String?, + callback: (Result) -> Unit + ) { + val channelName = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(aNullableBoolArg, aNullableIntArg, aNullableStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else if (it[0] == null) { + callback( + Result.failure( + FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + ""))) + } else { + val output = it[0] as AllNullableTypesWithoutRecursion + callback(Result.success(output)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } /** Returns the passed boolean, to test serialization and deserialization. */ fun echoBool(aBoolArg: Boolean, callback: (Result) -> Unit) { val channelName = diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt index 8b4e8bc4fb1..c64aab7d34f 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt @@ -4,19 +4,18 @@ package com.example.test_plugin -import androidx.annotation.NonNull import io.flutter.embedding.engine.plugins.FlutterPlugin /** This plugin handles the native side of the integration tests in example/integration_test/. */ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { var flutterApi: FlutterIntegrationCoreApi? = null - override fun onAttachedToEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { - HostIntegrationCoreApi.setUp(binding.getBinaryMessenger(), this) - flutterApi = FlutterIntegrationCoreApi(binding.getBinaryMessenger()) + override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { + HostIntegrationCoreApi.setUp(binding.binaryMessenger, this) + flutterApi = FlutterIntegrationCoreApi(binding.binaryMessenger) } - override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {} + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {} // HostIntegrationCoreApi @@ -30,6 +29,12 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { return everything } + override fun echoAllNullableTypesWithoutRecursion( + everything: AllNullableTypesWithoutRecursion? + ): AllNullableTypesWithoutRecursion? { + return everything + } + override fun throwError(): Any? { throw Exception("An error") } @@ -113,6 +118,17 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { aNullableString = aNullableString) } + override fun sendMultipleNullableTypesWithoutRecursion( + aNullableBool: Boolean?, + aNullableInt: Long?, + aNullableString: String? + ): AllNullableTypesWithoutRecursion { + return AllNullableTypesWithoutRecursion( + aNullableBool = aNullableBool, + aNullableInt = aNullableInt, + aNullableString = aNullableString) + } + override fun echoNullableInt(aNullableInt: Long?): Long? { return aNullableInt } @@ -184,6 +200,13 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { callback(Result.success(everything)) } + override fun echoAsyncNullableAllNullableTypesWithoutRecursion( + everything: AllNullableTypesWithoutRecursion?, + callback: (Result) -> Unit + ) { + callback(Result.success(everything)) + } + override fun echoAsyncInt(anInt: Long, callback: (Result) -> Unit) { callback(Result.success(anInt)) } @@ -292,6 +315,25 @@ class TestPlugin : FlutterPlugin, HostIntegrationCoreApi { } } + override fun callFlutterEchoAllNullableTypesWithoutRecursion( + everything: AllNullableTypesWithoutRecursion?, + callback: (Result) -> Unit + ) { + flutterApi!!.echoAllNullableTypesWithoutRecursion(everything) { echo -> callback(echo) } + } + + override fun callFlutterSendMultipleNullableTypesWithoutRecursion( + aNullableBool: Boolean?, + aNullableInt: Long?, + aNullableString: String?, + callback: (Result) -> Unit + ) { + flutterApi!!.sendMultipleNullableTypesWithoutRecursion( + aNullableBool, aNullableInt, aNullableString) { echo -> + callback(echo) + } + } + override fun callFlutterEchoBool(aBool: Boolean, callback: (Result) -> Unit) { flutterApi!!.echoBool(aBool) { echo -> callback(echo) } } diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 88b39e155af..7b99f400ced 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -255,6 +255,90 @@ class AllNullableTypes { } } +/// Generated class from Pigeon that represents data sent in messages. +struct AllNullableTypesWithoutRecursion { + var aNullableBool: Bool? = nil + var aNullableInt: Int64? = nil + var aNullableInt64: Int64? = nil + var aNullableDouble: Double? = nil + var aNullableByteArray: FlutterStandardTypedData? = nil + var aNullable4ByteArray: FlutterStandardTypedData? = nil + var aNullable8ByteArray: FlutterStandardTypedData? = nil + var aNullableFloatArray: FlutterStandardTypedData? = nil + var aNullableList: [Any?]? = nil + var aNullableMap: [AnyHashable: Any?]? = nil + var nullableNestedList: [[Bool?]?]? = nil + var nullableMapWithAnnotations: [String?: String?]? = nil + var nullableMapWithObject: [String?: Any?]? = nil + var aNullableEnum: AnEnum? = nil + var aNullableString: String? = nil + var aNullableObject: Any? = nil + + static func fromList(_ list: [Any?]) -> AllNullableTypesWithoutRecursion? { + let aNullableBool: Bool? = nilOrValue(list[0]) + let aNullableInt: Int64? = + isNullish(list[1]) ? nil : (list[1] is Int64? ? list[1] as! Int64? : Int64(list[1] as! Int32)) + let aNullableInt64: Int64? = + isNullish(list[2]) ? nil : (list[2] is Int64? ? list[2] as! Int64? : Int64(list[2] as! Int32)) + let aNullableDouble: Double? = nilOrValue(list[3]) + let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(list[4]) + let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(list[5]) + let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(list[6]) + let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(list[7]) + let aNullableList: [Any?]? = nilOrValue(list[8]) + let aNullableMap: [AnyHashable: Any?]? = nilOrValue(list[9]) + let nullableNestedList: [[Bool?]?]? = nilOrValue(list[10]) + let nullableMapWithAnnotations: [String?: String?]? = nilOrValue(list[11]) + let nullableMapWithObject: [String?: Any?]? = nilOrValue(list[12]) + var aNullableEnum: AnEnum? = nil + let aNullableEnumEnumVal: Int? = nilOrValue(list[13]) + if let aNullableEnumRawValue = aNullableEnumEnumVal { + aNullableEnum = AnEnum(rawValue: aNullableEnumRawValue)! + } + let aNullableString: String? = nilOrValue(list[14]) + let aNullableObject: Any? = list[15] + + return AllNullableTypesWithoutRecursion( + aNullableBool: aNullableBool, + aNullableInt: aNullableInt, + aNullableInt64: aNullableInt64, + aNullableDouble: aNullableDouble, + aNullableByteArray: aNullableByteArray, + aNullable4ByteArray: aNullable4ByteArray, + aNullable8ByteArray: aNullable8ByteArray, + aNullableFloatArray: aNullableFloatArray, + aNullableList: aNullableList, + aNullableMap: aNullableMap, + nullableNestedList: nullableNestedList, + nullableMapWithAnnotations: nullableMapWithAnnotations, + nullableMapWithObject: nullableMapWithObject, + aNullableEnum: aNullableEnum, + aNullableString: aNullableString, + aNullableObject: aNullableObject + ) + } + func toList() -> [Any?] { + return [ + aNullableBool, + aNullableInt, + aNullableInt64, + aNullableDouble, + aNullableByteArray, + aNullable4ByteArray, + aNullable8ByteArray, + aNullableFloatArray, + aNullableList, + aNullableMap, + nullableNestedList, + nullableMapWithAnnotations, + nullableMapWithObject, + aNullableEnum?.rawValue, + aNullableString, + aNullableObject, + ] + } +} + /// A class for testing nested class handling. /// /// This is needed to test nested nullable and non-nullable classes, @@ -264,23 +348,31 @@ class AllNullableTypes { /// Generated class from Pigeon that represents data sent in messages. struct AllClassesWrapper { var allNullableTypes: AllNullableTypes + var allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nil var allTypes: AllTypes? = nil static func fromList(_ list: [Any?]) -> AllClassesWrapper? { let allNullableTypes = AllNullableTypes.fromList(list[0] as! [Any?])! + var allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nil + if let allNullableTypesWithoutRecursionList: [Any?] = nilOrValue(list[1]) { + allNullableTypesWithoutRecursion = AllNullableTypesWithoutRecursion.fromList( + allNullableTypesWithoutRecursionList) + } var allTypes: AllTypes? = nil - if let allTypesList: [Any?] = nilOrValue(list[1]) { + if let allTypesList: [Any?] = nilOrValue(list[2]) { allTypes = AllTypes.fromList(allTypesList) } return AllClassesWrapper( allNullableTypes: allNullableTypes, + allNullableTypesWithoutRecursion: allNullableTypesWithoutRecursion, allTypes: allTypes ) } func toList() -> [Any?] { return [ allNullableTypes.toList(), + allNullableTypesWithoutRecursion?.toList(), allTypes?.toList(), ] } @@ -314,8 +406,10 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader { case 129: return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: - return AllTypes.fromList(self.readValue() as! [Any?]) + return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) case 131: + return AllTypes.fromList(self.readValue() as! [Any?]) + case 132: return TestMessage.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -331,12 +425,15 @@ private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter { } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) - } else if let value = value as? AllTypes { + } else if let value = value as? AllNullableTypesWithoutRecursion { super.writeByte(130) super.writeValue(value.toList()) - } else if let value = value as? TestMessage { + } else if let value = value as? AllTypes { super.writeByte(131) super.writeValue(value.toList()) + } else if let value = value as? TestMessage { + super.writeByte(132) + super.writeValue(value.toList()) } else { super.writeValue(value) } @@ -402,6 +499,9 @@ protocol HostIntegrationCoreApi { func echoRequired(_ anInt: Int64) throws -> Int64 /// Returns the passed object, to test serialization and deserialization. func echo(_ everything: AllNullableTypes?) throws -> AllNullableTypes? + /// Returns the passed object, to test serialization and deserialization. + func echo(_ everything: AllNullableTypesWithoutRecursion?) throws + -> AllNullableTypesWithoutRecursion? /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. func extractNestedNullableString(from wrapper: AllClassesWrapper) throws -> String? @@ -412,6 +512,10 @@ protocol HostIntegrationCoreApi { func sendMultipleNullableTypes( aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String? ) throws -> AllNullableTypes + /// Returns passed in arguments of multiple types. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String? + ) throws -> AllNullableTypesWithoutRecursion /// Returns passed in int. func echo(_ aNullableInt: Int64?) throws -> Int64? /// Returns passed in double. @@ -469,6 +573,10 @@ protocol HostIntegrationCoreApi { func echoAsync( _ everything: AllNullableTypes?, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoAsync( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) /// Returns passed in int asynchronously. func echoAsyncNullable(_ anInt: Int64?, completion: @escaping (Result) -> Void) /// Returns passed in double asynchronously. @@ -501,6 +609,12 @@ protocol HostIntegrationCoreApi { func callFlutterSendMultipleNullableTypes( aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?, completion: @escaping (Result) -> Void) + func callFlutterEcho( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) + func callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?, + completion: @escaping (Result) -> Void) func callFlutterEcho(_ aBool: Bool, completion: @escaping (Result) -> Void) func callFlutterEcho(_ anInt: Int64, completion: @escaping (Result) -> Void) func callFlutterEcho(_ aDouble: Double, completion: @escaping (Result) -> Void) @@ -874,6 +988,25 @@ class HostIntegrationCoreApiSetup { } else { echoAllNullableTypesChannel.setMessageHandler(nil) } + /// Returns the passed object, to test serialization and deserialization. + let echoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + do { + let result = try api.echo(everythingArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. let extractNestedNullableStringChannel = FlutterBasicMessageChannel( @@ -938,6 +1071,30 @@ class HostIntegrationCoreApiSetup { } else { sendMultipleNullableTypesChannel.setMessageHandler(nil) } + /// Returns passed in arguments of multiple types. + let sendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = + isNullish(args[1]) + ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) + let aNullableStringArg: String? = nilOrValue(args[2]) + do { + let result = try api.sendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } /// Returns passed in int. let echoNullableIntChannel = FlutterBasicMessageChannel( name: "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt", @@ -1438,6 +1595,27 @@ class HostIntegrationCoreApiSetup { } else { echoAsyncNullableAllNullableTypesChannel.setMessageHandler(nil) } + /// Returns the passed object, to test serialization and deserialization. + let echoAsyncNullableAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.echoAsync(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } /// Returns passed in int asynchronously. let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( name: @@ -1748,6 +1926,53 @@ class HostIntegrationCoreApiSetup { } else { callFlutterSendMultipleNullableTypesChannel.setMessageHandler(nil) } + let callFlutterEchoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } + let callFlutterSendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { + message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = + isNullish(args[1]) + ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) + let aNullableStringArg: String? = nilOrValue(args[2]) + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( name: "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool", @@ -2078,8 +2303,10 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader { case 129: return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: - return AllTypes.fromList(self.readValue() as! [Any?]) + return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) case 131: + return AllTypes.fromList(self.readValue() as! [Any?]) + case 132: return TestMessage.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -2095,12 +2322,15 @@ private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter { } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) - } else if let value = value as? AllTypes { + } else if let value = value as? AllNullableTypesWithoutRecursion { super.writeByte(130) super.writeValue(value.toList()) - } else if let value = value as? TestMessage { + } else if let value = value as? AllTypes { super.writeByte(131) super.writeValue(value.toList()) + } else if let value = value as? TestMessage { + super.writeByte(132) + super.writeValue(value.toList()) } else { super.writeValue(value) } @@ -2148,6 +2378,17 @@ protocol FlutterIntegrationCoreApiProtocol { aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void) /// Returns the passed boolean, to test serialization and deserialization. func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) /// Returns the passed int, to test serialization and deserialization. @@ -2362,6 +2603,66 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { } } } + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(FlutterError(code: code, message: message, details: details))) + } else { + let result: AllNullableTypesWithoutRecursion? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(FlutterError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + FlutterError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllNullableTypesWithoutRecursion + completion(.success(result)) + } + } + } /// Returns the passed boolean, to test serialization and deserialization. func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { let channelName: String = diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift index 0d04c9544ca..d444e5c0bac 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift @@ -10,6 +10,7 @@ extension FlutterError: Error {} /// This plugin handles the native side of the integration tests in /// example/integration_test/. public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { + var flutterAPI: FlutterIntegrationCoreApi public static func register(with registrar: FlutterPluginRegistrar) { @@ -34,6 +35,11 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { func echo(_ everything: AllNullableTypes?) -> AllNullableTypes? { return everything } + func echo(_ everything: AllNullableTypesWithoutRecursion?) throws + -> AllNullableTypesWithoutRecursion? + { + return everything + } func throwError() throws -> Any? { throw FlutterError(code: "code", message: "message", details: "details") @@ -103,6 +109,14 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return someThings } + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String? + ) throws -> AllNullableTypesWithoutRecursion { + let someThings = AllNullableTypesWithoutRecursion( + aNullableBool: aNullableBool, aNullableInt: aNullableInt, aNullableString: aNullableString) + return someThings + } + func echo(_ aNullableInt: Int64?) -> Int64? { return aNullableInt } @@ -186,6 +200,13 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { completion(.success(everything)) } + func echoAsync( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + completion(.success(everything)) + } + func echoAsync(_ anInt: Int64, completion: @escaping (Result) -> Void) { completion(.success(anInt)) } @@ -331,6 +352,20 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } + func callFlutterEcho( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + flutterAPI.echoNullable(everything) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + func callFlutterSendMultipleNullableTypes( aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, @@ -351,6 +386,24 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } + func callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?, + completion: @escaping (Result) -> Void + ) { + flutterAPI.sendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBool, + anInt: aNullableInt, + aString: aNullableString + ) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + func callFlutterEcho(_ aBool: Bool, completion: @escaping (Result) -> Void) { flutterAPI.echo(aBool) { response in switch response { diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 88b39e155af..7b99f400ced 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -255,6 +255,90 @@ class AllNullableTypes { } } +/// Generated class from Pigeon that represents data sent in messages. +struct AllNullableTypesWithoutRecursion { + var aNullableBool: Bool? = nil + var aNullableInt: Int64? = nil + var aNullableInt64: Int64? = nil + var aNullableDouble: Double? = nil + var aNullableByteArray: FlutterStandardTypedData? = nil + var aNullable4ByteArray: FlutterStandardTypedData? = nil + var aNullable8ByteArray: FlutterStandardTypedData? = nil + var aNullableFloatArray: FlutterStandardTypedData? = nil + var aNullableList: [Any?]? = nil + var aNullableMap: [AnyHashable: Any?]? = nil + var nullableNestedList: [[Bool?]?]? = nil + var nullableMapWithAnnotations: [String?: String?]? = nil + var nullableMapWithObject: [String?: Any?]? = nil + var aNullableEnum: AnEnum? = nil + var aNullableString: String? = nil + var aNullableObject: Any? = nil + + static func fromList(_ list: [Any?]) -> AllNullableTypesWithoutRecursion? { + let aNullableBool: Bool? = nilOrValue(list[0]) + let aNullableInt: Int64? = + isNullish(list[1]) ? nil : (list[1] is Int64? ? list[1] as! Int64? : Int64(list[1] as! Int32)) + let aNullableInt64: Int64? = + isNullish(list[2]) ? nil : (list[2] is Int64? ? list[2] as! Int64? : Int64(list[2] as! Int32)) + let aNullableDouble: Double? = nilOrValue(list[3]) + let aNullableByteArray: FlutterStandardTypedData? = nilOrValue(list[4]) + let aNullable4ByteArray: FlutterStandardTypedData? = nilOrValue(list[5]) + let aNullable8ByteArray: FlutterStandardTypedData? = nilOrValue(list[6]) + let aNullableFloatArray: FlutterStandardTypedData? = nilOrValue(list[7]) + let aNullableList: [Any?]? = nilOrValue(list[8]) + let aNullableMap: [AnyHashable: Any?]? = nilOrValue(list[9]) + let nullableNestedList: [[Bool?]?]? = nilOrValue(list[10]) + let nullableMapWithAnnotations: [String?: String?]? = nilOrValue(list[11]) + let nullableMapWithObject: [String?: Any?]? = nilOrValue(list[12]) + var aNullableEnum: AnEnum? = nil + let aNullableEnumEnumVal: Int? = nilOrValue(list[13]) + if let aNullableEnumRawValue = aNullableEnumEnumVal { + aNullableEnum = AnEnum(rawValue: aNullableEnumRawValue)! + } + let aNullableString: String? = nilOrValue(list[14]) + let aNullableObject: Any? = list[15] + + return AllNullableTypesWithoutRecursion( + aNullableBool: aNullableBool, + aNullableInt: aNullableInt, + aNullableInt64: aNullableInt64, + aNullableDouble: aNullableDouble, + aNullableByteArray: aNullableByteArray, + aNullable4ByteArray: aNullable4ByteArray, + aNullable8ByteArray: aNullable8ByteArray, + aNullableFloatArray: aNullableFloatArray, + aNullableList: aNullableList, + aNullableMap: aNullableMap, + nullableNestedList: nullableNestedList, + nullableMapWithAnnotations: nullableMapWithAnnotations, + nullableMapWithObject: nullableMapWithObject, + aNullableEnum: aNullableEnum, + aNullableString: aNullableString, + aNullableObject: aNullableObject + ) + } + func toList() -> [Any?] { + return [ + aNullableBool, + aNullableInt, + aNullableInt64, + aNullableDouble, + aNullableByteArray, + aNullable4ByteArray, + aNullable8ByteArray, + aNullableFloatArray, + aNullableList, + aNullableMap, + nullableNestedList, + nullableMapWithAnnotations, + nullableMapWithObject, + aNullableEnum?.rawValue, + aNullableString, + aNullableObject, + ] + } +} + /// A class for testing nested class handling. /// /// This is needed to test nested nullable and non-nullable classes, @@ -264,23 +348,31 @@ class AllNullableTypes { /// Generated class from Pigeon that represents data sent in messages. struct AllClassesWrapper { var allNullableTypes: AllNullableTypes + var allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nil var allTypes: AllTypes? = nil static func fromList(_ list: [Any?]) -> AllClassesWrapper? { let allNullableTypes = AllNullableTypes.fromList(list[0] as! [Any?])! + var allNullableTypesWithoutRecursion: AllNullableTypesWithoutRecursion? = nil + if let allNullableTypesWithoutRecursionList: [Any?] = nilOrValue(list[1]) { + allNullableTypesWithoutRecursion = AllNullableTypesWithoutRecursion.fromList( + allNullableTypesWithoutRecursionList) + } var allTypes: AllTypes? = nil - if let allTypesList: [Any?] = nilOrValue(list[1]) { + if let allTypesList: [Any?] = nilOrValue(list[2]) { allTypes = AllTypes.fromList(allTypesList) } return AllClassesWrapper( allNullableTypes: allNullableTypes, + allNullableTypesWithoutRecursion: allNullableTypesWithoutRecursion, allTypes: allTypes ) } func toList() -> [Any?] { return [ allNullableTypes.toList(), + allNullableTypesWithoutRecursion?.toList(), allTypes?.toList(), ] } @@ -314,8 +406,10 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader { case 129: return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: - return AllTypes.fromList(self.readValue() as! [Any?]) + return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) case 131: + return AllTypes.fromList(self.readValue() as! [Any?]) + case 132: return TestMessage.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -331,12 +425,15 @@ private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter { } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) - } else if let value = value as? AllTypes { + } else if let value = value as? AllNullableTypesWithoutRecursion { super.writeByte(130) super.writeValue(value.toList()) - } else if let value = value as? TestMessage { + } else if let value = value as? AllTypes { super.writeByte(131) super.writeValue(value.toList()) + } else if let value = value as? TestMessage { + super.writeByte(132) + super.writeValue(value.toList()) } else { super.writeValue(value) } @@ -402,6 +499,9 @@ protocol HostIntegrationCoreApi { func echoRequired(_ anInt: Int64) throws -> Int64 /// Returns the passed object, to test serialization and deserialization. func echo(_ everything: AllNullableTypes?) throws -> AllNullableTypes? + /// Returns the passed object, to test serialization and deserialization. + func echo(_ everything: AllNullableTypesWithoutRecursion?) throws + -> AllNullableTypesWithoutRecursion? /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. func extractNestedNullableString(from wrapper: AllClassesWrapper) throws -> String? @@ -412,6 +512,10 @@ protocol HostIntegrationCoreApi { func sendMultipleNullableTypes( aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String? ) throws -> AllNullableTypes + /// Returns passed in arguments of multiple types. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String? + ) throws -> AllNullableTypesWithoutRecursion /// Returns passed in int. func echo(_ aNullableInt: Int64?) throws -> Int64? /// Returns passed in double. @@ -469,6 +573,10 @@ protocol HostIntegrationCoreApi { func echoAsync( _ everything: AllNullableTypes?, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoAsync( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) /// Returns passed in int asynchronously. func echoAsyncNullable(_ anInt: Int64?, completion: @escaping (Result) -> Void) /// Returns passed in double asynchronously. @@ -501,6 +609,12 @@ protocol HostIntegrationCoreApi { func callFlutterSendMultipleNullableTypes( aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?, completion: @escaping (Result) -> Void) + func callFlutterEcho( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) + func callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?, + completion: @escaping (Result) -> Void) func callFlutterEcho(_ aBool: Bool, completion: @escaping (Result) -> Void) func callFlutterEcho(_ anInt: Int64, completion: @escaping (Result) -> Void) func callFlutterEcho(_ aDouble: Double, completion: @escaping (Result) -> Void) @@ -874,6 +988,25 @@ class HostIntegrationCoreApiSetup { } else { echoAllNullableTypesChannel.setMessageHandler(nil) } + /// Returns the passed object, to test serialization and deserialization. + let echoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAllNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + do { + let result = try api.echo(everythingArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. let extractNestedNullableStringChannel = FlutterBasicMessageChannel( @@ -938,6 +1071,30 @@ class HostIntegrationCoreApiSetup { } else { sendMultipleNullableTypesChannel.setMessageHandler(nil) } + /// Returns passed in arguments of multiple types. + let sendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = + isNullish(args[1]) + ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) + let aNullableStringArg: String? = nilOrValue(args[2]) + do { + let result = try api.sendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + sendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } /// Returns passed in int. let echoNullableIntChannel = FlutterBasicMessageChannel( name: "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoNullableInt", @@ -1438,6 +1595,27 @@ class HostIntegrationCoreApiSetup { } else { echoAsyncNullableAllNullableTypesChannel.setMessageHandler(nil) } + /// Returns the passed object, to test serialization and deserialization. + let echoAsyncNullableAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.echoAsyncNullableAllNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.echoAsync(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + echoAsyncNullableAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } /// Returns passed in int asynchronously. let echoAsyncNullableIntChannel = FlutterBasicMessageChannel( name: @@ -1748,6 +1926,53 @@ class HostIntegrationCoreApiSetup { } else { callFlutterSendMultipleNullableTypesChannel.setMessageHandler(nil) } + let callFlutterEchoAllNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoAllNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let everythingArg: AllNullableTypesWithoutRecursion? = nilOrValue(args[0]) + api.callFlutterEcho(everythingArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterEchoAllNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } + let callFlutterSendMultipleNullableTypesWithoutRecursionChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypesWithoutRecursion", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler { + message, reply in + let args = message as! [Any?] + let aNullableBoolArg: Bool? = nilOrValue(args[0]) + let aNullableIntArg: Int64? = + isNullish(args[1]) + ? nil : (args[1] is Int64? ? args[1] as! Int64? : Int64(args[1] as! Int32)) + let aNullableStringArg: String? = nilOrValue(args[2]) + api.callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: aNullableStringArg + ) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + callFlutterSendMultipleNullableTypesWithoutRecursionChannel.setMessageHandler(nil) + } let callFlutterEchoBoolChannel = FlutterBasicMessageChannel( name: "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi.callFlutterEchoBool", @@ -2078,8 +2303,10 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader { case 129: return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: - return AllTypes.fromList(self.readValue() as! [Any?]) + return AllNullableTypesWithoutRecursion.fromList(self.readValue() as! [Any?]) case 131: + return AllTypes.fromList(self.readValue() as! [Any?]) + case 132: return TestMessage.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -2095,12 +2322,15 @@ private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter { } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) - } else if let value = value as? AllTypes { + } else if let value = value as? AllNullableTypesWithoutRecursion { super.writeByte(130) super.writeValue(value.toList()) - } else if let value = value as? TestMessage { + } else if let value = value as? AllTypes { super.writeByte(131) super.writeValue(value.toList()) + } else if let value = value as? TestMessage { + super.writeByte(132) + super.writeValue(value.toList()) } else { super.writeValue(value) } @@ -2148,6 +2378,17 @@ protocol FlutterIntegrationCoreApiProtocol { aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void) /// Returns the passed boolean, to test serialization and deserialization. func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) /// Returns the passed int, to test serialization and deserialization. @@ -2362,6 +2603,66 @@ class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { } } } + /// Returns the passed object, to test serialization and deserialization. + func echoNullable( + _ everythingArg: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypesWithoutRecursion" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([everythingArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(FlutterError(code: code, message: message, details: details))) + } else { + let result: AllNullableTypesWithoutRecursion? = nilOrValue(listResponse[0]) + completion(.success(result)) + } + } + } + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, + aString aNullableStringArg: String?, + completion: @escaping (Result) -> Void + ) { + let channelName: String = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypesWithoutRecursion" + let channel = FlutterBasicMessageChannel( + name: channelName, binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { + response in + guard let listResponse = response as? [Any?] else { + completion(.failure(createConnectionError(withChannelName: channelName))) + return + } + if listResponse.count > 1 { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(FlutterError(code: code, message: message, details: details))) + } else if listResponse[0] == nil { + completion( + .failure( + FlutterError( + code: "null-error", + message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! AllNullableTypesWithoutRecursion + completion(.success(result)) + } + } + } /// Returns the passed boolean, to test serialization and deserialization. func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { let channelName: String = diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift index 5da16290c7a..01986439465 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift @@ -34,6 +34,11 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { func echo(_ everything: AllNullableTypes?) -> AllNullableTypes? { return everything } + func echo(_ everything: AllNullableTypesWithoutRecursion?) throws + -> AllNullableTypesWithoutRecursion? + { + return everything + } func throwError() throws -> Any? { throw FlutterError(code: "code", message: "message", details: "details") @@ -87,18 +92,6 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return anEnum } - func echoNamedDefault(_ aString: String) throws -> String { - return aString - } - - func echoOptionalDefault(_ aDouble: Double) throws -> Double { - return aDouble - } - - func echoRequired(_ anInt: Int64) throws -> Int64 { - return anInt - } - func extractNestedNullableString(from wrapper: AllClassesWrapper) -> String? { return wrapper.allNullableTypes.aNullableString } @@ -115,6 +108,14 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return someThings } + func sendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String? + ) throws -> AllNullableTypesWithoutRecursion { + let someThings = AllNullableTypesWithoutRecursion( + aNullableBool: aNullableBool, aNullableInt: aNullableInt, aNullableString: aNullableString) + return someThings + } + func echo(_ aNullableInt: Int64?) -> Int64? { return aNullableInt } @@ -139,6 +140,18 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return aNullableObject } + func echoNamedDefault(_ aString: String) throws -> String { + return aString + } + + func echoOptionalDefault(_ aDouble: Double) throws -> Double { + return aDouble + } + + func echoRequired(_ anInt: Int64) throws -> Int64 { + return anInt + } + func echoNullable(_ aNullableList: [Any?]?) throws -> [Any?]? { return aNullableList } @@ -186,6 +199,13 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { completion(.success(everything)) } + func echoAsync( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + completion(.success(everything)) + } + func echoAsync(_ anInt: Int64, completion: @escaping (Result) -> Void) { completion(.success(anInt)) } @@ -331,6 +351,20 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } + func callFlutterEcho( + _ everything: AllNullableTypesWithoutRecursion?, + completion: @escaping (Result) -> Void + ) { + flutterAPI.echoNullable(everything) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + func callFlutterSendMultipleNullableTypes( aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, @@ -351,6 +385,24 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { } } + func callFlutterSendMultipleNullableTypesWithoutRecursion( + aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?, + completion: @escaping (Result) -> Void + ) { + flutterAPI.sendMultipleNullableTypesWithoutRecursion( + aBool: aNullableBool, + anInt: aNullableInt, + aString: aNullableString + ) { response in + switch response { + case .success(let res): + completion(.success(res)) + case .failure(let error): + completion(.failure(error)) + } + } + } + func callFlutterEcho(_ aBool: Bool, completion: @escaping (Result) -> Void) { flutterAPI.echo(aBool) { response in switch response { 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 9ec333bc885..4ac4c57262f 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 @@ -608,14 +608,462 @@ AllNullableTypes AllNullableTypes::FromEncodableList( return decoded; } +// AllNullableTypesWithoutRecursion + +AllNullableTypesWithoutRecursion::AllNullableTypesWithoutRecursion() {} + +AllNullableTypesWithoutRecursion::AllNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const int64_t* a_nullable_int64, const double* a_nullable_double, + const std::vector* a_nullable_byte_array, + const std::vector* a_nullable4_byte_array, + const std::vector* a_nullable8_byte_array, + const std::vector* a_nullable_float_array, + const EncodableList* a_nullable_list, const EncodableMap* a_nullable_map, + const EncodableList* nullable_nested_list, + const EncodableMap* nullable_map_with_annotations, + const EncodableMap* nullable_map_with_object, const AnEnum* a_nullable_enum, + const std::string* a_nullable_string, + const EncodableValue* a_nullable_object) + : a_nullable_bool_(a_nullable_bool ? std::optional(*a_nullable_bool) + : std::nullopt), + a_nullable_int_(a_nullable_int ? std::optional(*a_nullable_int) + : std::nullopt), + a_nullable_int64_(a_nullable_int64 + ? std::optional(*a_nullable_int64) + : std::nullopt), + a_nullable_double_(a_nullable_double + ? std::optional(*a_nullable_double) + : std::nullopt), + a_nullable_byte_array_( + a_nullable_byte_array + ? std::optional>(*a_nullable_byte_array) + : std::nullopt), + a_nullable4_byte_array_( + a_nullable4_byte_array + ? std::optional>(*a_nullable4_byte_array) + : std::nullopt), + a_nullable8_byte_array_( + a_nullable8_byte_array + ? std::optional>(*a_nullable8_byte_array) + : std::nullopt), + a_nullable_float_array_( + a_nullable_float_array + ? std::optional>(*a_nullable_float_array) + : std::nullopt), + a_nullable_list_(a_nullable_list + ? std::optional(*a_nullable_list) + : std::nullopt), + a_nullable_map_(a_nullable_map + ? std::optional(*a_nullable_map) + : std::nullopt), + nullable_nested_list_(nullable_nested_list ? std::optional( + *nullable_nested_list) + : std::nullopt), + nullable_map_with_annotations_( + nullable_map_with_annotations + ? std::optional(*nullable_map_with_annotations) + : std::nullopt), + nullable_map_with_object_( + nullable_map_with_object + ? std::optional(*nullable_map_with_object) + : std::nullopt), + a_nullable_enum_(a_nullable_enum ? std::optional(*a_nullable_enum) + : std::nullopt), + a_nullable_string_(a_nullable_string + ? std::optional(*a_nullable_string) + : std::nullopt), + a_nullable_object_(a_nullable_object + ? std::optional(*a_nullable_object) + : std::nullopt) {} + +const bool* AllNullableTypesWithoutRecursion::a_nullable_bool() const { + return a_nullable_bool_ ? &(*a_nullable_bool_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_bool( + const bool* value_arg) { + a_nullable_bool_ = value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_bool(bool value_arg) { + a_nullable_bool_ = value_arg; +} + +const int64_t* AllNullableTypesWithoutRecursion::a_nullable_int() const { + return a_nullable_int_ ? &(*a_nullable_int_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_int( + const int64_t* value_arg) { + a_nullable_int_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_int(int64_t value_arg) { + a_nullable_int_ = value_arg; +} + +const int64_t* AllNullableTypesWithoutRecursion::a_nullable_int64() const { + return a_nullable_int64_ ? &(*a_nullable_int64_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_int64( + const int64_t* value_arg) { + a_nullable_int64_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_int64(int64_t value_arg) { + a_nullable_int64_ = value_arg; +} + +const double* AllNullableTypesWithoutRecursion::a_nullable_double() const { + return a_nullable_double_ ? &(*a_nullable_double_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_double( + const double* value_arg) { + a_nullable_double_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_double(double value_arg) { + a_nullable_double_ = value_arg; +} + +const std::vector* +AllNullableTypesWithoutRecursion::a_nullable_byte_array() const { + return a_nullable_byte_array_ ? &(*a_nullable_byte_array_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_byte_array( + const std::vector* value_arg) { + a_nullable_byte_array_ = value_arg + ? std::optional>(*value_arg) + : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_byte_array( + const std::vector& value_arg) { + a_nullable_byte_array_ = value_arg; +} + +const std::vector* +AllNullableTypesWithoutRecursion::a_nullable4_byte_array() const { + return a_nullable4_byte_array_ ? &(*a_nullable4_byte_array_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable4_byte_array( + const std::vector* value_arg) { + a_nullable4_byte_array_ = + value_arg ? std::optional>(*value_arg) + : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable4_byte_array( + const std::vector& value_arg) { + a_nullable4_byte_array_ = value_arg; +} + +const std::vector* +AllNullableTypesWithoutRecursion::a_nullable8_byte_array() const { + return a_nullable8_byte_array_ ? &(*a_nullable8_byte_array_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable8_byte_array( + const std::vector* value_arg) { + a_nullable8_byte_array_ = + value_arg ? std::optional>(*value_arg) + : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable8_byte_array( + const std::vector& value_arg) { + a_nullable8_byte_array_ = value_arg; +} + +const std::vector* +AllNullableTypesWithoutRecursion::a_nullable_float_array() const { + return a_nullable_float_array_ ? &(*a_nullable_float_array_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_float_array( + const std::vector* value_arg) { + a_nullable_float_array_ = + value_arg ? std::optional>(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_float_array( + const std::vector& value_arg) { + a_nullable_float_array_ = value_arg; +} + +const EncodableList* AllNullableTypesWithoutRecursion::a_nullable_list() const { + return a_nullable_list_ ? &(*a_nullable_list_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_list( + const EncodableList* value_arg) { + a_nullable_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_list( + const EncodableList& value_arg) { + a_nullable_list_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::a_nullable_map() const { + return a_nullable_map_ ? &(*a_nullable_map_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_map( + const EncodableMap* value_arg) { + a_nullable_map_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_map( + const EncodableMap& value_arg) { + a_nullable_map_ = value_arg; +} + +const EncodableList* AllNullableTypesWithoutRecursion::nullable_nested_list() + const { + return nullable_nested_list_ ? &(*nullable_nested_list_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_nullable_nested_list( + const EncodableList* value_arg) { + nullable_nested_list_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_nullable_nested_list( + const EncodableList& value_arg) { + nullable_nested_list_ = value_arg; +} + +const EncodableMap* +AllNullableTypesWithoutRecursion::nullable_map_with_annotations() const { + return nullable_map_with_annotations_ ? &(*nullable_map_with_annotations_) + : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_nullable_map_with_annotations( + const EncodableMap* value_arg) { + nullable_map_with_annotations_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_nullable_map_with_annotations( + const EncodableMap& value_arg) { + nullable_map_with_annotations_ = value_arg; +} + +const EncodableMap* AllNullableTypesWithoutRecursion::nullable_map_with_object() + const { + return nullable_map_with_object_ ? &(*nullable_map_with_object_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_nullable_map_with_object( + const EncodableMap* value_arg) { + nullable_map_with_object_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_nullable_map_with_object( + const EncodableMap& value_arg) { + nullable_map_with_object_ = value_arg; +} + +const AnEnum* AllNullableTypesWithoutRecursion::a_nullable_enum() const { + return a_nullable_enum_ ? &(*a_nullable_enum_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_enum( + const AnEnum* value_arg) { + a_nullable_enum_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_enum( + const AnEnum& value_arg) { + a_nullable_enum_ = value_arg; +} + +const std::string* AllNullableTypesWithoutRecursion::a_nullable_string() const { + return a_nullable_string_ ? &(*a_nullable_string_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_string( + const std::string_view* value_arg) { + a_nullable_string_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_string( + std::string_view value_arg) { + a_nullable_string_ = value_arg; +} + +const EncodableValue* AllNullableTypesWithoutRecursion::a_nullable_object() + const { + return a_nullable_object_ ? &(*a_nullable_object_) : nullptr; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_object( + const EncodableValue* value_arg) { + a_nullable_object_ = + value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void AllNullableTypesWithoutRecursion::set_a_nullable_object( + const EncodableValue& value_arg) { + a_nullable_object_ = value_arg; +} + +EncodableList AllNullableTypesWithoutRecursion::ToEncodableList() const { + EncodableList list; + list.reserve(16); + list.push_back(a_nullable_bool_ ? EncodableValue(*a_nullable_bool_) + : EncodableValue()); + list.push_back(a_nullable_int_ ? EncodableValue(*a_nullable_int_) + : EncodableValue()); + list.push_back(a_nullable_int64_ ? EncodableValue(*a_nullable_int64_) + : EncodableValue()); + list.push_back(a_nullable_double_ ? EncodableValue(*a_nullable_double_) + : EncodableValue()); + list.push_back(a_nullable_byte_array_ + ? EncodableValue(*a_nullable_byte_array_) + : EncodableValue()); + list.push_back(a_nullable4_byte_array_ + ? EncodableValue(*a_nullable4_byte_array_) + : EncodableValue()); + list.push_back(a_nullable8_byte_array_ + ? EncodableValue(*a_nullable8_byte_array_) + : EncodableValue()); + list.push_back(a_nullable_float_array_ + ? EncodableValue(*a_nullable_float_array_) + : EncodableValue()); + list.push_back(a_nullable_list_ ? EncodableValue(*a_nullable_list_) + : EncodableValue()); + list.push_back(a_nullable_map_ ? EncodableValue(*a_nullable_map_) + : EncodableValue()); + list.push_back(nullable_nested_list_ ? EncodableValue(*nullable_nested_list_) + : EncodableValue()); + list.push_back(nullable_map_with_annotations_ + ? EncodableValue(*nullable_map_with_annotations_) + : EncodableValue()); + list.push_back(nullable_map_with_object_ + ? EncodableValue(*nullable_map_with_object_) + : EncodableValue()); + list.push_back(a_nullable_enum_ ? EncodableValue((int)(*a_nullable_enum_)) + : EncodableValue()); + list.push_back(a_nullable_string_ ? EncodableValue(*a_nullable_string_) + : EncodableValue()); + list.push_back(a_nullable_object_ ? *a_nullable_object_ : EncodableValue()); + return list; +} + +AllNullableTypesWithoutRecursion +AllNullableTypesWithoutRecursion::FromEncodableList(const EncodableList& list) { + AllNullableTypesWithoutRecursion decoded; + auto& encodable_a_nullable_bool = list[0]; + if (!encodable_a_nullable_bool.IsNull()) { + decoded.set_a_nullable_bool(std::get(encodable_a_nullable_bool)); + } + auto& encodable_a_nullable_int = list[1]; + if (!encodable_a_nullable_int.IsNull()) { + decoded.set_a_nullable_int(encodable_a_nullable_int.LongValue()); + } + auto& encodable_a_nullable_int64 = list[2]; + if (!encodable_a_nullable_int64.IsNull()) { + decoded.set_a_nullable_int64(encodable_a_nullable_int64.LongValue()); + } + auto& encodable_a_nullable_double = list[3]; + if (!encodable_a_nullable_double.IsNull()) { + decoded.set_a_nullable_double( + std::get(encodable_a_nullable_double)); + } + auto& encodable_a_nullable_byte_array = list[4]; + if (!encodable_a_nullable_byte_array.IsNull()) { + decoded.set_a_nullable_byte_array( + std::get>(encodable_a_nullable_byte_array)); + } + auto& encodable_a_nullable4_byte_array = list[5]; + if (!encodable_a_nullable4_byte_array.IsNull()) { + decoded.set_a_nullable4_byte_array( + std::get>(encodable_a_nullable4_byte_array)); + } + auto& encodable_a_nullable8_byte_array = list[6]; + if (!encodable_a_nullable8_byte_array.IsNull()) { + decoded.set_a_nullable8_byte_array( + std::get>(encodable_a_nullable8_byte_array)); + } + auto& encodable_a_nullable_float_array = list[7]; + if (!encodable_a_nullable_float_array.IsNull()) { + decoded.set_a_nullable_float_array( + std::get>(encodable_a_nullable_float_array)); + } + auto& encodable_a_nullable_list = list[8]; + if (!encodable_a_nullable_list.IsNull()) { + decoded.set_a_nullable_list( + std::get(encodable_a_nullable_list)); + } + auto& encodable_a_nullable_map = list[9]; + if (!encodable_a_nullable_map.IsNull()) { + decoded.set_a_nullable_map( + std::get(encodable_a_nullable_map)); + } + auto& encodable_nullable_nested_list = list[10]; + if (!encodable_nullable_nested_list.IsNull()) { + decoded.set_nullable_nested_list( + std::get(encodable_nullable_nested_list)); + } + auto& encodable_nullable_map_with_annotations = list[11]; + if (!encodable_nullable_map_with_annotations.IsNull()) { + decoded.set_nullable_map_with_annotations( + std::get(encodable_nullable_map_with_annotations)); + } + auto& encodable_nullable_map_with_object = list[12]; + if (!encodable_nullable_map_with_object.IsNull()) { + decoded.set_nullable_map_with_object( + std::get(encodable_nullable_map_with_object)); + } + auto& encodable_a_nullable_enum = list[13]; + if (!encodable_a_nullable_enum.IsNull()) { + decoded.set_a_nullable_enum( + (AnEnum)(std::get(encodable_a_nullable_enum))); + } + auto& encodable_a_nullable_string = list[14]; + if (!encodable_a_nullable_string.IsNull()) { + decoded.set_a_nullable_string( + std::get(encodable_a_nullable_string)); + } + auto& encodable_a_nullable_object = list[15]; + if (!encodable_a_nullable_object.IsNull()) { + decoded.set_a_nullable_object(encodable_a_nullable_object); + } + return decoded; +} + // AllClassesWrapper AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types) : all_nullable_types_(all_nullable_types) {} AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types, + const AllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion, const AllTypes* all_types) : all_nullable_types_(all_nullable_types), + all_nullable_types_without_recursion_( + all_nullable_types_without_recursion + ? std::optional( + *all_nullable_types_without_recursion) + : std::nullopt), all_types_(all_types ? std::optional(*all_types) : std::nullopt) {} @@ -628,6 +1076,25 @@ void AllClassesWrapper::set_all_nullable_types( all_nullable_types_ = value_arg; } +const AllNullableTypesWithoutRecursion* +AllClassesWrapper::all_nullable_types_without_recursion() const { + return all_nullable_types_without_recursion_ + ? &(*all_nullable_types_without_recursion_) + : nullptr; +} + +void AllClassesWrapper::set_all_nullable_types_without_recursion( + const AllNullableTypesWithoutRecursion* value_arg) { + all_nullable_types_without_recursion_ = + value_arg ? std::optional(*value_arg) + : std::nullopt; +} + +void AllClassesWrapper::set_all_nullable_types_without_recursion( + const AllNullableTypesWithoutRecursion& value_arg) { + all_nullable_types_without_recursion_ = value_arg; +} + const AllTypes* AllClassesWrapper::all_types() const { return all_types_ ? &(*all_types_) : nullptr; } @@ -642,8 +1109,13 @@ void AllClassesWrapper::set_all_types(const AllTypes& value_arg) { EncodableList AllClassesWrapper::ToEncodableList() const { EncodableList list; - list.reserve(2); + list.reserve(3); list.push_back(EncodableValue(all_nullable_types_.ToEncodableList())); + list.push_back( + all_nullable_types_without_recursion_ + ? EncodableValue( + all_nullable_types_without_recursion_->ToEncodableList()) + : EncodableValue()); list.push_back(all_types_ ? EncodableValue(all_types_->ToEncodableList()) : EncodableValue()); return list; @@ -653,7 +1125,14 @@ AllClassesWrapper AllClassesWrapper::FromEncodableList( const EncodableList& list) { AllClassesWrapper decoded( AllNullableTypes::FromEncodableList(std::get(list[0]))); - auto& encodable_all_types = list[1]; + auto& encodable_all_nullable_types_without_recursion = list[1]; + if (!encodable_all_nullable_types_without_recursion.IsNull()) { + decoded.set_all_nullable_types_without_recursion( + AllNullableTypesWithoutRecursion::FromEncodableList( + std::get( + encodable_all_nullable_types_without_recursion))); + } + auto& encodable_all_types = list[2]; if (!encodable_all_types.IsNull()) { decoded.set_all_types(AllTypes::FromEncodableList( std::get(encodable_all_types))); @@ -711,9 +1190,13 @@ EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType( return CustomEncodableValue(AllNullableTypes::FromEncodableList( std::get(ReadValue(stream)))); case 130: + return CustomEncodableValue( + AllNullableTypesWithoutRecursion::FromEncodableList( + std::get(ReadValue(stream)))); + case 131: return CustomEncodableValue(AllTypes::FromEncodableList( std::get(ReadValue(stream)))); - case 131: + case 132: return CustomEncodableValue(TestMessage::FromEncodableList( std::get(ReadValue(stream)))); default: @@ -740,15 +1223,23 @@ void HostIntegrationCoreApiCodecSerializer::WriteValue( stream); return; } - if (custom_value->type() == typeid(AllTypes)) { + if (custom_value->type() == typeid(AllNullableTypesWithoutRecursion)) { stream->WriteByte(130); + WriteValue(EncodableValue(std::any_cast( + *custom_value) + .ToEncodableList()), + stream); + return; + } + if (custom_value->type() == typeid(AllTypes)) { + stream->WriteByte(131); WriteValue(EncodableValue( std::any_cast(*custom_value).ToEncodableList()), stream); return; } if (custom_value->type() == typeid(TestMessage)) { - stream->WriteByte(131); + stream->WriteByte(132); WriteValue( EncodableValue( std::any_cast(*custom_value).ToEncodableList()), @@ -1380,11 +1871,51 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_everything_arg = args.at(0); const auto* everything_arg = - &(std::any_cast( + &(std::any_cast( + std::get( + encodable_everything_arg))); + ErrorOr> output = + api->EchoAllNullableTypes(everything_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back( + CustomEncodableValue(std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAllNullableTypesWithoutRecursion", + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + &(std::any_cast( std::get( encodable_everything_arg))); - ErrorOr> output = - api->EchoAllNullableTypes(everything_arg); + ErrorOr> output = + api->EchoAllNullableTypesWithoutRecursion(everything_arg); if (output.has_error()) { reply(WrapError(output.error())); return; @@ -1527,6 +2058,53 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, channel.SetMessageHandler(nullptr); } } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "sendMultipleNullableTypesWithoutRecursion", + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_nullable_bool_arg = args.at(0); + const auto* a_nullable_bool_arg = + std::get_if(&encodable_a_nullable_bool_arg); + const auto& encodable_a_nullable_int_arg = args.at(1); + const int64_t a_nullable_int_arg_value = + encodable_a_nullable_int_arg.IsNull() + ? 0 + : encodable_a_nullable_int_arg.LongValue(); + const auto* a_nullable_int_arg = + encodable_a_nullable_int_arg.IsNull() + ? nullptr + : &a_nullable_int_arg_value; + const auto& encodable_a_nullable_string_arg = args.at(2); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + ErrorOr output = + api->SendMultipleNullableTypesWithoutRecursion( + a_nullable_bool_arg, a_nullable_int_arg, + a_nullable_string_arg); + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." @@ -2490,6 +3068,50 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, channel.SetMessageHandler(nullptr); } } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "echoAsyncNullableAllNullableTypesWithoutRecursion", + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + &(std::any_cast( + std::get( + encodable_everything_arg))); + api->EchoAsyncNullableAllNullableTypesWithoutRecursion( + everything_arg, + [reply]( + ErrorOr>&& + output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back(CustomEncodableValue( + std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." @@ -3077,6 +3699,98 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, channel.SetMessageHandler(nullptr); } } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterEchoAllNullableTypesWithoutRecursion", + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_everything_arg = args.at(0); + const auto* everything_arg = + &(std::any_cast( + std::get( + encodable_everything_arg))); + api->CallFlutterEchoAllNullableTypesWithoutRecursion( + everything_arg, + [reply]( + ErrorOr>&& + output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + auto output_optional = std::move(output).TakeValue(); + if (output_optional) { + wrapped.push_back(CustomEncodableValue( + std::move(output_optional).value())); + } else { + wrapped.push_back(EncodableValue()); + } + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } + { + BasicMessageChannel<> channel( + binary_messenger, + "dev.flutter.pigeon.pigeon_integration_tests.HostIntegrationCoreApi." + "callFlutterSendMultipleNullableTypesWithoutRecursion", + &GetCodec()); + if (api != nullptr) { + channel.SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_a_nullable_bool_arg = args.at(0); + const auto* a_nullable_bool_arg = + std::get_if(&encodable_a_nullable_bool_arg); + const auto& encodable_a_nullable_int_arg = args.at(1); + const int64_t a_nullable_int_arg_value = + encodable_a_nullable_int_arg.IsNull() + ? 0 + : encodable_a_nullable_int_arg.LongValue(); + const auto* a_nullable_int_arg = + encodable_a_nullable_int_arg.IsNull() + ? nullptr + : &a_nullable_int_arg_value; + const auto& encodable_a_nullable_string_arg = args.at(2); + const auto* a_nullable_string_arg = + std::get_if(&encodable_a_nullable_string_arg); + api->CallFlutterSendMultipleNullableTypesWithoutRecursion( + a_nullable_bool_arg, a_nullable_int_arg, + a_nullable_string_arg, + [reply](ErrorOr&& output) { + if (output.has_error()) { + reply(WrapError(output.error())); + return; + } + EncodableList wrapped; + wrapped.push_back( + CustomEncodableValue(std::move(output).TakeValue())); + reply(EncodableValue(std::move(wrapped))); + }); + } catch (const std::exception& exception) { + reply(WrapError(exception.what())); + } + }); + } else { + channel.SetMessageHandler(nullptr); + } + } { BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.pigeon_integration_tests." @@ -3732,9 +4446,13 @@ EncodableValue FlutterIntegrationCoreApiCodecSerializer::ReadValueOfType( return CustomEncodableValue(AllNullableTypes::FromEncodableList( std::get(ReadValue(stream)))); case 130: + return CustomEncodableValue( + AllNullableTypesWithoutRecursion::FromEncodableList( + std::get(ReadValue(stream)))); + case 131: return CustomEncodableValue(AllTypes::FromEncodableList( std::get(ReadValue(stream)))); - case 131: + case 132: return CustomEncodableValue(TestMessage::FromEncodableList( std::get(ReadValue(stream)))); default: @@ -3761,15 +4479,23 @@ void FlutterIntegrationCoreApiCodecSerializer::WriteValue( stream); return; } - if (custom_value->type() == typeid(AllTypes)) { + if (custom_value->type() == typeid(AllNullableTypesWithoutRecursion)) { stream->WriteByte(130); + WriteValue(EncodableValue(std::any_cast( + *custom_value) + .ToEncodableList()), + stream); + return; + } + if (custom_value->type() == typeid(AllTypes)) { + stream->WriteByte(131); WriteValue(EncodableValue( std::any_cast(*custom_value).ToEncodableList()), stream); return; } if (custom_value->type() == typeid(TestMessage)) { - stream->WriteByte(131); + stream->WriteByte(132); WriteValue( EncodableValue( std::any_cast(*custom_value).ToEncodableList()), @@ -4005,6 +4731,88 @@ void FlutterIntegrationCoreApi::SendMultipleNullableTypes( }); } +void FlutterIntegrationCoreApi::EchoAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "echoAllNullableTypesWithoutRecursion"; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + everything_arg ? CustomEncodableValue(*everything_arg) : EncodableValue(), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto* return_value = + &(std::any_cast( + std::get(list_return_value->at(0)))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + +void FlutterIntegrationCoreApi::SendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool_arg, const int64_t* a_nullable_int_arg, + const std::string* a_nullable_string_arg, + std::function&& on_success, + std::function&& on_error) { + const std::string channel_name = + "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi." + "sendMultipleNullableTypesWithoutRecursion"; + BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + a_nullable_bool_arg ? EncodableValue(*a_nullable_bool_arg) + : EncodableValue(), + a_nullable_int_arg ? EncodableValue(*a_nullable_int_arg) + : EncodableValue(), + a_nullable_string_arg ? EncodableValue(*a_nullable_string_arg) + : EncodableValue(), + }); + channel.Send( + encoded_api_arguments, [channel_name, on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error( + FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::any_cast( + std::get(list_return_value->at(0))); + on_success(return_value); + } + } else { + on_error(CreateConnectionError(channel_name)); + } + }); +} + void FlutterIntegrationCoreApi::EchoBool( bool a_bool_arg, std::function&& on_success, std::function&& on_error) { 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 0140bbd68e5..13f8f0fba1f 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 @@ -287,6 +287,128 @@ class AllNullableTypes { std::optional all_nullable_types_; }; +// Generated class from Pigeon that represents data sent in messages. +class AllNullableTypesWithoutRecursion { + public: + // Constructs an object setting all non-nullable fields. + AllNullableTypesWithoutRecursion(); + + // Constructs an object setting all fields. + explicit AllNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const int64_t* a_nullable_int64, const double* a_nullable_double, + const std::vector* a_nullable_byte_array, + const std::vector* a_nullable4_byte_array, + const std::vector* a_nullable8_byte_array, + const std::vector* a_nullable_float_array, + const flutter::EncodableList* a_nullable_list, + const flutter::EncodableMap* a_nullable_map, + const flutter::EncodableList* nullable_nested_list, + const flutter::EncodableMap* nullable_map_with_annotations, + const flutter::EncodableMap* nullable_map_with_object, + const AnEnum* a_nullable_enum, const std::string* a_nullable_string, + const flutter::EncodableValue* a_nullable_object); + + const bool* a_nullable_bool() const; + void set_a_nullable_bool(const bool* value_arg); + void set_a_nullable_bool(bool value_arg); + + const int64_t* a_nullable_int() const; + void set_a_nullable_int(const int64_t* value_arg); + void set_a_nullable_int(int64_t value_arg); + + const int64_t* a_nullable_int64() const; + void set_a_nullable_int64(const int64_t* value_arg); + void set_a_nullable_int64(int64_t value_arg); + + const double* a_nullable_double() const; + void set_a_nullable_double(const double* value_arg); + void set_a_nullable_double(double value_arg); + + const std::vector* a_nullable_byte_array() const; + void set_a_nullable_byte_array(const std::vector* value_arg); + void set_a_nullable_byte_array(const std::vector& value_arg); + + const std::vector* a_nullable4_byte_array() const; + void set_a_nullable4_byte_array(const std::vector* value_arg); + void set_a_nullable4_byte_array(const std::vector& value_arg); + + const std::vector* a_nullable8_byte_array() const; + void set_a_nullable8_byte_array(const std::vector* value_arg); + void set_a_nullable8_byte_array(const std::vector& value_arg); + + const std::vector* a_nullable_float_array() const; + void set_a_nullable_float_array(const std::vector* value_arg); + void set_a_nullable_float_array(const std::vector& value_arg); + + const flutter::EncodableList* a_nullable_list() const; + void set_a_nullable_list(const flutter::EncodableList* value_arg); + void set_a_nullable_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableMap* a_nullable_map() const; + void set_a_nullable_map(const flutter::EncodableMap* value_arg); + void set_a_nullable_map(const flutter::EncodableMap& value_arg); + + const flutter::EncodableList* nullable_nested_list() const; + void set_nullable_nested_list(const flutter::EncodableList* value_arg); + void set_nullable_nested_list(const flutter::EncodableList& value_arg); + + const flutter::EncodableMap* nullable_map_with_annotations() const; + void set_nullable_map_with_annotations( + const flutter::EncodableMap* value_arg); + void set_nullable_map_with_annotations( + const flutter::EncodableMap& value_arg); + + const flutter::EncodableMap* nullable_map_with_object() const; + void set_nullable_map_with_object(const flutter::EncodableMap* value_arg); + void set_nullable_map_with_object(const flutter::EncodableMap& value_arg); + + const AnEnum* a_nullable_enum() const; + void set_a_nullable_enum(const AnEnum* value_arg); + void set_a_nullable_enum(const AnEnum& value_arg); + + const std::string* a_nullable_string() const; + void set_a_nullable_string(const std::string_view* value_arg); + void set_a_nullable_string(std::string_view value_arg); + + const flutter::EncodableValue* a_nullable_object() const; + void set_a_nullable_object(const flutter::EncodableValue* value_arg); + void set_a_nullable_object(const flutter::EncodableValue& value_arg); + + private: + static AllNullableTypesWithoutRecursion FromEncodableList( + const flutter::EncodableList& list); + flutter::EncodableList ToEncodableList() const; + friend class AllClassesWrapper; + friend class HostIntegrationCoreApi; + friend class HostIntegrationCoreApiCodecSerializer; + friend class FlutterIntegrationCoreApi; + friend class FlutterIntegrationCoreApiCodecSerializer; + friend class HostTrivialApi; + friend class HostTrivialApiCodecSerializer; + friend class HostSmallApi; + friend class HostSmallApiCodecSerializer; + friend class FlutterSmallApi; + friend class FlutterSmallApiCodecSerializer; + friend class CoreTestsTest; + std::optional a_nullable_bool_; + std::optional a_nullable_int_; + std::optional a_nullable_int64_; + std::optional a_nullable_double_; + std::optional> a_nullable_byte_array_; + std::optional> a_nullable4_byte_array_; + std::optional> a_nullable8_byte_array_; + std::optional> a_nullable_float_array_; + std::optional a_nullable_list_; + std::optional a_nullable_map_; + std::optional nullable_nested_list_; + std::optional nullable_map_with_annotations_; + std::optional nullable_map_with_object_; + std::optional a_nullable_enum_; + std::optional a_nullable_string_; + std::optional a_nullable_object_; +}; + // A class for testing nested class handling. // // This is needed to test nested nullable and non-nullable classes, @@ -301,11 +423,20 @@ class AllClassesWrapper { // Constructs an object setting all fields. explicit AllClassesWrapper(const AllNullableTypes& all_nullable_types, + const AllNullableTypesWithoutRecursion* + all_nullable_types_without_recursion, const AllTypes* all_types); const AllNullableTypes& all_nullable_types() const; void set_all_nullable_types(const AllNullableTypes& value_arg); + const AllNullableTypesWithoutRecursion* all_nullable_types_without_recursion() + const; + void set_all_nullable_types_without_recursion( + const AllNullableTypesWithoutRecursion* value_arg); + void set_all_nullable_types_without_recursion( + const AllNullableTypesWithoutRecursion& value_arg); + const AllTypes* all_types() const; void set_all_types(const AllTypes* value_arg); void set_all_types(const AllTypes& value_arg); @@ -326,6 +457,8 @@ class AllClassesWrapper { friend class FlutterSmallApiCodecSerializer; friend class CoreTestsTest; AllNullableTypes all_nullable_types_; + std::optional + all_nullable_types_without_recursion_; std::optional all_types_; }; @@ -436,6 +569,10 @@ class HostIntegrationCoreApi { // Returns the passed object, to test serialization and deserialization. virtual ErrorOr> EchoAllNullableTypes( const AllNullableTypes* everything) = 0; + // Returns the passed object, to test serialization and deserialization. + virtual ErrorOr> + EchoAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything) = 0; // Returns the inner `aString` value from the wrapped object, to test // sending of nested objects. virtual ErrorOr> ExtractNestedNullableString( @@ -448,6 +585,11 @@ class HostIntegrationCoreApi { virtual ErrorOr SendMultipleNullableTypes( const bool* a_nullable_bool, const int64_t* a_nullable_int, const std::string* a_nullable_string) = 0; + // Returns passed in arguments of multiple types. + virtual ErrorOr + SendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string) = 0; // Returns passed in int. virtual ErrorOr> EchoNullableInt( const int64_t* a_nullable_int) = 0; @@ -540,6 +682,12 @@ class HostIntegrationCoreApi { const AllNullableTypes* everything, std::function> reply)> result) = 0; + // Returns the passed object, to test serialization and deserialization. + virtual void EchoAsyncNullableAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything, + std::function< + void(ErrorOr> reply)> + result) = 0; // Returns passed in int asynchronously. virtual void EchoAsyncNullableInt( const int64_t* an_int, @@ -602,6 +750,16 @@ class HostIntegrationCoreApi { const bool* a_nullable_bool, const int64_t* a_nullable_int, const std::string* a_nullable_string, std::function reply)> result) = 0; + virtual void CallFlutterEchoAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything, + std::function< + void(ErrorOr> reply)> + result) = 0; + virtual void CallFlutterSendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string, + std::function reply)> + result) = 0; virtual void CallFlutterEchoBool( bool a_bool, std::function reply)> result) = 0; virtual void CallFlutterEchoInt( @@ -718,6 +876,19 @@ class FlutterIntegrationCoreApi { const std::string* a_nullable_string, std::function&& on_success, std::function&& on_error); + // Returns the passed object, to test serialization and deserialization. + void EchoAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything, + std::function&& on_success, + std::function&& on_error); + // Returns passed in arguments of multiple types. + // + // Tests multiple-arity FlutterApi handling. + void SendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string, + std::function&& on_success, + std::function&& on_error); // Returns the passed boolean, to test serialization and deserialization. void EchoBool(bool a_bool, std::function&& on_success, std::function&& on_error); diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp index 46535b3be80..8069938e1b2 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp @@ -18,6 +18,7 @@ namespace test_plugin { using core_tests_pigeontest::AllClassesWrapper; using core_tests_pigeontest::AllNullableTypes; +using core_tests_pigeontest::AllNullableTypesWithoutRecursion; using core_tests_pigeontest::AllTypes; using core_tests_pigeontest::AnEnum; using core_tests_pigeontest::ErrorOr; @@ -58,6 +59,15 @@ ErrorOr> TestPlugin::EchoAllNullableTypes( return *everything; } +ErrorOr> +TestPlugin::EchoAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything) { + if (!everything) { + return std::nullopt; + } + return *everything; +} + ErrorOr> TestPlugin::ThrowError() { return FlutterError("An error"); } @@ -157,6 +167,24 @@ ErrorOr TestPlugin::SendMultipleNullableTypes( return someTypes; }; +ErrorOr +TestPlugin::SendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string) { + AllNullableTypesWithoutRecursion someTypes; + someTypes.set_a_nullable_bool(a_nullable_bool); + someTypes.set_a_nullable_int(a_nullable_int); + // The string pointer can't be passed through directly since the setter for + // a string takes a std::string_view rather than std::string so the pointer + // types don't match. + if (a_nullable_string) { + someTypes.set_a_nullable_string(*a_nullable_string); + } else { + someTypes.set_a_nullable_string(nullptr); + } + return someTypes; +}; + ErrorOr> TestPlugin::EchoNullableInt( const int64_t* a_nullable_int) { if (!a_nullable_int) { @@ -328,6 +356,16 @@ void TestPlugin::EchoAsyncNullableAllNullableTypes( : std::nullopt); } +void TestPlugin::EchoAsyncNullableAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything, + std::function< + void(ErrorOr> reply)> + result) { + result(everything + ? std::optional(*everything) + : std::nullopt); +} + void TestPlugin::EchoAsyncNullableInt( const int64_t* an_int, std::function> reply)> result) { @@ -437,6 +475,31 @@ void TestPlugin::CallFlutterSendMultipleNullableTypes( [result](const FlutterError& error) { result(error); }); } +void TestPlugin::CallFlutterEchoAllNullableTypesWithoutRecursion( + const AllNullableTypesWithoutRecursion* everything, + std::function< + void(ErrorOr> reply)> + result) { + flutter_api_->EchoAllNullableTypesWithoutRecursion( + everything, + [result](const AllNullableTypesWithoutRecursion* echo) { + result(echo ? std::optional(*echo) + : std::nullopt); + }, + [result](const FlutterError& error) { result(error); }); +} + +void TestPlugin::CallFlutterSendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string, + std::function reply)> + result) { + flutter_api_->SendMultipleNullableTypes( + a_nullable_bool, a_nullable_int, a_nullable_string, + [result](const AllNullableTypesWithoutRecursion& echo) { result(echo); }, + [result](const FlutterError& error) { result(error); }); +} + void TestPlugin::CallFlutterEchoBool( bool a_bool, std::function reply)> result) { flutter_api_->EchoBool( diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h index e9fd9c6f2de..372f7440d53 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h @@ -39,6 +39,11 @@ class TestPlugin : public flutter::Plugin, std::optional> EchoAllNullableTypes( const core_tests_pigeontest::AllNullableTypes* everything) override; + core_tests_pigeontest::ErrorOr< + std::optional> + EchoAllNullableTypesWithoutRecursion( + const core_tests_pigeontest::AllNullableTypesWithoutRecursion* everything) + override; core_tests_pigeontest::ErrorOr> ThrowError() override; std::optional ThrowErrorFromVoid() @@ -78,6 +83,11 @@ class TestPlugin : public flutter::Plugin, SendMultipleNullableTypes(const bool* a_nullable_bool, const int64_t* a_nullable_int, const std::string* a_nullable_string) override; + core_tests_pigeontest::ErrorOr< + core_tests_pigeontest::AllNullableTypesWithoutRecursion> + SendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string) override; core_tests_pigeontest::ErrorOr> EchoNullableInt( const int64_t* a_nullable_int) override; core_tests_pigeontest::ErrorOr> EchoNullableDouble( @@ -130,6 +140,13 @@ class TestPlugin : public flutter::Plugin, std::optional> reply)> result) override; + void EchoAsyncNullableAllNullableTypesWithoutRecursion( + const core_tests_pigeontest::AllNullableTypesWithoutRecursion* everything, + std::function< + void(core_tests_pigeontest::ErrorOr> + reply)> + result) override; void EchoAsyncInt( int64_t an_int, std::function reply)> result) @@ -253,6 +270,21 @@ class TestPlugin : public flutter::Plugin, core_tests_pigeontest::AllNullableTypes> reply)> result) override; + void CallFlutterEchoAllNullableTypesWithoutRecursion( + const core_tests_pigeontest::AllNullableTypesWithoutRecursion* everything, + std::function< + void(core_tests_pigeontest::ErrorOr> + reply)> + result) override; + void CallFlutterSendMultipleNullableTypesWithoutRecursion( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string, + std::function< + void(core_tests_pigeontest::ErrorOr< + core_tests_pigeontest::AllNullableTypesWithoutRecursion> + reply)> + result) override; void CallFlutterEchoBool( bool a_bool, std::function reply)> result) From a992a23223b8fd9fbdd5d1b71826f84756278cd3 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 19:31:59 -0700 Subject: [PATCH 08/16] @objc annotation --- packages/pigeon/lib/ast.dart | 6 ++++++ packages/pigeon/lib/pigeon_lib.dart | 8 ++++++++ packages/pigeon/lib/swift_generator.dart | 7 ++++++- packages/pigeon/pigeons/core_tests.dart | 1 + .../test_plugin/ios/Classes/CoreTests.gen.swift | 3 ++- .../test_plugin/macos/Classes/CoreTests.gen.swift | 3 ++- 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index 08eef8cc6c7..c2083f7f952 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -639,6 +639,7 @@ class Class extends Node { Class({ required this.name, required this.fields, + this.isSwiftObjcInteropClass = false, this.isSwiftClass = false, this.documentationComments = const [], }); @@ -649,6 +650,11 @@ class Class extends Node { /// All the fields contained in the class. List fields; + /// Determines whether the defined class should inherit from NSObject in Swift. + /// + /// Defaults to false. + bool isSwiftObjcInteropClass; + /// Determines whether the defined class should be represented as a struct or /// a class in Swift generation. /// diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index addce55d54a..8dad9cb6337 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -183,6 +183,12 @@ class SwiftClass { const SwiftClass(); } +/// Metadata to annotate data classes to be defined as inheriting from NSObject. +class SwiftObjcInteropClass { + /// Constructor. + const SwiftObjcInteropClass(); +} + /// Type of TaskQueue which determines how handlers are dispatched for /// HostApi's. enum TaskQueueType { @@ -1557,6 +1563,8 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { name: node.name.lexeme, fields: [], isSwiftClass: _hasMetadata(node.metadata, 'SwiftClass'), + isSwiftObjcInteropClass: + _hasMetadata(node.metadata, 'SwiftObjcInteropClass'), documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index f9857b99194..af868099ae4 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -126,7 +126,12 @@ class SwiftGenerator extends StructuredGenerator { generatorComments: generatedComments); if (classDefinition.isSwiftClass) { - indent.write('class ${classDefinition.name} '); + String inheritNSObject = ''; + if (classDefinition.isSwiftObjcInteropClass) { + inheritNSObject = ': NSObject'; + indent.writeln('@objc'); + } + indent.write('class ${classDefinition.name}$inheritNSObject '); } else { indent.write('struct ${classDefinition.name} '); } diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index 3fd036f9c96..8c5fe8a8edb 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -49,6 +49,7 @@ class AllTypes { /// A class containing all supported nullable types. @SwiftClass() +@SwiftObjcInteropClass() class AllNullableTypes { AllNullableTypes( this.aNullableBool, diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 7b99f400ced..2e89f08bf9b 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -128,7 +128,8 @@ struct AllTypes { /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -class AllNullableTypes { +@objc +class AllNullableTypes: NSObject { init( aNullableBool: Bool? = nil, aNullableInt: Int64? = nil, diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 7b99f400ced..2e89f08bf9b 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -128,7 +128,8 @@ struct AllTypes { /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -class AllNullableTypes { +@objc +class AllNullableTypes: NSObject { init( aNullableBool: Bool? = nil, aNullableInt: Int64? = nil, From 73935b962faf581f2244daa67804de3a8fa48a8b Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 21 Mar 2024 21:01:58 -0700 Subject: [PATCH 09/16] fix android unit test bug, merge annotations, one windows fix --- packages/pigeon/lib/pigeon_lib.dart | 18 ++++++++++-------- packages/pigeon/pigeons/core_tests.dart | 3 +-- .../example/test_plugin/AllDatatypesTest.kt | 1 + .../test_plugin/windows/test_plugin.cpp | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 8dad9cb6337..420923bc775 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -180,13 +180,10 @@ class SwiftFunction { /// Metadata to annotate data classes to be defined as class in Swift output. class SwiftClass { /// Constructor. - const SwiftClass(); -} + const SwiftClass({this.inheritNSObject = false}); -/// Metadata to annotate data classes to be defined as inheriting from NSObject. -class SwiftObjcInteropClass { - /// Constructor. - const SwiftObjcInteropClass(); + /// Whether to define data class as inheriting from NSObject with `@objc` annotation. + final bool inheritNSObject; } /// Type of TaskQueue which determines how handlers are dispatched for @@ -1563,8 +1560,13 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { name: node.name.lexeme, fields: [], isSwiftClass: _hasMetadata(node.metadata, 'SwiftClass'), - isSwiftObjcInteropClass: - _hasMetadata(node.metadata, 'SwiftObjcInteropClass'), + isSwiftObjcInteropClass: _findMetadata(node.metadata, 'SwiftClass') + ?.arguments + ?.arguments + .first + .toString() + .contains('true') ?? + false, documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index 8c5fe8a8edb..e0eceaca4dd 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -48,8 +48,7 @@ class AllTypes { } /// A class containing all supported nullable types. -@SwiftClass() -@SwiftObjcInteropClass() +@SwiftClass(inheritNSObject: true) class AllNullableTypes { AllNullableTypes( this.aNullableBool, diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt index 7a506d3d130..81207b03f58 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt @@ -160,6 +160,7 @@ internal class AllDatatypesTest : TestCase() { null, null, null, + null, null) val everything2 = AllNullableTypes.fromList(list2) diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp index 8069938e1b2..3b22d1e3620 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp @@ -494,7 +494,7 @@ void TestPlugin::CallFlutterSendMultipleNullableTypesWithoutRecursion( const std::string* a_nullable_string, std::function reply)> result) { - flutter_api_->SendMultipleNullableTypes( + flutter_api_->SendMultipleNullableTypesWithoutRecursion( a_nullable_bool, a_nullable_int, a_nullable_string, [result](const AllNullableTypesWithoutRecursion& echo) { result(echo); }, [result](const FlutterError& error) { result(error); }); From 7e2966a245327dc7cd36327cea74738a02de1949 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 22 Mar 2024 08:42:27 -0700 Subject: [PATCH 10/16] nits --- packages/pigeon/README.md | 2 +- packages/pigeon/pigeons/core_tests.dart | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/pigeon/README.md b/packages/pigeon/README.md index b8614e4647d..0fd52e0b691 100644 --- a/packages/pigeon/README.md +++ b/packages/pigeon/README.md @@ -28,7 +28,7 @@ Custom classes, nested datatypes, and enums are also supported. Nullable enums in Objective-C generated code will be wrapped in a class to allow for nullability. By default, custom classes in Swift are defined as structs. -If you need classes instead - for recursive data, or objc interop - +If you need classes instead - for recursive data, or Objective-C interop - use the @SwiftClass annotation when defining the class. ### Synchronous and Asynchronous methods diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index e0eceaca4dd..ec98a73c797 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -91,6 +91,9 @@ class AllNullableTypes { AllNullableTypes? allNullableTypes; } +/// The primary purpose for this class is to ensure coverage of Swift structs +/// with nullable items, as the primary [AllNullableTypes] class is being used to +/// test Swift classes. class AllNullableTypesWithoutRecursion { AllNullableTypesWithoutRecursion( this.aNullableBool, From 58ca10e607175890e4a085d3f62c0b2dbe8db77e Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 22 Mar 2024 12:58:19 -0400 Subject: [PATCH 11/16] Convert custom classes to unique_ptr. --- packages/pigeon/lib/cpp_generator.dart | 154 +++++++++++++++++-- packages/pigeon/test/cpp_generator_test.dart | 28 ++-- 2 files changed, 160 insertions(+), 22 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index c5e3a1c053a..5e984622e4a 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -255,6 +255,35 @@ class CppHeaderGenerator extends StructuredGenerator { _writeClassConstructor(root, indent, classDefinition, orderedFields, 'Constructs an object setting all fields.'); + // If any fields are pointer type, then the class requires a custom + // copy constructor, so declare the rule-of-five group of functions. + if (orderedFields.any((NamedType field) => _isPointerField( + getFieldHostDatatype(field, _baseCppTypeForBuiltinDartType)))) { + final String className = classDefinition.name; + // Add the default destructor, since unique_ptr destroys itself. + _writeFunctionDeclaration(indent, '~$className', defaultImpl: true); + // Declare custom copy/assign to deep-copy the pointer. + _writeFunctionDeclaration(indent, className, + isConstructor: true, + isCopy: true, + parameters: ['const $className& other']); + _writeFunctionDeclaration(indent, 'operator=', + returnType: '$className&', + parameters: ['const $className& other']); + // Re-add the default move operations, since they work fine with + // unique_ptr. + _writeFunctionDeclaration(indent, className, + isConstructor: true, + isCopy: true, + parameters: ['$className&& other'], + defaultImpl: true); + _writeFunctionDeclaration(indent, 'operator=', + returnType: '$className&', + parameters: ['$className&& other'], + defaultImpl: true, + noexcept: true); + } + for (final NamedType field in orderedFields) { addDocumentationComments( indent, field.documentationComments, _docCommentSpec); @@ -313,7 +342,7 @@ class CppHeaderGenerator extends StructuredGenerator { final HostDatatype hostDatatype = getFieldHostDatatype(field, _baseCppTypeForBuiltinDartType); indent.writeln( - '${_valueType(hostDatatype)} ${_makeInstanceVariableName(field)};'); + '${_fieldType(hostDatatype)} ${_makeInstanceVariableName(field)};'); } }); }, nestCount: 0); @@ -693,6 +722,13 @@ class CppSourceGenerator extends StructuredGenerator { // All-field constructor. _writeClassConstructor(root, indent, classDefinition, orderedFields); + // Custom copy/assign to handle pointer fields, if necessary. + if (orderedFields.any((NamedType field) => _isPointerField( + getFieldHostDatatype(field, _baseCppTypeForBuiltinDartType)))) { + _writeCopyConstructor(root, indent, classDefinition, orderedFields); + _writeAssignmentOperator(root, indent, classDefinition, orderedFields); + } + // Getters and setters. for (final NamedType field in orderedFields) { _writeCppSourceClassField( @@ -1169,15 +1205,79 @@ return EncodableValue(EncodableList{ initializers: initializerStrings); } + void _writeCopyConstructor(Root root, Indent indent, Class classDefinition, + Iterable fields) { + final List initializerStrings = fields.map((NamedType param) { + final String fieldName = _makeInstanceVariableName(param); + final HostDatatype hostType = getFieldHostDatatype( + param, + _shortBaseCppTypeForBuiltinDartType, + ); + return '$fieldName(${_fieldValueExpression(hostType, 'other.$fieldName', sourceIsField: true)})'; + }).toList(); + _writeFunctionDefinition(indent, classDefinition.name, + scope: classDefinition.name, + parameters: ['const ${classDefinition.name}& other'], + initializers: initializerStrings); + } + + void _writeAssignmentOperator(Root root, Indent indent, Class classDefinition, + Iterable fields) { + _writeFunctionDefinition(indent, 'operator=', + scope: classDefinition.name, + returnType: '${classDefinition.name}&', + parameters: ['const ${classDefinition.name}& other'], body: () { + for (final NamedType field in fields) { + final HostDatatype hostDatatype = + getFieldHostDatatype(field, _shortBaseCppTypeForBuiltinDartType); + + final String ivarName = _makeInstanceVariableName(field); + final String otherIvar = 'other.$ivarName'; + final String valueExpression; + if (_isPointerField(hostDatatype)) { + final String constructor = + 'std::make_unique<${hostDatatype.datatype}>(*$otherIvar)'; + valueExpression = hostDatatype.isNullable + ? '$otherIvar ? $constructor : nullptr' + : constructor; + } else { + valueExpression = otherIvar; + } + indent.writeln('$ivarName = $valueExpression;'); + } + indent.writeln('return *this;'); + }); + } + + /* + + final String className = classDefinition.name; + _writeFunctionDeclaration(indent, className, + isConstructor: true, parameters: ['const $className& other']); + _writeFunctionDeclaration(indent, 'operator=', + returnType: '$className&', + parameters: ['const $className& other']); + */ + void _writeCppSourceClassField(CppOptions generatorOptions, Root root, Indent indent, Class classDefinition, NamedType field) { final HostDatatype hostDatatype = getFieldHostDatatype(field, _shortBaseCppTypeForBuiltinDartType); final String instanceVariableName = _makeInstanceVariableName(field); final String setterName = _makeSetterName(field); - final String returnExpression = hostDatatype.isNullable - ? '$instanceVariableName ? &(*$instanceVariableName) : nullptr' - : instanceVariableName; + final String returnExpression; + if (_isPointerField(hostDatatype)) { + // Convert std::unique_ptr to either T* or const T&. + returnExpression = hostDatatype.isNullable + ? '$instanceVariableName.get()' + : '*$instanceVariableName'; + } else if (hostDatatype.isNullable) { + // Convert std::optional to T*. + returnExpression = + '$instanceVariableName ? &(*$instanceVariableName) : nullptr'; + } else { + returnExpression = instanceVariableName; + } // Writes a setter treating the type as [type], to allow generating multiple // setter variants. @@ -1220,10 +1320,20 @@ return EncodableValue(EncodableList{ /// Returns the value to use when setting a field of the given type from /// an argument of that type. /// - /// For non-nullable values this is just the variable itself, but for nullable - /// values this handles the conversion between an argument type (a pointer) - /// and the field type (a std::optional). - String _fieldValueExpression(HostDatatype type, String variable) { + /// For non-nullable and non-custom-class values this is just the variable + /// itself, but for other values this handles the conversion between an + /// argument type (a pointer or value/reference) and the field type + /// (a std::optional or std::unique_ptr). + String _fieldValueExpression(HostDatatype type, String variable, + {bool sourceIsField = false}) { + if (_isPointerField(type)) { + final String constructor = 'std::make_unique<${type.datatype}>'; + // If the source is a pointer field, it always needs dereferencing. + final String maybeDereference = sourceIsField ? '*' : ''; + return type.isNullable + ? '$variable ? $constructor(*$variable) : nullptr' + : '$constructor($maybeDereference$variable)'; + } return type.isNullable ? '$variable ? ${_valueType(type)}(*$variable) : std::nullopt' : variable; @@ -1309,7 +1419,8 @@ ${prefix}reply(EncodableValue(std::move(wrapped)));'''; if (!hostType.isBuiltin && root.classes.any((Class c) => c.name == dartType.baseName)) { if (preSerializeClasses) { - final String operator = hostType.isNullable ? '->' : '.'; + final String operator = + hostType.isNullable || _isPointerField(hostType) ? '->' : '.'; encodableValue = 'EncodableValue($variableName${operator}ToEncodableList())'; } else { @@ -1547,6 +1658,23 @@ String _valueType(HostDatatype type) { return type.isNullable ? 'std::optional<$baseType>' : baseType; } +/// Returns the C++ type to use when declaring a data class field for the +/// given type. +String _fieldType(HostDatatype type) { + return _isPointerField(type) + ? 'std::unique_ptr<${type.datatype}>' + : _valueType(type); +} + +/// Returns true if [type] should be stored as a pointer, rather than a +/// value type, in a data class. +bool _isPointerField(HostDatatype type) { + // Custom class types are stored as `unique_ptr`s since they can have + // arbitrary size, and can also be arbitrarily (including recursively) + // nested, so must be stored as pointers. + return !type.isBuiltin && !type.isEnum; +} + /// Returns the C++ type to use in an argument context without ownership /// transfer for the given base type. String _unownedArgumentType(HostDatatype type) { @@ -1723,17 +1851,21 @@ void _writeFunctionDeclaration( bool isStatic = false, bool isVirtual = false, bool isConstructor = false, + bool isCopy = false, bool isPureVirtual = false, bool isConst = false, bool isOverride = false, bool deleted = false, + bool defaultImpl = false, bool inlineNoop = false, + bool noexcept = false, void Function()? inlineBody, }) { assert(!(isVirtual && isOverride), 'virtual is redundant with override'); assert(isVirtual || !isPureVirtual, 'pure virtual methods must be virtual'); assert(returnType == null || !isConstructor, 'constructors cannot have return types'); + assert(!(deleted && defaultImpl), 'a function cannot be deleted and default'); _writeFunction( indent, inlineNoop || (inlineBody != null) @@ -1746,12 +1878,14 @@ void _writeFunctionDeclaration( if (inlineBody != null) 'inline', if (isStatic) 'static', if (isVirtual) 'virtual', - if (isConstructor && parameters.isNotEmpty) 'explicit' + if (isConstructor && parameters.isNotEmpty && !isCopy) 'explicit' ], trailingAnnotations: [ if (isConst) 'const', + if (noexcept) 'noexcept', if (isOverride) 'override', if (deleted) '= delete', + if (defaultImpl) '= default', if (isPureVirtual) '= 0', ], body: inlineBody, diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index 9c1b9cbd091..c2fdcd68f68 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -584,11 +584,12 @@ void main() { contains('void set_nullable_string(std::string_view value_arg)')); expect( code, contains('void set_nullable_nested(const Nested& value_arg)')); - // Instance variables should be std::optionals. + // Most instance variables should be std::optionals. expect(code, contains('std::optional nullable_bool_')); expect(code, contains('std::optional nullable_int_')); expect(code, contains('std::optional nullable_string_')); - expect(code, contains('std::optional nullable_nested_')); + // Custom classes are the exception, to avoid inline storage. + expect(code, contains('std::unique_ptr nullable_nested_')); } { final StringBuffer sink = StringBuffer(); @@ -624,10 +625,7 @@ void main() { code, contains( 'return nullable_string_ ? &(*nullable_string_) : nullptr;')); - expect( - code, - contains( - 'return nullable_nested_ ? &(*nullable_nested_) : nullptr;')); + expect(code, contains('return nullable_nested_.get();')); // Setters convert to optionals. expect( code, @@ -643,8 +641,8 @@ void main() { 'std::optional(*value_arg) : std::nullopt;')); expect( code, - contains('nullable_nested_ = value_arg ? ' - 'std::optional(*value_arg) : std::nullopt;')); + contains( + 'nullable_nested_ = value_arg ? std::make_unique(*value_arg) : nullptr;')); // Serialization handles optionals. expect( code, @@ -763,7 +761,8 @@ void main() { expect(code, contains('bool non_nullable_bool_;')); expect(code, contains('int64_t non_nullable_int_;')); expect(code, contains('std::string non_nullable_string_;')); - expect(code, contains('Nested non_nullable_nested_;')); + // Except for custom classes. + expect(code, contains('std::unique_ptr non_nullable_nested_;')); } { final StringBuffer sink = StringBuffer(); @@ -793,15 +792,20 @@ void main() { expect(code, contains('return non_nullable_bool_;')); expect(code, contains('return non_nullable_int_;')); expect(code, contains('return non_nullable_string_;')); - expect(code, contains('return non_nullable_nested_;')); + // Unless it's a custom class. + expect(code, contains('return *non_nullable_nested_;')); // Setters just assign the value. expect(code, contains('non_nullable_bool_ = value_arg;')); expect(code, contains('non_nullable_int_ = value_arg;')); expect(code, contains('non_nullable_string_ = value_arg;')); - expect(code, contains('non_nullable_nested_ = value_arg;')); + // Unless it's a custom class. + expect( + code, + contains( + 'non_nullable_nested_ = std::make_unique(value_arg);')); // Serialization uses the value directly. expect(code, contains('EncodableValue(non_nullable_bool_)')); - expect(code, contains('non_nullable_nested_.ToEncodableList()')); + expect(code, contains('non_nullable_nested_->ToEncodableList()')); // Serialization should use push_back, not initializer lists, to avoid // copies. From e608372196436b55b7c9d097d6fdc3d452b53f1d Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 22 Mar 2024 16:25:57 -0400 Subject: [PATCH 12/16] Add Windows note to CHANGELOG --- packages/pigeon/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 1245668dd43..be39b24414c 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,6 +1,7 @@ ## 17.3.0 * [swift] Adds `@SwiftClass` annotation to allow choice between `struct` and `class` for data classes. +* [cpp] Adds support for recursive data class definitions. ## 17.2.0 From b043459e2a596725f6e2491899892ad93f2d4899 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Mon, 25 Mar 2024 17:06:10 -0700 Subject: [PATCH 13/16] nits --- packages/pigeon/lib/ast.dart | 4 ++-- packages/pigeon/lib/cpp_generator.dart | 10 ---------- packages/pigeon/lib/pigeon_lib.dart | 2 +- packages/pigeon/lib/swift_generator.dart | 2 +- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index c2083f7f952..5fee4e15c55 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -639,7 +639,7 @@ class Class extends Node { Class({ required this.name, required this.fields, - this.isSwiftObjcInteropClass = false, + this.isNSObjectSubclass = false, this.isSwiftClass = false, this.documentationComments = const [], }); @@ -653,7 +653,7 @@ class Class extends Node { /// Determines whether the defined class should inherit from NSObject in Swift. /// /// Defaults to false. - bool isSwiftObjcInteropClass; + bool isNSObjectSubclass; /// Determines whether the defined class should be represented as a struct or /// a class in Swift generation. diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 5e984622e4a..5e993137b9f 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -1249,16 +1249,6 @@ return EncodableValue(EncodableList{ }); } - /* - - final String className = classDefinition.name; - _writeFunctionDeclaration(indent, className, - isConstructor: true, parameters: ['const $className& other']); - _writeFunctionDeclaration(indent, 'operator=', - returnType: '$className&', - parameters: ['const $className& other']); - */ - void _writeCppSourceClassField(CppOptions generatorOptions, Root root, Indent indent, Class classDefinition, NamedType field) { final HostDatatype hostDatatype = diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 420923bc775..f98017b4b4b 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -1560,7 +1560,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { name: node.name.lexeme, fields: [], isSwiftClass: _hasMetadata(node.metadata, 'SwiftClass'), - isSwiftObjcInteropClass: _findMetadata(node.metadata, 'SwiftClass') + isNSObjectSubclass: _findMetadata(node.metadata, 'SwiftClass') ?.arguments ?.arguments .first diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index af868099ae4..4ed418f945a 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -127,7 +127,7 @@ class SwiftGenerator extends StructuredGenerator { if (classDefinition.isSwiftClass) { String inheritNSObject = ''; - if (classDefinition.isSwiftObjcInteropClass) { + if (classDefinition.isNSObjectSubclass) { inheritNSObject = ': NSObject'; indent.writeln('@objc'); } From b62c0eeb5324386c13e2634064e280bc0dcf08e1 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Mon, 25 Mar 2024 17:06:28 -0700 Subject: [PATCH 14/16] readme --- packages/pigeon/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/README.md b/packages/pigeon/README.md index 0fd52e0b691..8e1edaa30df 100644 --- a/packages/pigeon/README.md +++ b/packages/pigeon/README.md @@ -28,8 +28,9 @@ Custom classes, nested datatypes, and enums are also supported. Nullable enums in Objective-C generated code will be wrapped in a class to allow for nullability. By default, custom classes in Swift are defined as structs. -If you need classes instead - for recursive data, or Objective-C interop - -use the @SwiftClass annotation when defining the class. +Structs don't support some features - recursive data, or Objective-C interop. +Use the @SwiftClass annotation when defining the class to generate the data +as a Swift class instead. ### Synchronous and Asynchronous methods From 6d919958ad3cc0755e0cb57d2dcf8319df6e31b8 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Mon, 25 Mar 2024 17:12:01 -0700 Subject: [PATCH 15/16] remove @objc --- packages/pigeon/lib/ast.dart | 6 - packages/pigeon/lib/pigeon_lib.dart | 12 +- packages/pigeon/lib/swift_generator.dart | 7 +- packages/pigeon/pigeons/core_tests.dart | 2 +- .../CoreTests.java | 7 +- .../ios/Classes/CoreTests.gen.h | 3 + .../macos/Classes/CoreTests.gen.h | 3 + .../lib/src/generated/core_tests.gen.dart | 3 + .../com/example/test_plugin/CoreTests.gen.kt | 7 +- .../ios/Classes/CoreTests.gen.swift | 7 +- .../macos/Classes/CoreTests.gen.swift | 7 +- .../windows/pigeon/core_tests.gen.cpp | 164 +++++++++++++++--- .../windows/pigeon/core_tests.gen.h | 22 ++- 13 files changed, 192 insertions(+), 58 deletions(-) diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index 5fee4e15c55..08eef8cc6c7 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -639,7 +639,6 @@ class Class extends Node { Class({ required this.name, required this.fields, - this.isNSObjectSubclass = false, this.isSwiftClass = false, this.documentationComments = const [], }); @@ -650,11 +649,6 @@ class Class extends Node { /// All the fields contained in the class. List fields; - /// Determines whether the defined class should inherit from NSObject in Swift. - /// - /// Defaults to false. - bool isNSObjectSubclass; - /// Determines whether the defined class should be represented as a struct or /// a class in Swift generation. /// diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index f98017b4b4b..addce55d54a 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -180,10 +180,7 @@ class SwiftFunction { /// Metadata to annotate data classes to be defined as class in Swift output. class SwiftClass { /// Constructor. - const SwiftClass({this.inheritNSObject = false}); - - /// Whether to define data class as inheriting from NSObject with `@objc` annotation. - final bool inheritNSObject; + const SwiftClass(); } /// Type of TaskQueue which determines how handlers are dispatched for @@ -1560,13 +1557,6 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { name: node.name.lexeme, fields: [], isSwiftClass: _hasMetadata(node.metadata, 'SwiftClass'), - isNSObjectSubclass: _findMetadata(node.metadata, 'SwiftClass') - ?.arguments - ?.arguments - .first - .toString() - .contains('true') ?? - false, documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 4ed418f945a..f9857b99194 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -126,12 +126,7 @@ class SwiftGenerator extends StructuredGenerator { generatorComments: generatedComments); if (classDefinition.isSwiftClass) { - String inheritNSObject = ''; - if (classDefinition.isNSObjectSubclass) { - inheritNSObject = ': NSObject'; - indent.writeln('@objc'); - } - indent.write('class ${classDefinition.name}$inheritNSObject '); + indent.write('class ${classDefinition.name} '); } else { indent.write('struct ${classDefinition.name} '); } diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index ec98a73c797..3fbac83fff8 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -48,7 +48,7 @@ class AllTypes { } /// A class containing all supported nullable types. -@SwiftClass(inheritNSObject: true) +@SwiftClass() class AllNullableTypes { AllNullableTypes( this.aNullableBool, 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 e2f52c0954f..93dad382878 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 @@ -859,7 +859,12 @@ ArrayList toList() { } } - /** Generated class from Pigeon that represents data sent in messages. */ + /** + * The primary purpose for this class is to ensure coverage of Swift structs with nullable items, + * as the primary [AllNullableTypes] class is being used to test Swift classes. + * + *

Generated class from Pigeon that represents data sent in messages. + */ public static final class AllNullableTypesWithoutRecursion { private @Nullable Boolean aNullableBool; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 7c7bfe42c15..72c1e9d2ec2 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -106,6 +106,9 @@ typedef NS_ENUM(NSUInteger, FLTAnEnum) { @property(nonatomic, strong, nullable) FLTAllNullableTypes *allNullableTypes; @end +/// The primary purpose for this class is to ensure coverage of Swift structs +/// with nullable items, as the primary [AllNullableTypes] class is being used to +/// test Swift classes. @interface FLTAllNullableTypesWithoutRecursion : NSObject + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool aNullableInt:(nullable NSNumber *)aNullableInt diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h index 78ca94e00f0..a7ec37232c1 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h @@ -106,6 +106,9 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, strong, nullable) AllNullableTypes *allNullableTypes; @end +/// The primary purpose for this class is to ensure coverage of Swift structs +/// with nullable items, as the primary [AllNullableTypes] class is being used to +/// test Swift classes. @interface AllNullableTypesWithoutRecursion : NSObject + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool aNullableInt:(nullable NSNumber *)aNullableInt 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 d0ffaf17932..1b3bc1f5304 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 @@ -227,6 +227,9 @@ class AllNullableTypes { } } +/// The primary purpose for this class is to ensure coverage of Swift structs +/// with nullable items, as the primary [AllNullableTypes] class is being used to +/// test Swift classes. class AllNullableTypesWithoutRecursion { AllNullableTypesWithoutRecursion({ this.aNullableBool, 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 5dbb8e50af7..002c621784a 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 @@ -210,7 +210,12 @@ data class AllNullableTypes( } } -/** Generated class from Pigeon that represents data sent in messages. */ +/** + * The primary purpose for this class is to ensure coverage of Swift structs with nullable items, as + * the primary [AllNullableTypes] class is being used to test Swift classes. + * + * Generated class from Pigeon that represents data sent in messages. + */ data class AllNullableTypesWithoutRecursion( val aNullableBool: Boolean? = null, val aNullableInt: Long? = null, diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 2e89f08bf9b..cc697abad48 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -128,8 +128,7 @@ struct AllTypes { /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -@objc -class AllNullableTypes: NSObject { +class AllNullableTypes { init( aNullableBool: Bool? = nil, aNullableInt: Int64? = nil, @@ -256,6 +255,10 @@ class AllNullableTypes: NSObject { } } +/// The primary purpose for this class is to ensure coverage of Swift structs +/// with nullable items, as the primary [AllNullableTypes] class is being used to +/// test Swift classes. +/// /// Generated class from Pigeon that represents data sent in messages. struct AllNullableTypesWithoutRecursion { var aNullableBool: Bool? = nil diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 2e89f08bf9b..cc697abad48 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -128,8 +128,7 @@ struct AllTypes { /// A class containing all supported nullable types. /// /// Generated class from Pigeon that represents data sent in messages. -@objc -class AllNullableTypes: NSObject { +class AllNullableTypes { init( aNullableBool: Bool? = nil, aNullableInt: Int64? = nil, @@ -256,6 +255,10 @@ class AllNullableTypes: NSObject { } } +/// The primary purpose for this class is to ensure coverage of Swift structs +/// with nullable items, as the primary [AllNullableTypes] class is being used to +/// test Swift classes. +/// /// Generated class from Pigeon that represents data sent in messages. struct AllNullableTypesWithoutRecursion { var aNullableBool: Bool? = nil 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 4ac4c57262f..fd12459454a 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 @@ -230,9 +230,98 @@ AllNullableTypes::AllNullableTypes( a_nullable_object_(a_nullable_object ? std::optional(*a_nullable_object) : std::nullopt), - all_nullable_types_(all_nullable_types ? std::optional( - *all_nullable_types) - : std::nullopt) {} + all_nullable_types_( + all_nullable_types + ? std::make_unique(*all_nullable_types) + : nullptr) {} + +AllNullableTypes::AllNullableTypes(const AllNullableTypes& other) + : a_nullable_bool_(other.a_nullable_bool_ + ? std::optional(*other.a_nullable_bool_) + : std::nullopt), + a_nullable_int_(other.a_nullable_int_ + ? std::optional(*other.a_nullable_int_) + : std::nullopt), + a_nullable_int64_(other.a_nullable_int64_ + ? std::optional(*other.a_nullable_int64_) + : std::nullopt), + a_nullable_double_(other.a_nullable_double_ + ? std::optional(*other.a_nullable_double_) + : std::nullopt), + a_nullable_byte_array_(other.a_nullable_byte_array_ + ? std::optional>( + *other.a_nullable_byte_array_) + : std::nullopt), + a_nullable4_byte_array_(other.a_nullable4_byte_array_ + ? std::optional>( + *other.a_nullable4_byte_array_) + : std::nullopt), + a_nullable8_byte_array_(other.a_nullable8_byte_array_ + ? std::optional>( + *other.a_nullable8_byte_array_) + : std::nullopt), + a_nullable_float_array_(other.a_nullable_float_array_ + ? std::optional>( + *other.a_nullable_float_array_) + : std::nullopt), + a_nullable_list_(other.a_nullable_list_ ? std::optional( + *other.a_nullable_list_) + : std::nullopt), + a_nullable_map_(other.a_nullable_map_ + ? std::optional(*other.a_nullable_map_) + : std::nullopt), + nullable_nested_list_( + other.nullable_nested_list_ + ? std::optional(*other.nullable_nested_list_) + : std::nullopt), + nullable_map_with_annotations_( + other.nullable_map_with_annotations_ + ? std::optional( + *other.nullable_map_with_annotations_) + : std::nullopt), + nullable_map_with_object_( + other.nullable_map_with_object_ + ? std::optional(*other.nullable_map_with_object_) + : std::nullopt), + a_nullable_enum_(other.a_nullable_enum_ + ? std::optional(*other.a_nullable_enum_) + : std::nullopt), + a_nullable_string_( + other.a_nullable_string_ + ? std::optional(*other.a_nullable_string_) + : std::nullopt), + a_nullable_object_( + other.a_nullable_object_ + ? std::optional(*other.a_nullable_object_) + : std::nullopt), + all_nullable_types_( + other.all_nullable_types_ + ? std::make_unique(*other.all_nullable_types_) + : nullptr) {} + +AllNullableTypes& AllNullableTypes::operator=(const AllNullableTypes& other) { + a_nullable_bool_ = other.a_nullable_bool_; + a_nullable_int_ = other.a_nullable_int_; + a_nullable_int64_ = other.a_nullable_int64_; + a_nullable_double_ = other.a_nullable_double_; + a_nullable_byte_array_ = other.a_nullable_byte_array_; + a_nullable4_byte_array_ = other.a_nullable4_byte_array_; + a_nullable8_byte_array_ = other.a_nullable8_byte_array_; + a_nullable_float_array_ = other.a_nullable_float_array_; + a_nullable_list_ = other.a_nullable_list_; + a_nullable_map_ = other.a_nullable_map_; + nullable_nested_list_ = other.nullable_nested_list_; + nullable_map_with_annotations_ = other.nullable_map_with_annotations_; + nullable_map_with_object_ = other.nullable_map_with_object_; + a_nullable_enum_ = other.a_nullable_enum_; + a_nullable_string_ = other.a_nullable_string_; + a_nullable_object_ = other.a_nullable_object_; + all_nullable_types_ = + other.all_nullable_types_ + ? std::make_unique(*other.all_nullable_types_) + : nullptr; + return *this; +} const bool* AllNullableTypes::a_nullable_bool() const { return a_nullable_bool_ ? &(*a_nullable_bool_) : nullptr; @@ -461,18 +550,18 @@ void AllNullableTypes::set_a_nullable_object(const EncodableValue& value_arg) { } const AllNullableTypes* AllNullableTypes::all_nullable_types() const { - return all_nullable_types_ ? &(*all_nullable_types_) : nullptr; + return all_nullable_types_.get(); } void AllNullableTypes::set_all_nullable_types( const AllNullableTypes* value_arg) { all_nullable_types_ = - value_arg ? std::optional(*value_arg) : std::nullopt; + value_arg ? std::make_unique(*value_arg) : nullptr; } void AllNullableTypes::set_all_nullable_types( const AllNullableTypes& value_arg) { - all_nullable_types_ = value_arg; + all_nullable_types_ = std::make_unique(value_arg); } EncodableList AllNullableTypes::ToEncodableList() const { @@ -1052,65 +1141,92 @@ AllNullableTypesWithoutRecursion::FromEncodableList(const EncodableList& list) { // AllClassesWrapper AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types) - : all_nullable_types_(all_nullable_types) {} + : all_nullable_types_( + std::make_unique(all_nullable_types)) {} AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types, const AllNullableTypesWithoutRecursion* all_nullable_types_without_recursion, const AllTypes* all_types) - : all_nullable_types_(all_nullable_types), + : all_nullable_types_( + std::make_unique(all_nullable_types)), all_nullable_types_without_recursion_( all_nullable_types_without_recursion - ? std::optional( + ? std::make_unique( *all_nullable_types_without_recursion) - : std::nullopt), - all_types_(all_types ? std::optional(*all_types) - : std::nullopt) {} + : nullptr), + all_types_(all_types ? std::make_unique(*all_types) : nullptr) { +} + +AllClassesWrapper::AllClassesWrapper(const AllClassesWrapper& other) + : all_nullable_types_( + std::make_unique(*other.all_nullable_types_)), + all_nullable_types_without_recursion_( + other.all_nullable_types_without_recursion_ + ? std::make_unique( + *other.all_nullable_types_without_recursion_) + : nullptr), + all_types_(other.all_types_ + ? std::make_unique(*other.all_types_) + : nullptr) {} + +AllClassesWrapper& AllClassesWrapper::operator=( + const AllClassesWrapper& other) { + all_nullable_types_ = + std::make_unique(*other.all_nullable_types_); + all_nullable_types_without_recursion_ = + other.all_nullable_types_without_recursion_ + ? std::make_unique( + *other.all_nullable_types_without_recursion_) + : nullptr; + all_types_ = other.all_types_ ? std::make_unique(*other.all_types_) + : nullptr; + return *this; +} const AllNullableTypes& AllClassesWrapper::all_nullable_types() const { - return all_nullable_types_; + return *all_nullable_types_; } void AllClassesWrapper::set_all_nullable_types( const AllNullableTypes& value_arg) { - all_nullable_types_ = value_arg; + all_nullable_types_ = std::make_unique(value_arg); } const AllNullableTypesWithoutRecursion* AllClassesWrapper::all_nullable_types_without_recursion() const { - return all_nullable_types_without_recursion_ - ? &(*all_nullable_types_without_recursion_) - : nullptr; + return all_nullable_types_without_recursion_.get(); } void AllClassesWrapper::set_all_nullable_types_without_recursion( const AllNullableTypesWithoutRecursion* value_arg) { all_nullable_types_without_recursion_ = - value_arg ? std::optional(*value_arg) - : std::nullopt; + value_arg ? std::make_unique(*value_arg) + : nullptr; } void AllClassesWrapper::set_all_nullable_types_without_recursion( const AllNullableTypesWithoutRecursion& value_arg) { - all_nullable_types_without_recursion_ = value_arg; + all_nullable_types_without_recursion_ = + std::make_unique(value_arg); } const AllTypes* AllClassesWrapper::all_types() const { - return all_types_ ? &(*all_types_) : nullptr; + return all_types_.get(); } void AllClassesWrapper::set_all_types(const AllTypes* value_arg) { - all_types_ = value_arg ? std::optional(*value_arg) : std::nullopt; + all_types_ = value_arg ? std::make_unique(*value_arg) : nullptr; } void AllClassesWrapper::set_all_types(const AllTypes& value_arg) { - all_types_ = value_arg; + all_types_ = std::make_unique(value_arg); } EncodableList AllClassesWrapper::ToEncodableList() const { EncodableList list; list.reserve(3); - list.push_back(EncodableValue(all_nullable_types_.ToEncodableList())); + list.push_back(EncodableValue(all_nullable_types_->ToEncodableList())); list.push_back( all_nullable_types_without_recursion_ ? EncodableValue( 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 13f8f0fba1f..4b15d9dbbe7 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 @@ -183,6 +183,11 @@ class AllNullableTypes { const flutter::EncodableValue* a_nullable_object, const AllNullableTypes* all_nullable_types); + ~AllNullableTypes() = default; + AllNullableTypes(const AllNullableTypes& other); + AllNullableTypes& operator=(const AllNullableTypes& other); + AllNullableTypes(AllNullableTypes&& other) = default; + AllNullableTypes& operator=(AllNullableTypes&& other) noexcept = default; const bool* a_nullable_bool() const; void set_a_nullable_bool(const bool* value_arg); void set_a_nullable_bool(bool value_arg); @@ -284,9 +289,13 @@ class AllNullableTypes { std::optional a_nullable_enum_; std::optional a_nullable_string_; std::optional a_nullable_object_; - std::optional all_nullable_types_; + std::unique_ptr all_nullable_types_; }; +// The primary purpose for this class is to ensure coverage of Swift structs +// with nullable items, as the primary [AllNullableTypes] class is being used to +// test Swift classes. +// // Generated class from Pigeon that represents data sent in messages. class AllNullableTypesWithoutRecursion { public: @@ -427,6 +436,11 @@ class AllClassesWrapper { all_nullable_types_without_recursion, const AllTypes* all_types); + ~AllClassesWrapper() = default; + AllClassesWrapper(const AllClassesWrapper& other); + AllClassesWrapper& operator=(const AllClassesWrapper& other); + AllClassesWrapper(AllClassesWrapper&& other) = default; + AllClassesWrapper& operator=(AllClassesWrapper&& other) noexcept = default; const AllNullableTypes& all_nullable_types() const; void set_all_nullable_types(const AllNullableTypes& value_arg); @@ -456,10 +470,10 @@ class AllClassesWrapper { friend class FlutterSmallApi; friend class FlutterSmallApiCodecSerializer; friend class CoreTestsTest; - AllNullableTypes all_nullable_types_; - std::optional + std::unique_ptr all_nullable_types_; + std::unique_ptr all_nullable_types_without_recursion_; - std::optional all_types_; + std::unique_ptr all_types_; }; // A data class containing a List, used in unit tests. From ee5eda047f248c153ef38d99344f1853181d3793 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Mon, 25 Mar 2024 17:18:13 -0700 Subject: [PATCH 16/16] cleaner classes --- packages/pigeon/lib/swift_generator.dart | 6 ++-- .../ios/Classes/CoreTests.gen.swift | 34 +++++++++---------- .../macos/Classes/CoreTests.gen.swift | 34 +++++++++---------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index f9857b99194..791cdd2e936 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -142,7 +142,7 @@ class SwiftGenerator extends StructuredGenerator { addDocumentationComments( indent, field.documentationComments, _docCommentSpec); indent.write('var '); - _writeClassField(indent, field); + _writeClassField(indent, field, addNil: !classDefinition.isSwiftClass); indent.newln(); } @@ -183,9 +183,9 @@ class SwiftGenerator extends StructuredGenerator { }); } - void _writeClassField(Indent indent, NamedType field) { + void _writeClassField(Indent indent, NamedType field, {bool addNil = true}) { indent.add('${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); - final String defaultNil = field.type.isNullable ? ' = nil' : ''; + final String defaultNil = field.type.isNullable && addNil ? ' = nil' : ''; indent.add(defaultNil); } diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index cc697abad48..3a45a12a40f 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -166,23 +166,23 @@ class AllNullableTypes { self.aNullableObject = aNullableObject self.allNullableTypes = allNullableTypes } - var aNullableBool: Bool? = nil - var aNullableInt: Int64? = nil - var aNullableInt64: Int64? = nil - var aNullableDouble: Double? = nil - var aNullableByteArray: FlutterStandardTypedData? = nil - var aNullable4ByteArray: FlutterStandardTypedData? = nil - var aNullable8ByteArray: FlutterStandardTypedData? = nil - var aNullableFloatArray: FlutterStandardTypedData? = nil - var aNullableList: [Any?]? = nil - var aNullableMap: [AnyHashable: Any?]? = nil - var nullableNestedList: [[Bool?]?]? = nil - var nullableMapWithAnnotations: [String?: String?]? = nil - var nullableMapWithObject: [String?: Any?]? = nil - var aNullableEnum: AnEnum? = nil - var aNullableString: String? = nil - var aNullableObject: Any? = nil - var allNullableTypes: AllNullableTypes? = nil + var aNullableBool: Bool? + var aNullableInt: Int64? + var aNullableInt64: Int64? + var aNullableDouble: Double? + var aNullableByteArray: FlutterStandardTypedData? + var aNullable4ByteArray: FlutterStandardTypedData? + var aNullable8ByteArray: FlutterStandardTypedData? + var aNullableFloatArray: FlutterStandardTypedData? + var aNullableList: [Any?]? + var aNullableMap: [AnyHashable: Any?]? + var nullableNestedList: [[Bool?]?]? + var nullableMapWithAnnotations: [String?: String?]? + var nullableMapWithObject: [String?: Any?]? + var aNullableEnum: AnEnum? + var aNullableString: String? + var aNullableObject: Any? + var allNullableTypes: AllNullableTypes? static func fromList(_ list: [Any?]) -> AllNullableTypes? { let aNullableBool: Bool? = nilOrValue(list[0]) diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index cc697abad48..3a45a12a40f 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -166,23 +166,23 @@ class AllNullableTypes { self.aNullableObject = aNullableObject self.allNullableTypes = allNullableTypes } - var aNullableBool: Bool? = nil - var aNullableInt: Int64? = nil - var aNullableInt64: Int64? = nil - var aNullableDouble: Double? = nil - var aNullableByteArray: FlutterStandardTypedData? = nil - var aNullable4ByteArray: FlutterStandardTypedData? = nil - var aNullable8ByteArray: FlutterStandardTypedData? = nil - var aNullableFloatArray: FlutterStandardTypedData? = nil - var aNullableList: [Any?]? = nil - var aNullableMap: [AnyHashable: Any?]? = nil - var nullableNestedList: [[Bool?]?]? = nil - var nullableMapWithAnnotations: [String?: String?]? = nil - var nullableMapWithObject: [String?: Any?]? = nil - var aNullableEnum: AnEnum? = nil - var aNullableString: String? = nil - var aNullableObject: Any? = nil - var allNullableTypes: AllNullableTypes? = nil + var aNullableBool: Bool? + var aNullableInt: Int64? + var aNullableInt64: Int64? + var aNullableDouble: Double? + var aNullableByteArray: FlutterStandardTypedData? + var aNullable4ByteArray: FlutterStandardTypedData? + var aNullable8ByteArray: FlutterStandardTypedData? + var aNullableFloatArray: FlutterStandardTypedData? + var aNullableList: [Any?]? + var aNullableMap: [AnyHashable: Any?]? + var nullableNestedList: [[Bool?]?]? + var nullableMapWithAnnotations: [String?: String?]? + var nullableMapWithObject: [String?: Any?]? + var aNullableEnum: AnEnum? + var aNullableString: String? + var aNullableObject: Any? + var allNullableTypes: AllNullableTypes? static func fromList(_ list: [Any?]) -> AllNullableTypes? { let aNullableBool: Bool? = nilOrValue(list[0])