Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/pigeon/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

* Relocates generator classes. (Reverted)
Expand Down
15 changes: 15 additions & 0 deletions packages/pigeon/lib/cpp_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,11 @@ const flutter::StandardMessageCodec& ${api.name}::GetCodec() {
// ... then declare the arg as a reference to that local.
indent.writeln(
'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) {
indent.writeln(
'const auto* $argName = std::get_if<${hostType.datatype}>(&$encodableArgName);');
Expand All @@ -564,6 +569,13 @@ const flutter::StandardMessageCodec& ${api.name}::GetCodec() {
// requires an int64_t so that it can handle any case.
indent.writeln(
'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) {
indent.writeln(
'const auto& $argName = std::get<${hostType.datatype}>($encodableArgName);');
Expand Down Expand Up @@ -902,6 +914,7 @@ String? _baseCppTypeForBuiltinDartType(TypeDeclaration type) {
'Float64List': 'std::vector<double>',
'Map': 'flutter::EncodableMap',
'List': 'flutter::EncodableList',
'Object': 'flutter::EncodableValue',
};
if (cppTypeForDartTypeMap.containsKey(type.baseName)) {
return cppTypeForDartTypeMap[type.baseName];
Expand Down Expand Up @@ -931,6 +944,8 @@ String _unownedArgumentType(HostDatatype type) {
if (isString || _isPodType(type)) {
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&';
}

Expand Down
12 changes: 8 additions & 4 deletions packages/pigeon/lib/dart_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,17 @@ final BinaryMessenger? _binaryMessenger;
indent.writeln('binaryMessenger: _binaryMessenger);');
});
final String returnType = _makeGenericTypeArguments(func.returnType);
final String castCall = _makeGenericCastCall(func.returnType);
final String genericCastCall = _makeGenericCastCall(func.returnType);
const String accessor = 'replyList[0]';
final String nullHandler =
func.returnType.isNullable ? (castCall.isEmpty ? '' : '?') : '!';
// Avoid warnings from pointlessly casting to `Object?`.
final String nullablyTypedAccessor =
returnType == 'Object' ? accessor : '($accessor as $returnType?)';
final String nullHandler = func.returnType.isNullable
? (genericCastCall.isEmpty ? '' : '?')
: '!';
final String returnStatement = func.returnType.isVoid
? 'return;'
: 'return ($accessor as $returnType?)$nullHandler$castCall;';
: 'return $nullablyTypedAccessor$nullHandler$genericCastCall;';
indent.format('''
final List<Object?>? replyList =
\t\tawait channel.send($sendArgument) as List<Object?>?;
Expand Down
2 changes: 1 addition & 1 deletion packages/pigeon/lib/generator_tools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'dart:mirrors';
import 'ast.dart';

/// 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.
String readStdin() {
Expand Down
3 changes: 3 additions & 0 deletions packages/pigeon/lib/swift_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ String _castForceUnwrap(String value, TypeDeclaration type, Root root) {
final String nullableConditionPrefix =
type.isNullable ? '$value == nil ? nil : ' : '';
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 {
final String castUnwrap = type.isNullable ? '?' : '!';
return '$value as$castUnwrap ${_swiftTypeForDartType(type)}';
Expand Down
8 changes: 8 additions & 0 deletions packages/pigeon/pigeons/core_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ abstract class HostIntegrationCoreApi {
@ObjCSelector('echoUint8List:')
Uint8List echoUint8List(Uint8List aUint8List);

/// Returns the passed in generic Object.
@ObjCSelector('echoObject:')
Object echoObject(Object anObject);

// ========== Syncronous nullable method tests ==========

/// Returns the inner `aString` value from the wrapped object, to test
Expand Down Expand Up @@ -162,6 +166,10 @@ abstract class HostIntegrationCoreApi {
@ObjCSelector('echoNullableUint8List:')
Uint8List? echoNullableUint8List(Uint8List? aNullableUint8List);

/// Returns the passed in generic Object.
@ObjCSelector('echoNullableObject:')
Object? echoNullableObject(Object? aNullableObject);

// ========== Asyncronous method tests ==========

/// A no-op function taking no arguments and returning no value, to sanity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public byte[] echoUint8List(@NonNull byte[] aUint8List) {
return aUint8List;
}

@Override
public @NonNull Object echoObject(@NonNull Object anObject) {
return anObject;
}

@Override
public @Nullable String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper) {
return wrapper.getValues().getANullableString();
Expand Down Expand Up @@ -124,6 +129,11 @@ public byte[] echoUint8List(@NonNull byte[] aUint8List) {
return aNullableUint8List;
}

@Override
public @Nullable Object echoNullableObject(@Nullable Object aNullableObject) {
return aNullableObject;
}

@Override
public void noopAsync(Result<Void> result) {
result.success(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (v4.2.15), do not edit directly.
// Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon

package com.example.alternate_language_test_plugin;
Expand Down Expand Up @@ -713,12 +713,9 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));

case (byte) 129:
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));

case (byte) 130:
return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer));

case (byte) 131:
case (byte) 130:
return AllTypes.fromList((ArrayList<Object>) readValue(buffer));

default:
Expand All @@ -731,14 +728,11 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
if (value instanceof AllNullableTypes) {
stream.write(128);
writeValue(stream, ((AllNullableTypes) value).toList());
} else if (value instanceof AllNullableTypes) {
stream.write(129);
writeValue(stream, ((AllNullableTypes) value).toList());
} else if (value instanceof AllNullableTypesWrapper) {
stream.write(130);
stream.write(129);
writeValue(stream, ((AllNullableTypesWrapper) value).toList());
} else if (value instanceof AllTypes) {
stream.write(131);
stream.write(130);
writeValue(stream, ((AllTypes) value).toList());
} else {
super.writeValue(stream, value);
Expand Down Expand Up @@ -780,6 +774,9 @@ public interface HostIntegrationCoreApi {
/** Returns the passed in Uint8List. */
@NonNull
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.
*/
Expand Down Expand Up @@ -811,6 +808,9 @@ AllNullableTypes sendMultipleNullableTypes(
/** Returns the passed in Uint8List. */
@Nullable
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
* asynchronous calling.
Expand Down Expand Up @@ -1072,6 +1072,35 @@ static void setup(BinaryMessenger binaryMessenger, HostIntegrationCoreApi api) {
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 =
new BasicMessageChannel<>(
Expand Down Expand Up @@ -1292,6 +1321,32 @@ static void setup(BinaryMessenger binaryMessenger, HostIntegrationCoreApi api) {
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 =
new BasicMessageChannel<>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ - (nullable FlutterStandardTypedData *)echoUint8List:(FlutterStandardTypedData *
return aUint8List;
}

- (nullable id)echoObject:(id)anObject error:(FlutterError *_Nullable *_Nonnull)error {
return anObject;
}

- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper
error:(FlutterError *_Nullable *_Nonnull)error {
return wrapper.values.aNullableString;
Expand Down Expand Up @@ -114,6 +118,11 @@ - (nullable NSString *)echoNullableString:(nullable NSString *)aNullableString
return aNullableUint8List;
}

- (nullable id)echoNullableObject:(nullable id)aNullableObject
error:(FlutterError *_Nullable *_Nonnull)error {
return aNullableObject;
}

- (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion {
completion(nil);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (v4.2.15), do not edit directly.
// Autogenerated from Pigeon (v4.2.16), do not edit directly.
// See also: https://pub.dev/packages/pigeon
#import <Foundation/Foundation.h>
@protocol FlutterBinaryMessenger;
Expand Down Expand Up @@ -131,6 +131,10 @@ NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec(void);
/// @return `nil` only when `error != nil`.
- (nullable FlutterStandardTypedData *)echoUint8List:(FlutterStandardTypedData *)aUint8List
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
/// sending of nested objects.
- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper
Expand Down Expand Up @@ -166,6 +170,9 @@ NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec(void);
- (nullable FlutterStandardTypedData *)
echoNullableUint8List:(nullable FlutterStandardTypedData *)aNullableUint8List
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
/// test basic asynchronous calling.
- (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion;
Expand Down
Loading