diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index e1450041324d..6e05728aa341 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,8 @@ +## 16.0.0 + +* [java] Adds `VoidResult` type for `Void` returns. +* **Breaking Change** [java] Updates all `Void` return types to use new `VoidResult`. + ## 15.0.3 * Fixes new lint warnings. diff --git a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java index 5d1b693b8230..1167e53d5fb8 100644 --- a/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java +++ b/packages/pigeon/example/app/android/app/src/main/java/io/flutter/plugins/Messages.java @@ -216,6 +216,14 @@ public interface NullableResult { /** Failure case callback method for handling errors. */ void error(@NonNull Throwable error); } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } private static class ExampleHostApiCodec extends StandardMessageCodec { public static final ExampleHostApiCodec INSTANCE = new ExampleHostApiCodec(); diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index fcf255bb8bf0..ba32f720a2a0 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -13,7 +13,7 @@ import 'ast.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '15.0.3'; +const String pigeonVersion = '16.0.0'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 55866c7d59d9..43b42c40e909 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -448,8 +448,7 @@ class JavaGenerator extends StructuredGenerator { }); for (final Method func in api.methods) { - final String resultType = - func.returnType.isNullable ? 'NullableResult' : 'Result'; + final String resultType = _getResultType(func.returnType); final String returnType = func.returnType.isVoid ? 'Void' : _javaTypeForDartType(func.returnType); @@ -457,8 +456,8 @@ class JavaGenerator extends StructuredGenerator { addDocumentationComments( indent, func.documentationComments, _docCommentSpec); if (func.parameters.isEmpty) { - indent.write( - 'public void ${func.name}(@NonNull $resultType<$returnType> result) '); + indent + .write('public void ${func.name}(@NonNull $resultType result) '); sendArgument = 'null'; } else { final Iterable argTypes = func.parameters @@ -478,7 +477,7 @@ class JavaGenerator extends StructuredGenerator { map2(argTypes, argNames, (String x, String y) => '$x $y') .join(', '); indent.write( - 'public void ${func.name}($argsSignature, @NonNull $resultType<$returnType> result) '); + 'public void ${func.name}($argsSignature, @NonNull $resultType result) '); } indent.addScoped('{', '}', () { const String channel = 'channel'; @@ -513,7 +512,7 @@ class JavaGenerator extends StructuredGenerator { } indent.addScoped('else {', '}', () { if (func.returnType.isVoid) { - indent.writeln('result.success(null);'); + indent.writeln('result.success();'); } else { const String output = 'output'; final String outputExpression; @@ -633,8 +632,7 @@ class JavaGenerator extends StructuredGenerator { /// int add(int x, int y); void _writeInterfaceMethod(JavaOptions generatorOptions, Root root, Indent indent, Api api, final Method method) { - final String resultType = - method.returnType.isNullable ? 'NullableResult' : 'Result'; + final String resultType = _getResultType(method.returnType); final String nullableType = method.isAsynchronous ? '' : _nullabilityAnnotationFromType(method.returnType); @@ -653,10 +651,7 @@ class JavaGenerator extends StructuredGenerator { })); } if (method.isAsynchronous) { - final String returnType = method.returnType.isVoid - ? 'Void' - : _javaTypeForDartType(method.returnType); - argSignature.add('@NonNull $resultType<$returnType> result'); + argSignature.add('@NonNull $resultType result'); } if (method.documentationComments.isNotEmpty) { addDocumentationComments( @@ -748,14 +743,17 @@ class JavaGenerator extends StructuredGenerator { ? ' == null ? null : $resultValue.index' : '.index'; } - final String resultType = - method.returnType.isNullable ? 'NullableResult' : 'Result'; + final String resultType = _getResultType(method.returnType); + final String resultParam = + method.returnType.isVoid ? '' : '$returnType result'; + final String addResultArg = + method.returnType.isVoid ? 'null' : '$resultValue$enumTag'; const String resultName = 'resultCallback'; indent.format(''' -$resultType<$returnType> $resultName = -\t\tnew $resultType<$returnType>() { -\t\t\tpublic void success($returnType result) { -\t\t\t\twrapped.add(0, $resultValue$enumTag); +$resultType $resultName = +\t\tnew $resultType() { +\t\t\tpublic void success($resultParam) { +\t\t\t\twrapped.add(0, $addResultArg); \t\t\t\treply.reply(wrapped); \t\t\t} @@ -895,6 +893,19 @@ $resultType<$returnType> $resultName = .writeln('/** Failure case callback method for handling errors. */'); indent.writeln('void error(@NonNull Throwable error);'); }); + + indent.writeln( + '/** Asynchronous error handling return type for void API method returns. */'); + indent.write('public interface VoidResult '); + indent.addScoped('{', '}', () { + indent + .writeln('/** Success case callback method for handling returns. */'); + indent.writeln('void success();'); + indent.newln(); + indent + .writeln('/** Failure case callback method for handling errors. */'); + indent.writeln('void error(@NonNull Throwable error);'); + }); } void _writeErrorClass(Indent indent) { @@ -1102,3 +1113,14 @@ String _castObject(NamedType field, String varName) { return _cast(varName, javaType: hostDatatype.datatype); } } + +/// Returns string of Result class type for method based on [TypeDeclaration]. +String _getResultType(TypeDeclaration type) { + if (type.isVoid) { + return 'VoidResult'; + } + if (type.isNullable) { + return 'NullableResult<${_javaTypeForDartType(type)}>'; + } + return 'Result<${_javaTypeForDartType(type)}>'; +} diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java index 21037c5e99c8..a99aa2ef913f 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java @@ -14,6 +14,7 @@ import com.example.alternate_language_test_plugin.CoreTests.HostIntegrationCoreApi; import com.example.alternate_language_test_plugin.CoreTests.NullableResult; import com.example.alternate_language_test_plugin.CoreTests.Result; +import com.example.alternate_language_test_plugin.CoreTests.VoidResult; import io.flutter.embedding.engine.plugins.FlutterPlugin; import java.util.List; import java.util.Map; @@ -208,8 +209,8 @@ public void throwErrorFromVoid() { } @Override - public void noopAsync(@NonNull Result result) { - result.success(null); + public void noopAsync(@NonNull VoidResult result) { + result.success(); } @Override @@ -218,7 +219,7 @@ public void throwAsyncError(@NonNull NullableResult result) { } @Override - public void throwAsyncErrorFromVoid(@NonNull Result result) { + public void throwAsyncErrorFromVoid(@NonNull VoidResult result) { result.error(new RuntimeException("An error")); } @@ -338,7 +339,7 @@ public void echoAsyncNullableEnum( } @Override - public void callFlutterNoop(@NonNull Result result) { + public void callFlutterNoop(@NonNull VoidResult result) { flutterApi.noop(result); } @@ -348,7 +349,7 @@ public void callFlutterThrowError(@NonNull NullableResult result) { } @Override - public void callFlutterThrowErrorFromVoid(@NonNull Result result) { + public void callFlutterThrowErrorFromVoid(@NonNull VoidResult result) { flutterApi.throwErrorFromVoid(result); } diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index b6a72835e4ac..8585b13315ae 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -980,6 +980,14 @@ public interface NullableResult { /** Failure case callback method for handling errors. */ void error(@NonNull Throwable error); } + /** Asynchronous error handling return type for void API method returns. */ + public interface VoidResult { + /** Success case callback method for handling returns. */ + void success(); + + /** Failure case callback method for handling errors. */ + void error(@NonNull Throwable error); + } private static class HostIntegrationCoreApiCodec extends StandardMessageCodec { public static final HostIntegrationCoreApiCodec INSTANCE = new HostIntegrationCoreApiCodec(); @@ -1139,7 +1147,7 @@ AllNullableTypes sendMultipleNullableTypes( * A no-op function taking no arguments and returning no value, to sanity test basic * asynchronous calling. */ - void noopAsync(@NonNull Result result); + void noopAsync(@NonNull VoidResult result); /** Returns passed in int asynchronously. */ void echoAsyncInt(@NonNull Long anInt, @NonNull Result result); /** Returns passed in double asynchronously. */ @@ -1162,7 +1170,7 @@ void echoAsyncMap( /** Responds with an error from an async function returning a value. */ void throwAsyncError(@NonNull NullableResult result); /** Responds with an error from an async void function. */ - void throwAsyncErrorFromVoid(@NonNull Result result); + void throwAsyncErrorFromVoid(@NonNull VoidResult result); /** Responds with a Flutter error from an async function returning a value. */ void throwAsyncFlutterError(@NonNull NullableResult result); /** Returns the passed object, to test async serialization and deserialization. */ @@ -1192,11 +1200,11 @@ void echoAsyncNullableMap( /** Returns the passed enum, to test asynchronous serialization and deserialization. */ void echoAsyncNullableEnum(@Nullable AnEnum anEnum, @NonNull NullableResult result); - void callFlutterNoop(@NonNull Result result); + void callFlutterNoop(@NonNull VoidResult result); void callFlutterThrowError(@NonNull NullableResult result); - void callFlutterThrowErrorFromVoid(@NonNull Result result); + void callFlutterThrowErrorFromVoid(@NonNull VoidResult result); void callFlutterEchoAllTypes(@NonNull AllTypes everything, @NonNull Result result); @@ -2097,9 +2105,9 @@ static void setUp( channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); - Result resultCallback = - new Result() { - public void success(Void result) { + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } @@ -2434,9 +2442,9 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); - Result resultCallback = - new Result() { - public void success(Void result) { + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } @@ -2834,9 +2842,9 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); - Result resultCallback = - new Result() { - public void success(Void result) { + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } @@ -2892,9 +2900,9 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); - Result resultCallback = - new Result() { - public void success(Void result) { + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } @@ -3574,7 +3582,7 @@ public FlutterIntegrationCoreApi(@NonNull BinaryMessenger argBinaryMessenger) { /** * A no-op function taking no arguments and returning no value, to sanity test basic calling. */ - public void noop(@NonNull Result result) { + public void noop(@NonNull VoidResult result) { final String channelName = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop"; BasicMessageChannel channel = @@ -3591,7 +3599,7 @@ public void noop(@NonNull Result result) { (String) listReply.get(1), (String) listReply.get(2))); } else { - result.success(null); + result.success(); } } else { result.error(createConnectionError(channelName)); @@ -3626,7 +3634,7 @@ public void throwError(@NonNull NullableResult result) { }); } /** Responds with an error from an async void function. */ - public void throwErrorFromVoid(@NonNull Result result) { + public void throwErrorFromVoid(@NonNull VoidResult result) { final String channelName = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid"; BasicMessageChannel channel = @@ -3643,7 +3651,7 @@ public void throwErrorFromVoid(@NonNull Result result) { (String) listReply.get(1), (String) listReply.get(2))); } else { - result.success(null); + result.success(); } } else { result.error(createConnectionError(channelName)); @@ -4251,7 +4259,7 @@ public void echoNullableEnum( * A no-op function taking no arguments and returning no value, to sanity test basic * asynchronous calling. */ - public void noopAsync(@NonNull Result result) { + public void noopAsync(@NonNull VoidResult result) { final String channelName = "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noopAsync"; BasicMessageChannel channel = @@ -4268,7 +4276,7 @@ public void noopAsync(@NonNull Result result) { (String) listReply.get(1), (String) listReply.get(2))); } else { - result.success(null); + result.success(); } } else { result.error(createConnectionError(channelName)); @@ -4358,7 +4366,7 @@ public interface HostSmallApi { void echo(@NonNull String aString, @NonNull Result result); - void voidVoid(@NonNull Result result); + void voidVoid(@NonNull VoidResult result); /** The codec used by HostSmallApi. */ static @NonNull MessageCodec getCodec() { @@ -4407,9 +4415,9 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); - Result resultCallback = - new Result() { - public void success(Void result) { + VoidResult resultCallback = + new VoidResult() { + public void success() { wrapped.add(0, null); reply.reply(wrapped); } diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AsyncTest.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AsyncTest.java index 3eefea01e9d5..188c1d49aad3 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AsyncTest.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AsyncTest.java @@ -24,8 +24,8 @@ public void echo(@NonNull String value, Result result) { } @Override - public void voidVoid(Result result) { - result.success(null); + public void voidVoid(VoidResult result) { + result.success(); } } @@ -36,7 +36,7 @@ public void echo(@NonNull String value, Result result) { } @Override - public void voidVoid(Result result) { + public void voidVoid(VoidResult result) { result.error(new Exception("error")); } } diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 09b821814534..c820df9256f8 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -2,7 +2,7 @@ name: pigeon description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. repository: https://github.com/flutter/packages/tree/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pigeon%22 -version: 15.0.3 # This must match the version in lib/generator_tools.dart +version: 16.0.0 # This must match the version in lib/generator_tools.dart environment: sdk: ">=3.0.0 <4.0.0" diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index 1cae5f664a55..cba2d702255c 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -397,8 +397,8 @@ void main() { expect( code, contains( - 'public void doSomething(@NonNull Input arg0Arg, @NonNull Result result)')); - expect(code, contains('result.success(null);')); + 'public void doSomething(@NonNull Input arg0Arg, @NonNull VoidResult result)')); + expect(code, contains('result.success();')); }); test('gen host void argument api', () { @@ -1307,7 +1307,7 @@ void main() { expect( code, contains( - 'public void doit(@Nullable Long fooArg, @NonNull Result result) {')); + 'public void doit(@Nullable Long fooArg, @NonNull VoidResult result) {')); }); test('background platform channel', () {