[pigeon] Fix Object arguments in Swift and C++ (#3020)

Fixes a warning in generated Swift output when an argument is of type Object. This is blocking flutter/plugins#6914 since we check our macOS and iOS plugin code for warnings in CI.

Rather than add a Dart generator unit test for this one specific case, I tightened the Swift compilation settings for our test plugin to treat warnings as errors (per flutter/flutter#59116 (comment)) to catch the entire class of errors, and added echo* variants for Object to make sure this one then showed up.

Incidental fixes:

I had to make a similar fix to the Dart generator for a similar warning with casting to Object?, which we'd never noticed because we weren't analyzing any generated code that returning Object or Object? before.
I had to make a change to the C++ generator so that generation would succeed, because it turned out we had no handling at all of Object in the C++ generator, causing it to throw. I'm not sure this is the output I'll keep for C++ (thus the TODO), but it's the simple fix to make it work at all.
Fixes flutter/flutter#117994
Part of flutter/flutter#59116
This commit is contained in:
stuartmorgan
2023-01-05 14:27:55 -08:00
committed by GitHub
parent 3ef0f63290
commit 394dd8d792
27 changed files with 546 additions and 88 deletions

View File

@ -1,3 +1,9 @@
## 4.2.16
* [swift] Fixes warnings with `Object` parameters.
* [dart] Fixes warnings with `Object` return values.
* [c++] Generation of APIs that use `Object` no longer fails.
## 4.2.15 ## 4.2.15
* Relocates generator classes. (Reverted) * Relocates generator classes. (Reverted)

View File

@ -547,6 +547,11 @@ const flutter::StandardMessageCodec& ${api.name}::GetCodec() {
// ... then declare the arg as a reference to that local. // ... then declare the arg as a reference to that local.
indent.writeln( indent.writeln(
'const auto* $argName = $encodableArgName.IsNull() ? nullptr : &$valueVarName;'); 'const auto* $argName = $encodableArgName.IsNull() ? nullptr : &$valueVarName;');
} else if (hostType.datatype == 'flutter::EncodableValue') {
// Generic objects just pass the EncodableValue through
// directly.
indent.writeln(
'const auto* $argName = &$encodableArgName;');
} else if (hostType.isBuiltin) { } else if (hostType.isBuiltin) {
indent.writeln( indent.writeln(
'const auto* $argName = std::get_if<${hostType.datatype}>(&$encodableArgName);'); 'const auto* $argName = std::get_if<${hostType.datatype}>(&$encodableArgName);');
@ -564,6 +569,13 @@ const flutter::StandardMessageCodec& ${api.name}::GetCodec() {
// requires an int64_t so that it can handle any case. // requires an int64_t so that it can handle any case.
indent.writeln( indent.writeln(
'const int64_t $argName = $encodableArgName.LongValue();'); 'const int64_t $argName = $encodableArgName.LongValue();');
} else if (hostType.datatype == 'flutter::EncodableValue') {
// Generic objects just pass the EncodableValue through
// directly. This creates an alias just to avoid having to
// special-case the argName/encodableArgName distinction
// at a higher level.
indent
.writeln('const auto& $argName = $encodableArgName;');
} else if (hostType.isBuiltin) { } else if (hostType.isBuiltin) {
indent.writeln( indent.writeln(
'const auto& $argName = std::get<${hostType.datatype}>($encodableArgName);'); 'const auto& $argName = std::get<${hostType.datatype}>($encodableArgName);');
@ -902,6 +914,7 @@ String? _baseCppTypeForBuiltinDartType(TypeDeclaration type) {
'Float64List': 'std::vector<double>', 'Float64List': 'std::vector<double>',
'Map': 'flutter::EncodableMap', 'Map': 'flutter::EncodableMap',
'List': 'flutter::EncodableList', 'List': 'flutter::EncodableList',
'Object': 'flutter::EncodableValue',
}; };
if (cppTypeForDartTypeMap.containsKey(type.baseName)) { if (cppTypeForDartTypeMap.containsKey(type.baseName)) {
return cppTypeForDartTypeMap[type.baseName]; return cppTypeForDartTypeMap[type.baseName];
@ -931,6 +944,8 @@ String _unownedArgumentType(HostDatatype type) {
if (isString || _isPodType(type)) { if (isString || _isPodType(type)) {
return type.isNullable ? 'const $baseType*' : baseType; return type.isNullable ? 'const $baseType*' : baseType;
} }
// TODO(stuartmorgan): Consider special-casing `Object?` here, so that there
// aren't two ways of representing null (nullptr or an isNull EncodableValue).
return type.isNullable ? 'const $baseType*' : 'const $baseType&'; return type.isNullable ? 'const $baseType*' : 'const $baseType&';
} }

View File

@ -230,13 +230,17 @@ final BinaryMessenger? _binaryMessenger;
indent.writeln('binaryMessenger: _binaryMessenger);'); indent.writeln('binaryMessenger: _binaryMessenger);');
}); });
final String returnType = _makeGenericTypeArguments(func.returnType); final String returnType = _makeGenericTypeArguments(func.returnType);
final String castCall = _makeGenericCastCall(func.returnType); final String genericCastCall = _makeGenericCastCall(func.returnType);
const String accessor = 'replyList[0]'; const String accessor = 'replyList[0]';
final String nullHandler = // Avoid warnings from pointlessly casting to `Object?`.
func.returnType.isNullable ? (castCall.isEmpty ? '' : '?') : '!'; final String nullablyTypedAccessor =
returnType == 'Object' ? accessor : '($accessor as $returnType?)';
final String nullHandler = func.returnType.isNullable
? (genericCastCall.isEmpty ? '' : '?')
: '!';
final String returnStatement = func.returnType.isVoid final String returnStatement = func.returnType.isVoid
? 'return;' ? 'return;'
: 'return ($accessor as $returnType?)$nullHandler$castCall;'; : 'return $nullablyTypedAccessor$nullHandler$genericCastCall;';
indent.format(''' indent.format('''
final List<Object?>? replyList = final List<Object?>? replyList =
\t\tawait channel.send($sendArgument) as List<Object?>?; \t\tawait channel.send($sendArgument) as List<Object?>?;

View File

@ -9,7 +9,7 @@ import 'dart:mirrors';
import 'ast.dart'; import 'ast.dart';
/// The current version of pigeon. This must match the version in pubspec.yaml. /// The current version of pigeon. This must match the version in pubspec.yaml.
const String pigeonVersion = '4.2.15'; const String pigeonVersion = '4.2.16';
/// Read all the content from [stdin] to a String. /// Read all the content from [stdin] to a String.
String readStdin() { String readStdin() {

View File

@ -365,6 +365,9 @@ String _castForceUnwrap(String value, TypeDeclaration type, Root root) {
final String nullableConditionPrefix = final String nullableConditionPrefix =
type.isNullable ? '$value == nil ? nil : ' : ''; type.isNullable ? '$value == nil ? nil : ' : '';
return '$nullableConditionPrefix${_swiftTypeForDartType(type)}(rawValue: $value as! Int)$forceUnwrap'; return '$nullableConditionPrefix${_swiftTypeForDartType(type)}(rawValue: $value as! Int)$forceUnwrap';
} else if (type.baseName == 'Object') {
// Special-cased to avoid warnings about using 'as' with Any.
return type.isNullable ? value : '$value!';
} else { } else {
final String castUnwrap = type.isNullable ? '?' : '!'; final String castUnwrap = type.isNullable ? '?' : '!';
return '$value as$castUnwrap ${_swiftTypeForDartType(type)}'; return '$value as$castUnwrap ${_swiftTypeForDartType(type)}';

View File

@ -125,6 +125,10 @@ abstract class HostIntegrationCoreApi {
@ObjCSelector('echoUint8List:') @ObjCSelector('echoUint8List:')
Uint8List echoUint8List(Uint8List aUint8List); Uint8List echoUint8List(Uint8List aUint8List);
/// Returns the passed in generic Object.
@ObjCSelector('echoObject:')
Object echoObject(Object anObject);
// ========== Syncronous nullable method tests ========== // ========== Syncronous nullable method tests ==========
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
@ -162,6 +166,10 @@ abstract class HostIntegrationCoreApi {
@ObjCSelector('echoNullableUint8List:') @ObjCSelector('echoNullableUint8List:')
Uint8List? echoNullableUint8List(Uint8List? aNullableUint8List); Uint8List? echoNullableUint8List(Uint8List? aNullableUint8List);
/// Returns the passed in generic Object.
@ObjCSelector('echoNullableObject:')
Object? echoNullableObject(Object? aNullableObject);
// ========== Asyncronous method tests ========== // ========== Asyncronous method tests ==========
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity

View File

@ -72,6 +72,11 @@ public class AlternateLanguageTestPlugin implements FlutterPlugin, HostIntegrati
return aUint8List; return aUint8List;
} }
@Override
public @NonNull Object echoObject(@NonNull Object anObject) {
return anObject;
}
@Override @Override
public @Nullable String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper) { public @Nullable String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper) {
return wrapper.getValues().getANullableString(); return wrapper.getValues().getANullableString();
@ -124,6 +129,11 @@ public class AlternateLanguageTestPlugin implements FlutterPlugin, HostIntegrati
return aNullableUint8List; return aNullableUint8List;
} }
@Override
public @Nullable Object echoNullableObject(@Nullable Object aNullableObject) {
return aNullableObject;
}
@Override @Override
public void noopAsync(Result<Void> result) { public void noopAsync(Result<Void> result) {
result.success(null); result.success(null);

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
package com.example.alternate_language_test_plugin; package com.example.alternate_language_test_plugin;
@ -713,12 +713,9 @@ public class CoreTests {
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer)); return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 129: case (byte) 129:
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 130:
return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer)); return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 131: case (byte) 130:
return AllTypes.fromList((ArrayList<Object>) readValue(buffer)); return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
default: default:
@ -731,14 +728,11 @@ public class CoreTests {
if (value instanceof AllNullableTypes) { if (value instanceof AllNullableTypes) {
stream.write(128); stream.write(128);
writeValue(stream, ((AllNullableTypes) value).toList()); writeValue(stream, ((AllNullableTypes) value).toList());
} else if (value instanceof AllNullableTypes) {
stream.write(129);
writeValue(stream, ((AllNullableTypes) value).toList());
} else if (value instanceof AllNullableTypesWrapper) { } else if (value instanceof AllNullableTypesWrapper) {
stream.write(130); stream.write(129);
writeValue(stream, ((AllNullableTypesWrapper) value).toList()); writeValue(stream, ((AllNullableTypesWrapper) value).toList());
} else if (value instanceof AllTypes) { } else if (value instanceof AllTypes) {
stream.write(131); stream.write(130);
writeValue(stream, ((AllTypes) value).toList()); writeValue(stream, ((AllTypes) value).toList());
} else { } else {
super.writeValue(stream, value); super.writeValue(stream, value);
@ -780,6 +774,9 @@ public class CoreTests {
/** Returns the passed in Uint8List. */ /** Returns the passed in Uint8List. */
@NonNull @NonNull
byte[] echoUint8List(@NonNull byte[] aUint8List); byte[] echoUint8List(@NonNull byte[] aUint8List);
/** Returns the passed in generic Object. */
@NonNull
Object echoObject(@NonNull Object anObject);
/** /**
* Returns the inner `aString` value from the wrapped object, to test sending of nested objects. * Returns the inner `aString` value from the wrapped object, to test sending of nested objects.
*/ */
@ -811,6 +808,9 @@ public class CoreTests {
/** Returns the passed in Uint8List. */ /** Returns the passed in Uint8List. */
@Nullable @Nullable
byte[] echoNullableUint8List(@Nullable byte[] aNullableUint8List); byte[] echoNullableUint8List(@Nullable byte[] aNullableUint8List);
/** Returns the passed in generic Object. */
@Nullable
Object echoNullableObject(@Nullable Object aNullableObject);
/** /**
* A no-op function taking no arguments and returning no value, to sanity test basic * A no-op function taking no arguments and returning no value, to sanity test basic
* asynchronous calling. * asynchronous calling.
@ -1072,6 +1072,35 @@ public class CoreTests {
channel.setMessageHandler(null); channel.setMessageHandler(null);
} }
} }
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.HostIntegrationCoreApi.echoObject",
getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList wrapped = new ArrayList<>();
try {
ArrayList<Object> args = (ArrayList<Object>) message;
assert args != null;
Object anObjectArg = args.get(0);
if (anObjectArg == null) {
throw new NullPointerException("anObjectArg unexpectedly null.");
}
Object output = api.echoObject(anObjectArg);
wrapped.add(0, output);
} catch (Error | RuntimeException exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{ {
BasicMessageChannel<Object> channel = BasicMessageChannel<Object> channel =
new BasicMessageChannel<>( new BasicMessageChannel<>(
@ -1292,6 +1321,32 @@ public class CoreTests {
channel.setMessageHandler(null); channel.setMessageHandler(null);
} }
} }
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject",
getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList wrapped = new ArrayList<>();
try {
ArrayList<Object> args = (ArrayList<Object>) message;
assert args != null;
Object aNullableObjectArg = args.get(0);
Object output = api.echoNullableObject(aNullableObjectArg);
wrapped.add(0, output);
} catch (Error | RuntimeException exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{ {
BasicMessageChannel<Object> channel = BasicMessageChannel<Object> channel =
new BasicMessageChannel<>( new BasicMessageChannel<>(

View File

@ -63,6 +63,10 @@
return aUint8List; return aUint8List;
} }
- (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull)error {
return anObject;
}
- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper - (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper
error:(FlutterError *_Nullable *_Nonnull)error { error:(FlutterError *_Nullable *_Nonnull)error {
return wrapper.values.aNullableString; return wrapper.values.aNullableString;
@ -114,6 +118,11 @@
return aNullableUint8List; return aNullableUint8List;
} }
- (nullable id)echoNullableObject:(nullable id)aNullableObject
error:(FlutterError *_Nullable *_Nonnull)error {
return aNullableObject;
}
- (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion { - (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion {
completion(nil); completion(nil);
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@protocol FlutterBinaryMessenger; @protocol FlutterBinaryMessenger;
@ -131,6 +131,10 @@ NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec(void);
/// @return `nil` only when `error != nil`. /// @return `nil` only when `error != nil`.
- (nullable FlutterStandardTypedData *)echoUint8List:(FlutterStandardTypedData *)aUint8List - (nullable FlutterStandardTypedData *)echoUint8List:(FlutterStandardTypedData *)aUint8List
error:(FlutterError *_Nullable *_Nonnull)error; error:(FlutterError *_Nullable *_Nonnull)error;
/// Returns the passed in generic Object.
///
/// @return `nil` only when `error != nil`.
- (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull)error;
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
/// sending of nested objects. /// sending of nested objects.
- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper - (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper
@ -166,6 +170,9 @@ NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec(void);
- (nullable FlutterStandardTypedData *) - (nullable FlutterStandardTypedData *)
echoNullableUint8List:(nullable FlutterStandardTypedData *)aNullableUint8List echoNullableUint8List:(nullable FlutterStandardTypedData *)aNullableUint8List
error:(FlutterError *_Nullable *_Nonnull)error; error:(FlutterError *_Nullable *_Nonnull)error;
/// Returns the passed in generic Object.
- (nullable id)echoNullableObject:(nullable id)aNullableObject
error:(FlutterError *_Nullable *_Nonnull)error;
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity
/// test basic asynchronous calling. /// test basic asynchronous calling.
- (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion; - (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion;

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
#import "CoreTests.gen.h" #import "CoreTests.gen.h"
#import <Flutter/Flutter.h> #import <Flutter/Flutter.h>
@ -220,12 +220,9 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
return [AllNullableTypes fromList:[self readValue]]; return [AllNullableTypes fromList:[self readValue]];
case 129: case 129:
return [AllNullableTypes fromList:[self readValue]];
case 130:
return [AllNullableTypesWrapper fromList:[self readValue]]; return [AllNullableTypesWrapper fromList:[self readValue]];
case 131: case 130:
return [AllTypes fromList:[self readValue]]; return [AllTypes fromList:[self readValue]];
default: default:
@ -241,14 +238,11 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
if ([value isKindOfClass:[AllNullableTypes class]]) { if ([value isKindOfClass:[AllNullableTypes class]]) {
[self writeByte:128]; [self writeByte:128];
[self writeValue:[value toList]]; [self writeValue:[value toList]];
} else if ([value isKindOfClass:[AllNullableTypes class]]) { } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) {
[self writeByte:129]; [self writeByte:129];
[self writeValue:[value toList]]; [self writeValue:[value toList]];
} else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) {
[self writeByte:130];
[self writeValue:[value toList]];
} else if ([value isKindOfClass:[AllTypes class]]) { } else if ([value isKindOfClass:[AllTypes class]]) {
[self writeByte:131]; [self writeByte:130];
[self writeValue:[value toList]]; [self writeValue:[value toList]];
} else { } else {
[super writeValue:value]; [super writeValue:value];
@ -470,6 +464,27 @@ void HostIntegrationCoreApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
[channel setMessageHandler:nil]; [channel setMessageHandler:nil];
} }
} }
/// Returns the passed in generic Object.
{
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoObject"
binaryMessenger:binaryMessenger
codec:HostIntegrationCoreApiGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(echoObject:error:)],
@"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoObject:error:)",
api);
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
NSArray *args = message;
id arg_anObject = GetNullableObjectAtIndex(args, 0);
FlutterError *error;
id output = [api echoObject:arg_anObject error:&error];
callback(wrapResult(output, error));
}];
} else {
[channel setMessageHandler:nil];
}
}
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
/// sending of nested objects. /// sending of nested objects.
{ {
@ -656,6 +671,28 @@ void HostIntegrationCoreApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
[channel setMessageHandler:nil]; [channel setMessageHandler:nil];
} }
} }
/// Returns the passed in generic Object.
{
FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject"
binaryMessenger:binaryMessenger
codec:HostIntegrationCoreApiGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(echoNullableObject:error:)],
@"HostIntegrationCoreApi api (%@) doesn't respond to "
@"@selector(echoNullableObject:error:)",
api);
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
NSArray *args = message;
id arg_aNullableObject = GetNullableObjectAtIndex(args, 0);
FlutterError *error;
id output = [api echoNullableObject:arg_aNullableObject error:&error];
callback(wrapResult(output, error));
}];
} else {
[channel setMessageHandler:nil];
}
}
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity
/// test basic asynchronous calling. /// test basic asynchronous calling.
{ {

View File

@ -351,6 +351,19 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) {
expect(receivedUint8List, sentUint8List); expect(receivedUint8List, sentUint8List);
}); });
testWidgets('generic Objects serialize and deserialize correctly',
(WidgetTester _) async {
final HostIntegrationCoreApi api = HostIntegrationCoreApi();
const Object sentString = "I'm a computer";
final Object receivedString = await api.echoObject(sentString);
expect(receivedString, sentString);
// Echo a second type as well to ensure the handling is generic.
const Object sentInt = 42;
final Object receivedInt = await api.echoObject(sentInt);
expect(receivedInt, sentInt);
});
testWidgets('Nullable Ints serialize and deserialize correctly', testWidgets('Nullable Ints serialize and deserialize correctly',
(WidgetTester _) async { (WidgetTester _) async {
final HostIntegrationCoreApi api = HostIntegrationCoreApi(); final HostIntegrationCoreApi api = HostIntegrationCoreApi();
@ -449,6 +462,27 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) {
await api.echoNullableUint8List(null); await api.echoNullableUint8List(null);
expect(receivedNullUint8List, null); expect(receivedNullUint8List, null);
}); });
testWidgets('generic nullable Objects serialize and deserialize correctly',
(WidgetTester _) async {
final HostIntegrationCoreApi api = HostIntegrationCoreApi();
const Object sentString = "I'm a computer";
final Object? receivedString = await api.echoNullableObject(sentString);
expect(receivedString, sentString);
// Echo a second type as well to ensure the handling is generic.
const Object sentInt = 42;
final Object? receivedInt = await api.echoNullableObject(sentInt);
expect(receivedInt, sentInt);
});
testWidgets('Null generic Objects serialize and deserialize correctly',
(WidgetTester _) async {
final HostIntegrationCoreApi api = HostIntegrationCoreApi();
final Object? receivedNullObject = await api.echoNullableObject(null);
expect(receivedNullObject, null);
});
}); });
group('Host async API tests', () { group('Host async API tests', () {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // 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 // 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
import 'dart:async'; import 'dart:async';
@ -205,14 +205,11 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
if (value is AllNullableTypes) { if (value is AllNullableTypes) {
buffer.putUint8(128); buffer.putUint8(128);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is AllNullableTypes) { } else if (value is AllNullableTypesWrapper) {
buffer.putUint8(129); buffer.putUint8(129);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else if (value is AllNullableTypesWrapper) {
buffer.putUint8(130);
writeValue(buffer, value.encode());
} else if (value is AllTypes) { } else if (value is AllTypes) {
buffer.putUint8(131); buffer.putUint8(130);
writeValue(buffer, value.encode()); writeValue(buffer, value.encode());
} else { } else {
super.writeValue(buffer, value); super.writeValue(buffer, value);
@ -226,12 +223,9 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
return AllNullableTypes.decode(readValue(buffer)!); return AllNullableTypes.decode(readValue(buffer)!);
case 129: case 129:
return AllNullableTypes.decode(readValue(buffer)!);
case 130:
return AllNullableTypesWrapper.decode(readValue(buffer)!); return AllNullableTypesWrapper.decode(readValue(buffer)!);
case 131: case 130:
return AllTypes.decode(readValue(buffer)!); return AllTypes.decode(readValue(buffer)!);
default: default:
@ -489,6 +483,34 @@ class HostIntegrationCoreApi {
} }
} }
/// Returns the passed in generic Object.
Future<Object> echoObject(Object arg_anObject) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.HostIntegrationCoreApi.echoObject', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_anObject]) as List<Object?>?;
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]!;
}
}
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
/// sending of nested objects. /// sending of nested objects.
Future<String?> extractNestedNullableString( Future<String?> extractNestedNullableString(
@ -694,6 +716,29 @@ class HostIntegrationCoreApi {
} }
} }
/// Returns the passed in generic Object.
Future<Object?> echoNullableObject(Object? arg_aNullableObject) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_aNullableObject]) as List<Object?>?;
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 {
return replyList[0];
}
}
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity
/// test basic asynchronous calling. /// test basic asynchronous calling.
Future<void> noopAsync() async { Future<void> noopAsync() async {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
package com.example.test_plugin package com.example.test_plugin
@ -169,16 +169,11 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() {
} }
} }
129.toByte() -> { 129.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
AllNullableTypes.fromList(it)
}
}
130.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let { return (readValue(buffer) as? List<Any?>)?.let {
AllNullableTypesWrapper.fromList(it) AllNullableTypesWrapper.fromList(it)
} }
} }
131.toByte() -> { 130.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let { return (readValue(buffer) as? List<Any?>)?.let {
AllTypes.fromList(it) AllTypes.fromList(it)
} }
@ -192,16 +187,12 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() {
stream.write(128) stream.write(128)
writeValue(stream, value.toList()) writeValue(stream, value.toList())
} }
is AllNullableTypes -> { is AllNullableTypesWrapper -> {
stream.write(129) stream.write(129)
writeValue(stream, value.toList()) writeValue(stream, value.toList())
} }
is AllNullableTypesWrapper -> {
stream.write(130)
writeValue(stream, value.toList())
}
is AllTypes -> { is AllTypes -> {
stream.write(131) stream.write(130)
writeValue(stream, value.toList()) writeValue(stream, value.toList())
} }
else -> super.writeValue(stream, value) else -> super.writeValue(stream, value)
@ -237,6 +228,8 @@ interface HostIntegrationCoreApi {
fun echoString(aString: String): String fun echoString(aString: String): String
/** Returns the passed in Uint8List. */ /** Returns the passed in Uint8List. */
fun echoUint8List(aUint8List: ByteArray): ByteArray fun echoUint8List(aUint8List: ByteArray): ByteArray
/** Returns the passed in generic Object. */
fun echoObject(anObject: Any): Any
/** /**
* Returns the inner `aString` value from the wrapped object, to test * Returns the inner `aString` value from the wrapped object, to test
* sending of nested objects. * sending of nested objects.
@ -259,6 +252,8 @@ interface HostIntegrationCoreApi {
fun echoNullableString(aNullableString: String?): String? fun echoNullableString(aNullableString: String?): String?
/** Returns the passed in Uint8List. */ /** Returns the passed in Uint8List. */
fun echoNullableUint8List(aNullableUint8List: ByteArray?): ByteArray? fun echoNullableUint8List(aNullableUint8List: ByteArray?): ByteArray?
/** Returns the passed in generic Object. */
fun echoNullableObject(aNullableObject: Any?): Any?
/** /**
* A no-op function taking no arguments and returning no value, to sanity * A no-op function taking no arguments and returning no value, to sanity
* test basic asynchronous calling. * test basic asynchronous calling.
@ -437,6 +432,24 @@ interface HostIntegrationCoreApi {
channel.setMessageHandler(null) channel.setMessageHandler(null)
} }
} }
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
var wrapped = listOf<Any?>()
try {
val args = message as List<Any?>
val anObjectArg = args[0] as Any
wrapped = listOf<Any?>(api.echoObject(anObjectArg))
} catch (exception: Error) {
wrapped = wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
run { run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", codec) val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", codec)
if (api != null) { if (api != null) {
@ -583,6 +596,24 @@ interface HostIntegrationCoreApi {
channel.setMessageHandler(null) channel.setMessageHandler(null)
} }
} }
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
var wrapped = listOf<Any?>()
try {
val args = message as List<Any?>
val aNullableObjectArg = args[0] as? Any
wrapped = listOf<Any?>(api.echoNullableObject(aNullableObjectArg))
} catch (exception: Error) {
wrapped = wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
run { run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", codec) val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", codec)
if (api != null) { if (api != null) {

View File

@ -64,6 +64,10 @@ class TestPlugin: FlutterPlugin, HostIntegrationCoreApi {
return aUint8List return aUint8List
} }
override fun echoObject(anObject: Any): Any {
return anObject
}
override fun extractNestedNullableString(wrapper: AllNullableTypesWrapper): String? { override fun extractNestedNullableString(wrapper: AllNullableTypesWrapper): String? {
return wrapper.values.aNullableString return wrapper.values.aNullableString
} }
@ -75,22 +79,31 @@ class TestPlugin: FlutterPlugin, HostIntegrationCoreApi {
override fun sendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?): AllNullableTypes { override fun sendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?): AllNullableTypes {
return AllNullableTypes(aNullableBool = aNullableBool, aNullableInt = aNullableInt, aNullableString = aNullableString) return AllNullableTypes(aNullableBool = aNullableBool, aNullableInt = aNullableInt, aNullableString = aNullableString)
} }
override fun echoNullableInt(aNullableInt: Long?): Long? { override fun echoNullableInt(aNullableInt: Long?): Long? {
return aNullableInt return aNullableInt
} }
override fun echoNullableDouble(aNullableDouble: Double?): Double? { override fun echoNullableDouble(aNullableDouble: Double?): Double? {
return aNullableDouble return aNullableDouble
} }
override fun echoNullableBool(aNullableBool: Boolean?): Boolean? { override fun echoNullableBool(aNullableBool: Boolean?): Boolean? {
return aNullableBool return aNullableBool
} }
override fun echoNullableString(aNullableString: String?): String? { override fun echoNullableString(aNullableString: String?): String? {
return aNullableString return aNullableString
} }
override fun echoNullableUint8List(aNullableUint8List: ByteArray?): ByteArray? { override fun echoNullableUint8List(aNullableUint8List: ByteArray?): ByteArray? {
return aNullableUint8List return aNullableUint8List
} }
override fun echoNullableObject(aNullableObject: Any?): Any? {
return aNullableObject
}
override fun noopAsync(callback: () -> Unit) { override fun noopAsync(callback: () -> Unit) {
callback() callback()
} }

View File

@ -41,5 +41,9 @@ end
post_install do |installer| post_install do |installer|
installer.pods_project.targets.each do |target| installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target) flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['SWIFT_TREAT_WARNINGS_AS_ERRORS'] = 'YES'
end
end end
end end

View File

@ -40,5 +40,9 @@ end
post_install do |installer| post_install do |installer|
installer.pods_project.targets.each do |target| installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target) flutter_additional_macos_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['SWIFT_TREAT_WARNINGS_AS_ERRORS'] = 'YES'
end
end end
end end

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
import Foundation import Foundation
@ -178,10 +178,8 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
case 128: case 128:
return AllNullableTypes.fromList(self.readValue() as! [Any]) return AllNullableTypes.fromList(self.readValue() as! [Any])
case 129: case 129:
return AllNullableTypes.fromList(self.readValue() as! [Any])
case 130:
return AllNullableTypesWrapper.fromList(self.readValue() as! [Any]) return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
case 131: case 130:
return AllTypes.fromList(self.readValue() as! [Any]) return AllTypes.fromList(self.readValue() as! [Any])
default: default:
return super.readValue(ofType: type) return super.readValue(ofType: type)
@ -194,14 +192,11 @@ private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter {
if let value = value as? AllNullableTypes { if let value = value as? AllNullableTypes {
super.writeByte(128) super.writeByte(128)
super.writeValue(value.toList()) super.writeValue(value.toList())
} else if let value = value as? AllNullableTypes { } else if let value = value as? AllNullableTypesWrapper {
super.writeByte(129) super.writeByte(129)
super.writeValue(value.toList()) super.writeValue(value.toList())
} else if let value = value as? AllNullableTypesWrapper {
super.writeByte(130)
super.writeValue(value.toList())
} else if let value = value as? AllTypes { } else if let value = value as? AllTypes {
super.writeByte(131) super.writeByte(130)
super.writeValue(value.toList()) super.writeValue(value.toList())
} else { } else {
super.writeValue(value) super.writeValue(value)
@ -247,6 +242,8 @@ protocol HostIntegrationCoreApi {
func echoString(aString: String) -> String func echoString(aString: String) -> String
/// Returns the passed in Uint8List. /// Returns the passed in Uint8List.
func echoUint8List(aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData func echoUint8List(aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData
/// Returns the passed in generic Object.
func echoObject(anObject: Any) -> Any
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
/// sending of nested objects. /// sending of nested objects.
func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String?
@ -265,6 +262,8 @@ protocol HostIntegrationCoreApi {
func echoNullableString(aNullableString: String?) -> String? func echoNullableString(aNullableString: String?) -> String?
/// Returns the passed in Uint8List. /// Returns the passed in Uint8List.
func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData? func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData?
/// Returns the passed in generic Object.
func echoNullableObject(aNullableObject: Any?) -> Any?
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity
/// test basic asynchronous calling. /// test basic asynchronous calling.
func noopAsync(completion: @escaping () -> Void) func noopAsync(completion: @escaping () -> Void)
@ -385,6 +384,18 @@ class HostIntegrationCoreApiSetup {
} else { } else {
echoUint8ListChannel.setMessageHandler(nil) echoUint8ListChannel.setMessageHandler(nil)
} }
/// Returns the passed in generic Object.
let echoObjectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
echoObjectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let anObjectArg = args[0]!
let result = api.echoObject(anObject: anObjectArg)
reply(wrapResult(result))
}
} else {
echoObjectChannel.setMessageHandler(nil)
}
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
/// sending of nested objects. /// sending of nested objects.
let extractNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", binaryMessenger: binaryMessenger, codec: codec) let extractNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
@ -485,6 +496,18 @@ class HostIntegrationCoreApiSetup {
} else { } else {
echoNullableUint8ListChannel.setMessageHandler(nil) echoNullableUint8ListChannel.setMessageHandler(nil)
} }
/// Returns the passed in generic Object.
let echoNullableObjectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
echoNullableObjectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let aNullableObjectArg = args[0]
let result = api.echoNullableObject(aNullableObject: aNullableObjectArg)
reply(wrapResult(result))
}
} else {
echoNullableObjectChannel.setMessageHandler(nil)
}
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity
/// test basic asynchronous calling. /// test basic asynchronous calling.
let noopAsyncChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec) let noopAsyncChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec)

View File

@ -59,6 +59,10 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi {
return aUint8List return aUint8List
} }
func echoObject(anObject: Any) -> Any {
return anObject
}
func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? { func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? {
return wrapper.values.aNullableString; return wrapper.values.aNullableString;
} }
@ -92,6 +96,10 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi {
return aNullableUint8List return aNullableUint8List
} }
func echoNullableObject(aNullableObject: Any?) -> Any? {
return aNullableObject
}
func noopAsync(completion: @escaping () -> Void) { func noopAsync(completion: @escaping () -> Void) {
completion() completion()
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
import Foundation import Foundation
@ -178,10 +178,8 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
case 128: case 128:
return AllNullableTypes.fromList(self.readValue() as! [Any]) return AllNullableTypes.fromList(self.readValue() as! [Any])
case 129: case 129:
return AllNullableTypes.fromList(self.readValue() as! [Any])
case 130:
return AllNullableTypesWrapper.fromList(self.readValue() as! [Any]) return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
case 131: case 130:
return AllTypes.fromList(self.readValue() as! [Any]) return AllTypes.fromList(self.readValue() as! [Any])
default: default:
return super.readValue(ofType: type) return super.readValue(ofType: type)
@ -194,14 +192,11 @@ private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter {
if let value = value as? AllNullableTypes { if let value = value as? AllNullableTypes {
super.writeByte(128) super.writeByte(128)
super.writeValue(value.toList()) super.writeValue(value.toList())
} else if let value = value as? AllNullableTypes { } else if let value = value as? AllNullableTypesWrapper {
super.writeByte(129) super.writeByte(129)
super.writeValue(value.toList()) super.writeValue(value.toList())
} else if let value = value as? AllNullableTypesWrapper {
super.writeByte(130)
super.writeValue(value.toList())
} else if let value = value as? AllTypes { } else if let value = value as? AllTypes {
super.writeByte(131) super.writeByte(130)
super.writeValue(value.toList()) super.writeValue(value.toList())
} else { } else {
super.writeValue(value) super.writeValue(value)
@ -247,6 +242,8 @@ protocol HostIntegrationCoreApi {
func echoString(aString: String) -> String func echoString(aString: String) -> String
/// Returns the passed in Uint8List. /// Returns the passed in Uint8List.
func echoUint8List(aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData func echoUint8List(aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData
/// Returns the passed in generic Object.
func echoObject(anObject: Any) -> Any
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
/// sending of nested objects. /// sending of nested objects.
func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String?
@ -265,6 +262,8 @@ protocol HostIntegrationCoreApi {
func echoNullableString(aNullableString: String?) -> String? func echoNullableString(aNullableString: String?) -> String?
/// Returns the passed in Uint8List. /// Returns the passed in Uint8List.
func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData? func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData?
/// Returns the passed in generic Object.
func echoNullableObject(aNullableObject: Any?) -> Any?
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity
/// test basic asynchronous calling. /// test basic asynchronous calling.
func noopAsync(completion: @escaping () -> Void) func noopAsync(completion: @escaping () -> Void)
@ -385,6 +384,18 @@ class HostIntegrationCoreApiSetup {
} else { } else {
echoUint8ListChannel.setMessageHandler(nil) echoUint8ListChannel.setMessageHandler(nil)
} }
/// Returns the passed in generic Object.
let echoObjectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
echoObjectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let anObjectArg = args[0]!
let result = api.echoObject(anObject: anObjectArg)
reply(wrapResult(result))
}
} else {
echoObjectChannel.setMessageHandler(nil)
}
/// Returns the inner `aString` value from the wrapped object, to test /// Returns the inner `aString` value from the wrapped object, to test
/// sending of nested objects. /// sending of nested objects.
let extractNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", binaryMessenger: binaryMessenger, codec: codec) let extractNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
@ -485,6 +496,18 @@ class HostIntegrationCoreApiSetup {
} else { } else {
echoNullableUint8ListChannel.setMessageHandler(nil) echoNullableUint8ListChannel.setMessageHandler(nil)
} }
/// Returns the passed in generic Object.
let echoNullableObjectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
echoNullableObjectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let aNullableObjectArg = args[0]
let result = api.echoNullableObject(aNullableObject: aNullableObjectArg)
reply(wrapResult(result))
}
} else {
echoNullableObjectChannel.setMessageHandler(nil)
}
/// A no-op function taking no arguments and returning no value, to sanity /// A no-op function taking no arguments and returning no value, to sanity
/// test basic asynchronous calling. /// test basic asynchronous calling.
let noopAsyncChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec) let noopAsyncChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec)

View File

@ -59,6 +59,10 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi {
return aUint8List return aUint8List
} }
func echoObject(anObject: Any) -> Any {
return anObject
}
func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? { func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? {
return wrapper.values.aNullableString; return wrapper.values.aNullableString;
} }
@ -92,6 +96,10 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi {
return aNullableUint8List return aNullableUint8List
} }
func echoNullableObject(aNullableObject: Any?) -> Any? {
return aNullableObject
}
func noopAsync(completion: @escaping () -> Void) { func noopAsync(completion: @escaping () -> Void) {
completion() completion()
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
#undef _HAS_EXCEPTIONS #undef _HAS_EXCEPTIONS
@ -490,14 +490,10 @@ flutter::EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType(
std::get<flutter::EncodableList>(ReadValue(stream)))); std::get<flutter::EncodableList>(ReadValue(stream))));
case 129: case 129:
return flutter::CustomEncodableValue(AllNullableTypes(
std::get<flutter::EncodableList>(ReadValue(stream))));
case 130:
return flutter::CustomEncodableValue(AllNullableTypesWrapper( return flutter::CustomEncodableValue(AllNullableTypesWrapper(
std::get<flutter::EncodableList>(ReadValue(stream)))); std::get<flutter::EncodableList>(ReadValue(stream))));
case 131: case 130:
return flutter::CustomEncodableValue( return flutter::CustomEncodableValue(
AllTypes(std::get<flutter::EncodableList>(ReadValue(stream)))); AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));
@ -519,16 +515,8 @@ void HostIntegrationCoreApiCodecSerializer::WriteValue(
stream); stream);
return; return;
} }
if (custom_value->type() == typeid(AllNullableTypes)) {
stream->WriteByte(129);
WriteValue(
flutter::EncodableValue(
std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
stream);
return;
}
if (custom_value->type() == typeid(AllNullableTypesWrapper)) { if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
stream->WriteByte(130); stream->WriteByte(129);
WriteValue(flutter::EncodableValue( WriteValue(flutter::EncodableValue(
std::any_cast<AllNullableTypesWrapper>(*custom_value) std::any_cast<AllNullableTypesWrapper>(*custom_value)
.ToEncodableList()), .ToEncodableList()),
@ -536,7 +524,7 @@ void HostIntegrationCoreApiCodecSerializer::WriteValue(
return; return;
} }
if (custom_value->type() == typeid(AllTypes)) { if (custom_value->type() == typeid(AllTypes)) {
stream->WriteByte(131); stream->WriteByte(130);
WriteValue(flutter::EncodableValue( WriteValue(flutter::EncodableValue(
std::any_cast<AllTypes>(*custom_value).ToEncodableList()), std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
stream); stream);
@ -869,6 +857,43 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger,
channel->SetMessageHandler(nullptr); channel->SetMessageHandler(nullptr);
} }
} }
{
auto channel =
std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
binary_messenger,
"dev.flutter.pigeon.HostIntegrationCoreApi.echoObject",
&GetCodec());
if (api != nullptr) {
channel->SetMessageHandler(
[api](const flutter::EncodableValue& message,
const flutter::MessageReply<flutter::EncodableValue>& reply) {
flutter::EncodableList wrapped;
try {
const auto& args = std::get<flutter::EncodableList>(message);
const auto& encodable_an_object_arg = args.at(0);
if (encodable_an_object_arg.IsNull()) {
reply(flutter::EncodableValue(
WrapError("an_object_arg unexpectedly null.")));
return;
}
const auto& an_object_arg = encodable_an_object_arg;
ErrorOr<flutter::EncodableValue> output =
api->EchoObject(an_object_arg);
if (output.has_error()) {
wrapped = WrapError(output.error());
} else {
wrapped.push_back(
flutter::EncodableValue(std::move(output).TakeValue()));
}
} catch (const std::exception& exception) {
wrapped = WrapError(exception.what());
}
reply(flutter::EncodableValue(std::move(wrapped)));
});
} else {
channel->SetMessageHandler(nullptr);
}
}
{ {
auto channel = std::make_unique< auto channel = std::make_unique<
flutter::BasicMessageChannel<flutter::EncodableValue>>( flutter::BasicMessageChannel<flutter::EncodableValue>>(
@ -1190,6 +1215,44 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger,
channel->SetMessageHandler(nullptr); channel->SetMessageHandler(nullptr);
} }
} }
{
auto channel =
std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(
binary_messenger,
"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject",
&GetCodec());
if (api != nullptr) {
channel->SetMessageHandler(
[api](const flutter::EncodableValue& message,
const flutter::MessageReply<flutter::EncodableValue>& reply) {
flutter::EncodableList wrapped;
try {
const auto& args = std::get<flutter::EncodableList>(message);
const auto& encodable_a_nullable_object_arg = args.at(0);
const auto* a_nullable_object_arg =
&encodable_a_nullable_object_arg;
ErrorOr<std::optional<flutter::EncodableValue>> output =
api->EchoNullableObject(a_nullable_object_arg);
if (output.has_error()) {
wrapped = WrapError(output.error());
} else {
auto output_optional = std::move(output).TakeValue();
if (output_optional) {
wrapped.push_back(flutter::EncodableValue(
std::move(output_optional).value()));
} else {
wrapped.push_back(flutter::EncodableValue());
}
}
} catch (const std::exception& exception) {
wrapped = WrapError(exception.what());
}
reply(flutter::EncodableValue(std::move(wrapped)));
});
} else {
channel->SetMessageHandler(nullptr);
}
}
{ {
auto channel = auto channel =
std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>( std::make_unique<flutter::BasicMessageChannel<flutter::EncodableValue>>(

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Autogenerated from Pigeon (v4.2.15), do not edit directly. // Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon // See also: https://pub.dev/packages/pigeon
#ifndef PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_ #ifndef PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_
@ -283,6 +283,9 @@ class HostIntegrationCoreApi {
// Returns the passed in Uint8List. // Returns the passed in Uint8List.
virtual ErrorOr<std::vector<uint8_t>> EchoUint8List( virtual ErrorOr<std::vector<uint8_t>> EchoUint8List(
const std::vector<uint8_t>& a_uint8_list) = 0; const std::vector<uint8_t>& a_uint8_list) = 0;
// Returns the passed in generic Object.
virtual ErrorOr<flutter::EncodableValue> EchoObject(
const flutter::EncodableValue& an_object) = 0;
// Returns the inner `aString` value from the wrapped object, to test // Returns the inner `aString` value from the wrapped object, to test
// sending of nested objects. // sending of nested objects.
virtual ErrorOr<std::optional<std::string>> ExtractNestedNullableString( virtual ErrorOr<std::optional<std::string>> ExtractNestedNullableString(
@ -310,6 +313,9 @@ class HostIntegrationCoreApi {
// Returns the passed in Uint8List. // Returns the passed in Uint8List.
virtual ErrorOr<std::optional<std::vector<uint8_t>>> EchoNullableUint8List( virtual ErrorOr<std::optional<std::vector<uint8_t>>> EchoNullableUint8List(
const std::vector<uint8_t>* a_nullable_uint8_list) = 0; const std::vector<uint8_t>* a_nullable_uint8_list) = 0;
// Returns the passed in generic Object.
virtual ErrorOr<std::optional<flutter::EncodableValue>> EchoNullableObject(
const flutter::EncodableValue* a_nullable_object) = 0;
// A no-op function taking no arguments and returning no value, to sanity // A no-op function taking no arguments and returning no value, to sanity
// test basic asynchronous calling. // test basic asynchronous calling.
virtual void NoopAsync( virtual void NoopAsync(

View File

@ -73,6 +73,11 @@ ErrorOr<std::vector<uint8_t>> TestPlugin::EchoUint8List(
return a_uint8_list; return a_uint8_list;
} }
ErrorOr<flutter::EncodableValue> TestPlugin::EchoObject(
const flutter::EncodableValue& an_object) {
return an_object;
}
ErrorOr<std::optional<std::string>> TestPlugin::ExtractNestedNullableString( ErrorOr<std::optional<std::string>> TestPlugin::ExtractNestedNullableString(
const AllNullableTypesWrapper& wrapper) { const AllNullableTypesWrapper& wrapper) {
const std::string* inner_string = wrapper.values().a_nullable_string(); const std::string* inner_string = wrapper.values().a_nullable_string();
@ -153,6 +158,14 @@ ErrorOr<std::optional<std::vector<uint8_t>>> TestPlugin::EchoNullableUint8List(
return *a_nullable_uint8_list; return *a_nullable_uint8_list;
}; };
ErrorOr<std::optional<flutter::EncodableValue>> TestPlugin::EchoNullableObject(
const flutter::EncodableValue* a_nullable_object) {
if (!a_nullable_object) {
return std::nullopt;
}
return *a_nullable_object;
};
void TestPlugin::NoopAsync( void TestPlugin::NoopAsync(
std::function<void(std::optional<FlutterError> reply)> result) { std::function<void(std::optional<FlutterError> reply)> result) {
result(std::nullopt); result(std::nullopt);

View File

@ -47,6 +47,8 @@ class TestPlugin : public flutter::Plugin,
const std::string& a_string) override; const std::string& a_string) override;
core_tests_pigeontest::ErrorOr<std::vector<uint8_t>> EchoUint8List( core_tests_pigeontest::ErrorOr<std::vector<uint8_t>> EchoUint8List(
const std::vector<uint8_t>& a_uint8_list) override; const std::vector<uint8_t>& a_uint8_list) override;
core_tests_pigeontest::ErrorOr<flutter::EncodableValue> EchoObject(
const flutter::EncodableValue& an_object) override;
core_tests_pigeontest::ErrorOr<std::optional<std::string>> core_tests_pigeontest::ErrorOr<std::optional<std::string>>
ExtractNestedNullableString( ExtractNestedNullableString(
const core_tests_pigeontest::AllNullableTypesWrapper& wrapper) override; const core_tests_pigeontest::AllNullableTypesWrapper& wrapper) override;
@ -67,7 +69,8 @@ class TestPlugin : public flutter::Plugin,
core_tests_pigeontest::ErrorOr<std::optional<std::vector<uint8_t>>> core_tests_pigeontest::ErrorOr<std::optional<std::vector<uint8_t>>>
EchoNullableUint8List( EchoNullableUint8List(
const std::vector<uint8_t>* a_nullable_uint8_list) override; const std::vector<uint8_t>* a_nullable_uint8_list) override;
core_tests_pigeontest::ErrorOr<std::optional<flutter::EncodableValue>>
EchoNullableObject(const flutter::EncodableValue* a_nullable_object) override;
void NoopAsync(std::function< void NoopAsync(std::function<
void(std::optional<core_tests_pigeontest::FlutterError> reply)> void(std::optional<core_tests_pigeontest::FlutterError> reply)>
result) override; result) override;

View File

@ -2,7 +2,7 @@ name: pigeon
description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. 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 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 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon
version: 4.2.15 # This must match the version in lib/generator_tools.dart version: 4.2.16 # This must match the version in lib/generator_tools.dart
environment: environment:
sdk: ">=2.12.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"

View File

@ -809,6 +809,12 @@ void main() {
baseName: 'ParameterObject', baseName: 'ParameterObject',
isNullable: true, isNullable: true,
)), )),
NamedType(
name: 'aGenericObject',
type: const TypeDeclaration(
baseName: 'Object',
isNullable: true,
)),
], ],
returnType: const TypeDeclaration.voidDeclaration(), returnType: const TypeDeclaration.voidDeclaration(),
), ),
@ -834,7 +840,8 @@ void main() {
'const std::string* a_string, ' 'const std::string* a_string, '
'const flutter::EncodableList* a_list, ' 'const flutter::EncodableList* a_list, '
'const flutter::EncodableMap* a_map, ' 'const flutter::EncodableMap* a_map, '
'const ParameterObject* an_object)')); 'const ParameterObject* an_object, '
'const flutter::EncodableValue* a_generic_object)'));
} }
{ {
final StringBuffer sink = StringBuffer(); final StringBuffer sink = StringBuffer();
@ -875,6 +882,12 @@ void main() {
code, code,
contains( contains(
'const auto* an_object_arg = &(std::any_cast<const ParameterObject&>(std::get<flutter::CustomEncodableValue>(encodable_an_object_arg)));')); 'const auto* an_object_arg = &(std::any_cast<const ParameterObject&>(std::get<flutter::CustomEncodableValue>(encodable_an_object_arg)));'));
// "Object" requires no extraction at all since it has to use
// EncodableValue directly.
expect(
code,
contains(
'const auto* a_generic_object_arg = &encodable_a_generic_object_arg;'));
} }
}); });
@ -927,6 +940,12 @@ void main() {
baseName: 'ParameterObject', baseName: 'ParameterObject',
isNullable: false, isNullable: false,
)), )),
NamedType(
name: 'aGenericObject',
type: const TypeDeclaration(
baseName: 'Object',
isNullable: false,
)),
], ],
returnType: const TypeDeclaration.voidDeclaration(), returnType: const TypeDeclaration.voidDeclaration(),
), ),
@ -952,7 +971,8 @@ void main() {
'const std::string& a_string, ' 'const std::string& a_string, '
'const flutter::EncodableList& a_list, ' 'const flutter::EncodableList& a_list, '
'const flutter::EncodableMap& a_map, ' 'const flutter::EncodableMap& a_map, '
'const ParameterObject& an_object)')); 'const ParameterObject& an_object, '
'const flutter::EncodableValue& a_generic_object)'));
} }
{ {
final StringBuffer sink = StringBuffer(); final StringBuffer sink = StringBuffer();
@ -988,6 +1008,12 @@ void main() {
code, code,
contains( contains(
'const auto& an_object_arg = std::any_cast<const ParameterObject&>(std::get<flutter::CustomEncodableValue>(encodable_an_object_arg));')); 'const auto& an_object_arg = std::any_cast<const ParameterObject&>(std::get<flutter::CustomEncodableValue>(encodable_an_object_arg));'));
// "Object" requires no extraction at all since it has to use
// EncodableValue directly.
expect(
code,
contains(
'const auto& a_generic_object_arg = encodable_a_generic_object_arg;'));
} }
}); });