diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 1df17ccee8bf..14ee437e452b 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2 + +* Removed static analysis warnings from generated Java code. + ## 0.1.1 * Fixed issue where nested types didn't work if they weren't present in the Api. diff --git a/packages/pigeon/e2e_tests/test_objc/android/app/src/main/java/io/flutter/plugins/Pigeon.java b/packages/pigeon/e2e_tests/test_objc/android/app/src/main/java/io/flutter/plugins/Pigeon.java new file mode 100644 index 000000000000..a6962f7c990e --- /dev/null +++ b/packages/pigeon/e2e_tests/test_objc/android/app/src/main/java/io/flutter/plugins/Pigeon.java @@ -0,0 +1,232 @@ +// Autogenerated from Pigeon (v0.1.2), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +package dev.flutter.aaclarke.pigeon; + +import io.flutter.plugin.common.BasicMessageChannel; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.StandardMessageCodec; +import java.util.HashMap; + +/** Generated class from Pigeon. */ +@SuppressWarnings("unused") +public class Pigeon { + + /** Generated class from Pigeon that represents data sent in messages. */ + public static class SearchReply { + private String result; + + public String getResult() { + return result; + } + + public void setResult(String setterArg) { + this.result = setterArg; + } + + private String error; + + public String getError() { + return error; + } + + public void setError(String setterArg) { + this.error = setterArg; + } + + HashMap toMap() { + HashMap toMapResult = new HashMap<>(); + toMapResult.put("result", result); + toMapResult.put("error", error); + return toMapResult; + } + + static SearchReply fromMap(HashMap map) { + SearchReply fromMapResult = new SearchReply(); + Object result = map.get("result"); + fromMapResult.result = (String) result; + Object error = map.get("error"); + fromMapResult.error = (String) error; + return fromMapResult; + } + } + + /** Generated class from Pigeon that represents data sent in messages. */ + public static class SearchRequest { + private String query; + + public String getQuery() { + return query; + } + + public void setQuery(String setterArg) { + this.query = setterArg; + } + + private Long anInt; + + public Long getAnInt() { + return anInt; + } + + public void setAnInt(Long setterArg) { + this.anInt = setterArg; + } + + private Boolean aBool; + + public Boolean getABool() { + return aBool; + } + + public void setABool(Boolean setterArg) { + this.aBool = setterArg; + } + + HashMap toMap() { + HashMap toMapResult = new HashMap<>(); + toMapResult.put("query", query); + toMapResult.put("anInt", anInt); + toMapResult.put("aBool", aBool); + return toMapResult; + } + + static SearchRequest fromMap(HashMap map) { + SearchRequest fromMapResult = new SearchRequest(); + Object query = map.get("query"); + fromMapResult.query = (String) query; + Object anInt = map.get("anInt"); + fromMapResult.anInt = + (anInt == null) ? null : ((anInt instanceof Integer) ? (Integer) anInt : (Long) anInt); + Object aBool = map.get("aBool"); + fromMapResult.aBool = (Boolean) aBool; + return fromMapResult; + } + } + + /** Generated class from Pigeon that represents data sent in messages. */ + public static class Nested { + private SearchRequest request; + + public SearchRequest getRequest() { + return request; + } + + public void setRequest(SearchRequest setterArg) { + this.request = setterArg; + } + + HashMap toMap() { + HashMap toMapResult = new HashMap<>(); + toMapResult.put("request", request); + return toMapResult; + } + + static Nested fromMap(HashMap map) { + Nested fromMapResult = new Nested(); + Object request = map.get("request"); + fromMapResult.request = (SearchRequest) request; + return fromMapResult; + } + } + + /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ + public static class FlutterSearchApi { + private final BinaryMessenger binaryMessenger; + + public FlutterSearchApi(BinaryMessenger argBinaryMessenger) { + this.binaryMessenger = argBinaryMessenger; + } + + public interface Reply { + void reply(T reply); + } + + public void search(SearchRequest argInput, Reply callback) { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.FlutterSearchApi.search", + new StandardMessageCodec()); + HashMap inputMap = argInput.toMap(); + channel.send( + inputMap, + channelReply -> { + HashMap outputMap = (HashMap) channelReply; + @SuppressWarnings("ConstantConditions") + SearchReply output = SearchReply.fromMap(outputMap); + callback.reply(output); + }); + } + } + + /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ + public interface NestedApi { + SearchReply search(Nested arg); + + /** Sets up an instance of `NestedApi` to handle messages through the `binaryMessenger` */ + static void setup(BinaryMessenger binaryMessenger, NestedApi api) { + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, "dev.flutter.pigeon.NestedApi.search", new StandardMessageCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + HashMap wrapped = new HashMap<>(); + try { + @SuppressWarnings("ConstantConditions") + Nested input = Nested.fromMap((HashMap) message); + SearchReply output = api.search(input); + wrapped.put("result", output.toMap()); + } catch (Exception exception) { + wrapped.put("error", wrapError(exception)); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } + + /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ + public interface Api { + SearchReply search(SearchRequest arg); + + /** Sets up an instance of `Api` to handle messages through the `binaryMessenger` */ + static void setup(BinaryMessenger binaryMessenger, Api api) { + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, "dev.flutter.pigeon.Api.search", new StandardMessageCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + HashMap wrapped = new HashMap<>(); + try { + @SuppressWarnings("ConstantConditions") + SearchRequest input = SearchRequest.fromMap((HashMap) message); + SearchReply output = api.search(input); + wrapped.put("result", output.toMap()); + } catch (Exception exception) { + wrapped.put("error", wrapError(exception)); + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } + + private static HashMap wrapError(Exception exception) { + HashMap errorMap = new HashMap<>(); + errorMap.put("message", exception.toString()); + errorMap.put("code", null); + errorMap.put("details", null); + return errorMap; + } +} diff --git a/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.h b/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.h index 8ef38d789b61..3844745fc0b9 100644 --- a/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.h +++ b/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.h @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.0), do not edit directly. +// Autogenerated from Pigeon (v0.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @protocol FlutterBinaryMessenger; diff --git a/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.m b/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.m index 2865b26a3be7..7b52efa3208e 100644 --- a/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.m +++ b/packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.m @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.0), do not edit directly. +// Autogenerated from Pigeon (v0.1.2), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "dartle.h" #import diff --git a/packages/pigeon/e2e_tests/test_objc/lib/dartle.dart b/packages/pigeon/e2e_tests/test_objc/lib/dartle.dart index 5c76d82f0221..9f0db48b7eaf 100644 --- a/packages/pigeon/e2e_tests/test_objc/lib/dartle.dart +++ b/packages/pigeon/e2e_tests/test_objc/lib/dartle.dart @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.0), do not edit directly. +// Autogenerated from Pigeon (v0.1.2), 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 import 'dart:async'; diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 18c85908c13f..c65c2f2509dc 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -8,7 +8,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. -const String pigeonVersion = '0.1.0'; +const String pigeonVersion = '0.1.2'; /// 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 0015bf39d26b..176dc2df7d3f 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -40,7 +40,7 @@ void _writeHostApi(Indent indent, Api api) { indent.writeln( '/** Sets up an instance of `${api.name}` to handle messages through the `binaryMessenger` */'); indent.write( - 'public static void setup(BinaryMessenger binaryMessenger, ${api.name} api) '); + 'static void setup(BinaryMessenger binaryMessenger, ${api.name} api) '); indent.scoped('{', '}', () { for (Method method in api.methods) { final String channelName = makeChannelName(api, method); @@ -50,48 +50,44 @@ void _writeHostApi(Indent indent, Api api) { indent.inc(); indent.inc(); indent.writeln( - 'new BasicMessageChannel(binaryMessenger, "$channelName", new StandardMessageCodec());'); + 'new BasicMessageChannel<>(binaryMessenger, "$channelName", new StandardMessageCodec());'); indent.dec(); indent.dec(); indent.write('if (api != null) '); indent.scoped('{', '} else {', () { - indent.write( - 'channel.setMessageHandler(new BasicMessageChannel.MessageHandler() '); + indent.write('channel.setMessageHandler((message, reply) -> '); indent.scoped('{', '});', () { - indent.write( - 'public void onMessage(Object message, BasicMessageChannel.Reply reply) '); + final String argType = method.argType; + final String returnType = method.returnType; + indent.writeln( + 'HashMap wrapped = new HashMap<>();'); + indent.write('try '); indent.scoped('{', '}', () { - final String argType = method.argType; - final String returnType = method.returnType; String methodArgument; if (argType == 'void') { methodArgument = ''; } else { + indent.writeln('@SuppressWarnings("ConstantConditions")'); indent.writeln( '$argType input = $argType.fromMap((HashMap)message);'); methodArgument = 'input'; } - indent.writeln( - 'HashMap wrapped = new HashMap();'); - indent.write('try '); - indent.scoped('{', '}', () { - final String call = 'api.${method.name}($methodArgument)'; - if (method.returnType == 'void') { - indent.writeln('$call;'); - indent.writeln('wrapped.put("${Keys.result}", null);'); - } else { - indent.writeln('$returnType output = $call;'); - indent.writeln( - 'wrapped.put("${Keys.result}", output.toMap());'); - } - }); - indent.write('catch (Exception exception) '); - indent.scoped('{', '}', () { + final String call = 'api.${method.name}($methodArgument)'; + if (method.returnType == 'void') { + indent.writeln('$call;'); + indent.writeln('wrapped.put("${Keys.result}", null);'); + } else { + indent.writeln('$returnType output = $call;'); indent.writeln( - 'wrapped.put("${Keys.error}", wrapError(exception));'); - }); - indent.writeln('reply.reply(wrapped);'); + 'wrapped.put("${Keys.result}", output.toMap());'); + } }); + indent.write('catch (Exception exception) '); + indent.scoped('{', '}', () { + indent.writeln( + 'wrapped.put("${Keys.error}", wrapError(exception));'); + }); + indent.writeln('reply.reply(wrapped);'); }); }); indent.scoped(null, '}', () { @@ -109,7 +105,7 @@ void _writeFlutterApi(Indent indent, Api api) { '/** Generated class from Pigeon that represents Flutter messages that can be called from Java.*/'); indent.write('public static class ${api.name} '); indent.scoped('{', '}', () { - indent.writeln('private BinaryMessenger binaryMessenger;'); + indent.writeln('private final BinaryMessenger binaryMessenger;'); indent.write('public ${api.name}(BinaryMessenger argBinaryMessenger)'); indent.scoped('{', '}', () { indent.writeln('this.binaryMessenger = argBinaryMessenger;'); @@ -136,26 +132,23 @@ void _writeFlutterApi(Indent indent, Api api) { indent.inc(); indent.inc(); indent.writeln( - 'new BasicMessageChannel(binaryMessenger, "$channelName", new StandardMessageCodec());'); + 'new BasicMessageChannel<>(binaryMessenger, "$channelName", new StandardMessageCodec());'); indent.dec(); indent.dec(); if (func.argType != 'void') { indent.writeln('HashMap inputMap = argInput.toMap();'); } - indent.write( - 'channel.send($sendArgument, new BasicMessageChannel.Reply() '); + indent.write('channel.send($sendArgument, channelReply -> '); indent.scoped('{', '});', () { - indent.write('public void reply(Object channelReply) '); - indent.scoped('{', '}', () { - if (func.returnType == 'void') { - indent.writeln('callback.reply(null);'); - } else { - indent.writeln('HashMap outputMap = (HashMap)channelReply;'); - indent.writeln( - '${func.returnType} output = ${func.returnType}.fromMap(outputMap);'); - indent.writeln('callback.reply(output);'); - } - }); + if (func.returnType == 'void') { + indent.writeln('callback.reply(null);'); + } else { + indent.writeln('HashMap outputMap = (HashMap)channelReply;'); + indent.writeln('@SuppressWarnings("ConstantConditions")'); + indent.writeln( + '${func.returnType} output = ${func.returnType}.fromMap(outputMap);'); + indent.writeln('callback.reply(output);'); + } }); }); } @@ -178,14 +171,13 @@ String _javaTypeForDartType(String datatype) { return _javaTypeForDartTypeMap[datatype]; } -String _mapGetter(Field field, List classes, String mapName) { +String _castObject(Field field, List classes, String varName) { final HostDatatype hostDatatype = getHostDatatype(field, classes, _javaTypeForDartType); - final String result = '$mapName.get("${field.name}")'; if (field.dataType == 'int') { - return '($result instanceof Integer) ? (Integer)$result : (${hostDatatype.datatype})$result'; + return '($varName == null) ? null : (($varName instanceof Integer) ? (Integer)$varName : (${hostDatatype.datatype})$varName)'; } else { - return '(${hostDatatype.datatype})$result'; + return '(${hostDatatype.datatype})$varName'; } } @@ -200,16 +192,15 @@ void generateJava(JavaOptions options, Root root, StringSink sink) { indent.writeln('package ${options.package};'); } indent.addln(''); - - indent.writeln('import java.util.HashMap;'); - 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.StandardMessageCodec;'); + indent.writeln('import java.util.HashMap;'); indent.addln(''); assert(options.className != null); indent.writeln('/** Generated class from Pigeon. */'); + indent.writeln('@SuppressWarnings("unused")'); indent.write('public class ${options.className} '); indent.scoped('{', '}', () { for (Class klass in root.classes) { @@ -231,7 +222,7 @@ void generateJava(JavaOptions options, Root root, StringSink sink) { indent.write('HashMap toMap() '); indent.scoped('{', '}', () { indent.writeln( - 'HashMap toMapResult = new HashMap();'); + 'HashMap toMapResult = new HashMap<>();'); for (Field field in klass.fields) { indent.writeln('toMapResult.put("${field.name}", ${field.name});'); } @@ -241,8 +232,9 @@ void generateJava(JavaOptions options, Root root, StringSink sink) { indent.scoped('{', '}', () { indent.writeln('${klass.name} fromMapResult = new ${klass.name}();'); for (Field field in klass.fields) { + indent.writeln('Object ${field.name} = map.get("${field.name}");'); indent.writeln( - 'fromMapResult.${field.name} = ${_mapGetter(field, root.classes, 'map')};'); + 'fromMapResult.${field.name} = ${_castObject(field, root.classes, field.name)};'); } indent.writeln('return fromMapResult;'); }); @@ -259,7 +251,7 @@ void generateJava(JavaOptions options, Root root, StringSink sink) { } indent.format('''private static HashMap wrapError(Exception exception) { -\tHashMap errorMap = new HashMap(); +\tHashMap errorMap = new HashMap<>(); \terrorMap.put("${Keys.errorMessage}", exception.toString()); \terrorMap.put("${Keys.errorCode}", null); \terrorMap.put("${Keys.errorDetails}", null); diff --git a/packages/pigeon/mock_handler_tester/test/message.dart b/packages/pigeon/mock_handler_tester/test/message.dart index 5c76d82f0221..9f0db48b7eaf 100644 --- a/packages/pigeon/mock_handler_tester/test/message.dart +++ b/packages/pigeon/mock_handler_tester/test/message.dart @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v0.1.0), do not edit directly. +// Autogenerated from Pigeon (v0.1.2), 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 import 'dart:async'; diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 537ac2f3bee0..b78d923a8dad 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -1,5 +1,5 @@ name: pigeon -version: 0.1.1 +version: 0.1.2 description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. homepage: https://github.com/flutter/packages/tree/master/packages/pigeon dependencies: diff --git a/packages/pigeon/run_tests.sh b/packages/pigeon/run_tests.sh index 9a81105489cf..3bfbaf71e083 100755 --- a/packages/pigeon/run_tests.sh +++ b/packages/pigeon/run_tests.sh @@ -74,11 +74,13 @@ popd DARTLE_H="e2e_tests/test_objc/ios/Runner/dartle.h" DARTLE_M="e2e_tests/test_objc/ios/Runner/dartle.m" DARTLE_DART="e2e_tests/test_objc/lib/dartle.dart" +PIGEON_JAVA="e2e_tests/test_objc/android/app/src/main/java/io/flutter/plugins/Pigeon.java" pub run pigeon \ --input pigeons/message.dart \ --dart_out $DARTLE_DART \ --objc_header_out $DARTLE_H \ - --objc_source_out $DARTLE_M + --objc_source_out $DARTLE_M \ + --java_out $PIGEON_JAVA dartfmt -w $DARTLE_DART pushd $PWD