[pigeon] wrap encodable lists in encodable value before reply (#2968)
* wrap encodable lists before reply
* Changelog
* changelog
* basic test
* positive test and move
* nit
diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index ce7e6f6..39ccd55 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 4.2.14
+
+* [c++] Fixes reply sending non EncodableValue wrapped lists.
+
## 4.2.13
* Add documentation comment support for Enum members.
diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart
index e06d5d1..744f6e9 100644
--- a/packages/pigeon/lib/cpp_generator.dart
+++ b/packages/pigeon/lib/cpp_generator.dart
@@ -590,7 +590,7 @@
indent.write('if ($encodableArgName.IsNull()) ');
indent.scoped('{', '}', () {
indent.writeln(
- 'reply(WrapError("$argName unexpectedly null."));');
+ 'reply(flutter::EncodableValue(WrapError("$argName unexpectedly null.")));');
indent.writeln('return;');
});
}
@@ -656,7 +656,7 @@
if (method.isAsynchronous) {
methodArgument.add(
'[&wrapped, &reply]($returnTypeName&& output) {${indent.newline}'
- '${wrapResponse('\treply(wrapped);${indent.newline}', method.returnType)}'
+ '${wrapResponse('\treply(flutter::EncodableValue(std::move(wrapped)));${indent.newline}', method.returnType)}'
'}',
);
}
@@ -673,11 +673,13 @@
indent.scoped('{', '}', () {
indent.writeln('wrapped = WrapError(exception.what());');
if (method.isAsynchronous) {
- indent.writeln('reply(wrapped);');
+ indent.writeln(
+ 'reply(flutter::EncodableValue(std::move(wrapped)));');
}
});
if (!method.isAsynchronous) {
- indent.writeln('reply(wrapped);');
+ indent.writeln(
+ 'reply(flutter::EncodableValue(std::move(wrapped)));');
}
});
});
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index 8140cbb..4d8ed37 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -9,7 +9,7 @@
import 'ast.dart';
/// The current version of pigeon. This must match the version in pubspec.yaml.
-const String pigeonVersion = '4.2.13';
+const String pigeonVersion = '4.2.14';
/// Read all the content from [stdin] to a String.
String readStdin() {
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index a68cd75..c6d4029 100644
--- a/packages/pigeon/pubspec.yaml
+++ b/packages/pigeon/pubspec.yaml
@@ -2,7 +2,7 @@
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: 4.2.13 # This must match the version in lib/generator_tools.dart
+version: 4.2.14 # This must match the version in lib/generator_tools.dart
environment:
sdk: ">=2.12.0 <3.0.0"
diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart
index 4021d56..d089b0a 100644
--- a/packages/pigeon/test/cpp_generator_test.dart
+++ b/packages/pigeon/test/cpp_generator_test.dart
@@ -1203,4 +1203,74 @@
final String code = sink.toString();
expect(code, contains(' : public flutter::StandardCodecSerializer'));
});
+
+ test('Does not send unwrapped EncodableLists', () {
+ final Root root = Root(apis: <Api>[
+ Api(name: 'Api', location: ApiLocation.host, methods: <Method>[
+ Method(
+ name: 'doSomething',
+ arguments: <NamedType>[
+ NamedType(
+ name: 'aBool',
+ type: const TypeDeclaration(
+ baseName: 'bool',
+ isNullable: false,
+ )),
+ NamedType(
+ name: 'anInt',
+ type: const TypeDeclaration(
+ baseName: 'int',
+ isNullable: false,
+ )),
+ NamedType(
+ name: 'aString',
+ type: const TypeDeclaration(
+ baseName: 'String',
+ isNullable: false,
+ )),
+ NamedType(
+ name: 'aList',
+ type: const TypeDeclaration(
+ baseName: 'List',
+ typeArguments: <TypeDeclaration>[
+ TypeDeclaration(baseName: 'Object', isNullable: true)
+ ],
+ isNullable: false,
+ )),
+ NamedType(
+ name: 'aMap',
+ type: const TypeDeclaration(
+ baseName: 'Map',
+ typeArguments: <TypeDeclaration>[
+ TypeDeclaration(baseName: 'String', isNullable: true),
+ TypeDeclaration(baseName: 'Object', isNullable: true),
+ ],
+ isNullable: false,
+ )),
+ NamedType(
+ name: 'anObject',
+ type: const TypeDeclaration(
+ baseName: 'ParameterObject',
+ isNullable: false,
+ )),
+ ],
+ returnType: const TypeDeclaration.voidDeclaration(),
+ ),
+ ])
+ ], classes: <Class>[
+ Class(name: 'ParameterObject', fields: <NamedType>[
+ NamedType(
+ type: const TypeDeclaration(
+ baseName: 'bool',
+ isNullable: false,
+ ),
+ name: 'aValue'),
+ ]),
+ ], enums: <Enum>[]);
+ final StringBuffer sink = StringBuffer();
+ generateCppSource(const CppOptions(), root, sink);
+ final String code = sink.toString();
+ expect(code, isNot(contains('reply(wrap')));
+ expect(code, contains('reply(flutter::EncodableValue('));
+ });
}