diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 0d75ae838188..d43ff5d560ea 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,8 @@ +## 15.0.2 + +* [dart] Adds named parameters to flutter API methods. +* [dart] Fixes named parameters in test output of host API methods. + ## 15.0.1 * [java] Adds @CanIgnoreReturnValue annotation to class builder. diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index 261ba62040d3..9d79a781afbd 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -277,7 +277,7 @@ class Parameter extends NamedType { bool? isPositional, bool? isRequired, super.documentationComments, - }) : isNamed = isNamed ?? true, + }) : isNamed = isNamed ?? false, isOptional = isOptional ?? false, isPositional = isPositional ?? true, isRequired = isRequired ?? true; diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 1f0b4dac38c8..52e2d0e68d95 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -418,9 +418,9 @@ $resultAt != null } }); final Iterable argNames = - indexMap(func.parameters, (int index, NamedType field) { + indexMap(func.parameters, (int index, Parameter field) { final String name = _getSafeArgumentName(index, field); - return '$name${field.type.isNullable ? '' : '!'}'; + return '${field.isNamed ? '${field.name}: ' : ''}$name${field.type.isNullable ? '' : '!'}'; }); call = 'api.${func.name}(${argNames.join(', ')})'; } diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index c7b29e5f1438..a510b55bd74c 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.1'; +const String pigeonVersion = '15.0.2'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 032cb691788f..6a29df87716b 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -1132,10 +1132,10 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { ), name: formalParameter.name?.lexeme ?? '', offset: formalParameter.offset, - isNamed: isNamed, - isOptional: isOptional, - isPositional: isPositional, - isRequired: isRequired, + isNamed: isNamed ?? formalParameter.isNamed, + isOptional: isOptional ?? formalParameter.isOptional, + isPositional: isPositional ?? formalParameter.isPositional, + isRequired: isRequired ?? formalParameter.isRequired, defaultValue: defaultValue, ); } else if (simpleFormalParameter != null) { diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index a0c6a3ccf29f..c0a8acbacb15 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -473,6 +473,11 @@ abstract class HostIntegrationCoreApi { @SwiftFunction('callFlutterEcho(_:)') AnEnum callFlutterEchoEnum(AnEnum anEnum); + @async + @ObjCSelector('callFlutterEchoNamedString:') + @SwiftFunction('callFlutterEchoNamed(_:)') + String callFlutterEchoNamedString({String aString = 'default'}); + @async @ObjCSelector('callFlutterEchoNullableBool:') @SwiftFunction('callFlutterEchoNullable(_:)') @@ -513,6 +518,11 @@ abstract class HostIntegrationCoreApi { @ObjCSelector('callFlutterEchoNullableEnum:') @SwiftFunction('callFlutterNullableEcho(_:)') AnEnum? callFlutterEchoNullableEnum(AnEnum? anEnum); + + @async + @ObjCSelector('callFlutterEchoNullableNamedString:') + @SwiftFunction('callFlutterEchoNullableNamed(_:)') + String callFlutterEchoNullableNamedString({String? aString}); } /// The core interface that the Dart platform_test code implements for host @@ -589,6 +599,11 @@ abstract class FlutterIntegrationCoreApi { @SwiftFunction('echo(_:)') AnEnum echoEnum(AnEnum anEnum); + /// Returns the default string. + @ObjCSelector('echoNamedDefaultString:') + @SwiftFunction('echoNamedDefault(_:)') + String echoNamedDefaultString({String aString = 'default'}); + // ========== Nullable argument/return type tests ========== /// Returns the passed boolean, to test serialization and deserialization. @@ -631,6 +646,11 @@ abstract class FlutterIntegrationCoreApi { @SwiftFunction('echoNullable(_:)') AnEnum? echoNullableEnum(AnEnum? anEnum); + /// Returns the passed in string. + @ObjCSelector('echoNamedNullableString:') + @SwiftFunction('echoNamed(_:)') + String? echoNamedNullableString({String? aNullableString}); + // ========== Async tests ========== // These are minimal since async FlutterApi only changes Dart generation. // Currently they aren't integration tested, but having them here ensures diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 5571abfd3bd3..67f7fa73e691 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.1 # This must match the version in lib/generator_tools.dart +version: 15.0.2 # This must match the version in lib/generator_tools.dart environment: sdk: ">=3.0.0 <4.0.0" diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index 2ab5f3f8df08..83a6556c7fab 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -1417,6 +1417,41 @@ void main() { expect(code, contains('void doit(int? foo);')); }); + test('named argument flutter', () { + final Root root = Root( + apis: [ + Api(name: 'Api', location: ApiLocation.flutter, methods: [ + Method( + name: 'doit', + returnType: const TypeDeclaration.voidDeclaration(), + parameters: [ + Parameter( + name: 'foo', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + isNamed: true, + isPositional: false), + ]) + ]) + ], + classes: [], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const DartGenerator generator = DartGenerator(); + generator.generate( + const DartOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + expect(code, contains('void doit({required int foo});')); + expect(code, contains('api.doit(foo: arg_foo!)')); + }); + test('uses output package name for imports', () { const String overriddenPackageName = 'custom_name'; const String outputPackageName = 'some_output_package';