diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index addd59f7268d..4e941c00aad4 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.1.2 + +* [swift] Fixes a crash when passing `null` for nested nullable classes. + ## 10.1.1 * Updates README to better reflect modern usage. diff --git a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java index c1c3b7a898d5..1f5aaebba66e 100644 --- a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java +++ b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon import android.util.Log; diff --git a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt index bc2dfa818ad7..4aa5169e7f33 100644 --- a/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt +++ b/packages/pigeon/example/app/android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon diff --git a/packages/pigeon/example/app/ios/Runner/Messages.g.swift b/packages/pigeon/example/app/ios/Runner/Messages.g.swift index 8dd1a6b8878c..3467edf3c3c1 100644 --- a/packages/pigeon/example/app/ios/Runner/Messages.g.swift +++ b/packages/pigeon/example/app/ios/Runner/Messages.g.swift @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/example/app/lib/src/messages.g.dart b/packages/pigeon/example/app/lib/src/messages.g.dart index 25e75e3f1ab9..66ae5c55f33e 100644 --- a/packages/pigeon/example/app/lib/src/messages.g.dart +++ b/packages/pigeon/example/app/lib/src/messages.g.dart @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/example/app/macos/Runner/messages.g.h b/packages/pigeon/example/app/macos/Runner/messages.g.h index d789948007bb..5fb709ca3d26 100644 --- a/packages/pigeon/example/app/macos/Runner/messages.g.h +++ b/packages/pigeon/example/app/macos/Runner/messages.g.h @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import diff --git a/packages/pigeon/example/app/macos/Runner/messages.g.m b/packages/pigeon/example/app/macos/Runner/messages.g.m index 8aa843612a55..8a43bffac320 100644 --- a/packages/pigeon/example/app/macos/Runner/messages.g.m +++ b/packages/pigeon/example/app/macos/Runner/messages.g.m @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "messages.g.h" diff --git a/packages/pigeon/example/app/windows/runner/messages.g.cpp b/packages/pigeon/example/app/windows/runner/messages.g.cpp index ba7c06bb697c..50053cf23347 100644 --- a/packages/pigeon/example/app/windows/runner/messages.g.cpp +++ b/packages/pigeon/example/app/windows/runner/messages.g.cpp @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS diff --git a/packages/pigeon/example/app/windows/runner/messages.g.h b/packages/pigeon/example/app/windows/runner/messages.g.h index 1bf5dddf798a..917de2da37ab 100644 --- a/packages/pigeon/example/app/windows/runner/messages.g.h +++ b/packages/pigeon/example/app/windows/runner/messages.g.h @@ -1,7 +1,7 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v10.1.1), do not edit directly. +// Autogenerated from Pigeon (v10.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_MESSAGES_G_H_ diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 2b67bd552c45..f697cb41f22e 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -11,7 +11,7 @@ import 'ast.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '10.1.1'; +const String pigeonVersion = '10.1.2'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index a133a24ed4e1..26547fb65914 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -627,7 +627,8 @@ import FlutterMacOS if (listEncodedClassNames != null && listEncodedClassNames.contains(type.baseName)) { indent.writeln('var $variableName: $fieldType? = nil'); - indent.write('if let ${variableName}List = $value as! [Any?]? '); + indent + .write('if let ${variableName}List: [Any?] = nilOrValue($value) '); indent.addScoped('{', '}', () { indent.writeln( '$variableName = $fieldType.fromList(${variableName}List)'); diff --git a/packages/pigeon/mock_handler_tester/test/message.dart b/packages/pigeon/mock_handler_tester/test/message.dart index ac7d0bf0ab71..de2b7db48b57 100644 --- a/packages/pigeon/mock_handler_tester/test/message.dart +++ b/packages/pigeon/mock_handler_tester/test/message.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/mock_handler_tester/test/test.dart b/packages/pigeon/mock_handler_tester/test/test.dart index 31140756656c..3af78ca43ca6 100644 --- a/packages/pigeon/mock_handler_tester/test/test.dart +++ b/packages/pigeon/mock_handler_tester/test/test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import // ignore_for_file: avoid_relative_lib_imports diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index 15de1ffbbbc6..ceb1de2f36ab 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -10,7 +10,7 @@ enum AnEnum { three, } -// A class containing all supported types. +/// A class containing all supported types. class AllTypes { AllTypes({ this.aBool = false, @@ -43,7 +43,7 @@ class AllTypes { String aString; } -// A class containing all supported nullable types. +/// A class containing all supported nullable types. class AllNullableTypes { AllNullableTypes( this.aNullableBool, @@ -82,10 +82,15 @@ class AllNullableTypes { String? aNullableString; } -// A class for testing nested object handling. -class AllNullableTypesWrapper { - AllNullableTypesWrapper(this.values); - AllNullableTypes values; +/// 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); + AllNullableTypes allNullableTypes; + AllTypes? allTypes; } /// The core interface that each host language plugin must implement in @@ -152,6 +157,11 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('echo(_:)') Map echoMap(Map aMap); + /// Returns the passed map to test nested class serialization and deserialization. + @ObjCSelector('echoClassWrapper:') + @SwiftFunction('echo(_:)') + AllClassesWrapper echoClassWrapper(AllClassesWrapper wrapper); + // ========== Synchronous nullable method tests ========== /// Returns the passed object, to test serialization and deserialization. @@ -163,13 +173,13 @@ abstract class HostIntegrationCoreApi { /// sending of nested objects. @ObjCSelector('extractNestedNullableStringFrom:') @SwiftFunction('extractNestedNullableString(from:)') - String? extractNestedNullableString(AllNullableTypesWrapper wrapper); + String? extractNestedNullableString(AllClassesWrapper wrapper); /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. @ObjCSelector('createNestedObjectWithNullableString:') @SwiftFunction('createNestedObject(with:)') - AllNullableTypesWrapper createNestedNullableString(String? nullableString); + AllClassesWrapper createNestedNullableString(String? nullableString); /// Returns passed in arguments of multiple types. @ObjCSelector('sendMultipleNullableTypesABool:anInt:aString:') 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 6ca4c01f3576..c9c4406d688f 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 @@ -6,8 +6,8 @@ import androidx.annotation.NonNull; 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.AllNullableTypesWrapper; import com.example.alternate_language_test_plugin.CoreTests.AllTypes; import com.example.alternate_language_test_plugin.CoreTests.FlutterIntegrationCoreApi; import com.example.alternate_language_test_plugin.CoreTests.HostIntegrationCoreApi; @@ -99,17 +99,21 @@ public void throwErrorFromVoid() { return aMap; } + @NonNull + public AllClassesWrapper echoClassWrapper(@NonNull AllClassesWrapper wrapper) { + return wrapper; + } + @Override - public @Nullable String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper) { - return wrapper.getValues().getANullableString(); + public @Nullable String extractNestedNullableString(@NonNull AllClassesWrapper wrapper) { + return wrapper.getAllNullableTypes().getANullableString(); } @Override - public @NonNull AllNullableTypesWrapper createNestedNullableString( - @Nullable String nullableString) { + public @NonNull AllClassesWrapper createNestedNullableString(@Nullable String nullableString) { AllNullableTypes innerObject = new AllNullableTypes.Builder().setANullableString(nullableString).build(); - return new AllNullableTypesWrapper.Builder().setValues(innerObject).build(); + return new AllClassesWrapper.Builder().setAllNullableTypes(innerObject).build(); } @Override 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 8b8f6b5e2611..aa53e509c281 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 @@ -71,7 +71,11 @@ private AnEnum(final int index) { } } - /** Generated class from Pigeon that represents data sent in messages. */ + /** + * A class containing all supported types. + * + *

Generated class from Pigeon that represents data sent in messages. + */ public static final class AllTypes { private @NonNull Boolean aBool; @@ -388,7 +392,11 @@ ArrayList toList() { } } - /** Generated class from Pigeon that represents data sent in messages. */ + /** + * A class containing all supported nullable types. + * + *

Generated class from Pigeon that represents data sent in messages. + */ public static final class AllNullableTypes { private @Nullable Boolean aNullableBool; @@ -735,52 +743,84 @@ ArrayList toList() { } } - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class AllNullableTypesWrapper { - private @NonNull AllNullableTypes values; + /** + * 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). + * + *

Generated class from Pigeon that represents data sent in messages. + */ + public static final class AllClassesWrapper { + private @NonNull AllNullableTypes allNullableTypes; - public @NonNull AllNullableTypes getValues() { - return values; + public @NonNull AllNullableTypes getAllNullableTypes() { + return allNullableTypes; } - public void setValues(@NonNull AllNullableTypes setterArg) { + public void setAllNullableTypes(@NonNull AllNullableTypes setterArg) { if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"values\" is null."); + throw new IllegalStateException("Nonnull field \"allNullableTypes\" is null."); } - this.values = setterArg; + this.allNullableTypes = setterArg; + } + + private @Nullable AllTypes allTypes; + + public @Nullable AllTypes getAllTypes() { + return allTypes; + } + + public void setAllTypes(@Nullable AllTypes setterArg) { + this.allTypes = setterArg; } /** Constructor is non-public to enforce null safety; use Builder. */ - AllNullableTypesWrapper() {} + AllClassesWrapper() {} public static final class Builder { - private @Nullable AllNullableTypes values; + private @Nullable AllNullableTypes allNullableTypes; + + public @NonNull Builder setAllNullableTypes(@NonNull AllNullableTypes setterArg) { + this.allNullableTypes = setterArg; + return this; + } + + private @Nullable AllTypes allTypes; - public @NonNull Builder setValues(@NonNull AllNullableTypes setterArg) { - this.values = setterArg; + public @NonNull Builder setAllTypes(@Nullable AllTypes setterArg) { + this.allTypes = setterArg; return this; } - public @NonNull AllNullableTypesWrapper build() { - AllNullableTypesWrapper pigeonReturn = new AllNullableTypesWrapper(); - pigeonReturn.setValues(values); + public @NonNull AllClassesWrapper build() { + AllClassesWrapper pigeonReturn = new AllClassesWrapper(); + pigeonReturn.setAllNullableTypes(allNullableTypes); + pigeonReturn.setAllTypes(allTypes); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(1); - toListResult.add((values == null) ? null : values.toList()); + ArrayList toListResult = new ArrayList(2); + toListResult.add((allNullableTypes == null) ? null : allNullableTypes.toList()); + toListResult.add((allTypes == null) ? null : allTypes.toList()); return toListResult; } - static @NonNull AllNullableTypesWrapper fromList(@NonNull ArrayList list) { - AllNullableTypesWrapper pigeonResult = new AllNullableTypesWrapper(); - Object values = list.get(0); - pigeonResult.setValues( - (values == null) ? null : AllNullableTypes.fromList((ArrayList) values)); + static @NonNull AllClassesWrapper fromList(@NonNull ArrayList list) { + AllClassesWrapper pigeonResult = new AllClassesWrapper(); + Object allNullableTypes = list.get(0); + pigeonResult.setAllNullableTypes( + (allNullableTypes == null) + ? null + : AllNullableTypes.fromList((ArrayList) allNullableTypes)); + Object allTypes = list.get(1); + pigeonResult.setAllTypes( + (allTypes == null) ? null : AllTypes.fromList((ArrayList) allTypes)); return pigeonResult; } } @@ -848,9 +888,9 @@ private HostIntegrationCoreApiCodec() {} protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { case (byte) 128: - return AllNullableTypes.fromList((ArrayList) readValue(buffer)); + return AllClassesWrapper.fromList((ArrayList) readValue(buffer)); case (byte) 129: - return AllNullableTypesWrapper.fromList((ArrayList) readValue(buffer)); + return AllNullableTypes.fromList((ArrayList) readValue(buffer)); case (byte) 130: return AllTypes.fromList((ArrayList) readValue(buffer)); case (byte) 131: @@ -862,12 +902,12 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof AllNullableTypes) { + if (value instanceof AllClassesWrapper) { stream.write(128); - writeValue(stream, ((AllNullableTypes) value).toList()); - } else if (value instanceof AllNullableTypesWrapper) { + writeValue(stream, ((AllClassesWrapper) value).toList()); + } else if (value instanceof AllNullableTypes) { stream.write(129); - writeValue(stream, ((AllNullableTypesWrapper) value).toList()); + writeValue(stream, ((AllNullableTypes) value).toList()); } else if (value instanceof AllTypes) { stream.write(130); writeValue(stream, ((AllTypes) value).toList()); @@ -926,6 +966,9 @@ public interface HostIntegrationCoreApi { /** Returns the passed map, to test serialization and deserialization. */ @NonNull Map echoMap(@NonNull Map aMap); + /** Returns the passed map to test nested class serialization and deserialization. */ + @NonNull + AllClassesWrapper echoClassWrapper(@NonNull AllClassesWrapper wrapper); /** Returns the passed object, to test serialization and deserialization. */ @Nullable AllNullableTypes echoAllNullableTypes(@Nullable AllNullableTypes everything); @@ -933,12 +976,12 @@ public interface HostIntegrationCoreApi { * Returns the inner `aString` value from the wrapped object, to test sending of nested objects. */ @Nullable - String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper); + String extractNestedNullableString(@NonNull AllClassesWrapper wrapper); /** * Returns the inner `aString` value from the wrapped object, to test sending of nested objects. */ @NonNull - AllNullableTypesWrapper createNestedNullableString(@Nullable String nullableString); + AllClassesWrapper createNestedNullableString(@Nullable String nullableString); /** Returns passed in arguments of multiple types. */ @NonNull AllNullableTypes sendMultipleNullableTypes( @@ -1382,6 +1425,31 @@ static void setup( channel.setMessageHandler(null); } } + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper", + getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + AllClassesWrapper wrapperArg = (AllClassesWrapper) args.get(0); + try { + AllClassesWrapper output = api.echoClassWrapper(wrapperArg); + wrapped.add(0, output); + } catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -1418,7 +1486,7 @@ static void setup( (message, reply) -> { ArrayList wrapped = new ArrayList(); ArrayList args = (ArrayList) message; - AllNullableTypesWrapper wrapperArg = (AllNullableTypesWrapper) args.get(0); + AllClassesWrapper wrapperArg = (AllClassesWrapper) args.get(0); try { String output = api.extractNestedNullableString(wrapperArg); wrapped.add(0, output); @@ -1445,8 +1513,7 @@ static void setup( ArrayList args = (ArrayList) message; String nullableStringArg = (String) args.get(0); try { - AllNullableTypesWrapper output = - api.createNestedNullableString(nullableStringArg); + AllClassesWrapper output = api.createNestedNullableString(nullableStringArg); wrapped.add(0, output); } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); @@ -2968,9 +3035,9 @@ private FlutterIntegrationCoreApiCodec() {} protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { switch (type) { case (byte) 128: - return AllNullableTypes.fromList((ArrayList) readValue(buffer)); + return AllClassesWrapper.fromList((ArrayList) readValue(buffer)); case (byte) 129: - return AllNullableTypesWrapper.fromList((ArrayList) readValue(buffer)); + return AllNullableTypes.fromList((ArrayList) readValue(buffer)); case (byte) 130: return AllTypes.fromList((ArrayList) readValue(buffer)); case (byte) 131: @@ -2982,12 +3049,12 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { @Override protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof AllNullableTypes) { + if (value instanceof AllClassesWrapper) { stream.write(128); - writeValue(stream, ((AllNullableTypes) value).toList()); - } else if (value instanceof AllNullableTypesWrapper) { + writeValue(stream, ((AllClassesWrapper) value).toList()); + } else if (value instanceof AllNullableTypes) { stream.write(129); - writeValue(stream, ((AllNullableTypesWrapper) value).toList()); + writeValue(stream, ((AllNullableTypes) value).toList()); } else if (value instanceof AllTypes) { stream.write(130); writeValue(stream, ((AllTypes) value).toList()); diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java index e2d6414ad9de..cba21e76f496 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java @@ -8,6 +8,7 @@ import static org.mockito.Mockito.*; import com.example.alternate_language_test_plugin.CoreTests.AllNullableTypes; +import com.example.alternate_language_test_plugin.CoreTests.AllTypes; import com.example.alternate_language_test_plugin.CoreTests.FlutterIntegrationCoreApi; import io.flutter.plugin.common.BinaryMessenger; import java.nio.ByteBuffer; @@ -17,6 +18,58 @@ import org.junit.Test; public class AllDatatypesTest { + + void compareAllTypes(AllTypes firstTypes, AllTypes secondTypes) { + assertEquals(firstTypes == null, secondTypes == null); + if (firstTypes == null || secondTypes == null) { + return; + } + assertEquals(firstTypes.getABool(), secondTypes.getABool()); + assertEquals(firstTypes.getAnInt(), secondTypes.getAnInt()); + assertEquals(firstTypes.getAnInt64(), secondTypes.getAnInt64()); + + assertEquals(firstTypes.getADouble(), secondTypes.getADouble()); + assertArrayEquals(firstTypes.getAByteArray(), secondTypes.getAByteArray()); + assertArrayEquals(firstTypes.getA4ByteArray(), secondTypes.getA4ByteArray()); + assertArrayEquals(firstTypes.getA8ByteArray(), secondTypes.getA8ByteArray()); + assertTrue(floatArraysEqual(firstTypes.getAFloatArray(), secondTypes.getAFloatArray())); + assertArrayEquals(firstTypes.getAList().toArray(), secondTypes.getAList().toArray()); + assertArrayEquals( + firstTypes.getAMap().keySet().toArray(), secondTypes.getAMap().keySet().toArray()); + assertArrayEquals( + firstTypes.getAMap().values().toArray(), secondTypes.getAMap().values().toArray()); + assertEquals(firstTypes.getAnEnum(), secondTypes.getAnEnum()); + assertEquals(firstTypes.getAString(), secondTypes.getAString()); + } + + void compareAllNullableTypes(AllNullableTypes firstTypes, AllNullableTypes secondTypes) { + assertEquals(firstTypes == null, secondTypes == null); + if (firstTypes == null || secondTypes == null) { + return; + } + assertEquals(firstTypes.getANullableBool(), secondTypes.getANullableBool()); + assertEquals(firstTypes.getANullableInt(), secondTypes.getANullableInt()); + assertEquals(firstTypes.getANullableDouble(), secondTypes.getANullableDouble()); + assertEquals(firstTypes.getANullableString(), secondTypes.getANullableString()); + assertArrayEquals(firstTypes.getANullableByteArray(), secondTypes.getANullableByteArray()); + assertArrayEquals(firstTypes.getANullable4ByteArray(), secondTypes.getANullable4ByteArray()); + assertArrayEquals(firstTypes.getANullable8ByteArray(), secondTypes.getANullable8ByteArray()); + assertTrue( + floatArraysEqual( + firstTypes.getANullableFloatArray(), secondTypes.getANullableFloatArray())); + assertArrayEquals( + firstTypes.getANullableList().toArray(), secondTypes.getANullableList().toArray()); + assertArrayEquals( + firstTypes.getANullableMap().keySet().toArray(), + secondTypes.getANullableMap().keySet().toArray()); + assertArrayEquals( + firstTypes.getANullableMap().values().toArray(), + secondTypes.getANullableMap().values().toArray()); + assertArrayEquals( + firstTypes.getNullableMapWithObject().values().toArray(), + secondTypes.getNullableMapWithObject().values().toArray()); + } + @Test public void nullValues() { AllNullableTypes everything = new AllNullableTypes(); @@ -84,18 +137,37 @@ private static boolean floatArraysEqual(double[] x, double[] y) { @Test public void hasValues() { - AllNullableTypes everything = new AllNullableTypes(); - everything.setANullableBool(false); - everything.setANullableInt(1234L); - everything.setANullableDouble(2.0); - everything.setANullableString("hello"); - everything.setANullableByteArray(new byte[] {1, 2, 3, 4}); - everything.setANullable4ByteArray(new int[] {1, 2, 3, 4}); - everything.setANullable8ByteArray(new long[] {1, 2, 3, 4}); - everything.setANullableFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}); - everything.setANullableList(Arrays.asList(new int[] {1, 2, 3})); - everything.setANullableMap(makeMap("hello", 1234)); - everything.setNullableMapWithObject(makeStringMap("hello", 1234)); + AllTypes allEverything = + new AllTypes.Builder() + .setABool(false) + .setAnInt(1234L) + .setAnInt64(4321L) + .setADouble(2.0) + .setAString("hello") + .setAByteArray(new byte[] {1, 2, 3, 4}) + .setA4ByteArray(new int[] {1, 2, 3, 4}) + .setA8ByteArray(new long[] {1, 2, 3, 4}) + .setAFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}) + .setAList(Arrays.asList(new int[] {1, 2, 3})) + .setAMap(makeMap("hello", 1234)) + .setAnEnum(CoreTests.AnEnum.ONE) + .build(); + + AllNullableTypes everything = + new AllNullableTypes.Builder() + .setANullableBool(false) + .setANullableInt(1234L) + .setANullableDouble(2.0) + .setANullableString("hello") + .setANullableByteArray(new byte[] {1, 2, 3, 4}) + .setANullable4ByteArray(new int[] {1, 2, 3, 4}) + .setANullable8ByteArray(new long[] {1, 2, 3, 4}) + .setANullableFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}) + .setANullableList(Arrays.asList(new int[] {1, 2, 3})) + .setANullableMap(makeMap("hello", 1234)) + .setNullableMapWithObject(makeStringMap("hello", 1234)) + .build(); + BinaryMessenger binaryMessenger = mock(BinaryMessenger.class); doAnswer( invocation -> { @@ -119,27 +191,7 @@ public void hasValues() { everything, (result) -> { didCall[0] = true; - assertEquals(everything.getANullableBool(), result.getANullableBool()); - assertEquals(everything.getANullableInt(), result.getANullableInt()); - assertEquals(everything.getANullableDouble(), result.getANullableDouble()); - assertEquals(everything.getANullableString(), result.getANullableString()); - assertArrayEquals(everything.getANullableByteArray(), result.getANullableByteArray()); - assertArrayEquals(everything.getANullable4ByteArray(), result.getANullable4ByteArray()); - assertArrayEquals(everything.getANullable8ByteArray(), result.getANullable8ByteArray()); - assertTrue( - floatArraysEqual( - everything.getANullableFloatArray(), result.getANullableFloatArray())); - assertArrayEquals( - everything.getANullableList().toArray(), result.getANullableList().toArray()); - assertArrayEquals( - everything.getANullableMap().keySet().toArray(), - result.getANullableMap().keySet().toArray()); - assertArrayEquals( - everything.getANullableMap().values().toArray(), - result.getANullableMap().values().toArray()); - assertArrayEquals( - everything.getNullableMapWithObject().values().toArray(), - result.getNullableMapWithObject().values().toArray()); + compareAllNullableTypes(everything, result); }); assertTrue(didCall[0]); } 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 843232acf3a3..1df7a3457541 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 @@ -87,17 +87,22 @@ - (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull) return aMap; } -- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper +- (nullable AllClassesWrapper *)echoClassWrapper:(AllClassesWrapper *)wrapper + error:(FlutterError *_Nullable *_Nonnull)error { + return wrapper; +} + +- (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrapper error:(FlutterError *_Nullable *_Nonnull)error { - return wrapper.values.aNullableString; + return wrapper.allNullableTypes.aNullableString; } -- (nullable AllNullableTypesWrapper *) +- (nullable AllClassesWrapper *) createNestedObjectWithNullableString:(nullable NSString *)nullableString error:(FlutterError *_Nullable *_Nonnull)error { AllNullableTypes *innerObject = [[AllNullableTypes alloc] init]; innerObject.aNullableString = nullableString; - return [AllNullableTypesWrapper makeWithValues:innerObject]; + return [AllClassesWrapper makeWithAllNullableTypes:innerObject allTypes:nil]; } - (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber *)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 cbe0a6a80f4a..185e866273b7 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 @@ -22,9 +22,10 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @class AllTypes; @class AllNullableTypes; -@class AllNullableTypesWrapper; +@class AllClassesWrapper; @class TestMessage; +/// A class containing all supported types. @interface AllTypes : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; @@ -54,6 +55,7 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, copy) NSString *aString; @end +/// A class containing all supported nullable types. @interface AllNullableTypes : NSObject + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool aNullableInt:(nullable NSNumber *)aNullableInt @@ -89,11 +91,18 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, copy, nullable) NSString *aNullableString; @end -@interface AllNullableTypesWrapper : NSObject +/// 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). +@interface AllClassesWrapper : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithValues:(AllNullableTypes *)values; -@property(nonatomic, strong) AllNullableTypes *values; ++ (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes + allTypes:(nullable AllTypes *)allTypes; +@property(nonatomic, strong) AllNullableTypes *allNullableTypes; +@property(nonatomic, strong, nullable) AllTypes *allTypes; @end /// A data class containing a List, used in unit tests. @@ -159,18 +168,23 @@ NSObject *HostIntegrationCoreApiGetCodec(void); /// @return `nil` only when `error != nil`. - (nullable NSDictionary *)echoMap:(NSDictionary *)aMap error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map to test nested class serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable AllClassesWrapper *)echoClassWrapper:(AllClassesWrapper *)wrapper + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the passed object, to test serialization and deserialization. - (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes *)everything error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. -- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper +- (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrapper error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. /// /// @return `nil` only when `error != nil`. -- (nullable AllNullableTypesWrapper *) +- (nullable AllClassesWrapper *) createNestedObjectWithNullableString:(nullable NSString *)nullableString error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in arguments of multiple types. 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 34c07a7a091b..510b9a8f96b0 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 @@ -42,9 +42,9 @@ + (nullable AllNullableTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@interface AllNullableTypesWrapper () -+ (AllNullableTypesWrapper *)fromList:(NSArray *)list; -+ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list; +@interface AllClassesWrapper () ++ (AllClassesWrapper *)fromList:(NSArray *)list; ++ (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end @@ -208,24 +208,29 @@ - (NSArray *)toList { } @end -@implementation AllNullableTypesWrapper -+ (instancetype)makeWithValues:(AllNullableTypes *)values { - AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init]; - pigeonResult.values = values; +@implementation AllClassesWrapper ++ (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes + allTypes:(nullable AllTypes *)allTypes { + AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; + pigeonResult.allNullableTypes = allNullableTypes; + pigeonResult.allTypes = allTypes; return pigeonResult; } -+ (AllNullableTypesWrapper *)fromList:(NSArray *)list { - AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init]; - pigeonResult.values = [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))]; - NSAssert(pigeonResult.values != nil, @""); ++ (AllClassesWrapper *)fromList:(NSArray *)list { + AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; + pigeonResult.allNullableTypes = + [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))]; + NSAssert(pigeonResult.allNullableTypes != nil, @""); + pigeonResult.allTypes = [AllTypes nullableFromList:(GetNullableObjectAtIndex(list, 1))]; return pigeonResult; } -+ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list { - return (list) ? [AllNullableTypesWrapper fromList:list] : nil; ++ (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list { + return (list) ? [AllClassesWrapper fromList:list] : nil; } - (NSArray *)toList { return @[ - (self.values ? [self.values toList] : [NSNull null]), + (self.allNullableTypes ? [self.allNullableTypes toList] : [NSNull null]), + (self.allTypes ? [self.allTypes toList] : [NSNull null]), ]; } @end @@ -257,9 +262,9 @@ @implementation HostIntegrationCoreApiCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { case 128: - return [AllNullableTypes fromList:[self readValue]]; + return [AllClassesWrapper fromList:[self readValue]]; case 129: - return [AllNullableTypesWrapper fromList:[self readValue]]; + return [AllNullableTypes fromList:[self readValue]]; case 130: return [AllTypes fromList:[self readValue]]; case 131: @@ -274,10 +279,10 @@ @interface HostIntegrationCoreApiCodecWriter : FlutterStandardWriter @end @implementation HostIntegrationCoreApiCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[AllNullableTypes class]]) { + if ([value isKindOfClass:[AllClassesWrapper class]]) { [self writeByte:128]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) { + } else if ([value isKindOfClass:[AllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[AllTypes class]]) { @@ -587,6 +592,28 @@ void HostIntegrationCoreApiSetup(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns the passed map to test nested class serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper" + binaryMessenger:binaryMessenger + codec:HostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(echoClassWrapper:error:)], + @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoClassWrapper:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + AllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + AllClassesWrapper *output = [api echoClassWrapper:arg_wrapper error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] @@ -623,7 +650,7 @@ void HostIntegrationCoreApiSetup(id binaryMessenger, api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + AllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); FlutterError *error; NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error]; callback(wrapResult(output, error)); @@ -648,8 +675,8 @@ void HostIntegrationCoreApiSetup(id binaryMessenger, NSArray *args = message; NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllNullableTypesWrapper *output = - [api createNestedObjectWithNullableString:arg_nullableString error:&error]; + AllClassesWrapper *output = [api createNestedObjectWithNullableString:arg_nullableString + error:&error]; callback(wrapResult(output, error)); }]; } else { @@ -1797,9 +1824,9 @@ @implementation FlutterIntegrationCoreApiCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { case 128: - return [AllNullableTypes fromList:[self readValue]]; + return [AllClassesWrapper fromList:[self readValue]]; case 129: - return [AllNullableTypesWrapper fromList:[self readValue]]; + return [AllNullableTypes fromList:[self readValue]]; case 130: return [AllTypes fromList:[self readValue]]; case 131: @@ -1814,10 +1841,10 @@ @interface FlutterIntegrationCoreApiCodecWriter : FlutterStandardWriter @end @implementation FlutterIntegrationCoreApiCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[AllNullableTypes class]]) { + if ([value isKindOfClass:[AllClassesWrapper class]]) { [self writeByte:128]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) { + } else if ([value isKindOfClass:[AllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[AllTypes class]]) { diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/lib/main.dart b/packages/pigeon/platform_tests/alternate_language_test_plugin/lib/main.dart new file mode 100644 index 000000000000..84de3a47beda --- /dev/null +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/lib/main.dart @@ -0,0 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// There is intentionally no code here; tests use generated Pigeon APIs +// directly, as wrapping them in a plugin would just add maintenance burden +// when changing tests. 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 276b9a05f4ab..488ff0dfb2c2 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 @@ -87,17 +87,22 @@ - (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull) return aMap; } -- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper +- (nullable AllClassesWrapper *)echoClassWrapper:(AllClassesWrapper *)wrapper + error:(FlutterError *_Nullable *_Nonnull)error { + return wrapper; +} + +- (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrapper error:(FlutterError *_Nullable *_Nonnull)error { - return wrapper.values.aNullableString; + return wrapper.allNullableTypes.aNullableString; } -- (nullable AllNullableTypesWrapper *) +- (nullable AllClassesWrapper *) createNestedObjectWithNullableString:(nullable NSString *)nullableString error:(FlutterError *_Nullable *_Nonnull)error { AllNullableTypes *innerObject = [[AllNullableTypes alloc] init]; innerObject.aNullableString = nullableString; - return [AllNullableTypesWrapper makeWithValues:innerObject]; + return [AllClassesWrapper makeWithAllNullableTypes:innerObject allTypes:nil]; } - (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool 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 cbe0a6a80f4a..185e866273b7 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 @@ -22,9 +22,10 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @class AllTypes; @class AllNullableTypes; -@class AllNullableTypesWrapper; +@class AllClassesWrapper; @class TestMessage; +/// A class containing all supported types. @interface AllTypes : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; @@ -54,6 +55,7 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, copy) NSString *aString; @end +/// A class containing all supported nullable types. @interface AllNullableTypes : NSObject + (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool aNullableInt:(nullable NSNumber *)aNullableInt @@ -89,11 +91,18 @@ typedef NS_ENUM(NSUInteger, AnEnum) { @property(nonatomic, copy, nullable) NSString *aNullableString; @end -@interface AllNullableTypesWrapper : NSObject +/// 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). +@interface AllClassesWrapper : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithValues:(AllNullableTypes *)values; -@property(nonatomic, strong) AllNullableTypes *values; ++ (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes + allTypes:(nullable AllTypes *)allTypes; +@property(nonatomic, strong) AllNullableTypes *allNullableTypes; +@property(nonatomic, strong, nullable) AllTypes *allTypes; @end /// A data class containing a List, used in unit tests. @@ -159,18 +168,23 @@ NSObject *HostIntegrationCoreApiGetCodec(void); /// @return `nil` only when `error != nil`. - (nullable NSDictionary *)echoMap:(NSDictionary *)aMap error:(FlutterError *_Nullable *_Nonnull)error; +/// Returns the passed map to test nested class serialization and deserialization. +/// +/// @return `nil` only when `error != nil`. +- (nullable AllClassesWrapper *)echoClassWrapper:(AllClassesWrapper *)wrapper + error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the passed object, to test serialization and deserialization. - (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes *)everything error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. -- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper +- (nullable NSString *)extractNestedNullableStringFrom:(AllClassesWrapper *)wrapper error:(FlutterError *_Nullable *_Nonnull)error; /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. /// /// @return `nil` only when `error != nil`. -- (nullable AllNullableTypesWrapper *) +- (nullable AllClassesWrapper *) createNestedObjectWithNullableString:(nullable NSString *)nullableString error:(FlutterError *_Nullable *_Nonnull)error; /// Returns passed in arguments of multiple types. 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 34c07a7a091b..510b9a8f96b0 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 @@ -42,9 +42,9 @@ + (nullable AllNullableTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@interface AllNullableTypesWrapper () -+ (AllNullableTypesWrapper *)fromList:(NSArray *)list; -+ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list; +@interface AllClassesWrapper () ++ (AllClassesWrapper *)fromList:(NSArray *)list; ++ (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end @@ -208,24 +208,29 @@ - (NSArray *)toList { } @end -@implementation AllNullableTypesWrapper -+ (instancetype)makeWithValues:(AllNullableTypes *)values { - AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init]; - pigeonResult.values = values; +@implementation AllClassesWrapper ++ (instancetype)makeWithAllNullableTypes:(AllNullableTypes *)allNullableTypes + allTypes:(nullable AllTypes *)allTypes { + AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; + pigeonResult.allNullableTypes = allNullableTypes; + pigeonResult.allTypes = allTypes; return pigeonResult; } -+ (AllNullableTypesWrapper *)fromList:(NSArray *)list { - AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init]; - pigeonResult.values = [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))]; - NSAssert(pigeonResult.values != nil, @""); ++ (AllClassesWrapper *)fromList:(NSArray *)list { + AllClassesWrapper *pigeonResult = [[AllClassesWrapper alloc] init]; + pigeonResult.allNullableTypes = + [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))]; + NSAssert(pigeonResult.allNullableTypes != nil, @""); + pigeonResult.allTypes = [AllTypes nullableFromList:(GetNullableObjectAtIndex(list, 1))]; return pigeonResult; } -+ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list { - return (list) ? [AllNullableTypesWrapper fromList:list] : nil; ++ (nullable AllClassesWrapper *)nullableFromList:(NSArray *)list { + return (list) ? [AllClassesWrapper fromList:list] : nil; } - (NSArray *)toList { return @[ - (self.values ? [self.values toList] : [NSNull null]), + (self.allNullableTypes ? [self.allNullableTypes toList] : [NSNull null]), + (self.allTypes ? [self.allTypes toList] : [NSNull null]), ]; } @end @@ -257,9 +262,9 @@ @implementation HostIntegrationCoreApiCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { case 128: - return [AllNullableTypes fromList:[self readValue]]; + return [AllClassesWrapper fromList:[self readValue]]; case 129: - return [AllNullableTypesWrapper fromList:[self readValue]]; + return [AllNullableTypes fromList:[self readValue]]; case 130: return [AllTypes fromList:[self readValue]]; case 131: @@ -274,10 +279,10 @@ @interface HostIntegrationCoreApiCodecWriter : FlutterStandardWriter @end @implementation HostIntegrationCoreApiCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[AllNullableTypes class]]) { + if ([value isKindOfClass:[AllClassesWrapper class]]) { [self writeByte:128]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) { + } else if ([value isKindOfClass:[AllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[AllTypes class]]) { @@ -587,6 +592,28 @@ void HostIntegrationCoreApiSetup(id binaryMessenger, [channel setMessageHandler:nil]; } } + /// Returns the passed map to test nested class serialization and deserialization. + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper" + binaryMessenger:binaryMessenger + codec:HostIntegrationCoreApiGetCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(echoClassWrapper:error:)], + @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoClassWrapper:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + AllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + AllClassesWrapper *output = [api echoClassWrapper:arg_wrapper error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } /// Returns the passed object, to test serialization and deserialization. { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] @@ -623,7 +650,7 @@ void HostIntegrationCoreApiSetup(id binaryMessenger, api); [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { NSArray *args = message; - AllNullableTypesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); + AllClassesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0); FlutterError *error; NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error]; callback(wrapResult(output, error)); @@ -648,8 +675,8 @@ void HostIntegrationCoreApiSetup(id binaryMessenger, NSArray *args = message; NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0); FlutterError *error; - AllNullableTypesWrapper *output = - [api createNestedObjectWithNullableString:arg_nullableString error:&error]; + AllClassesWrapper *output = [api createNestedObjectWithNullableString:arg_nullableString + error:&error]; callback(wrapResult(output, error)); }]; } else { @@ -1797,9 +1824,9 @@ @implementation FlutterIntegrationCoreApiCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { case 128: - return [AllNullableTypes fromList:[self readValue]]; + return [AllClassesWrapper fromList:[self readValue]]; case 129: - return [AllNullableTypesWrapper fromList:[self readValue]]; + return [AllNullableTypes fromList:[self readValue]]; case 130: return [AllTypes fromList:[self readValue]]; case 131: @@ -1814,10 +1841,10 @@ @interface FlutterIntegrationCoreApiCodecWriter : FlutterStandardWriter @end @implementation FlutterIntegrationCoreApiCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[AllNullableTypes class]]) { + if ([value isKindOfClass:[AllClassesWrapper class]]) { [self writeByte:128]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) { + } else if ([value isKindOfClass:[AllNullableTypes class]]) { [self writeByte:129]; [self writeValue:[value toList]]; } else if ([value isKindOfClass:[AllTypes class]]) { diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart index 8cd39604220b..a66b1c5cb91a 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import @@ -188,23 +188,30 @@ class AllNullableTypes { } } -class AllNullableTypesWrapper { - AllNullableTypesWrapper({ - required this.values, +class AllClassesWrapper { + AllClassesWrapper({ + required this.allNullableTypes, + this.allTypes, }); - AllNullableTypes values; + AllNullableTypes allNullableTypes; + + AllTypes? allTypes; Object encode() { return [ - values.encode(), + allNullableTypes.encode(), + allTypes?.encode(), ]; } - static AllNullableTypesWrapper decode(Object result) { + static AllClassesWrapper decode(Object result) { result as List; - return AllNullableTypesWrapper( - values: AllNullableTypes.decode(result[0]! as List), + return AllClassesWrapper( + allNullableTypes: AllNullableTypes.decode(result[0]! as List), + allTypes: result[1] != null + ? AllTypes.decode(result[1]! as List) + : null, ); } } @@ -235,10 +242,10 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { const _HostIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllNullableTypes) { + if (value is AllClassesWrapper) { buffer.putUint8(128); writeValue(buffer, value.encode()); - } else if (value is AllNullableTypesWrapper) { + } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is AllTypes) { @@ -256,9 +263,9 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: - return AllNullableTypes.decode(readValue(buffer)!); + return AllClassesWrapper.decode(readValue(buffer)!); case 129: - return AllNullableTypesWrapper.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); case 130: return AllTypes.decode(readValue(buffer)!); case 131: @@ -622,6 +629,35 @@ class HostIntegrationCoreApi { } } + /// Returns the passed map to test nested class serialization and deserialization. + Future echoClassWrapper( + AllClassesWrapper arg_wrapper) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_wrapper]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as AllClassesWrapper?)!; + } + } + /// Returns the passed object, to test serialization and deserialization. Future echoAllNullableTypes( AllNullableTypes? arg_everything) async { @@ -649,7 +685,7 @@ class HostIntegrationCoreApi { /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. Future extractNestedNullableString( - AllNullableTypesWrapper arg_wrapper) async { + AllClassesWrapper arg_wrapper) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString', codec, @@ -674,7 +710,7 @@ class HostIntegrationCoreApi { /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - Future createNestedNullableString( + Future createNestedNullableString( String? arg_nullableString) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString', @@ -699,7 +735,7 @@ class HostIntegrationCoreApi { message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as AllNullableTypesWrapper?)!; + return (replyList[0] as AllClassesWrapper?)!; } } @@ -1970,10 +2006,10 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { const _FlutterIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllNullableTypes) { + if (value is AllClassesWrapper) { buffer.putUint8(128); writeValue(buffer, value.encode()); - } else if (value is AllNullableTypesWrapper) { + } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is AllTypes) { @@ -1991,9 +2027,9 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: - return AllNullableTypes.decode(readValue(buffer)!); + return AllClassesWrapper.decode(readValue(buffer)!); case 129: - return AllNullableTypesWrapper.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); case 130: return AllTypes.decode(readValue(buffer)!); case 131: diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/flutter_unittests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/flutter_unittests.gen.dart index f8e8b21584f7..fc3f96d8c501 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/flutter_unittests.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/flutter_unittests.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart index 6cfd7a3ece5c..9790d321d4b9 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart index 6fa2ee5d5f5d..8c344ea46495 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart index 379e13700b28..77a0e1e0c4c4 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart index 50ae58f3bda7..f001b42b1a88 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.gen.dart index c5981a987d90..1590e7c575a7 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v9.2.5), do not edit directly. +// Autogenerated from Pigeon (v10.1.1), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import 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 730dedfc9d49..0a22cbeb735d 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 @@ -39,6 +39,92 @@ enum TargetGenerator { void runPigeonIntegrationTests(TargetGenerator targetGenerator) { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + void compareAllTypes(AllTypes? allTypesOne, AllTypes? allTypesTwo) { + expect(allTypesOne == null, allTypesTwo == null); + if (allTypesOne == null || allTypesTwo == null) { + return; + } + expect(allTypesOne.aBool, allTypesTwo.aBool); + expect(allTypesOne.anInt, allTypesTwo.anInt); + expect(allTypesOne.anInt64, allTypesTwo.anInt64); + expect(allTypesOne.aDouble, allTypesTwo.aDouble); + expect(allTypesOne.aString, allTypesTwo.aString); + expect(allTypesOne.aByteArray, allTypesTwo.aByteArray); + expect(allTypesOne.a4ByteArray, allTypesTwo.a4ByteArray); + expect(allTypesOne.a8ByteArray, allTypesTwo.a8ByteArray); + expect(allTypesOne.aFloatArray, allTypesTwo.aFloatArray); + expect(listEquals(allTypesOne.aList, allTypesTwo.aList), true); + expect(mapEquals(allTypesOne.aMap, allTypesTwo.aMap), true); + expect(allTypesOne.anEnum, allTypesTwo.anEnum); + } + + void compareAllNullableTypes(AllNullableTypes? allNullableTypesOne, + AllNullableTypes? 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); + // TODO(stuartmorgan): Fix and re-enable. + // See https://github.com/flutter/flutter/issues/118733 + if (targetGenerator != TargetGenerator.objc) { + expect( + allNullableTypesOne.aNullableEnum, allNullableTypesTwo.aNullableEnum); + } + } + + void compareAllClassesWrapper( + AllClassesWrapper? wrapperOne, AllClassesWrapper? wrapperTwo) { + expect(wrapperOne == null, wrapperTwo == null); + if (wrapperOne == null || wrapperTwo == null) { + return; + } + + compareAllNullableTypes( + wrapperOne.allNullableTypes, wrapperTwo.allNullableTypes); + compareAllTypes(wrapperOne.allTypes, wrapperTwo.allTypes); + } + final AllTypes genericAllTypes = AllTypes( aBool: true, anInt: _regularInt, @@ -49,8 +135,14 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { a4ByteArray: Int32List.fromList([4, 5, 6]), a8ByteArray: Int64List.fromList([7, 8, 9]), aFloatArray: Float64List.fromList([2.71828, _doublePi]), - aList: ['Thing 1', 2, true, 3.14], - aMap: {'a': 1, 'b': 2.0, 'c': 'three', 'd': false}, + aList: ['Thing 1', 2, true, 3.14, null], + aMap: { + 'a': 1, + 'b': 2.0, + 'c': 'three', + 'd': false, + 'e': null + }, anEnum: AnEnum.two, ); @@ -64,12 +156,13 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { 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], + aNullableList: ['Thing 1', 2, true, 3.14, null], aNullableMap: { 'a': 1, 'b': 2.0, 'c': 'three', - 'd': false + 'd': false, + 'e': null }, nullableNestedList: >[ [true, false], @@ -92,19 +185,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); final AllTypes echoObject = await api.echoAllTypes(genericAllTypes); - - expect(echoObject.aBool, genericAllTypes.aBool); - expect(echoObject.anInt, genericAllTypes.anInt); - expect(echoObject.anInt64, genericAllTypes.anInt64); - expect(echoObject.aDouble, genericAllTypes.aDouble); - expect(echoObject.aString, genericAllTypes.aString); - expect(echoObject.aByteArray, genericAllTypes.aByteArray); - expect(echoObject.a4ByteArray, genericAllTypes.a4ByteArray); - expect(echoObject.a8ByteArray, genericAllTypes.a8ByteArray); - expect(echoObject.aFloatArray, genericAllTypes.aFloatArray); - expect(listEquals(echoObject.aList, genericAllTypes.aList), true); - expect(mapEquals(echoObject.aMap, genericAllTypes.aMap), true); - expect(echoObject.anEnum, genericAllTypes.anEnum); + compareAllTypes(echoObject, genericAllTypes); }); testWidgets('all nullable datatypes serialize and deserialize correctly', @@ -113,47 +194,8 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AllNullableTypes? echoObject = await api.echoAllNullableTypes(genericAllNullableTypes); - expect(echoObject?.aNullableBool, genericAllNullableTypes.aNullableBool); - expect(echoObject?.aNullableInt, genericAllNullableTypes.aNullableInt); - expect( - echoObject?.aNullableInt64, genericAllNullableTypes.aNullableInt64); - expect( - echoObject?.aNullableDouble, genericAllNullableTypes.aNullableDouble); - expect( - echoObject?.aNullableString, genericAllNullableTypes.aNullableString); - expect(echoObject?.aNullableByteArray, - genericAllNullableTypes.aNullableByteArray); - expect(echoObject?.aNullable4ByteArray, - genericAllNullableTypes.aNullable4ByteArray); - expect(echoObject?.aNullable8ByteArray, - genericAllNullableTypes.aNullable8ByteArray); - expect(echoObject?.aNullableFloatArray, - genericAllNullableTypes.aNullableFloatArray); - expect( - listEquals( - echoObject?.aNullableList, genericAllNullableTypes.aNullableList), - true); - expect( - mapEquals( - echoObject?.aNullableMap, genericAllNullableTypes.aNullableMap), - true); - expect(echoObject?.nullableNestedList?.length, - genericAllNullableTypes.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 < echoObject?.nullableNestedList!.length; i++) { - // expect(listEquals(echoObject?.nullableNestedList![i], genericAllNullableTypes.nullableNestedList![i]), - // true); - //} - expect( - mapEquals(echoObject?.nullableMapWithAnnotations, - genericAllNullableTypes.nullableMapWithAnnotations), - true); - expect( - mapEquals(echoObject?.nullableMapWithObject, - genericAllNullableTypes.nullableMapWithObject), - true); - expect(echoObject?.aNullableEnum, genericAllNullableTypes.aNullableEnum); + + compareAllNullableTypes(echoObject, genericAllNullableTypes); }); testWidgets('all null datatypes serialize and deserialize correctly', @@ -162,80 +204,36 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AllNullableTypes allTypesNull = AllNullableTypes(); - final AllNullableTypes? echoNullFilledObject = + final AllNullableTypes? echoNullFilledClass = await api.echoAllNullableTypes(allTypesNull); + compareAllNullableTypes(allTypesNull, echoNullFilledClass); + }); - expect(echoNullFilledObject?.aNullableBool, allTypesNull.aNullableBool); - expect(echoNullFilledObject?.aNullableBool, null); - - expect(echoNullFilledObject?.aNullableInt, allTypesNull.aNullableInt); - expect(echoNullFilledObject?.aNullableInt, null); - - expect(echoNullFilledObject?.aNullableInt64, allTypesNull.aNullableInt64); - expect(echoNullFilledObject?.aNullableInt64, null); - - expect( - echoNullFilledObject?.aNullableDouble, allTypesNull.aNullableDouble); - expect(echoNullFilledObject?.aNullableDouble, null); - - expect( - echoNullFilledObject?.aNullableString, allTypesNull.aNullableString); - expect(echoNullFilledObject?.aNullableString, null); - - expect(echoNullFilledObject?.aNullableByteArray, - allTypesNull.aNullableByteArray); - expect(echoNullFilledObject?.aNullableByteArray, null); - - expect(echoNullFilledObject?.aNullable4ByteArray, - allTypesNull.aNullable4ByteArray); - expect(echoNullFilledObject?.aNullable4ByteArray, null); + testWidgets('Classes with list of null serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - expect(echoNullFilledObject?.aNullable8ByteArray, - allTypesNull.aNullable8ByteArray); - expect(echoNullFilledObject?.aNullable8ByteArray, null); + final AllNullableTypes nullableListTypes = + AllNullableTypes(aNullableList: ['String', null]); - expect(echoNullFilledObject?.aNullableFloatArray, - allTypesNull.aNullableFloatArray); - expect(echoNullFilledObject?.aNullableFloatArray, null); + final AllNullableTypes? echoNullFilledClass = + await api.echoAllNullableTypes(nullableListTypes); - expect( - listEquals( - echoNullFilledObject?.aNullableList, allTypesNull.aNullableList), - true); - expect(echoNullFilledObject?.aNullableList, null); + compareAllNullableTypes(nullableListTypes, echoNullFilledClass); + }); - expect( - mapEquals( - echoNullFilledObject?.aNullableMap, allTypesNull.aNullableMap), - true); - expect(echoNullFilledObject?.aNullableMap, null); - - // TODO(stuartmorgan): Enable this once the Dart types are fixed; see - // https://github.com/flutter/flutter/issues/116117 - //for (int i = 0; i < echoNullFilledObject?.nullableNestedList!.length; i++) { - // expect(listEquals(echoNullFilledObject?.nullableNestedList![i], allTypesNull.nullableNestedList![i]), - // true); - //} - expect(echoNullFilledObject?.nullableNestedList, null); + testWidgets('Classes with map of null serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - expect( - mapEquals(echoNullFilledObject?.nullableMapWithAnnotations, - allTypesNull.nullableMapWithAnnotations), - true); - expect(echoNullFilledObject?.nullableMapWithAnnotations, null); + final AllNullableTypes nullableListTypes = AllNullableTypes( + aNullableMap: {'String': 'string', 'null': null}); - expect( - mapEquals(echoNullFilledObject?.nullableMapWithObject, - allTypesNull.nullableMapWithObject), - true); - expect(echoNullFilledObject?.nullableMapWithObject, null); + final AllNullableTypes? echoNullFilledClass = + await api.echoAllNullableTypes(nullableListTypes); - expect(echoNullFilledObject?.aNullableEnum, allTypesNull.aNullableEnum); - expect(echoNullFilledObject?.aNullableEnum, null); - }, - // TODO(stuartmorgan): Fix and re-enable. - // See https://github.com/flutter/flutter/issues/118733 - skip: targetGenerator == TargetGenerator.objc); + compareAllNullableTypes(nullableListTypes, echoNullFilledClass); + }); testWidgets('errors are returned correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -270,12 +268,12 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('nested objects can be sent correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllNullableTypesWrapper sentObject = - AllNullableTypesWrapper(values: genericAllNullableTypes); + final AllClassesWrapper sentObject = AllClassesWrapper( + allNullableTypes: genericAllNullableTypes, allTypes: genericAllTypes); final String? receivedString = await api.extractNestedNullableString(sentObject); - expect(receivedString, sentObject.values.aNullableString); + expect(receivedString, sentObject.allNullableTypes.aNullableString); }); testWidgets('nested objects can be received correctly', @@ -283,9 +281,33 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); const String sentString = 'Some string'; - final AllNullableTypesWrapper receivedObject = + final AllClassesWrapper receivedObject = await api.createNestedNullableString(sentString); - expect(receivedObject.values.aNullableString, sentString); + expect(receivedObject.allNullableTypes.aNullableString, sentString); + }); + + testWidgets('nested classes can serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllClassesWrapper sentWrapper = AllClassesWrapper( + allNullableTypes: AllNullableTypes(), allTypes: genericAllTypes); + + final AllClassesWrapper receivedClassWrapper = + await api.echoClassWrapper(sentWrapper); + compareAllClassesWrapper(sentWrapper, receivedClassWrapper); + }); + + testWidgets('nested null classes can serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllClassesWrapper sentWrapper = + AllClassesWrapper(allNullableTypes: AllNullableTypes()); + + final AllClassesWrapper receivedClassWrapper = + await api.echoClassWrapper(sentWrapper); + compareAllClassesWrapper(sentWrapper, receivedClassWrapper); }); testWidgets( @@ -308,11 +330,11 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllNullableTypes echoNullFilledObject = + final AllNullableTypes echoNullFilledClass = await api.sendMultipleNullableTypes(null, null, null); - expect(echoNullFilledObject.aNullableInt, null); - expect(echoNullFilledObject.aNullableBool, null); - expect(echoNullFilledObject.aNullableString, null); + expect(echoNullFilledClass.aNullableInt, null); + expect(echoNullFilledClass.aNullableBool, null); + expect(echoNullFilledClass.aNullableString, null); }); testWidgets('Int serialize and deserialize correctly', @@ -549,7 +571,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const List sentObject = [7, 'Hello Dart!']; + const List sentObject = [7, 'Hello Dart!', null]; final List? echoObject = await api.echoNullableList(sentObject); expect(listEquals(echoObject, sentObject), true); }); @@ -562,6 +584,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { 'a': 1, 'b': 2.3, 'c': 'four', + 'd': null, }; final Map? echoObject = await api.echoNullableMap(sentObject); @@ -630,18 +653,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AllTypes echoObject = await api.echoAsyncAllTypes(genericAllTypes); - expect(echoObject.aBool, genericAllTypes.aBool); - expect(echoObject.anInt, genericAllTypes.anInt); - expect(echoObject.anInt64, genericAllTypes.anInt64); - expect(echoObject.aDouble, genericAllTypes.aDouble); - expect(echoObject.aString, genericAllTypes.aString); - expect(echoObject.aByteArray, genericAllTypes.aByteArray); - expect(echoObject.a4ByteArray, genericAllTypes.a4ByteArray); - expect(echoObject.a8ByteArray, genericAllTypes.a8ByteArray); - expect(echoObject.aFloatArray, genericAllTypes.aFloatArray); - expect(listEquals(echoObject.aList, genericAllTypes.aList), true); - expect(mapEquals(echoObject.aMap, genericAllTypes.aMap), true); - expect(echoObject.anEnum, genericAllTypes.anEnum); + compareAllTypes(echoObject, genericAllTypes); }); testWidgets( @@ -651,47 +663,8 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AllNullableTypes? echoObject = await api.echoAsyncNullableAllNullableTypes(genericAllNullableTypes); - expect(echoObject?.aNullableBool, genericAllNullableTypes.aNullableBool); - expect(echoObject?.aNullableInt, genericAllNullableTypes.aNullableInt); - expect( - echoObject?.aNullableInt64, genericAllNullableTypes.aNullableInt64); - expect( - echoObject?.aNullableDouble, genericAllNullableTypes.aNullableDouble); - expect( - echoObject?.aNullableString, genericAllNullableTypes.aNullableString); - expect(echoObject?.aNullableByteArray, - genericAllNullableTypes.aNullableByteArray); - expect(echoObject?.aNullable4ByteArray, - genericAllNullableTypes.aNullable4ByteArray); - expect(echoObject?.aNullable8ByteArray, - genericAllNullableTypes.aNullable8ByteArray); - expect(echoObject?.aNullableFloatArray, - genericAllNullableTypes.aNullableFloatArray); - expect( - listEquals( - echoObject?.aNullableList, genericAllNullableTypes.aNullableList), - true); - expect( - mapEquals( - echoObject?.aNullableMap, genericAllNullableTypes.aNullableMap), - true); - expect(echoObject?.nullableNestedList?.length, - genericAllNullableTypes.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 < echoObject?.nullableNestedList!.length; i++) { - // expect(listEquals(echoObject?.nullableNestedList![i], genericAllNullableTypes.nullableNestedList![i]), - // true); - //} - expect( - mapEquals(echoObject?.nullableMapWithAnnotations, - genericAllNullableTypes.nullableMapWithAnnotations), - true); - expect( - mapEquals(echoObject?.nullableMapWithObject, - genericAllNullableTypes.nullableMapWithObject), - true); - expect(echoObject?.aNullableEnum, genericAllNullableTypes.aNullableEnum); + + compareAllNullableTypes(echoObject, genericAllNullableTypes); }); testWidgets('all null datatypes async serialize and deserialize correctly', @@ -700,80 +673,10 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AllNullableTypes allTypesNull = AllNullableTypes(); - final AllNullableTypes? echoNullFilledObject = + final AllNullableTypes? echoNullFilledClass = await api.echoAsyncNullableAllNullableTypes(allTypesNull); - - expect(echoNullFilledObject?.aNullableBool, allTypesNull.aNullableBool); - expect(echoNullFilledObject?.aNullableBool, null); - - expect(echoNullFilledObject?.aNullableInt, allTypesNull.aNullableInt); - expect(echoNullFilledObject?.aNullableInt, null); - - expect(echoNullFilledObject?.aNullableInt64, allTypesNull.aNullableInt64); - expect(echoNullFilledObject?.aNullableInt64, null); - - expect( - echoNullFilledObject?.aNullableDouble, allTypesNull.aNullableDouble); - expect(echoNullFilledObject?.aNullableDouble, null); - - expect( - echoNullFilledObject?.aNullableString, allTypesNull.aNullableString); - expect(echoNullFilledObject?.aNullableString, null); - - expect(echoNullFilledObject?.aNullableByteArray, - allTypesNull.aNullableByteArray); - expect(echoNullFilledObject?.aNullableByteArray, null); - - expect(echoNullFilledObject?.aNullable4ByteArray, - allTypesNull.aNullable4ByteArray); - expect(echoNullFilledObject?.aNullable4ByteArray, null); - - expect(echoNullFilledObject?.aNullable8ByteArray, - allTypesNull.aNullable8ByteArray); - expect(echoNullFilledObject?.aNullable8ByteArray, null); - - expect(echoNullFilledObject?.aNullableFloatArray, - allTypesNull.aNullableFloatArray); - expect(echoNullFilledObject?.aNullableFloatArray, null); - - expect( - listEquals( - echoNullFilledObject?.aNullableList, allTypesNull.aNullableList), - true); - expect(echoNullFilledObject?.aNullableList, null); - - expect( - mapEquals( - echoNullFilledObject?.aNullableMap, allTypesNull.aNullableMap), - true); - expect(echoNullFilledObject?.aNullableMap, null); - - // TODO(stuartmorgan): Enable this once the Dart types are fixed; see - // https://github.com/flutter/flutter/issues/116117 - //for (int i = 0; i < echoNullFilledObject?.nullableNestedList!.length; i++) { - // expect(listEquals(echoNullFilledObject?.nullableNestedList![i], allTypesNull.nullableNestedList![i]), - // true); - //} - expect(echoNullFilledObject?.nullableNestedList, null); - - expect( - mapEquals(echoNullFilledObject?.nullableMapWithAnnotations, - allTypesNull.nullableMapWithAnnotations), - true); - expect(echoNullFilledObject?.nullableMapWithAnnotations, null); - - expect( - mapEquals(echoNullFilledObject?.nullableMapWithObject, - allTypesNull.nullableMapWithObject), - true); - expect(echoNullFilledObject?.nullableMapWithObject, null); - - expect(echoNullFilledObject?.aNullableEnum, allTypesNull.aNullableEnum); - expect(echoNullFilledObject?.aNullableEnum, null); - }, - // TODO(stuartmorgan): Fix and re-enable. - // See https://github.com/flutter/flutter/issues/118733 - skip: targetGenerator == TargetGenerator.objc); + compareAllNullableTypes(echoNullFilledClass, allTypesNull); + }); testWidgets('Int async serialize and deserialize correctly', (WidgetTester _) async { @@ -1100,18 +1003,7 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final AllTypes echoObject = await api.callFlutterEchoAllTypes(genericAllTypes); - expect(echoObject.aBool, genericAllTypes.aBool); - expect(echoObject.anInt, genericAllTypes.anInt); - expect(echoObject.anInt64, genericAllTypes.anInt64); - expect(echoObject.aDouble, genericAllTypes.aDouble); - expect(echoObject.aString, genericAllTypes.aString); - expect(echoObject.aByteArray, genericAllTypes.aByteArray); - expect(echoObject.a4ByteArray, genericAllTypes.a4ByteArray); - expect(echoObject.a8ByteArray, genericAllTypes.a8ByteArray); - expect(echoObject.aFloatArray, genericAllTypes.aFloatArray); - expect(listEquals(echoObject.aList, genericAllTypes.aList), true); - expect(mapEquals(echoObject.aMap, genericAllTypes.aMap), true); - expect(echoObject.anEnum, genericAllTypes.anEnum); + compareAllTypes(echoObject, genericAllTypes); }); testWidgets( 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 d6878146198b..3920cb36096a 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 @@ -18,6 +18,7 @@ enum AnEnum { three, } +/// A class containing all supported types. class AllTypes { AllTypes({ required this.aBool, @@ -94,6 +95,7 @@ class AllTypes { } } +/// A class containing all supported nullable types. class AllNullableTypes { AllNullableTypes({ this.aNullableBool, @@ -188,23 +190,35 @@ class AllNullableTypes { } } -class AllNullableTypesWrapper { - AllNullableTypesWrapper({ - required this.values, +/// 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({ + required this.allNullableTypes, + this.allTypes, }); - AllNullableTypes values; + AllNullableTypes allNullableTypes; + + AllTypes? allTypes; Object encode() { return [ - values.encode(), + allNullableTypes.encode(), + allTypes?.encode(), ]; } - static AllNullableTypesWrapper decode(Object result) { + static AllClassesWrapper decode(Object result) { result as List; - return AllNullableTypesWrapper( - values: AllNullableTypes.decode(result[0]! as List), + return AllClassesWrapper( + allNullableTypes: AllNullableTypes.decode(result[0]! as List), + allTypes: result[1] != null + ? AllTypes.decode(result[1]! as List) + : null, ); } } @@ -235,10 +249,10 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { const _HostIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllNullableTypes) { + if (value is AllClassesWrapper) { buffer.putUint8(128); writeValue(buffer, value.encode()); - } else if (value is AllNullableTypesWrapper) { + } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is AllTypes) { @@ -256,9 +270,9 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: - return AllNullableTypes.decode(readValue(buffer)!); + return AllClassesWrapper.decode(readValue(buffer)!); case 129: - return AllNullableTypesWrapper.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); case 130: return AllTypes.decode(readValue(buffer)!); case 131: @@ -622,6 +636,35 @@ class HostIntegrationCoreApi { } } + /// Returns the passed map to test nested class serialization and deserialization. + Future echoClassWrapper( + AllClassesWrapper arg_wrapper) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_wrapper]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as AllClassesWrapper?)!; + } + } + /// Returns the passed object, to test serialization and deserialization. Future echoAllNullableTypes( AllNullableTypes? arg_everything) async { @@ -649,7 +692,7 @@ class HostIntegrationCoreApi { /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. Future extractNestedNullableString( - AllNullableTypesWrapper arg_wrapper) async { + AllClassesWrapper arg_wrapper) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString', codec, @@ -674,7 +717,7 @@ class HostIntegrationCoreApi { /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - Future createNestedNullableString( + Future createNestedNullableString( String? arg_nullableString) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString', @@ -699,7 +742,7 @@ class HostIntegrationCoreApi { message: 'Host platform returned null value for non-null return value.', ); } else { - return (replyList[0] as AllNullableTypesWrapper?)!; + return (replyList[0] as AllClassesWrapper?)!; } } @@ -1970,10 +2013,10 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { const _FlutterIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllNullableTypes) { + if (value is AllClassesWrapper) { buffer.putUint8(128); writeValue(buffer, value.encode()); - } else if (value is AllNullableTypesWrapper) { + } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); } else if (value is AllTypes) { @@ -1991,9 +2034,9 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: - return AllNullableTypes.decode(readValue(buffer)!); + return AllClassesWrapper.decode(readValue(buffer)!); case 129: - return AllNullableTypesWrapper.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); case 130: return AllTypes.decode(readValue(buffer)!); case 131: 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 eaf7359de6ab..0404656c16c6 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 @@ -59,7 +59,11 @@ enum class AnEnum(val raw: Int) { } } -/** Generated class from Pigeon that represents data sent in messages. */ +/** + * A class containing all supported types. + * + * Generated class from Pigeon that represents data sent in messages. + */ data class AllTypes ( val aBool: Boolean, val anInt: Long, @@ -111,7 +115,11 @@ data class AllTypes ( } } -/** Generated class from Pigeon that represents data sent in messages. */ +/** + * A class containing all supported nullable types. + * + * Generated class from Pigeon that represents data sent in messages. + */ data class AllNullableTypes ( val aNullableBool: Boolean? = null, val aNullableInt: Long? = null, @@ -174,21 +182,34 @@ data class AllNullableTypes ( } } -/** Generated class from Pigeon that represents data sent in messages. */ -data class AllNullableTypesWrapper ( - val values: AllNullableTypes +/** + * 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). + * + * Generated class from Pigeon that represents data sent in messages. + */ +data class AllClassesWrapper ( + val allNullableTypes: AllNullableTypes, + val allTypes: AllTypes? = null ) { companion object { @Suppress("UNCHECKED_CAST") - fun fromList(list: List): AllNullableTypesWrapper { - val values = AllNullableTypes.fromList(list[0] as List) - return AllNullableTypesWrapper(values) + 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) } } fun toList(): List { return listOf( - values.toList(), + allNullableTypes.toList(), + allTypes?.toList(), ) } } @@ -222,12 +243,12 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() { return when (type) { 128.toByte() -> { return (readValue(buffer) as? List)?.let { - AllNullableTypes.fromList(it) + AllClassesWrapper.fromList(it) } } 129.toByte() -> { return (readValue(buffer) as? List)?.let { - AllNullableTypesWrapper.fromList(it) + AllNullableTypes.fromList(it) } } 130.toByte() -> { @@ -245,11 +266,11 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() { } override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { when (value) { - is AllNullableTypes -> { + is AllClassesWrapper -> { stream.write(128) writeValue(stream, value.toList()) } - is AllNullableTypesWrapper -> { + is AllNullableTypes -> { stream.write(129) writeValue(stream, value.toList()) } @@ -302,18 +323,20 @@ interface HostIntegrationCoreApi { fun echoList(aList: List): List /** Returns the passed map, to test serialization and deserialization. */ fun echoMap(aMap: Map): Map + /** Returns the passed map to test nested class serialization and deserialization. */ + fun echoClassWrapper(wrapper: AllClassesWrapper): AllClassesWrapper /** Returns the passed object, to test serialization and deserialization. */ fun echoAllNullableTypes(everything: AllNullableTypes?): AllNullableTypes? /** * Returns the inner `aString` value from the wrapped object, to test * sending of nested objects. */ - fun extractNestedNullableString(wrapper: AllNullableTypesWrapper): String? + fun extractNestedNullableString(wrapper: AllClassesWrapper): String? /** * Returns the inner `aString` value from the wrapped object, to test * sending of nested objects. */ - fun createNestedNullableString(nullableString: String?): AllNullableTypesWrapper + fun createNestedNullableString(nullableString: String?): AllClassesWrapper /** Returns passed in arguments of multiple types. */ fun sendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?): AllNullableTypes /** Returns passed in int. */ @@ -635,6 +658,24 @@ interface HostIntegrationCoreApi { channel.setMessageHandler(null) } } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val wrapperArg = args[0] as AllClassesWrapper + var wrapped: List + try { + wrapped = listOf(api.echoClassWrapper(wrapperArg)) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", codec) if (api != null) { @@ -658,7 +699,7 @@ interface HostIntegrationCoreApi { if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val wrapperArg = args[0] as AllNullableTypesWrapper + val wrapperArg = args[0] as AllClassesWrapper var wrapped: List try { wrapped = listOf(api.extractNestedNullableString(wrapperArg)) @@ -1666,12 +1707,12 @@ private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() { return when (type) { 128.toByte() -> { return (readValue(buffer) as? List)?.let { - AllNullableTypes.fromList(it) + AllClassesWrapper.fromList(it) } } 129.toByte() -> { return (readValue(buffer) as? List)?.let { - AllNullableTypesWrapper.fromList(it) + AllNullableTypes.fromList(it) } } 130.toByte() -> { @@ -1689,11 +1730,11 @@ private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() { } override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { when (value) { - is AllNullableTypes -> { + is AllClassesWrapper -> { stream.write(128) writeValue(stream, value.toList()) } - is AllNullableTypesWrapper -> { + is AllNullableTypes -> { stream.write(129) writeValue(stream, value.toList()) } 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 1c2b68d8b41e..93a6615752fa 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 @@ -83,12 +83,16 @@ class TestPlugin: FlutterPlugin, HostIntegrationCoreApi { return aMap } - override fun extractNestedNullableString(wrapper: AllNullableTypesWrapper): String? { - return wrapper.values.aNullableString + override fun echoClassWrapper(wrapper: AllClassesWrapper): AllClassesWrapper { + return wrapper } - override fun createNestedNullableString(nullableString: String?): AllNullableTypesWrapper { - return AllNullableTypesWrapper(AllNullableTypes(aNullableString = nullableString)) + override fun extractNestedNullableString(wrapper: AllClassesWrapper): String? { + return wrapper.allNullableTypes.aNullableString + } + + override fun createNestedNullableString(nullableString: String?): AllClassesWrapper { + return AllClassesWrapper(AllNullableTypes(aNullableString = nullableString)) } override fun sendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?): AllNullableTypes { 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 62833efd5df8..09cedf4a2e2d 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 @@ -14,6 +14,43 @@ import java.util.ArrayList internal class AllDatatypesTest: TestCase() { + fun compareAllTypes(firstTypes: AllTypes?, secondTypes: AllTypes?) { + assertEquals(firstTypes == null, secondTypes == null) + if (firstTypes == null || secondTypes == null) { + return + } + assertEquals(firstTypes.aBool, secondTypes.aBool) + assertEquals(firstTypes.anInt, secondTypes.anInt) + assertEquals(firstTypes.anInt64, secondTypes.anInt64) + assertEquals(firstTypes.aDouble, secondTypes.aDouble) + assertEquals(firstTypes.aString, secondTypes.aString) + assertTrue(firstTypes.aByteArray.contentEquals(secondTypes.aByteArray)) + assertTrue(firstTypes.a4ByteArray.contentEquals(secondTypes.a4ByteArray)) + assertTrue(firstTypes.a8ByteArray.contentEquals(secondTypes.a8ByteArray)) + assertTrue(firstTypes.aFloatArray.contentEquals(secondTypes.aFloatArray)) + assertEquals(firstTypes.aList, secondTypes.aList) + assertEquals(firstTypes.aMap, secondTypes.aMap) + assertEquals(firstTypes.anEnum, secondTypes.anEnum) + } + + fun compareAllNullableTypes(firstTypes: AllNullableTypes?, secondTypes: AllNullableTypes?) { + assertEquals(firstTypes == null, secondTypes == null) + if (firstTypes == null || secondTypes == null) { + return + } + assertEquals(firstTypes.aNullableBool, secondTypes.aNullableBool) + assertEquals(firstTypes.aNullableInt, secondTypes.aNullableInt) + assertEquals(firstTypes.aNullableDouble, secondTypes.aNullableDouble) + assertEquals(firstTypes.aNullableString, secondTypes.aNullableString) + assertTrue(firstTypes.aNullableByteArray.contentEquals(secondTypes.aNullableByteArray)) + assertTrue(firstTypes.aNullable4ByteArray.contentEquals(secondTypes.aNullable4ByteArray)) + assertTrue(firstTypes.aNullable8ByteArray.contentEquals(secondTypes.aNullable8ByteArray)) + assertTrue(firstTypes.aNullableFloatArray.contentEquals(secondTypes.aNullableFloatArray)) + assertEquals(firstTypes.aNullableList, secondTypes.aNullableList) + assertEquals(firstTypes.aNullableMap, secondTypes.aNullableMap) + assertEquals(firstTypes.nullableMapWithObject, secondTypes.nullableMapWithObject) + } + @Test fun testNullValues() { val everything = AllNullableTypes() @@ -63,7 +100,7 @@ internal class AllDatatypesTest: TestCase() { aNullableFloatArray = doubleArrayOf(0.5, 0.25, 1.5, 1.25), aNullableList = listOf(1, 2, 3), aNullableMap = mapOf("hello" to 1234), - nullableMapWithObject = mapOf("hello" to 1234) + nullableMapWithObject = mapOf("hello" to 1234), ) val binaryMessenger = mockk() val api = FlutterIntegrationCoreApi(binaryMessenger) @@ -82,17 +119,7 @@ internal class AllDatatypesTest: TestCase() { var didCall = false api.echoAllNullableTypes(everything) { didCall = true - assertEquals(everything.aNullableBool, it.aNullableBool) - assertEquals(everything.aNullableInt, it.aNullableInt) - assertEquals(everything.aNullableDouble, it.aNullableDouble) - assertEquals(everything.aNullableString, it.aNullableString) - assertTrue(everything.aNullableByteArray.contentEquals(it.aNullableByteArray)) - assertTrue(everything.aNullable4ByteArray.contentEquals(it.aNullable4ByteArray)) - assertTrue(everything.aNullable8ByteArray.contentEquals(it.aNullable8ByteArray)) - assertTrue(everything.aNullableFloatArray.contentEquals(it.aNullableFloatArray)) - assertEquals(everything.aNullableList, it.aNullableList) - assertEquals(everything.aNullableMap, it.aNullableMap) - assertEquals(everything.nullableMapWithObject, it.nullableMapWithObject) + compareAllNullableTypes(everything, it) } assertTrue(didCall) diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj b/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj index eb200b273bb5..969f97022ebc 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/Runner.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + E04641FA2A46270400661C9E /* NSNullFieldTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E04641F92A46270400661C9E /* NSNullFieldTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -88,6 +89,7 @@ 9808B6775522250A40D7D452 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; BC37C4E8AE005B445F208C02 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BF5B776B52F984FB430C15A3 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + E04641F92A46270400661C9E /* NSNullFieldTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSNullFieldTests.swift; sourceTree = ""; }; EB04430DB6D43CCC08FA526B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -126,6 +128,7 @@ 33A341C6291ECDFD00D34E0F /* NullableReturnsTests.swift */, 33A341C7291ECDFD00D34E0F /* PrimitiveTests.swift */, 33A341B7291ECCA100D34E0F /* RunnerTests.swift */, + E04641F92A46270400661C9E /* NSNullFieldTests.swift */, 33A341CA291ECDFD00D34E0F /* Utils.swift */, ); path = RunnerTests; @@ -413,6 +416,7 @@ 33A341D5291ECDFD00D34E0F /* AsyncHandlersTest.swift in Sources */, 33A341CE291ECDFD00D34E0F /* EnumTests.swift in Sources */, 33A341CD291ECDFD00D34E0F /* ListTests.swift in Sources */, + E04641FA2A46270400661C9E /* NSNullFieldTests.swift in Sources */, 33A341D1291ECDFD00D34E0F /* MockBinaryMessenger.swift in Sources */, 33A341CF291ECDFD00D34E0F /* NonNullFieldsTest.swift in Sources */, 33A341CB291ECDFD00D34E0F /* MultipleArityTests.swift in Sources */, diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/NSNullFieldTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/NSNullFieldTests.swift new file mode 100644 index 000000000000..036608f2fd8a --- /dev/null +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/NSNullFieldTests.swift @@ -0,0 +1,61 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import XCTest +@testable import test_plugin + +/// Tests NSNull is correctly handled by `nilOrValue` helper, by manually setting nullable fields to NSNull. +final class NSNullFieldTests: XCTestCase { + + func testNSNull_nullListToCustomStructField() throws { + let reply = NullFieldsSearchReply( + result: nil, + error: nil, + indices: nil, + request: nil, + type: nil) + var list = reply.toList() + // request field + list[3] = NSNull() + let copy = NullFieldsSearchReply.fromList(list) + XCTAssertNotNil(copy) + XCTAssertNil(copy!.request) + } + + func testNSNull_nullListField() { + let reply = NullFieldsSearchReply( + result: nil, + error: nil, + indices: nil, + request: nil, + type: nil) + var list = reply.toList() + // indices field + list[2] = NSNull() + let copy = NullFieldsSearchReply.fromList(list) + XCTAssertNotNil(copy) + XCTAssertNil(copy!.indices) + } + + func testNSNull_nullBasicFields() throws { + let reply = NullFieldsSearchReply( + result: nil, + error: nil, + indices: nil, + request: nil, + type: nil) + var list = reply.toList() + // result field + list[0] = NSNull() + // error field + list[1] = NSNull() + // type field + list[4] = NSNull() + let copy = NullFieldsSearchReply.fromList(list) + XCTAssertNotNil(copy) + XCTAssertNil(copy!.result) + XCTAssertNil(copy!.error) + XCTAssertNil(copy!.type) + } +} 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 4c1dfa08b169..a2dd43f5bce9 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 @@ -44,6 +44,8 @@ enum AnEnum: Int { case three = 2 } +/// A class containing all supported types. +/// /// Generated class from Pigeon that represents data sent in messages. struct AllTypes { var aBool: Bool @@ -106,6 +108,8 @@ struct AllTypes { } } +/// A class containing all supported nullable types. +/// /// Generated class from Pigeon that represents data sent in messages. struct AllNullableTypes { var aNullableBool: Bool? = nil @@ -184,20 +188,33 @@ struct AllNullableTypes { } } +/// 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). +/// /// Generated class from Pigeon that represents data sent in messages. -struct AllNullableTypesWrapper { - var values: AllNullableTypes +struct AllClassesWrapper { + var allNullableTypes: AllNullableTypes + var allTypes: AllTypes? = nil - static func fromList(_ list: [Any?]) -> AllNullableTypesWrapper? { - let values = AllNullableTypes.fromList(list[0] as! [Any?])! + static func fromList(_ list: [Any?]) -> AllClassesWrapper? { + let allNullableTypes = AllNullableTypes.fromList(list[0] as! [Any?])! + var allTypes: AllTypes? = nil + if let allTypesList: [Any?] = nilOrValue(list[1]) { + allTypes = AllTypes.fromList(allTypesList) + } - return AllNullableTypesWrapper( - values: values + return AllClassesWrapper( + allNullableTypes: allNullableTypes, + allTypes: allTypes ) } func toList() -> [Any?] { return [ - values.toList(), + allNullableTypes.toList(), + allTypes?.toList(), ] } } @@ -226,9 +243,9 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 128: - return AllNullableTypes.fromList(self.readValue() as! [Any?]) + return AllClassesWrapper.fromList(self.readValue() as! [Any?]) case 129: - return AllNullableTypesWrapper.fromList(self.readValue() as! [Any?]) + return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: return AllTypes.fromList(self.readValue() as! [Any?]) case 131: @@ -241,10 +258,10 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader { private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { - if let value = value as? AllNullableTypes { + if let value = value as? AllClassesWrapper { super.writeByte(128) super.writeValue(value.toList()) - } else if let value = value as? AllNullableTypesWrapper { + } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) } else if let value = value as? AllTypes { @@ -305,14 +322,16 @@ protocol HostIntegrationCoreApi { func echo(_ aList: [Any?]) throws -> [Any?] /// Returns the passed map, to test serialization and deserialization. func echo(_ aMap: [String?: Any?]) throws -> [String?: Any?] + /// Returns the passed map to test nested class serialization and deserialization. + func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper /// Returns the passed object, to test serialization and deserialization. func echo(_ everything: AllNullableTypes?) throws -> AllNullableTypes? /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - func extractNestedNullableString(from wrapper: AllNullableTypesWrapper) throws -> String? + func extractNestedNullableString(from wrapper: AllClassesWrapper) throws -> String? /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - func createNestedObject(with nullableString: String?) throws -> AllNullableTypesWrapper + func createNestedObject(with nullableString: String?) throws -> AllClassesWrapper /// Returns passed in arguments of multiple types. func sendMultipleNullableTypes(aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?) throws -> AllNullableTypes /// Returns passed in int. @@ -604,6 +623,22 @@ class HostIntegrationCoreApiSetup { } else { echoMapChannel.setMessageHandler(nil) } + /// Returns the passed map to test nested class serialization and deserialization. + let echoClassWrapperChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoClassWrapperChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let wrapperArg = args[0] as! AllClassesWrapper + do { + let result = try api.echo(wrapperArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoClassWrapperChannel.setMessageHandler(nil) + } /// Returns the passed object, to test serialization and deserialization. let echoAllNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec) if let api = api { @@ -626,7 +661,7 @@ class HostIntegrationCoreApiSetup { if let api = api { extractNestedNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let wrapperArg = args[0] as! AllNullableTypesWrapper + let wrapperArg = args[0] as! AllClassesWrapper do { let result = try api.extractNestedNullableString(from: wrapperArg) reply(wrapResult(result)) @@ -1514,9 +1549,9 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 128: - return AllNullableTypes.fromList(self.readValue() as! [Any?]) + return AllClassesWrapper.fromList(self.readValue() as! [Any?]) case 129: - return AllNullableTypesWrapper.fromList(self.readValue() as! [Any?]) + return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: return AllTypes.fromList(self.readValue() as! [Any?]) case 131: @@ -1529,10 +1564,10 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader { private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { - if let value = value as? AllNullableTypes { + if let value = value as? AllClassesWrapper { super.writeByte(128) super.writeValue(value.toList()) - } else if let value = value as? AllNullableTypesWrapper { + } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) } else if let value = value as? AllTypes { 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 368dbdeb64fd..315c86c81e28 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift @@ -81,12 +81,16 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return aMap } - func extractNestedNullableString(from wrapper: AllNullableTypesWrapper) -> String? { - return wrapper.values.aNullableString; + func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper { + return wrapper + } + + func extractNestedNullableString(from wrapper: AllClassesWrapper) -> String? { + return wrapper.allNullableTypes.aNullableString; } - func createNestedObject(with nullableString: String?) -> AllNullableTypesWrapper { - return AllNullableTypesWrapper(values: AllNullableTypes(aNullableString: nullableString)) + func createNestedObject(with nullableString: String?) -> AllClassesWrapper { + return AllClassesWrapper(allNullableTypes: AllNullableTypes(aNullableString: nullableString)) } func sendMultipleNullableTypes(aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?) -> AllNullableTypes { 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 4c1dfa08b169..a2dd43f5bce9 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 @@ -44,6 +44,8 @@ enum AnEnum: Int { case three = 2 } +/// A class containing all supported types. +/// /// Generated class from Pigeon that represents data sent in messages. struct AllTypes { var aBool: Bool @@ -106,6 +108,8 @@ struct AllTypes { } } +/// A class containing all supported nullable types. +/// /// Generated class from Pigeon that represents data sent in messages. struct AllNullableTypes { var aNullableBool: Bool? = nil @@ -184,20 +188,33 @@ struct AllNullableTypes { } } +/// 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). +/// /// Generated class from Pigeon that represents data sent in messages. -struct AllNullableTypesWrapper { - var values: AllNullableTypes +struct AllClassesWrapper { + var allNullableTypes: AllNullableTypes + var allTypes: AllTypes? = nil - static func fromList(_ list: [Any?]) -> AllNullableTypesWrapper? { - let values = AllNullableTypes.fromList(list[0] as! [Any?])! + static func fromList(_ list: [Any?]) -> AllClassesWrapper? { + let allNullableTypes = AllNullableTypes.fromList(list[0] as! [Any?])! + var allTypes: AllTypes? = nil + if let allTypesList: [Any?] = nilOrValue(list[1]) { + allTypes = AllTypes.fromList(allTypesList) + } - return AllNullableTypesWrapper( - values: values + return AllClassesWrapper( + allNullableTypes: allNullableTypes, + allTypes: allTypes ) } func toList() -> [Any?] { return [ - values.toList(), + allNullableTypes.toList(), + allTypes?.toList(), ] } } @@ -226,9 +243,9 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 128: - return AllNullableTypes.fromList(self.readValue() as! [Any?]) + return AllClassesWrapper.fromList(self.readValue() as! [Any?]) case 129: - return AllNullableTypesWrapper.fromList(self.readValue() as! [Any?]) + return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: return AllTypes.fromList(self.readValue() as! [Any?]) case 131: @@ -241,10 +258,10 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader { private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { - if let value = value as? AllNullableTypes { + if let value = value as? AllClassesWrapper { super.writeByte(128) super.writeValue(value.toList()) - } else if let value = value as? AllNullableTypesWrapper { + } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) } else if let value = value as? AllTypes { @@ -305,14 +322,16 @@ protocol HostIntegrationCoreApi { func echo(_ aList: [Any?]) throws -> [Any?] /// Returns the passed map, to test serialization and deserialization. func echo(_ aMap: [String?: Any?]) throws -> [String?: Any?] + /// Returns the passed map to test nested class serialization and deserialization. + func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper /// Returns the passed object, to test serialization and deserialization. func echo(_ everything: AllNullableTypes?) throws -> AllNullableTypes? /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - func extractNestedNullableString(from wrapper: AllNullableTypesWrapper) throws -> String? + func extractNestedNullableString(from wrapper: AllClassesWrapper) throws -> String? /// Returns the inner `aString` value from the wrapped object, to test /// sending of nested objects. - func createNestedObject(with nullableString: String?) throws -> AllNullableTypesWrapper + func createNestedObject(with nullableString: String?) throws -> AllClassesWrapper /// Returns passed in arguments of multiple types. func sendMultipleNullableTypes(aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?) throws -> AllNullableTypes /// Returns passed in int. @@ -604,6 +623,22 @@ class HostIntegrationCoreApiSetup { } else { echoMapChannel.setMessageHandler(nil) } + /// Returns the passed map to test nested class serialization and deserialization. + let echoClassWrapperChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + echoClassWrapperChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let wrapperArg = args[0] as! AllClassesWrapper + do { + let result = try api.echo(wrapperArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + echoClassWrapperChannel.setMessageHandler(nil) + } /// Returns the passed object, to test serialization and deserialization. let echoAllNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec) if let api = api { @@ -626,7 +661,7 @@ class HostIntegrationCoreApiSetup { if let api = api { extractNestedNullableStringChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let wrapperArg = args[0] as! AllNullableTypesWrapper + let wrapperArg = args[0] as! AllClassesWrapper do { let result = try api.extractNestedNullableString(from: wrapperArg) reply(wrapResult(result)) @@ -1514,9 +1549,9 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { switch type { case 128: - return AllNullableTypes.fromList(self.readValue() as! [Any?]) + return AllClassesWrapper.fromList(self.readValue() as! [Any?]) case 129: - return AllNullableTypesWrapper.fromList(self.readValue() as! [Any?]) + return AllNullableTypes.fromList(self.readValue() as! [Any?]) case 130: return AllTypes.fromList(self.readValue() as! [Any?]) case 131: @@ -1529,10 +1564,10 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader { private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { - if let value = value as? AllNullableTypes { + if let value = value as? AllClassesWrapper { super.writeByte(128) super.writeValue(value.toList()) - } else if let value = value as? AllNullableTypesWrapper { + } else if let value = value as? AllNullableTypes { super.writeByte(129) super.writeValue(value.toList()) } else if let value = value as? AllTypes { 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 51a68c370e91..d5f27f6aea02 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift @@ -80,12 +80,16 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return aMap } - func extractNestedNullableString(from wrapper: AllNullableTypesWrapper) -> String? { - return wrapper.values.aNullableString; + func echo(_ wrapper: AllClassesWrapper) throws -> AllClassesWrapper { + return wrapper + } + + func extractNestedNullableString(from wrapper: AllClassesWrapper) -> String? { + return wrapper.allNullableTypes.aNullableString; } - func createNestedObject(with nullableString: String?) -> AllNullableTypesWrapper { - return AllNullableTypesWrapper(values: AllNullableTypes(aNullableString: nullableString)) + func createNestedObject(with nullableString: String?) -> AllClassesWrapper { + return AllClassesWrapper(allNullableTypes: AllNullableTypes(aNullableString: nullableString)) } func sendMultipleNullableTypes(aBool aNullableBool: Bool?, anInt aNullableInt: Int64?, aString aNullableString: String?) -> AllNullableTypes { 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 a4a17f99a77e..af8e5a20c455 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 @@ -543,30 +543,56 @@ AllNullableTypes AllNullableTypes::FromEncodableList( return decoded; } -// AllNullableTypesWrapper +// AllClassesWrapper -AllNullableTypesWrapper::AllNullableTypesWrapper(const AllNullableTypes& values) - : values_(values) {} +AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types) + : all_nullable_types_(all_nullable_types) {} -const AllNullableTypes& AllNullableTypesWrapper::values() const { - return values_; +AllClassesWrapper::AllClassesWrapper(const AllNullableTypes& all_nullable_types, + const AllTypes* all_types) + : all_nullable_types_(all_nullable_types), + all_types_(all_types ? std::optional(*all_types) + : std::nullopt) {} + +const AllNullableTypes& AllClassesWrapper::all_nullable_types() const { + return all_nullable_types_; +} + +void AllClassesWrapper::set_all_nullable_types( + const AllNullableTypes& value_arg) { + all_nullable_types_ = value_arg; +} + +const AllTypes* AllClassesWrapper::all_types() const { + return all_types_ ? &(*all_types_) : nullptr; +} + +void AllClassesWrapper::set_all_types(const AllTypes* value_arg) { + all_types_ = value_arg ? std::optional(*value_arg) : std::nullopt; } -void AllNullableTypesWrapper::set_values(const AllNullableTypes& value_arg) { - values_ = value_arg; +void AllClassesWrapper::set_all_types(const AllTypes& value_arg) { + all_types_ = value_arg; } -EncodableList AllNullableTypesWrapper::ToEncodableList() const { +EncodableList AllClassesWrapper::ToEncodableList() const { EncodableList list; - list.reserve(1); - list.push_back(EncodableValue(values_.ToEncodableList())); + list.reserve(2); + list.push_back(EncodableValue(all_nullable_types_.ToEncodableList())); + list.push_back(all_types_ ? EncodableValue(all_types_->ToEncodableList()) + : EncodableValue()); return list; } -AllNullableTypesWrapper AllNullableTypesWrapper::FromEncodableList( +AllClassesWrapper AllClassesWrapper::FromEncodableList( const EncodableList& list) { - AllNullableTypesWrapper decoded( + AllClassesWrapper decoded( AllNullableTypes::FromEncodableList(std::get(list[0]))); + auto& encodable_all_types = list[1]; + if (!encodable_all_types.IsNull()) { + decoded.set_all_types(AllTypes::FromEncodableList( + std::get(encodable_all_types))); + } return decoded; } @@ -614,10 +640,10 @@ EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType( uint8_t type, flutter::ByteStreamReader* stream) const { switch (type) { case 128: - return CustomEncodableValue(AllNullableTypes::FromEncodableList( + return CustomEncodableValue(AllClassesWrapper::FromEncodableList( std::get(ReadValue(stream)))); case 129: - return CustomEncodableValue(AllNullableTypesWrapper::FromEncodableList( + return CustomEncodableValue(AllNullableTypes::FromEncodableList( std::get(ReadValue(stream)))); case 130: return CustomEncodableValue(AllTypes::FromEncodableList( @@ -634,19 +660,18 @@ void HostIntegrationCoreApiCodecSerializer::WriteValue( const EncodableValue& value, flutter::ByteStreamWriter* stream) const { if (const CustomEncodableValue* custom_value = std::get_if(&value)) { - if (custom_value->type() == typeid(AllNullableTypes)) { + if (custom_value->type() == typeid(AllClassesWrapper)) { stream->WriteByte(128); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); + WriteValue(EncodableValue(std::any_cast(*custom_value) + .ToEncodableList()), + stream); return; } - if (custom_value->type() == typeid(AllNullableTypesWrapper)) { + if (custom_value->type() == typeid(AllNullableTypes)) { stream->WriteByte(129); WriteValue( - EncodableValue(std::any_cast(*custom_value) - .ToEncodableList()), + EncodableValue( + std::any_cast(*custom_value).ToEncodableList()), stream); return; } @@ -1090,6 +1115,42 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, channel->SetMessageHandler(nullptr); } } + { + auto channel = std::make_unique>( + binary_messenger, + "dev.flutter.pigeon.HostIntegrationCoreApi.echoClassWrapper", + &GetCodec()); + if (api != nullptr) { + channel->SetMessageHandler( + [api](const EncodableValue& message, + const flutter::MessageReply& reply) { + try { + const auto& args = std::get(message); + const auto& encodable_wrapper_arg = args.at(0); + if (encodable_wrapper_arg.IsNull()) { + reply(WrapError("wrapper_arg unexpectedly null.")); + return; + } + const auto& wrapper_arg = std::any_cast( + std::get(encodable_wrapper_arg)); + ErrorOr output = + api->EchoClassWrapper(wrapper_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); + } + } { auto channel = std::make_unique>( binary_messenger, @@ -1145,9 +1206,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, reply(WrapError("wrapper_arg unexpectedly null.")); return; } - const auto& wrapper_arg = - std::any_cast( - std::get(encodable_wrapper_arg)); + const auto& wrapper_arg = std::any_cast( + std::get(encodable_wrapper_arg)); ErrorOr> output = api->ExtractNestedNullableString(wrapper_arg); if (output.has_error()) { @@ -1185,7 +1245,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& encodable_nullable_string_arg = args.at(0); const auto* nullable_string_arg = std::get_if(&encodable_nullable_string_arg); - ErrorOr output = + ErrorOr output = api->CreateNestedNullableString(nullable_string_arg); if (output.has_error()) { reply(WrapError(output.error())); @@ -3088,10 +3148,10 @@ EncodableValue FlutterIntegrationCoreApiCodecSerializer::ReadValueOfType( uint8_t type, flutter::ByteStreamReader* stream) const { switch (type) { case 128: - return CustomEncodableValue(AllNullableTypes::FromEncodableList( + return CustomEncodableValue(AllClassesWrapper::FromEncodableList( std::get(ReadValue(stream)))); case 129: - return CustomEncodableValue(AllNullableTypesWrapper::FromEncodableList( + return CustomEncodableValue(AllNullableTypes::FromEncodableList( std::get(ReadValue(stream)))); case 130: return CustomEncodableValue(AllTypes::FromEncodableList( @@ -3108,19 +3168,18 @@ void FlutterIntegrationCoreApiCodecSerializer::WriteValue( const EncodableValue& value, flutter::ByteStreamWriter* stream) const { if (const CustomEncodableValue* custom_value = std::get_if(&value)) { - if (custom_value->type() == typeid(AllNullableTypes)) { + if (custom_value->type() == typeid(AllClassesWrapper)) { stream->WriteByte(128); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); + WriteValue(EncodableValue(std::any_cast(*custom_value) + .ToEncodableList()), + stream); return; } - if (custom_value->type() == typeid(AllNullableTypesWrapper)) { + if (custom_value->type() == typeid(AllNullableTypes)) { stream->WriteByte(129); WriteValue( - EncodableValue(std::any_cast(*custom_value) - .ToEncodableList()), + EncodableValue( + std::any_cast(*custom_value).ToEncodableList()), stream); return; } 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 413c19dae72b..67b0302938b1 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 @@ -67,6 +67,8 @@ class ErrorOr { enum class AnEnum { one = 0, two = 1, three = 2 }; +// A class containing all supported types. +// // Generated class from Pigeon that represents data sent in messages. class AllTypes { public: @@ -119,6 +121,7 @@ class AllTypes { private: static AllTypes FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; + friend class AllClassesWrapper; friend class HostIntegrationCoreApi; friend class HostIntegrationCoreApiCodecSerializer; friend class FlutterIntegrationCoreApi; @@ -144,6 +147,8 @@ class AllTypes { std::string a_string_; }; +// A class containing all supported nullable types. +// // Generated class from Pigeon that represents data sent in messages. class AllNullableTypes { public: @@ -230,7 +235,7 @@ class AllNullableTypes { private: static AllNullableTypes FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; - friend class AllNullableTypesWrapper; + friend class AllClassesWrapper; friend class HostIntegrationCoreApi; friend class HostIntegrationCoreApiCodecSerializer; friend class FlutterIntegrationCoreApi; @@ -259,17 +264,31 @@ class AllNullableTypes { std::optional a_nullable_string_; }; +// 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). +// // Generated class from Pigeon that represents data sent in messages. -class AllNullableTypesWrapper { +class AllClassesWrapper { public: + // Constructs an object setting all non-nullable fields. + explicit AllClassesWrapper(const AllNullableTypes& all_nullable_types); + // Constructs an object setting all fields. - explicit AllNullableTypesWrapper(const AllNullableTypes& values); + explicit AllClassesWrapper(const AllNullableTypes& all_nullable_types, + const AllTypes* all_types); + + const AllNullableTypes& all_nullable_types() const; + void set_all_nullable_types(const AllNullableTypes& value_arg); - const AllNullableTypes& values() const; - void set_values(const AllNullableTypes& value_arg); + const AllTypes* all_types() const; + void set_all_types(const AllTypes* value_arg); + void set_all_types(const AllTypes& value_arg); private: - static AllNullableTypesWrapper FromEncodableList( + static AllClassesWrapper FromEncodableList( const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; friend class HostIntegrationCoreApi; @@ -283,7 +302,8 @@ class AllNullableTypesWrapper { friend class FlutterSmallApi; friend class FlutterSmallApiCodecSerializer; friend class CoreTestsTest; - AllNullableTypes values_; + AllNullableTypes all_nullable_types_; + std::optional all_types_; }; // A data class containing a List, used in unit tests. @@ -377,16 +397,20 @@ class HostIntegrationCoreApi { // Returns the passed map, to test serialization and deserialization. virtual ErrorOr EchoMap( const flutter::EncodableMap& a_map) = 0; + // Returns the passed map to test nested class serialization and + // deserialization. + virtual ErrorOr EchoClassWrapper( + const AllClassesWrapper& wrapper) = 0; // Returns the passed object, to test serialization and deserialization. virtual ErrorOr> EchoAllNullableTypes( const AllNullableTypes* everything) = 0; // Returns the inner `aString` value from the wrapped object, to test // sending of nested objects. virtual ErrorOr> ExtractNestedNullableString( - const AllNullableTypesWrapper& wrapper) = 0; + const AllClassesWrapper& wrapper) = 0; // Returns the inner `aString` value from the wrapped object, to test // sending of nested objects. - virtual ErrorOr CreateNestedNullableString( + virtual ErrorOr CreateNestedNullableString( const std::string* nullable_string) = 0; // Returns passed in arguments of multiple types. virtual ErrorOr SendMultipleNullableTypes( 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 713f17bfd306..125771085cea 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp @@ -16,8 +16,8 @@ namespace test_plugin { +using core_tests_pigeontest::AllClassesWrapper; using core_tests_pigeontest::AllNullableTypes; -using core_tests_pigeontest::AllNullableTypesWrapper; using core_tests_pigeontest::AllTypes; using core_tests_pigeontest::ErrorOr; using core_tests_pigeontest::FlutterError; @@ -98,14 +98,20 @@ ErrorOr TestPlugin::EchoMap(const EncodableMap& a_map) { return a_map; } +ErrorOr TestPlugin::EchoClassWrapper( + const AllClassesWrapper& wrapper) { + return wrapper; +} + ErrorOr> TestPlugin::ExtractNestedNullableString( - const AllNullableTypesWrapper& wrapper) { - const std::string* inner_string = wrapper.values().a_nullable_string(); + const AllClassesWrapper& wrapper) { + const std::string* inner_string = + wrapper.all_nullable_types().a_nullable_string(); return inner_string ? std::optional(*inner_string) : std::nullopt; } -ErrorOr TestPlugin::CreateNestedNullableString( +ErrorOr TestPlugin::CreateNestedNullableString( const std::string* nullable_string) { AllNullableTypes inner_object; // The string pointer can't be passed through directly since the setter for @@ -116,7 +122,7 @@ ErrorOr TestPlugin::CreateNestedNullableString( } else { inner_object.set_a_nullable_string(nullptr); } - AllNullableTypesWrapper wrapper(inner_object); + AllClassesWrapper wrapper(inner_object); return wrapper; } 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 c65931d91c74..649d20fab5da 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h @@ -58,10 +58,13 @@ class TestPlugin : public flutter::Plugin, const flutter::EncodableList& a_list) override; core_tests_pigeontest::ErrorOr EchoMap( const flutter::EncodableMap& a_map) override; + core_tests_pigeontest::ErrorOr + EchoClassWrapper( + const core_tests_pigeontest::AllClassesWrapper& wrapper) override; core_tests_pigeontest::ErrorOr> ExtractNestedNullableString( - const core_tests_pigeontest::AllNullableTypesWrapper& wrapper) override; - core_tests_pigeontest::ErrorOr + const core_tests_pigeontest::AllClassesWrapper& wrapper) override; + core_tests_pigeontest::ErrorOr CreateNestedNullableString(const std::string* nullable_string) override; core_tests_pigeontest::ErrorOr SendMultipleNullableTypes(const bool* a_nullable_bool, diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 82531c4a8871..3d2d6a658cf8 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%3Apigeon -version: 10.1.1 # This must match the version in lib/generator_tools.dart +version: 10.1.2 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.19.0 <4.0.0"