[pigeon] moved to a custom codec (#399)
diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index b365f8b..5bca85d 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -3,6 +3,7 @@
* [front-end] Added a more explicit error if generic fields are used.
* [front-end] Added a more explicit error for static fields.
* [front-end] Added more errors for incorrect usage of Pigeon (previously they were just ignored).
+* Moved Pigeon to using a custom codec which allows collection types to contain custom classes.
## 0.3.0
diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart
index de6ca68..8e6d59b 100644
--- a/packages/pigeon/lib/dart_generator.dart
+++ b/packages/pigeon/lib/dart_generator.dart
@@ -49,8 +49,54 @@
.replaceAll(r"'", r"\'");
}
+String _getCodecName(Api api) => '_${api.name}Codec';
+
+void _writeCodec(Indent indent, String codecName, Api api) {
+ indent.write('class $codecName extends StandardMessageCodec ');
+ indent.scoped('{', '}', () {
+ indent.writeln('const $codecName();');
+ if (getCodecClasses(api).isNotEmpty) {
+ indent.writeln('@override');
+ indent.write('void writeValue(WriteBuffer buffer, Object? value) ');
+ indent.scoped('{', '}', () {
+ for (final EnumeratedClass customClass in getCodecClasses(api)) {
+ indent.write('if (value is ${customClass.name}) ');
+ indent.scoped('{', '} else ', () {
+ indent.writeln('buffer.putUint8(${customClass.enumeration});');
+ indent.writeln('writeValue(buffer, value.encode());');
+ });
+ }
+ indent.scoped('{', '}', () {
+ indent.writeln('super.writeValue(buffer, value);');
+ });
+ });
+ indent.writeln('@override');
+ indent.write('Object? readValueOfType(int type, ReadBuffer buffer) ');
+ indent.scoped('{', '}', () {
+ indent.write('switch (type) ');
+ indent.scoped('{', '}', () {
+ for (final EnumeratedClass customClass in getCodecClasses(api)) {
+ indent.write('case ${customClass.enumeration}: ');
+ indent.writeScoped('', '', () {
+ indent.writeln(
+ 'return ${customClass.name}.decode(readValue(buffer)!);');
+ });
+ }
+ indent.write('default:');
+ indent.writeScoped('', '', () {
+ indent.writeln('return super.readValueOfType(type, buffer);');
+ });
+ });
+ });
+ }
+ });
+}
+
void _writeHostApi(DartOptions opt, Indent indent, Api api) {
assert(api.location == ApiLocation.host);
+ final String codecName = _getCodecName(api);
+ _writeCodec(indent, codecName, api);
+ indent.addln('');
final String nullTag = opt.isNullSafe ? '?' : '';
final String unwrapOperator = opt.isNullSafe ? '!' : '';
bool first = true;
@@ -65,6 +111,8 @@
final BinaryMessenger$nullTag _binaryMessenger;
''');
+ indent.writeln('static const MessageCodec<Object?> codec = $codecName();');
+ indent.addln('');
for (final Method func in api.methods) {
if (!first) {
indent.writeln('');
@@ -91,7 +139,7 @@
'final BasicMessageChannel<Object$nullTag> channel = BasicMessageChannel<Object$nullTag>(');
indent.nest(2, () {
indent.writeln(
- '\'$channelName\', const StandardMessageCodec(), binaryMessenger: _binaryMessenger);',
+ '\'$channelName\', codec, binaryMessenger: _binaryMessenger);',
);
});
final String returnStatement = func.returnType == 'void'
@@ -128,10 +176,14 @@
bool isMockHandler = false,
}) {
assert(api.location == ApiLocation.flutter);
+ final String codecName = _getCodecName(api);
+ _writeCodec(indent, codecName, api);
final String nullTag = opt.isNullSafe ? '?' : '';
final String unwrapOperator = opt.isNullSafe ? '!' : '';
indent.write('abstract class ${api.name} ');
indent.scoped('{', '}', () {
+ indent.writeln('static const MessageCodec<Object?> codec = $codecName();');
+ indent.addln('');
for (final Method func in api.methods) {
final bool isAsync = func.isAsynchronous;
final String returnType =
@@ -153,7 +205,7 @@
: channelNameFunc(func);
indent.nest(2, () {
indent.writeln(
- '\'$channelName\', StandardMessageCodec());',
+ '\'$channelName\', codec);',
);
});
final String messageHandlerSetter =
@@ -243,14 +295,16 @@
indent.writeln('// $generatedCodeWarning');
indent.writeln('// $seeAlsoWarning');
indent.writeln(
- '// 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',
+ '// 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',
);
indent.writeln('// @dart = ${opt.isNullSafe ? '2.12' : '2.8'}');
indent.writeln('import \'dart:async\';');
indent.writeln(
'import \'dart:typed_data\' show Uint8List, Int32List, Int64List, Float64List;',
);
- indent.writeln('');
+ indent.addln('');
+ indent.writeln(
+ 'import \'package:flutter/foundation.dart\' show WriteBuffer, ReadBuffer;');
indent.writeln('import \'package:flutter/services.dart\';');
for (final Enum anEnum in root.enums) {
indent.writeln('');
@@ -356,6 +410,8 @@
indent.writeln(
'import \'dart:typed_data\' show Uint8List, Int32List, Int64List, Float64List;',
);
+ indent.writeln(
+ 'import \'package:flutter/foundation.dart\' show WriteBuffer, ReadBuffer;');
indent.writeln('import \'package:flutter/services.dart\';');
indent.writeln('import \'package:flutter_test/flutter_test.dart\';');
indent.writeln('');
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index 1fe3386..e5f07d9 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -249,3 +249,42 @@
}
return result;
}
+
+/// A class name that is enumerated.
+class EnumeratedClass {
+ /// Constructor.
+ EnumeratedClass(this.name, this.enumeration);
+
+ /// The name of the class.
+ final String name;
+
+ /// The enumeration of the class.
+ final int enumeration;
+}
+
+/// Custom codecs' custom types are enumerated from 255 down to this number to
+/// avoid collisions with the StandardMessageCodec.
+const int _minimumCodecFieldKey = 128;
+
+/// Given an [Api], return the enumerated classes that must exist in the codec
+/// where the enumeration should be the key used in the buffer.
+Iterable<EnumeratedClass> getCodecClasses(Api api) sync* {
+ final Set<String> names = <String>{};
+ for (final Method method in api.methods) {
+ names.add(method.returnType);
+ names.add(method.argType);
+ }
+ final List<String> sortedNames =
+ names.where((String element) => element != 'void').toList();
+ sortedNames.sort();
+ int enumeration = _minimumCodecFieldKey;
+ const int maxCustomClassesPerApi = 255 - _minimumCodecFieldKey;
+ if (sortedNames.length > maxCustomClassesPerApi) {
+ throw Exception(
+ 'Pigeon doesn\'t support more than $maxCustomClassesPerApi referenced custom classes per API, try splitting up your APIs.');
+ }
+ for (final String name in sortedNames) {
+ yield EnumeratedClass(name, enumeration);
+ enumeration += 1;
+ }
+}
diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart
index 625e5f0..d53c829 100644
--- a/packages/pigeon/lib/java_generator.dart
+++ b/packages/pigeon/lib/java_generator.dart
@@ -64,6 +64,55 @@
}
}
+String _getCodecName(Api api) => '${api.name}Codec';
+
+void _writeCodec(Indent indent, Api api) {
+ final String codecName = _getCodecName(api);
+ indent.write('private static class $codecName extends StandardMessageCodec ');
+ indent.scoped('{', '}', () {
+ indent
+ .writeln('public static final $codecName INSTANCE = new $codecName();');
+ indent.writeln('private $codecName() {}');
+ if (getCodecClasses(api).isNotEmpty) {
+ indent.writeln('@Override');
+ indent.write(
+ 'protected Object readValueOfType(byte type, ByteBuffer buffer) ');
+ indent.scoped('{', '}', () {
+ indent.write('switch (type) ');
+ indent.scoped('{', '}', () {
+ for (final EnumeratedClass customClass in getCodecClasses(api)) {
+ indent.write('case (byte)${customClass.enumeration}: ');
+ indent.writeScoped('', '', () {
+ indent.writeln(
+ 'return ${customClass.name}.fromMap((Map<String, Object>) readValue(buffer));');
+ });
+ }
+ indent.write('default:');
+ indent.writeScoped('', '', () {
+ indent.writeln('return super.readValueOfType(type, buffer);');
+ });
+ });
+ });
+ indent.writeln('@Override');
+ indent.write(
+ 'protected void writeValue(ByteArrayOutputStream stream, Object value) ');
+ indent.writeScoped('{', '}', () {
+ for (final EnumeratedClass customClass in getCodecClasses(api)) {
+ indent.write('if (value instanceof ${customClass.name}) ');
+ indent.scoped('{', '} else ', () {
+ indent.writeln('stream.write(${customClass.enumeration});');
+ indent.writeln(
+ 'writeValue(stream, ((${customClass.name}) value).toMap());');
+ });
+ }
+ indent.scoped('{', '}', () {
+ indent.writeln('super.writeValue(stream, value);');
+ });
+ });
+ }
+ });
+}
+
void _writeHostApi(Indent indent, Api api) {
assert(api.location == ApiLocation.host);
@@ -86,6 +135,13 @@
indent.writeln('$returnType ${method.name}(${argSignature.join(', ')});');
}
indent.addln('');
+ final String codecName = _getCodecName(api);
+ indent.format('''
+/** The codec used by ${api.name}. */
+static MessageCodec<Object> getCodec() {
+\treturn $codecName.INSTANCE;
+}
+''');
indent.writeln(
'/** Sets up an instance of `${api.name}` to handle messages through the `binaryMessenger`. */');
indent.write(
@@ -99,7 +155,7 @@
indent.inc();
indent.inc();
indent.writeln(
- 'new BasicMessageChannel<>(binaryMessenger, "$channelName", new StandardMessageCodec());');
+ 'new BasicMessageChannel<>(binaryMessenger, "$channelName", getCodec());');
indent.dec();
indent.dec();
indent.write('if (api != null) ');
@@ -178,6 +234,12 @@
indent.scoped('{', '}', () {
indent.writeln('void reply(T reply);');
});
+ final String codecName = _getCodecName(api);
+ indent.format('''
+static MessageCodec<Object> getCodec() {
+\treturn $codecName.INSTANCE;
+}
+''');
for (final Method func in api.methods) {
final String channelName = makeChannelName(api, func);
final String returnType =
@@ -196,7 +258,7 @@
indent.inc();
indent.inc();
indent.writeln(
- 'new BasicMessageChannel<>(binaryMessenger, "$channelName", new StandardMessageCodec());');
+ 'new BasicMessageChannel<>(binaryMessenger, "$channelName", getCodec());');
indent.dec();
indent.dec();
if (func.argType != 'void') {
@@ -269,7 +331,10 @@
indent.addln('');
indent.writeln('import io.flutter.plugin.common.BasicMessageChannel;');
indent.writeln('import io.flutter.plugin.common.BinaryMessenger;');
+ indent.writeln('import io.flutter.plugin.common.MessageCodec;');
indent.writeln('import io.flutter.plugin.common.StandardMessageCodec;');
+ indent.writeln('import java.io.ByteArrayOutputStream;');
+ indent.writeln('import java.nio.ByteBuffer;');
indent.writeln('import java.util.List;');
indent.writeln('import java.util.Map;');
indent.writeln('import java.util.HashMap;');
@@ -368,6 +433,7 @@
}
for (final Api api in root.apis) {
+ _writeCodec(indent, api);
indent.addln('');
if (api.location == ApiLocation.host) {
_writeHostApi(indent, api);
diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart
index 283b672..c46708f 100644
--- a/packages/pigeon/lib/objc_generator.dart
+++ b/packages/pigeon/lib/objc_generator.dart
@@ -134,6 +134,85 @@
}
}
+String _getCodecName(String? prefix, String className) =>
+ '${_className(prefix, className)}Codec';
+
+String _getCodecGetterName(String? prefix, String className) =>
+ '${_className(prefix, className)}GetCodec';
+
+void _writeCodec(Indent indent, String name, ObjcOptions options, Api api) {
+ final String readerWriterName = '${name}ReaderWriter';
+ final String readerName = '${name}Reader';
+ final String writerName = '${name}Writer';
+ indent.writeln('@interface $readerName : FlutterStandardReader');
+ indent.writeln('@end');
+ indent.writeln('@implementation $readerName');
+ if (getCodecClasses(api).isNotEmpty) {
+ indent.writeln('- (nullable id)readValueOfType:(UInt8)type ');
+ indent.scoped('{', '}', () {
+ indent.write('switch (type) ');
+ indent.scoped('{', '}', () {
+ for (final EnumeratedClass customClass in getCodecClasses(api)) {
+ indent.write('case ${customClass.enumeration}: ');
+ indent.writeScoped('', '', () {
+ indent.writeln(
+ 'return [${_className(options.prefix, customClass.name)} fromMap:[self readValue]];');
+ });
+ }
+ indent.write('default:');
+ indent.writeScoped('', '', () {
+ indent.writeln('return [super readValueOfType:type];');
+ });
+ });
+ });
+ }
+ indent.writeln('@end');
+ indent.addln('');
+ indent.writeln('@interface $writerName : FlutterStandardWriter');
+ indent.writeln('@end');
+ indent.writeln('@implementation $writerName');
+ if (getCodecClasses(api).isNotEmpty) {
+ indent.writeln('- (void)writeValue:(id)value ');
+ indent.scoped('{', '}', () {
+ for (final EnumeratedClass customClass in getCodecClasses(api)) {
+ indent.write(
+ 'if ([value isKindOfClass:[${_className(options.prefix, customClass.name)} class]]) ');
+ indent.scoped('{', '} else ', () {
+ indent.writeln('[self writeByte:${customClass.enumeration}];');
+ indent.writeln('[self writeValue:[value toMap]];');
+ });
+ }
+ indent.scoped('{', '}', () {
+ indent.writeln('[super writeValue:value];');
+ });
+ });
+ }
+ indent.writeln('@end');
+ indent.addln('');
+ indent.format('''
+@interface $readerWriterName : FlutterStandardReaderWriter
+@end
+@implementation $readerWriterName
+- (FlutterStandardWriter*)writerWithData:(NSMutableData*)data {
+\treturn [[$writerName alloc] initWithData:data];
+}
+- (FlutterStandardReader*)readerWithData:(NSData*)data {
+\treturn [[$readerName alloc] initWithData:data];
+}
+@end
+
+NSObject<FlutterMessageCodec>* ${_getCodecGetterName(options.prefix, api.name)}() {
+\tstatic dispatch_once_t s_pred = 0;
+\tstatic FlutterStandardMessageCodec* s_sharedObject = nil;
+\tdispatch_once(&s_pred, ^{
+\t\t$readerWriterName* readerWriter = [[$readerWriterName alloc] init];
+\t\ts_sharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+\t});
+\treturn s_sharedObject;
+}
+''');
+}
+
void _writeHostApiDeclaration(Indent indent, Api api, ObjcOptions options) {
final String apiName = _className(options.prefix, api.name);
indent.writeln('@protocol $apiName');
@@ -209,6 +288,7 @@
indent.writeln('// $seeAlsoWarning');
indent.writeln('#import <Foundation/Foundation.h>');
indent.writeln('@protocol FlutterBinaryMessenger;');
+ indent.writeln('@protocol FlutterMessageCodec;');
indent.writeln('@class FlutterError;');
indent.writeln('@class FlutterStandardTypedData;');
indent.writeln('');
@@ -240,6 +320,11 @@
_writeClassDeclarations(indent, root.classes, root.enums, options.prefix);
for (final Api api in root.apis) {
+ indent.writeln(
+ '/// The codec used by ${_className(options.prefix, api.name)}.');
+ indent.writeln(
+ 'NSObject<FlutterMessageCodec>* ${_getCodecGetterName(options.prefix, api.name)}(void);');
+ indent.addln('');
if (api.location == ApiLocation.host) {
_writeHostApiDeclaration(indent, api, options);
} else if (api.location == ApiLocation.flutter) {
@@ -289,7 +374,9 @@
indent.inc();
indent
.writeln('messageChannelWithName:@"${makeChannelName(api, func)}"');
- indent.writeln('binaryMessenger:binaryMessenger];');
+ indent.writeln('binaryMessenger:binaryMessenger');
+ indent.writeln(
+ 'codec:${_getCodecGetterName(options.prefix, api.name)}()];');
indent.dec();
indent.dec();
@@ -402,7 +489,9 @@
indent.writeln('[FlutterBasicMessageChannel');
indent.inc();
indent.writeln('messageChannelWithName:@"${makeChannelName(api, func)}"');
- indent.writeln('binaryMessenger:self.binaryMessenger];');
+ indent.writeln('binaryMessenger:self.binaryMessenger');
+ indent.writeln(
+ 'codec:${_getCodecGetterName(options.prefix, api.name)}()];');
indent.dec();
indent.dec();
if (func.argType != 'void') {
@@ -510,6 +599,9 @@
}
for (final Api api in root.apis) {
+ final String codecName = _getCodecName(options.prefix, api.name);
+ _writeCodec(indent, codecName, options, api);
+ indent.addln('');
if (api.location == ApiLocation.host) {
_writeHostApiSource(indent, options, api);
} else if (api.location == ApiLocation.flutter) {
diff --git a/packages/pigeon/pigeons/all_void.dart b/packages/pigeon/pigeons/all_void.dart
new file mode 100644
index 0000000..ce80a55
--- /dev/null
+++ b/packages/pigeon/pigeons/all_void.dart
@@ -0,0 +1,15 @@
+// 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 'package:pigeon/pigeon.dart';
+
+@FlutterApi()
+abstract class AllVoidFlutterApi {
+ void doit();
+}
+
+@HostApi()
+abstract class AllVoidHostApi {
+ void doit();
+}
diff --git a/packages/pigeon/pigeons/flutter_unittests.dart b/packages/pigeon/pigeons/flutter_unittests.dart
index bf3576b..cb99095 100644
--- a/packages/pigeon/pigeons/flutter_unittests.dart
+++ b/packages/pigeon/pigeons/flutter_unittests.dart
@@ -27,4 +27,5 @@
abstract class Api {
SearchReply search(SearchRequest request);
SearchReplies doSearches(SearchRequests request);
+ SearchRequests echo(SearchRequests requests);
}
diff --git a/packages/pigeon/pigeons/list.dart b/packages/pigeon/pigeons/list.dart
index 9af7025..11359e7 100644
--- a/packages/pigeon/pigeons/list.dart
+++ b/packages/pigeon/pigeons/list.dart
@@ -13,3 +13,8 @@
abstract class TestApi {
void test(TestMessage msg);
}
+
+@FlutterApi()
+abstract class EchoApi {
+ TestMessage echo(TestMessage msg);
+}
diff --git a/packages/pigeon/platform_tests/android_unit_tests/android/app/src/test/java/com/example/android_unit_tests/ListTest.java b/packages/pigeon/platform_tests/android_unit_tests/android/app/src/test/java/com/example/android_unit_tests/ListTest.java
new file mode 100644
index 0000000..45093df
--- /dev/null
+++ b/packages/pigeon/platform_tests/android_unit_tests/android/app/src/test/java/com/example/android_unit_tests/ListTest.java
@@ -0,0 +1,48 @@
+// 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.
+
+package com.example.android_unit_tests;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import com.example.android_unit_tests.PigeonList.EchoApi;
+import com.example.android_unit_tests.PigeonList.TestMessage;
+import io.flutter.plugin.common.BinaryMessenger;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.junit.Test;
+
+public class ListTest {
+ @Test
+ public void listInList() {
+ TestMessage top = new TestMessage();
+ TestMessage inside = new TestMessage();
+ inside.setTestList(Arrays.asList(1, 2, 3));
+ top.setTestList(Arrays.asList(inside));
+ BinaryMessenger binaryMessenger = mock(BinaryMessenger.class);
+ doAnswer(
+ invocation -> {
+ ByteBuffer message = invocation.getArgument(1);
+ BinaryMessenger.BinaryReply reply = invocation.getArgument(2);
+ message.position(0);
+ reply.reply(message);
+ return null;
+ })
+ .when(binaryMessenger)
+ .send(anyString(), any(), any());
+ EchoApi api = new EchoApi(binaryMessenger);
+ boolean[] didCall = {false};
+ api.echo(
+ top,
+ (result) -> {
+ didCall[0] = true;
+ assertEquals(result.getTestList().size(), 1);
+ assertTrue(result.getTestList().get(0) instanceof TestMessage);
+ TestMessage readInside = (TestMessage) result.getTestList().get(0);
+ assertEquals(readInside.getTestList().size(), 3);
+ });
+ assertTrue(didCall[0]);
+ }
+}
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/all_datatypes.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/all_datatypes.dart
index 7550dc2..5ad97e5 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/all_datatypes.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/all_datatypes.dart
@@ -1,14 +1,15 @@
// 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 (v0.2.1), do not edit directly.
+//
+// Autogenerated from Pigeon (v0.3.0), 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
+// 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
// @dart = 2.12
import 'dart:async';
import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
+import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
import 'package:flutter/services.dart';
class Everything {
@@ -54,38 +55,26 @@
}
}
-abstract class FlutterEverything {
- Everything giveMeEverything();
- Everything echo(Everything arg);
- static void setup(FlutterEverything? api) {
- {
- const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
- 'dev.flutter.pigeon.FlutterEverything.giveMeEverything',
- StandardMessageCodec());
- if (api == null) {
- channel.setMessageHandler(null);
- } else {
- channel.setMessageHandler((Object? message) async {
- // ignore message
- final Everything output = api.giveMeEverything();
- return output.encode();
- });
- }
+class _HostEverythingCodec extends StandardMessageCodec {
+ const _HostEverythingCodec();
+ @override
+ void writeValue(WriteBuffer buffer, Object? value) {
+ if (value is Everything) {
+ buffer.putUint8(255);
+ writeValue(buffer, value.encode());
+ } else {
+ super.writeValue(buffer, value);
}
- {
- const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
- 'dev.flutter.pigeon.FlutterEverything.echo', StandardMessageCodec());
- if (api == null) {
- channel.setMessageHandler(null);
- } else {
- channel.setMessageHandler((Object? message) async {
- assert(message != null,
- 'Argument for dev.flutter.pigeon.FlutterEverything.echo was null. Expected Everything.');
- final Everything input = Everything.decode(message!);
- final Everything output = api.echo(input);
- return output.encode();
- });
- }
+ }
+
+ @override
+ Object? readValueOfType(int type, ReadBuffer buffer) {
+ switch (type) {
+ case 255:
+ return Everything.decode(readValue(buffer)!);
+
+ default:
+ return super.readValueOfType(type, buffer);
}
}
}
@@ -99,10 +88,11 @@
final BinaryMessenger? _binaryMessenger;
+ static const MessageCodec<Object?> codec = _HostEverythingCodec();
+
Future<Everything> giveMeEverything() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
- 'dev.flutter.pigeon.HostEverything.giveMeEverything',
- const StandardMessageCodec(),
+ 'dev.flutter.pigeon.HostEverything.giveMeEverything', codec,
binaryMessenger: _binaryMessenger);
final Map<Object?, Object?>? replyMap =
await channel.send(null) as Map<Object?, Object?>?;
@@ -128,7 +118,7 @@
Future<Everything> echo(Everything arg) async {
final Object encoded = arg.encode();
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
- 'dev.flutter.pigeon.HostEverything.echo', const StandardMessageCodec(),
+ 'dev.flutter.pigeon.HostEverything.echo', codec,
binaryMessenger: _binaryMessenger);
final Map<Object?, Object?>? replyMap =
await channel.send(encoded) as Map<Object?, Object?>?;
@@ -151,3 +141,64 @@
}
}
}
+
+class _FlutterEverythingCodec extends StandardMessageCodec {
+ const _FlutterEverythingCodec();
+ @override
+ void writeValue(WriteBuffer buffer, Object? value) {
+ if (value is Everything) {
+ buffer.putUint8(255);
+ writeValue(buffer, value.encode());
+ } else {
+ super.writeValue(buffer, value);
+ }
+ }
+
+ @override
+ Object? readValueOfType(int type, ReadBuffer buffer) {
+ switch (type) {
+ case 255:
+ return Everything.decode(readValue(buffer)!);
+
+ default:
+ return super.readValueOfType(type, buffer);
+ }
+ }
+}
+
+abstract class FlutterEverything {
+ static const MessageCodec<Object?> codec = _FlutterEverythingCodec();
+
+ Everything giveMeEverything();
+ Everything echo(Everything arg);
+ static void setup(FlutterEverything? api) {
+ {
+ const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.FlutterEverything.giveMeEverything', codec);
+ if (api == null) {
+ channel.setMessageHandler(null);
+ } else {
+ channel.setMessageHandler((Object? message) async {
+ // ignore message
+ final Everything output = api.giveMeEverything();
+ return output.encode();
+ });
+ }
+ }
+ {
+ const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.FlutterEverything.echo', codec);
+ if (api == null) {
+ channel.setMessageHandler(null);
+ } else {
+ channel.setMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.FlutterEverything.echo was null. Expected Everything.');
+ final Everything input = Everything.decode(message!);
+ final Everything output = api.echo(input);
+ return output.encode();
+ });
+ }
+ }
+ }
+}
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
index 8dce342..5445ab2 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
@@ -1,16 +1,32 @@
// 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 (v0.2.0), do not edit directly.
+//
+// Autogenerated from Pigeon (v0.3.0), 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
+// 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
// @dart = 2.12
import 'dart:async';
import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
+import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
import 'package:flutter/services.dart';
+class SearchRequest {
+ String? query;
+
+ Object encode() {
+ final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
+ pigeonMap['query'] = query;
+ return pigeonMap;
+ }
+
+ static SearchRequest decode(Object message) {
+ final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
+ return SearchRequest()..query = pigeonMap['query'] as String?;
+ }
+}
+
class SearchReply {
String? result;
String? error;
@@ -30,18 +46,18 @@
}
}
-class SearchRequest {
- String? query;
+class SearchRequests {
+ List<Object?>? requests;
Object encode() {
final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
- pigeonMap['query'] = query;
+ pigeonMap['requests'] = requests;
return pigeonMap;
}
- static SearchRequest decode(Object message) {
+ static SearchRequests decode(Object message) {
final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
- return SearchRequest()..query = pigeonMap['query'] as String?;
+ return SearchRequests()..requests = pigeonMap['requests'] as List<Object?>?;
}
}
@@ -60,18 +76,45 @@
}
}
-class SearchRequests {
- List<Object?>? requests;
-
- Object encode() {
- final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
- pigeonMap['requests'] = requests;
- return pigeonMap;
+class _ApiCodec extends StandardMessageCodec {
+ const _ApiCodec();
+ @override
+ void writeValue(WriteBuffer buffer, Object? value) {
+ if (value is SearchReplies) {
+ buffer.putUint8(255);
+ writeValue(buffer, value.encode());
+ } else if (value is SearchReply) {
+ buffer.putUint8(254);
+ writeValue(buffer, value.encode());
+ } else if (value is SearchRequest) {
+ buffer.putUint8(253);
+ writeValue(buffer, value.encode());
+ } else if (value is SearchRequests) {
+ buffer.putUint8(252);
+ writeValue(buffer, value.encode());
+ } else {
+ super.writeValue(buffer, value);
+ }
}
- static SearchRequests decode(Object message) {
- final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
- return SearchRequests()..requests = pigeonMap['requests'] as List<Object?>?;
+ @override
+ Object? readValueOfType(int type, ReadBuffer buffer) {
+ switch (type) {
+ case 255:
+ return SearchReplies.decode(readValue(buffer)!);
+
+ case 254:
+ return SearchReply.decode(readValue(buffer)!);
+
+ case 253:
+ return SearchRequest.decode(readValue(buffer)!);
+
+ case 252:
+ return SearchRequests.decode(readValue(buffer)!);
+
+ default:
+ return super.readValueOfType(type, buffer);
+ }
}
}
@@ -83,10 +126,12 @@
final BinaryMessenger? _binaryMessenger;
+ static const MessageCodec<Object?> codec = _ApiCodec();
+
Future<SearchReply> search(SearchRequest arg) async {
final Object encoded = arg.encode();
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
- 'dev.flutter.pigeon.Api.search', const StandardMessageCodec(),
+ 'dev.flutter.pigeon.Api.search', codec,
binaryMessenger: _binaryMessenger);
final Map<Object?, Object?>? replyMap =
await channel.send(encoded) as Map<Object?, Object?>?;
@@ -112,7 +157,7 @@
Future<SearchReplies> doSearches(SearchRequests arg) async {
final Object encoded = arg.encode();
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
- 'dev.flutter.pigeon.Api.doSearches', const StandardMessageCodec(),
+ 'dev.flutter.pigeon.Api.doSearches', codec,
binaryMessenger: _binaryMessenger);
final Map<Object?, Object?>? replyMap =
await channel.send(encoded) as Map<Object?, Object?>?;
@@ -134,4 +179,30 @@
return SearchReplies.decode(replyMap['result']!);
}
}
+
+ Future<SearchRequests> echo(SearchRequests arg) async {
+ final Object encoded = arg.encode();
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.Api.echo', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(encoded) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return SearchRequests.decode(replyMap['result']!);
+ }
+ }
}
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/all_datatypes_test.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/all_datatypes_test.dart
index acea867..b886c77 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/all_datatypes_test.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/all_datatypes_test.dart
@@ -53,10 +53,10 @@
final BinaryMessenger mockMessenger = MockBinaryMessenger();
when(mockMessenger.send('dev.flutter.pigeon.HostEverything.echo', any))
.thenAnswer((Invocation realInvocation) async {
- const StandardMessageCodec codec = StandardMessageCodec();
- final Object input =
+ final MessageCodec<Object?> codec = HostEverything.codec;
+ final Object? input =
codec.decodeMessage(realInvocation.positionalArguments[1]);
- return codec.encodeMessage(<String, Object>{'result': input});
+ return codec.encodeMessage(<String, Object>{'result': input!});
});
final HostEverything api = HostEverything(binaryMessenger: mockMessenger);
final Everything result = await api.echo(everything);
diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/null_safe_test.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/null_safe_test.dart
index 43aab25..769625c 100644
--- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/null_safe_test.dart
+++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/test/null_safe_test.dart
@@ -37,10 +37,9 @@
final SearchRequest request = SearchRequest()..query = 'hey';
final SearchReply reply = SearchReply()..result = 'ho';
final BinaryMessenger mockMessenger = MockBinaryMessenger();
- const MessageCodec<Object?> codec = StandardMessageCodec();
final Completer<ByteData?> completer = Completer<ByteData?>();
completer.complete(
- codec.encodeMessage(<String, Object>{'result': reply.encode()}));
+ Api.codec.encodeMessage(<String, Object>{'result': reply.encode()}));
final Future<ByteData?> sendResult = completer.future;
when(mockMessenger.send('dev.flutter.pigeon.Api.search', any))
.thenAnswer((Invocation realInvocation) => sendResult);
@@ -50,25 +49,21 @@
expect(reply.result, readReply.result);
});
- // TODO(gaaclarke): This test is a companion for the fix to https://github.com/flutter/flutter/issues/80538
- // test('send/receive list classes', () async {
- // final SearchRequest request = SearchRequest()
- // ..query = 'hey';
- // final SearchReply reply = SearchReply()
- // ..result = 'ho';
- // final SearchRequests requests = SearchRequests()
- // ..requests = <SearchRequest>[request];
- // final SearchReplies replies = SearchReplies()
- // ..replies = <SearchReply>[reply];
- // final BinaryMessenger mockMessenger = MockBinaryMessenger();
- // const MessageCodec<Object?> codec = StandardMessageCodec();
- // final Completer<ByteData?> completer = Completer<ByteData?>();
- // completer.complete(codec.encodeMessage(<String, Object>{'result' : replies.encode()}));
- // final Future<ByteData?> sendResult = completer.future;
- // when(mockMessenger.send('dev.flutter.pigeon.Api.search', any)).thenAnswer((Invocation realInvocation) => sendResult);
- // final Api api = Api(binaryMessenger: mockMessenger);
- // final SearchReplies readReplies = await api.doSearches(requests);
- // expect(readReplies, isNotNull);
- // expect(reply.result, (readReplies.replies![0] as SearchReply?)!.result);
- // });
+ test('send/receive list classes', () async {
+ final SearchRequest request = SearchRequest()..query = 'hey';
+ final SearchRequests requests = SearchRequests()
+ ..requests = <SearchRequest>[request];
+ final BinaryMessenger mockMessenger = MockBinaryMessenger();
+ when(mockMessenger.send('dev.flutter.pigeon.Api.echo', any))
+ .thenAnswer((Invocation realInvocation) async {
+ final MessageCodec<Object?> codec = Api.codec;
+ final Object? input =
+ codec.decodeMessage(realInvocation.positionalArguments[1]);
+ return codec.encodeMessage(<String, Object>{'result': input!});
+ });
+ final Api api = Api(binaryMessenger: mockMessenger);
+ final SearchRequests echo = await api.echo(requests);
+ expect(echo.requests!.length, 1);
+ expect((echo.requests![0] as SearchRequest?)!.query, 'hey');
+ });
}
diff --git a/packages/pigeon/platform_tests/ios_unit_tests/ios/Runner.xcodeproj/project.pbxproj b/packages/pigeon/platform_tests/ios_unit_tests/ios/Runner.xcodeproj/project.pbxproj
index 1c9dd58..1e35915 100644
--- a/packages/pigeon/platform_tests/ios_unit_tests/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/pigeon/platform_tests/ios_unit_tests/ios/Runner.xcodeproj/project.pbxproj
@@ -8,6 +8,8 @@
/* Begin PBXBuildFile section */
0D50127523FF75B100CD5B95 /* RunnerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D50127423FF75B100CD5B95 /* RunnerTests.m */; };
+ 0D7A910A268D4A050056B5E1 /* ListTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D7A9109268D4A050056B5E1 /* ListTest.m */; };
+ 0D7A910D268E5D700056B5E1 /* all_void.gen.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D7A910C268E5D700056B5E1 /* all_void.gen.m */; };
0D8C35EB25D45A7900B76435 /* AsyncHandlersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D8C35EA25D45A7900B76435 /* AsyncHandlersTest.m */; };
0DD2E6BA2684031300A7D764 /* void_arg_host.gen.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DD2E6A62684031200A7D764 /* void_arg_host.gen.m */; };
0DD2E6BB2684031300A7D764 /* list.gen.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DD2E6A72684031200A7D764 /* list.gen.m */; };
@@ -58,6 +60,9 @@
0D50127223FF75B100CD5B95 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
0D50127423FF75B100CD5B95 /* RunnerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerTests.m; sourceTree = "<group>"; };
0D50127623FF75B100CD5B95 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 0D7A9109268D4A050056B5E1 /* ListTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ListTest.m; sourceTree = "<group>"; };
+ 0D7A910B268E5D700056B5E1 /* all_void.gen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = all_void.gen.h; sourceTree = "<group>"; };
+ 0D7A910C268E5D700056B5E1 /* all_void.gen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = all_void.gen.m; sourceTree = "<group>"; };
0D8C35EA25D45A7900B76435 /* AsyncHandlersTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AsyncHandlersTest.m; sourceTree = "<group>"; };
0DD2E6A62684031200A7D764 /* void_arg_host.gen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = void_arg_host.gen.m; sourceTree = "<group>"; };
0DD2E6A72684031200A7D764 /* list.gen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = list.gen.m; sourceTree = "<group>"; };
@@ -127,6 +132,7 @@
0DF4E5C6266ED80900AEA855 /* EchoMessenger.h */,
0DF4E5C7266ED80900AEA855 /* EchoMessenger.m */,
0DF4E5CA266FDAE300AEA855 /* EnumTest.m */,
+ 0D7A9109268D4A050056B5E1 /* ListTest.m */,
);
path = RunnerTests;
sourceTree = "<group>";
@@ -164,6 +170,8 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
+ 0D7A910B268E5D700056B5E1 /* all_void.gen.h */,
+ 0D7A910C268E5D700056B5E1 /* all_void.gen.m */,
0DD2E6AA2684031300A7D764 /* all_datatypes.gen.h */,
0DD2E6B22684031300A7D764 /* all_datatypes.gen.m */,
0DD2E6AE2684031300A7D764 /* async_handlers.gen.h */,
@@ -346,6 +354,7 @@
0DF4E5C8266ED80900AEA855 /* EchoMessenger.m in Sources */,
0DF4E5CB266FDAE300AEA855 /* EnumTest.m in Sources */,
0D8C35EB25D45A7900B76435 /* AsyncHandlersTest.m in Sources */,
+ 0D7A910A268D4A050056B5E1 /* ListTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -354,6 +363,7 @@
buildActionMask = 2147483647;
files = (
0DD2E6BD2684031300A7D764 /* async_handlers.gen.m in Sources */,
+ 0D7A910D268E5D700056B5E1 /* all_void.gen.m in Sources */,
0DD2E6C12684031300A7D764 /* voidhost.gen.m in Sources */,
0DD2E6BB2684031300A7D764 /* list.gen.m in Sources */,
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
diff --git a/packages/pigeon/platform_tests/ios_unit_tests/ios/RunnerTests/ListTest.m b/packages/pigeon/platform_tests/ios_unit_tests/ios/RunnerTests/ListTest.m
new file mode 100644
index 0000000..c50cd14
--- /dev/null
+++ b/packages/pigeon/platform_tests/ios_unit_tests/ios/RunnerTests/ListTest.m
@@ -0,0 +1,35 @@
+// 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 <Flutter/Flutter.h>
+#import <XCTest/XCTest.h>
+#import "EchoMessenger.h"
+#import "list.gen.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////
+@interface ListTest : XCTestCase
+@end
+
+///////////////////////////////////////////////////////////////////////////////////////////
+@implementation ListTest
+
+- (void)testListInList {
+ LSTTestMessage* top = [[LSTTestMessage alloc] init];
+ LSTTestMessage* inside = [[LSTTestMessage alloc] init];
+ inside.testList = @[ @1, @2, @3 ];
+ top.testList = @[ inside ];
+ EchoBinaryMessenger* binaryMessenger = [[EchoBinaryMessenger alloc] init];
+ LSTEchoApi* api = [[LSTEchoApi alloc] initWithBinaryMessenger:binaryMessenger];
+ XCTestExpectation* expectation = [self expectationWithDescription:@"callback"];
+ [api echo:top
+ completion:^(LSTTestMessage* _Nonnull result, NSError* _Nullable err) {
+ XCTAssertEqual(1u, result.testList.count);
+ XCTAssertTrue([result.testList[0] isKindOfClass:[LSTTestMessage class]]);
+ XCTAssertEqualObjects(inside.testList, [result.testList[0] testList]);
+ [expectation fulfill];
+ }];
+ [self waitForExpectations:@[ expectation ] timeout:1.0];
+}
+
+@end
diff --git a/packages/pigeon/run_tests.sh b/packages/pigeon/run_tests.sh
index 0b8edd6..af121e4 100755
--- a/packages/pigeon/run_tests.sh
+++ b/packages/pigeon/run_tests.sh
@@ -230,6 +230,7 @@
cd e2e_tests/test_objc/
flutter pub get
popd
+ test_pigeon_dart ./pigeons/all_void.dart
test_pigeon_dart ./pigeons/async_handlers.dart
test_pigeon_dart ./pigeons/host2flutter.dart
test_pigeon_dart ./pigeons/list.dart
@@ -241,6 +242,7 @@
}
run_ios_unittests() {
+ gen_ios_unittests_code ./pigeons/all_void.dart ""
gen_ios_unittests_code ./pigeons/all_datatypes.dart ""
gen_ios_unittests_code ./pigeons/async_handlers.dart ""
gen_ios_unittests_code ./pigeons/enum.dart "AC"
@@ -293,6 +295,7 @@
run_android_unittests() {
pushd $PWD
gen_android_unittests_code ./pigeons/all_datatypes.dart AllDatatypes
+ gen_android_unittests_code ./pigeons/all_void.dart AllVoid
gen_android_unittests_code ./pigeons/android_unittests.dart Pigeon
gen_android_unittests_code ./pigeons/async_handlers.dart AsyncHandlers
gen_android_unittests_code ./pigeons/host2flutter.dart Host2Flutter
diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart
index 156603c..c26e85d 100644
--- a/packages/pigeon/test/dart_generator_test.dart
+++ b/packages/pigeon/test/dart_generator_test.dart
@@ -215,7 +215,6 @@
// we mention "doSomething" in the assertion message.
expect(code, isNot(matches('[^!]=.*doSomething')));
expect(code, contains('doSomething('));
- expect(code, isNot(contains('.encode()')));
});
test('flutter void argument', () {
diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart
index 9167aa9..84276b0 100644
--- a/packages/pigeon/test/java_generator_test.dart
+++ b/packages/pigeon/test/java_generator_test.dart
@@ -210,7 +210,6 @@
generateJava(javaOptions, root, sink);
final String code = sink.toString();
expect(code, contains('Reply<Void>'));
- expect(code, isNot(contains('.fromMap(')));
expect(code, contains('callback.reply(null)'));
});