diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 570cc706229..5d854091647 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,9 @@ +## 26.0.0 + +* **Breaking Change** [dart] Changes name of constructors used to create subclasses of ProxyApis to + `pigeon_**original_name**`. +* [dart] Adds ProxyApi overrides classes to be used in Flutter unit tests. + ## 25.5.0 * [dart] Changes the default InstanceManager and its initialization to no longer make a message call diff --git a/packages/pigeon/lib/src/ast.dart b/packages/pigeon/lib/src/ast.dart index 116654458e5..0cf4e4cd47f 100644 --- a/packages/pigeon/lib/src/ast.dart +++ b/packages/pigeon/lib/src/ast.dart @@ -240,34 +240,53 @@ class AstProxyApi extends Api { /// `implements`. Iterable apisOfInterfaces() => _recursiveFindAllInterfaceApis(); - /// All methods inherited from interfaces and the interfaces of interfaces. - Iterable flutterMethodsFromInterfaces() sync* { + /// Returns a record for each method inherited from an interface and its + /// corresponding ProxyApi. + Iterable<(Method, AstProxyApi)> flutterMethodsFromInterfacesWithApis() sync* { for (final AstProxyApi proxyApi in apisOfInterfaces()) { - yield* proxyApi.methods; + yield* proxyApi.methods.map((Method method) => (method, proxyApi)); } } - /// A list of Flutter methods inherited from the ProxyApi that this ProxyApi - /// `extends`. - /// - /// This also recursively checks the ProxyApi that the super class `extends` - /// and so on. + /// Returns a record for each Flutter method inherited from [superClass]. /// /// This also includes methods that super classes inherited from interfaces /// with `implements`. - Iterable flutterMethodsFromSuperClasses() sync* { + Iterable<(Method, AstProxyApi)> + flutterMethodsFromSuperClassesWithApis() sync* { for (final AstProxyApi proxyApi in allSuperClasses().toList().reversed) { - yield* proxyApi.flutterMethods; + yield* proxyApi.flutterMethods.map((Method method) => (method, proxyApi)); } if (superClass != null) { final Set interfaceApisFromSuperClasses = superClass!.associatedProxyApi!._recursiveFindAllInterfaceApis(); for (final AstProxyApi proxyApi in interfaceApisFromSuperClasses) { - yield* proxyApi.methods; + yield* proxyApi.methods.map((Method method) => (method, proxyApi)); } } } + /// All methods inherited from interfaces and the interfaces of interfaces. + Iterable flutterMethodsFromInterfaces() sync* { + yield* flutterMethodsFromInterfacesWithApis().map( + ((Method, AstProxyApi) method) => method.$1, + ); + } + + /// A list of Flutter methods inherited from the ProxyApi that this ProxyApi + /// `extends`. + /// + /// This also recursively checks the ProxyApi that the super class `extends` + /// and so on. + /// + /// This also includes methods that super classes inherited from interfaces + /// with `implements`. + Iterable flutterMethodsFromSuperClasses() sync* { + yield* flutterMethodsFromSuperClassesWithApis().map( + ((Method, AstProxyApi) method) => method.$1, + ); + } + /// Whether the API has a method that callbacks to Dart to add a new instance /// to the InstanceManager. /// diff --git a/packages/pigeon/lib/src/dart/dart_generator.dart b/packages/pigeon/lib/src/dart/dart_generator.dart index 2dcb9b2efad..c87eb456cd5 100644 --- a/packages/pigeon/lib/src/dart/dart_generator.dart +++ b/packages/pigeon/lib/src/dart/dart_generator.dart @@ -11,6 +11,7 @@ import '../ast.dart'; import '../functional.dart'; import '../generator.dart'; import '../generator_tools.dart'; +import 'proxy_api_generator_helper.dart' as proxy_api_helper; import 'templates.dart'; /// Documentation comment open symbol. @@ -20,14 +21,13 @@ const String _docCommentPrefix = '///'; const String _suffixVarName = '${varNamePrefix}messageChannelSuffix'; /// Name of the `InstanceManager` variable for a ProxyApi class; -const String _instanceManagerVarName = - '${classMemberNamePrefix}instanceManager'; +const String instanceManagerVarName = '${classMemberNamePrefix}instanceManager'; /// Name of field used for host API codec. const String _pigeonChannelCodec = 'pigeonChannelCodec'; /// Documentation comment spec. -const DocumentCommentSpecification _docCommentSpec = +const DocumentCommentSpecification docCommentSpec = DocumentCommentSpecification(_docCommentPrefix); /// The custom codec used for all pigeon APIs. @@ -38,6 +38,10 @@ const String _pigeonMethodChannelCodec = 'pigeonMethodCodec'; const String _overflowClassName = '_PigeonCodecOverflow'; +/// Name of the overrides class for overriding constructors and static members +/// of proxy APIs. +const String proxyApiOverridesClassName = '${proxyApiClassNamePrefix}Overrides'; + /// Options that control how Dart code will be generated. class DartOptions { /// Constructor for DartOptions. @@ -120,6 +124,11 @@ class DartGenerator extends StructuredGenerator { /// Instantiates a Dart Generator. const DartGenerator(); + // Formatter used to format code from `code_builder`. + DartFormatter get _formatter { + return DartFormatter(languageVersion: Version(3, 6, 0)); + } + @override void writeFilePrologue( InternalDartOptions generatorOptions, @@ -155,7 +164,7 @@ class DartGenerator extends StructuredGenerator { indent.newln(); indent.writeln( - "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer${root.containsProxyApi ? ', immutable, protected' : ''};"); + "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer${root.containsProxyApi ? ', immutable, protected, visibleForTesting' : ''};"); indent.writeln("import 'package:flutter/services.dart';"); if (root.containsProxyApi) { indent.writeln( @@ -174,12 +183,12 @@ class DartGenerator extends StructuredGenerator { }) { indent.newln(); addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); + indent, anEnum.documentationComments, docCommentSpec); indent.write('enum ${anEnum.name} '); indent.addScoped('{', '}', () { for (final EnumMember member in anEnum.members) { addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); + indent, member.documentationComments, docCommentSpec); indent.writeln('${member.name},'); } }); @@ -195,7 +204,7 @@ class DartGenerator extends StructuredGenerator { }) { indent.newln(); addDocumentationComments( - indent, classDefinition.documentationComments, _docCommentSpec); + indent, classDefinition.documentationComments, docCommentSpec); final String sealed = classDefinition.isSealed ? 'sealed ' : ''; final String implements = classDefinition.superClassName != null ? 'extends ${classDefinition.superClassName} ' @@ -211,9 +220,9 @@ class DartGenerator extends StructuredGenerator { for (final NamedType field in getFieldsInSerializationOrder(classDefinition)) { addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); + indent, field.documentationComments, docCommentSpec); - final String datatype = _addGenericTypesNullable(field.type); + final String datatype = addGenericTypesNullable(field.type); indent.writeln('$datatype ${field.name};'); indent.newln(); } @@ -500,8 +509,7 @@ class DartGenerator extends StructuredGenerator { required String dartPackageName, }) { indent.newln(); - addDocumentationComments( - indent, api.documentationComments, _docCommentSpec); + addDocumentationComments(indent, api.documentationComments, docCommentSpec); indent.write('abstract class ${api.name} '); indent.addScoped('{', '}', () { @@ -514,12 +522,12 @@ class DartGenerator extends StructuredGenerator { indent.newln(); for (final Method func in api.methods) { addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); + indent, func.documentationComments, docCommentSpec); final bool isAsync = func.isAsynchronous; final String returnType = isAsync - ? 'Future<${_addGenericTypesNullable(func.returnType)}>' - : _addGenericTypesNullable(func.returnType); + ? 'Future<${addGenericTypesNullable(func.returnType)}>' + : addGenericTypesNullable(func.returnType); final String argSignature = _getMethodParameterSignature(func.parameters); indent.writeln('$returnType ${func.name}($argSignature);'); @@ -576,8 +584,7 @@ class DartGenerator extends StructuredGenerator { }) { indent.newln(); bool first = true; - addDocumentationComments( - indent, api.documentationComments, _docCommentSpec); + addDocumentationComments(indent, api.documentationComments, docCommentSpec); indent.write('class ${api.name} '); indent.addScoped('{', '}', () { indent.format(''' @@ -623,8 +630,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; required String dartPackageName, }) { indent.newln(); - addDocumentationComments( - indent, api.documentationComments, _docCommentSpec); + addDocumentationComments(indent, api.documentationComments, docCommentSpec); for (final Method func in api.methods) { indent.format(''' Stream<${func.returnType.baseName}> ${func.name}(${_getMethodParameterSignature(func.parameters, addTrailingComma: true)} {String instanceName = ''}) { @@ -896,7 +902,7 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; ), ) ..docs.addAll( - asDocumentationComments(api.documentationComments, _docCommentSpec), + asDocumentationComments(api.documentationComments, docCommentSpec), ) ..constructors.addAll(_proxyApiConstructors( api.constructors, @@ -906,8 +912,10 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; codecInstanceName: codecInstanceName, superClassApi: api.superClass?.associatedProxyApi, unattachedFields: api.unattachedFields, - flutterMethodsFromSuperClasses: api.flutterMethodsFromSuperClasses(), - flutterMethodsFromInterfaces: api.flutterMethodsFromInterfaces(), + flutterMethodsFromSuperClasses: + api.flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: + api.flutterMethodsFromInterfacesWithApis(), declaredFlutterMethods: api.flutterMethods, )) ..constructors.add( @@ -916,8 +924,9 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; superClassApi: api.superClass?.associatedProxyApi, unattachedFields: api.unattachedFields, flutterMethodsFromSuperClasses: - api.flutterMethodsFromSuperClasses(), - flutterMethodsFromInterfaces: api.flutterMethodsFromInterfaces(), + api.flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: + api.flutterMethodsFromInterfacesWithApis(), declaredFlutterMethods: api.flutterMethods, ), ) @@ -937,6 +946,10 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; )) ..fields.addAll(_proxyApiInterfaceApiFields(api.apisOfInterfaces())) ..fields.addAll(_proxyApiAttachedFields(api.attachedFields)) + ..methods.addAll(proxy_api_helper.staticAttachedFieldsGetters( + api.attachedFields.where((ApiField field) => field.isStatic), + apiName: api.name, + )) ..methods.add( _proxyApiSetUpMessageHandlerMethod( flutterMethods: api.flutterMethods, @@ -967,17 +980,17 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; _proxyApiCopyMethod( apiName: api.name, unattachedFields: api.unattachedFields, - declaredAndInheritedFlutterMethods: api - .flutterMethodsFromSuperClasses() - .followedBy(api.flutterMethodsFromInterfaces()) - .followedBy(api.flutterMethods), + flutterMethodsFromSuperClasses: + api.flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: + api.flutterMethodsFromInterfacesWithApis(), + declaredFlutterMethods: api.flutterMethods, ), ), ); final cb.DartEmitter emitter = cb.DartEmitter(useNullSafetySyntax: true); - indent.format(DartFormatter(languageVersion: Version(3, 6, 0)) - .format('${proxyApi.accept(emitter)}')); + indent.format(_formatter.format('${proxyApi.accept(emitter)}')); } /// Generates Dart source code for test support libraries based on the given AST @@ -1080,6 +1093,13 @@ final BinaryMessenger? ${varNamePrefix}binaryMessenger; if (root.classes.isNotEmpty) { _writeDeepEquals(indent); } + if (root.containsProxyApi) { + proxy_api_helper.writeProxyApiPigeonOverrides( + indent, + formatter: _formatter, + proxyApis: root.apis.whereType(), + ); + } } /// Writes [wrapResponse] method. @@ -1189,10 +1209,10 @@ if (wrapped == null) { required String channelName, required bool addSuffixVariable, }) { - addDocumentationComments(indent, documentationComments, _docCommentSpec); + addDocumentationComments(indent, documentationComments, docCommentSpec); final String argSignature = _getMethodParameterSignature(parameters); indent.write( - 'Future<${_addGenericTypesNullable(returnType)}> $name($argSignature) async ', + 'Future<${addGenericTypesNullable(returnType)}> $name($argSignature) async ', ); indent.addScoped('{', '}', () { _writeHostMethodMessageCall( @@ -1217,7 +1237,7 @@ if (wrapped == null) { if (parameters.isNotEmpty) { final Iterable argExpressions = indexMap(parameters, (int index, NamedType type) { - final String name = _getParameterName(index, type); + final String name = getParameterName(index, type); return name; }); sendArgument = '[${argExpressions.join(', ')}]'; @@ -1334,7 +1354,7 @@ if (${varNamePrefix}replyList == null) { '$messageHandlerSetterWithOpeningParentheses(Object? message) async ', ); indent.addScoped('{', '});', () { - final String returnTypeString = _addGenericTypesNullable(returnType); + final String returnTypeString = addGenericTypesNullable(returnType); final bool isAsync = isAsynchronous; const String emptyReturnStatement = 'return wrapResponse(empty: true);'; @@ -1416,8 +1436,12 @@ if (${varNamePrefix}replyList == null) { return 'api.$methodName(${safeArgumentNames.join(', ')})'; } - /// Converts Constructors from the pigeon AST to a `code_builder` Constructor + /// Converts Constructors from the pigeon AST to `code_builder` Constructors /// for a ProxyApi. + /// + /// Creates a factory constructor that can return an overrideable static + /// method for testing and a constructor that calls to the native + /// API implementation Iterable _proxyApiConstructors( Iterable constructors, { required String apiName, @@ -1426,8 +1450,8 @@ if (${varNamePrefix}replyList == null) { required String codecInstanceName, required AstProxyApi? superClassApi, required Iterable unattachedFields, - required Iterable flutterMethodsFromSuperClasses, - required Iterable flutterMethodsFromInterfaces, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromSuperClasses, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromInterfaces, required Iterable declaredFlutterMethods, }) sync* { final cb.Parameter binaryMessengerParameter = cb.Parameter( @@ -1436,13 +1460,86 @@ if (${varNamePrefix}replyList == null) { ..named = true ..toSuper = true, ); - final cb.Parameter instanceManagerParameter = cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = _instanceManagerVarName - ..named = true - ..toSuper = true, - ); + for (final Constructor constructor in constructors) { + final String? factoryConstructorName = + constructor.name.isNotEmpty ? constructor.name : null; + final String constructorName = + '$classMemberNamePrefix${constructor.name.isNotEmpty ? constructor.name : 'new'}'; + final String overridesConstructorName = constructor.name.isNotEmpty + ? '${toLowerCamelCase(apiName)}_${constructor.name}' + : '${toLowerCamelCase(apiName)}_new'; + + // Factory constructor that forwards the parameters to the overrides class + // or to the constructor yielded below this one. + yield cb.Constructor( + (cb.ConstructorBuilder builder) { + final Iterable parameters = + proxy_api_helper.asConstructorParameters( + apiName: apiName, + parameters: constructor.parameters, + unattachedFields: unattachedFields, + flutterMethodsFromSuperClasses: flutterMethodsFromSuperClasses, + flutterMethodsFromInterfaces: flutterMethodsFromInterfaces, + declaredFlutterMethods: declaredFlutterMethods, + ); + final Iterable parametersWithoutMessengerAndManager = + proxy_api_helper.asConstructorParameters( + apiName: apiName, + parameters: constructor.parameters, + unattachedFields: unattachedFields, + flutterMethodsFromSuperClasses: flutterMethodsFromSuperClasses, + flutterMethodsFromInterfaces: flutterMethodsFromInterfaces, + declaredFlutterMethods: declaredFlutterMethods, + includeBinaryMessengerAndInstanceManager: false, + ); + builder + ..name = factoryConstructorName + ..factory = true + ..docs.addAll(asDocumentationComments( + constructor.documentationComments, + docCommentSpec, + )) + ..optionalParameters.addAll(parameters) + ..body = cb.Block( + (cb.BlockBuilder builder) { + final Map forwardedParams = + { + for (final cb.Parameter parameter in parameters) + parameter.name: cb.refer(parameter.name) + }; + final Map + forwardedParamsWithoutMessengerAndManager = + { + for (final cb.Parameter parameter + in parametersWithoutMessengerAndManager) + parameter.name: cb.refer(parameter.name) + }; + + builder.statements.addAll([ + cb.Code( + 'if ($proxyApiOverridesClassName.$overridesConstructorName != null) {'), + cb.CodeExpression( + cb.Code( + '$proxyApiOverridesClassName.$overridesConstructorName!'), + ) + .call( + [], + forwardedParamsWithoutMessengerAndManager, + ) + .returned + .statement, + const cb.Code('}'), + cb.CodeExpression(cb.Code('$apiName.$constructorName')) + .call([], forwardedParams) + .returned + .statement, + ]); + }, + ); + }, + ); + yield cb.Constructor( (cb.ConstructorBuilder builder) { final String channelName = makeChannelNameWithStrings( @@ -1453,52 +1550,22 @@ if (${varNamePrefix}replyList == null) { dartPackageName: dartPackageName, ); builder - ..name = constructor.name.isNotEmpty ? constructor.name : null + ..name = constructorName + ..annotations.add(cb.refer('protected')) ..docs.addAll(asDocumentationComments( constructor.documentationComments, - _docCommentSpec, + docCommentSpec, + )) + ..optionalParameters + .addAll(proxy_api_helper.asConstructorParameters( + apiName: apiName, + parameters: constructor.parameters, + unattachedFields: unattachedFields, + flutterMethodsFromSuperClasses: flutterMethodsFromSuperClasses, + flutterMethodsFromInterfaces: flutterMethodsFromInterfaces, + declaredFlutterMethods: declaredFlutterMethods, + defineType: false, )) - ..optionalParameters.addAll( - [ - binaryMessengerParameter, - instanceManagerParameter, - for (final ApiField field in unattachedFields) - cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = field.name - ..named = true - ..toThis = true - ..required = !field.type.isNullable, - ), - for (final Method method in flutterMethodsFromSuperClasses) - cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = method.name - ..named = true - ..toSuper = true - ..required = method.isRequired, - ), - for (final Method method in flutterMethodsFromInterfaces - .followedBy(declaredFlutterMethods)) - cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = method.name - ..named = true - ..toThis = true - ..required = method.isRequired, - ), - ...indexMap( - constructor.parameters, - (int index, NamedType parameter) => cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = _getParameterName(index, parameter) - ..type = _refer(parameter.type) - ..named = true - ..required = !parameter.type.isNullable, - ), - ) - ], - ) ..initializers.addAll( [ if (superClassApi != null) @@ -1534,7 +1601,7 @@ if (${varNamePrefix}replyList == null) { builder.statements.addAll([ const cb.Code( - 'final int ${varNamePrefix}instanceIdentifier = $_instanceManagerVarName.addDartCreatedInstance(this);', + 'final int ${varNamePrefix}instanceIdentifier = $instanceManagerVarName.addDartCreatedInstance(this);', ), cb.Code('final $codecName $_pigeonChannelCodec =\n' ' $codecInstanceName;'), @@ -1560,22 +1627,10 @@ if (${varNamePrefix}replyList == null) { required String apiName, required AstProxyApi? superClassApi, required Iterable unattachedFields, - required Iterable flutterMethodsFromSuperClasses, - required Iterable flutterMethodsFromInterfaces, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromSuperClasses, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromInterfaces, required Iterable declaredFlutterMethods, }) { - final cb.Parameter binaryMessengerParameter = cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = '${classMemberNamePrefix}binaryMessenger' - ..named = true - ..toSuper = true, - ); - final cb.Parameter instanceManagerParameter = cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = _instanceManagerVarName - ..named = true - ..toSuper = true, - ); return cb.Constructor( (cb.ConstructorBuilder builder) => builder ..name = '${classMemberNamePrefix}detached' @@ -1586,35 +1641,15 @@ if (${varNamePrefix}replyList == null) { '/// create copies for an [$dartInstanceManagerClassName].', ]) ..annotations.add(cb.refer('protected')) - ..optionalParameters.addAll([ - binaryMessengerParameter, - instanceManagerParameter, - for (final ApiField field in unattachedFields) - cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = field.name - ..named = true - ..toThis = true - ..required = !field.type.isNullable, - ), - for (final Method method in flutterMethodsFromSuperClasses) - cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = method.name - ..named = true - ..toSuper = true - ..required = method.isRequired, - ), - for (final Method method in flutterMethodsFromInterfaces - .followedBy(declaredFlutterMethods)) - cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = method.name - ..named = true - ..toThis = true - ..required = method.isRequired, - ), - ]) + ..optionalParameters.addAll(proxy_api_helper.asConstructorParameters( + apiName: apiName, + parameters: [], + unattachedFields: unattachedFields, + flutterMethodsFromSuperClasses: flutterMethodsFromSuperClasses, + flutterMethodsFromInterfaces: flutterMethodsFromInterfaces, + declaredFlutterMethods: declaredFlutterMethods, + defineType: false, + )) ..initializers.addAll([ if (superClassApi != null) const cb.Code('super.${classMemberNamePrefix}detached()'), @@ -1633,7 +1668,7 @@ if (${varNamePrefix}replyList == null) { ..type = cb.refer(codecName) ..late = true ..modifier = cb.FieldModifier.final$ - ..assignment = cb.Code('$codecName($_instanceManagerVarName)'), + ..assignment = cb.Code('$codecName($instanceManagerVarName)'), ); } @@ -1646,11 +1681,11 @@ if (${varNamePrefix}replyList == null) { yield cb.Field( (cb.FieldBuilder builder) => builder ..name = field.name - ..type = cb.refer(_addGenericTypesNullable(field.type)) + ..type = cb.refer(addGenericTypesNullable(field.type)) ..modifier = cb.FieldModifier.final$ ..docs.addAll(asDocumentationComments( field.documentationComments, - _docCommentSpec, + docCommentSpec, )), ); } @@ -1694,27 +1729,10 @@ if (${varNamePrefix}replyList == null) { 'release the associated Native object manually.', ], ], - _docCommentSpec, + docCommentSpec, )) - ..type = cb.FunctionType( - (cb.FunctionTypeBuilder builder) => builder - ..returnType = _refer( - method.returnType, - asFuture: method.isAsynchronous, - ) - ..isNullable = !method.isRequired - ..requiredParameters.addAll([ - cb.refer('$apiName ${classMemberNamePrefix}instance'), - ...indexMap( - method.parameters, - (int index, NamedType parameter) { - return cb.refer( - '${_addGenericTypesNullable(parameter.type)} ${_getParameterName(index, parameter)}', - ); - }, - ), - ]), - ), + ..type = + proxy_api_helper.methodAsFunctionType(method, apiName: apiName), ); } } @@ -1739,11 +1757,11 @@ if (${varNamePrefix}replyList == null) { ..annotations.add(cb.refer('override')) ..docs.addAll(asDocumentationComments( method.documentationComments, - _docCommentSpec, + docCommentSpec, )) ..type = cb.FunctionType( (cb.FunctionTypeBuilder builder) => builder - ..returnType = _refer( + ..returnType = refer( method.returnType, asFuture: method.isAsynchronous, ) @@ -1756,7 +1774,7 @@ if (${varNamePrefix}replyList == null) { method.parameters, (int index, NamedType parameter) { return cb.refer( - '${_addGenericTypesNullable(parameter.type)} ${_getParameterName(index, parameter)}', + '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', ); }, ), @@ -1781,14 +1799,14 @@ if (${varNamePrefix}replyList == null) { for (final ApiField field in fields) { yield cb.Field( (cb.FieldBuilder builder) => builder - ..name = field.name - ..type = cb.refer(_addGenericTypesNullable(field.type)) + ..name = '${field.isStatic ? '_' : ''}${field.name}' + ..type = cb.refer(addGenericTypesNullable(field.type)) ..modifier = cb.FieldModifier.final$ ..static = field.isStatic ..late = !field.isStatic ..docs.addAll(asDocumentationComments( field.documentationComments, - _docCommentSpec, + docCommentSpec, )) ..assignment = cb.Code('$varNamePrefix${field.name}()'), ); @@ -1834,7 +1852,7 @@ if (${varNamePrefix}replyList == null) { ), cb.Parameter( (cb.ParameterBuilder builder) => builder - ..name = _instanceManagerVarName + ..name = instanceManagerVarName ..named = true ..type = cb.refer('$dartInstanceManagerClassName?'), ), @@ -1852,7 +1870,7 @@ if (${varNamePrefix}replyList == null) { unattachedFields, (int index, ApiField field) { return cb.refer( - '${_addGenericTypesNullable(field.type)} ${_getParameterName(index, field)}', + '${addGenericTypesNullable(field.type)} ${getParameterName(index, field)}', ); }, ), @@ -1865,7 +1883,7 @@ if (${varNamePrefix}replyList == null) { ..name = method.name ..type = cb.FunctionType( (cb.FunctionTypeBuilder builder) => builder - ..returnType = _refer( + ..returnType = refer( method.returnType, asFuture: method.isAsynchronous, ) @@ -1876,7 +1894,7 @@ if (${varNamePrefix}replyList == null) { method.parameters, (int index, NamedType parameter) { return cb.refer( - '${_addGenericTypesNullable(parameter.type)} ${_getParameterName(index, parameter)}', + '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', ); }, ), @@ -1887,7 +1905,7 @@ if (${varNamePrefix}replyList == null) { ..body = cb.Block.of([ if (hasAnyMessageHandlers) ...[ cb.Code( - 'final $codecName $_pigeonChannelCodec = $codecName($_instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', + 'final $codecName $_pigeonChannelCodec = $codecName($instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', ), const cb.Code( 'final BinaryMessenger? binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', @@ -1935,12 +1953,12 @@ if (${varNamePrefix}replyList == null) { return '${parameter.name}: $safeArgName,\n'; }, ).skip(1).join(); - return '($_instanceManagerVarName ?? $dartInstanceManagerClassName.instance)\n' + return '($instanceManagerVarName ?? $dartInstanceManagerClassName.instance)\n' ' .addHostCreatedInstance(\n' ' $methodName?.call(${safeArgumentNames.skip(1).join(',')}) ??\n' ' $apiName.${classMemberNamePrefix}detached(' ' ${classMemberNamePrefix}binaryMessenger: ${classMemberNamePrefix}binaryMessenger,\n' - ' $_instanceManagerVarName: $_instanceManagerVarName,\n' + ' $instanceManagerVarName: $instanceManagerVarName,\n' ' $argsAsNamedParams\n' ' ),\n' ' ${safeArgumentNames.first},\n' @@ -2012,7 +2030,7 @@ if (${varNamePrefix}replyList == null) { for (final ApiField field in fields) { yield cb.Method( (cb.MethodBuilder builder) { - final String type = _addGenericTypesNullable(field.type); + final String type = addGenericTypesNullable(field.type); const String instanceName = '${varNamePrefix}instance'; const String identifierInstanceName = '${varNamePrefix}instanceIdentifier'; @@ -2064,7 +2082,7 @@ if (${varNamePrefix}replyList == null) { 'final BinaryMessenger? ${varNamePrefix}binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', ), const cb.Code( - 'final int $identifierInstanceName = $_instanceManagerVarName.addDartCreatedInstance($instanceName);', + 'final int $identifierInstanceName = $instanceManagerVarName.addDartCreatedInstance($instanceName);', ), ] else ...[ cb.Code( @@ -2105,6 +2123,16 @@ if (${varNamePrefix}replyList == null) { }) sync* { for (final Method method in methods) { assert(method.location == ApiLocation.host); + final Iterable parameters = indexMap( + method.parameters, + (int index, NamedType parameter) => cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = getParameterName(index, parameter) + ..type = cb.refer( + addGenericTypesNullable(parameter.type), + ), + ), + ); yield cb.Method( (cb.MethodBuilder builder) => builder ..name = method.name @@ -2112,21 +2140,10 @@ if (${varNamePrefix}replyList == null) { ..modifier = cb.MethodModifier.async ..docs.addAll(asDocumentationComments( method.documentationComments, - _docCommentSpec, + docCommentSpec, )) - ..returns = _refer(method.returnType, asFuture: true) - ..requiredParameters.addAll( - indexMap( - method.parameters, - (int index, NamedType parameter) => cb.Parameter( - (cb.ParameterBuilder builder) => builder - ..name = _getParameterName(index, parameter) - ..type = cb.refer( - _addGenericTypesNullable(parameter.type), - ), - ), - ), - ) + ..returns = refer(method.returnType, asFuture: true) + ..requiredParameters.addAll(parameters) ..optionalParameters.addAll([ if (method.isStatic) ...[ cb.Parameter( @@ -2137,7 +2154,7 @@ if (${varNamePrefix}replyList == null) { ), cb.Parameter( (cb.ParameterBuilder builder) => builder - ..name = _instanceManagerVarName + ..name = instanceManagerVarName ..type = cb.refer('$dartInstanceManagerClassName?'), ), ], @@ -2167,12 +2184,28 @@ if (${varNamePrefix}replyList == null) { returnType: method.returnType, ); builder.statements.addAll([ + if (method.isStatic) ...[ + cb.Code( + 'if ($proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${method.name} != null) {', + ), + cb.CodeExpression( + cb.Code( + '$proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${method.name}!', + ), + ) + .call(parameters.map( + (cb.Parameter parameter) => cb.refer(parameter.name), + )) + .returned + .statement, + const cb.Code('}'), + ], if (!method.isStatic) cb.Code('final $codecName $_pigeonChannelCodec =\n' ' $codecInstanceName;') else cb.Code( - 'final $codecName $_pigeonChannelCodec = $codecName($_instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', + 'final $codecName $_pigeonChannelCodec = $codecName($instanceManagerVarName ?? $dartInstanceManagerClassName.instance);', ), const cb.Code( 'final BinaryMessenger? ${varNamePrefix}binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', @@ -2193,8 +2226,19 @@ if (${varNamePrefix}replyList == null) { cb.Method _proxyApiCopyMethod({ required String apiName, required Iterable unattachedFields, - required Iterable declaredAndInheritedFlutterMethods, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromSuperClasses, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromInterfaces, + required Iterable declaredFlutterMethods, }) { + final Iterable parameters = + proxy_api_helper.asConstructorParameters( + apiName: apiName, + parameters: [], + unattachedFields: unattachedFields, + flutterMethodsFromSuperClasses: flutterMethodsFromSuperClasses, + flutterMethodsFromInterfaces: flutterMethodsFromInterfaces, + declaredFlutterMethods: declaredFlutterMethods, + ); return cb.Method( (cb.MethodBuilder builder) => builder ..name = '${classMemberNamePrefix}copy' @@ -2206,14 +2250,8 @@ if (${varNamePrefix}replyList == null) { .call( [], { - '${classMemberNamePrefix}binaryMessenger': - cb.refer('${classMemberNamePrefix}binaryMessenger'), - _instanceManagerVarName: cb.refer(_instanceManagerVarName), - for (final ApiField field in unattachedFields) - field.name: cb.refer(field.name), - for (final Method method - in declaredAndInheritedFlutterMethods) - method.name: cb.refer(method.name), + for (final cb.Parameter parameter in parameters) + parameter.name: cb.refer(parameter.name) }, ) .returned @@ -2223,8 +2261,9 @@ if (${varNamePrefix}replyList == null) { } } -cb.Reference _refer(TypeDeclaration type, {bool asFuture = false}) { - final String symbol = _addGenericTypesNullable(type); +/// Converts a [TypeDeclaration] to a `code_builder` Reference. +cb.Reference refer(TypeDeclaration type, {bool asFuture = false}) { + final String symbol = addGenericTypesNullable(type); return cb.refer(asFuture ? 'Future<$symbol>' : symbol); } @@ -2255,11 +2294,11 @@ String _getSafeArgumentName(int count, NamedType field) => field.name.isEmpty ? 'arg$count' : 'arg_${field.name}'; /// Generates a parameter name if one isn't defined. -String _getParameterName(int count, NamedType field) => +String getParameterName(int count, NamedType field) => field.name.isEmpty ? 'arg$count' : field.name; /// Generates the parameters code for [func] -/// Example: (func, _getParameterName) -> 'String? foo, int bar' +/// Example: (func, getParameterName) -> 'String? foo, int bar' String _getMethodParameterSignature( Iterable parameters, { bool addTrailingComma = false, @@ -2281,7 +2320,7 @@ String _getMethodParameterSignature( String getParameterString(Parameter p) { final String required = p.isRequired && !p.isPositional ? 'required ' : ''; - final String type = _addGenericTypesNullable(p.type); + final String type = addGenericTypesNullable(p.type); final String defaultValue = p.defaultValue == null ? '' : ' = ${p.defaultValue}'; @@ -2350,7 +2389,9 @@ String _addGenericTypes(TypeDeclaration type) { } } -String _addGenericTypesNullable(TypeDeclaration type) { +/// Converts the type signature of a [TypeDeclaration] that include generic +/// types. +String addGenericTypesNullable(TypeDeclaration type) { final String genericType = _addGenericTypes(type); return type.isNullable ? '$genericType?' : genericType; } diff --git a/packages/pigeon/lib/src/dart/proxy_api_generator_helper.dart b/packages/pigeon/lib/src/dart/proxy_api_generator_helper.dart new file mode 100644 index 00000000000..ca89ce6a034 --- /dev/null +++ b/packages/pigeon/lib/src/dart/proxy_api_generator_helper.dart @@ -0,0 +1,332 @@ +// 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:code_builder/code_builder.dart' as cb; +import 'package:collection/collection.dart'; +import 'package:dart_style/dart_style.dart'; + +import '../ast.dart'; +import '../generator_tools.dart'; +import 'dart_generator.dart'; +import 'templates.dart'; + +/// Converts fields and methods of a [AstProxyApi] constructor to the +/// `code_builder` Parameters. +Iterable asConstructorParameters({ + required String apiName, + required Iterable parameters, + required Iterable unattachedFields, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromSuperClasses, + required Iterable<(Method, AstProxyApi)> flutterMethodsFromInterfaces, + required Iterable declaredFlutterMethods, + bool defineType = true, + bool includeBinaryMessengerAndInstanceManager = true, +}) sync* { + if (includeBinaryMessengerAndInstanceManager) { + yield cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}binaryMessenger' + ..named = true + ..type = defineType ? cb.refer('BinaryMessenger?') : null + ..toSuper = !defineType + ..required = false, + ); + yield cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = instanceManagerVarName + ..named = true + ..type = defineType ? cb.refer('$dartInstanceManagerClassName?') : null + ..toSuper = !defineType + ..required = false, + ); + } + + for (final ApiField field in unattachedFields) { + yield cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = field.name + ..named = true + ..type = + defineType ? cb.refer(addGenericTypesNullable(field.type)) : null + ..toThis = !defineType + ..required = !field.type.isNullable, + ); + } + + for (final (Method method, AstProxyApi api) + in flutterMethodsFromSuperClasses) { + yield cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..type = + defineType ? methodAsFunctionType(method, apiName: api.name) : null + ..toSuper = !defineType + ..required = method.isRequired, + ); + } + + for (final (Method method, AstProxyApi api) in flutterMethodsFromInterfaces) { + yield cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..type = + defineType ? methodAsFunctionType(method, apiName: api.name) : null + ..toThis = !defineType + ..required = method.isRequired, + ); + } + + for (final Method method in declaredFlutterMethods) { + yield cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..type = + defineType ? methodAsFunctionType(method, apiName: apiName) : null + ..toThis = !defineType + ..required = method.isRequired, + ); + } + + yield* parameters.mapIndexed( + (int index, NamedType parameter) => cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = getParameterName(index, parameter) + ..type = refer(parameter.type) + ..named = true + ..required = !parameter.type.isNullable, + ), + ); +} + +/// Converts all the constructors of a ProxyApi into fields that are used to +/// override the corresponding factory constructor of the generated Dart class. +Iterable overridesClassConstructors( + Iterable proxyApis, +) sync* { + for (final AstProxyApi api in proxyApis) { + final String lowerCamelCaseApiName = toLowerCamelCase(api.name); + + for (final Constructor constructor in api.constructors) { + yield cb.Field( + (cb.FieldBuilder builder) { + final String constructorName = + constructor.name.isEmpty ? 'new' : constructor.name; + final Iterable parameters = asConstructorParameters( + apiName: api.name, + parameters: constructor.parameters, + unattachedFields: api.unattachedFields, + flutterMethodsFromSuperClasses: + api.flutterMethodsFromSuperClassesWithApis(), + flutterMethodsFromInterfaces: + api.flutterMethodsFromInterfacesWithApis(), + declaredFlutterMethods: api.flutterMethods, + includeBinaryMessengerAndInstanceManager: false, + ); + builder + ..name = constructor.name.isEmpty + ? '${lowerCamelCaseApiName}_new' + : '${lowerCamelCaseApiName}_${constructor.name}' + ..static = true + ..docs.add('/// Overrides [${api.name}.$constructorName].') + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = cb.refer(api.name) + ..isNullable = true + ..namedRequiredParameters.addAll({ + for (final cb.Parameter parameter in parameters + .where((cb.Parameter parameter) => parameter.required)) + parameter.name: parameter.type!, + }) + ..namedParameters.addAll({ + for (final cb.Parameter parameter in parameters + .where((cb.Parameter parameter) => !parameter.required)) + parameter.name: parameter.type!, + }), + ); + }, + ); + } + } +} + +/// Converts all the static fields of a ProxyApi into fields that are used to +/// override the corresponding static field of the generated Dart class. +Iterable overridesClassStaticFields( + Iterable proxyApis, +) sync* { + for (final AstProxyApi api in proxyApis) { + final String lowerCamelCaseApiName = toLowerCamelCase(api.name); + + for (final ApiField field + in api.fields.where((ApiField field) => field.isStatic)) { + yield cb.Field((cb.FieldBuilder builder) { + builder + ..name = '${lowerCamelCaseApiName}_${field.name}' + ..static = true + ..docs.add('/// Overrides [${api.name}.${field.name}].') + ..type = cb.refer('${field.type.baseName}?'); + }); + } + } +} + +/// Converts all the static methods of a ProxyApi into fields that are used to +/// override the corresponding static method of the generated Dart class. +Iterable overridesClassStaticMethods( + Iterable proxyApis, +) sync* { + for (final AstProxyApi api in proxyApis) { + final String lowerCamelCaseApiName = toLowerCamelCase(api.name); + + for (final Method method + in api.hostMethods.where((Method method) => method.isStatic)) { + yield cb.Field((cb.FieldBuilder builder) { + builder + ..name = '${lowerCamelCaseApiName}_${method.name}' + ..static = true + ..docs.add('/// Overrides [${api.name}.${method.name}].') + ..type = cb.FunctionType((cb.FunctionTypeBuilder builder) { + builder + ..isNullable = true + ..returnType = refer(method.returnType, asFuture: true) + ..requiredParameters.addAll([ + for (final Parameter parameter in method.parameters) + refer(parameter.type), + ]); + }); + }); + } + } +} + +/// Creates the reset method for the `PigeonOverrides` class that sets all +/// overrideable methods to null. +cb.Method overridesClassResetMethod( + Iterable proxyApis, +) { + return cb.Method.returnsVoid((cb.MethodBuilder builder) { + builder + ..name = '${classMemberNamePrefix}reset' + ..static = true + ..docs.addAll([ + '/// Sets all overridden ProxyApi class members to null.', + ]) + ..body = cb.Block.of([ + for (final AstProxyApi api in proxyApis) ...[ + for (final Constructor constructor in api.constructors) + cb.Code( + '${toLowerCamelCase(api.name)}_${constructor.name.isEmpty ? 'new' : constructor.name} = null;', + ), + for (final ApiField attachedField + in api.fields.where((ApiField field) => field.isStatic)) + cb.Code( + '${toLowerCamelCase(api.name)}_${attachedField.name} = null;', + ), + for (final Method staticMethod + in api.methods.where((Method method) => method.isStatic)) + cb.Code( + '${toLowerCamelCase(api.name)}_${staticMethod.name} = null;', + ), + ], + ]); + }); +} + +/// Converts a method to a `code_builder` FunctionType with all parameters as +/// positional arguments. +cb.FunctionType methodAsFunctionType( + Method method, { + required String apiName, +}) { + return cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = refer( + method.returnType, + asFuture: method.isAsynchronous, + ) + ..isNullable = !method.isRequired + ..requiredParameters.addAll([ + if (method.location == ApiLocation.flutter) + cb.refer('$apiName ${classMemberNamePrefix}instance'), + ...method.parameters.mapIndexed( + (int index, NamedType parameter) { + return cb.refer( + '${addGenericTypesNullable(parameter.type)} ${getParameterName(index, parameter)}', + ); + }, + ) + ]), + ); +} + +/// Converts static attached Fields from the pigeon AST to `code_builder` +/// Method. +/// +/// Static attached fields return an overrideable test value or returns the +/// private static instance. +/// +/// Example Output: +/// +/// ```dart +/// static MyClass get instance => PigeonMyClassOverrides.instance ?? _instance; +/// ``` +Iterable staticAttachedFieldsGetters( + Iterable fields, { + required String apiName, +}) sync* { + for (final ApiField field in fields) { + yield cb.Method((cb.MethodBuilder builder) => builder + ..name = field.name + ..type = cb.MethodType.getter + ..static = true + ..returns = cb.refer(addGenericTypesNullable(field.type)) + ..docs.addAll(asDocumentationComments( + field.documentationComments, + docCommentSpec, + )) + ..lambda = true + ..body = cb.Code( + '$proxyApiOverridesClassName.${toLowerCamelCase(apiName)}_${field.name} ?? _${field.name}', + )); + } +} + +/// Write the `PigeonOverrides` class that provides overrides for constructors +/// and static members of each generated Dart class of a ProxyApi. +void writeProxyApiPigeonOverrides( + Indent indent, { + required DartFormatter formatter, + required Iterable proxyApis, +}) { + final cb.Class proxyApiOverrides = cb.Class( + (cb.ClassBuilder builder) => builder + ..name = proxyApiOverridesClassName + ..annotations.add(cb.refer('visibleForTesting')) + ..docs.addAll([ + '/// Provides overrides for the constructors and static members of each proxy', + '/// API.', + '///', + '/// This is only intended to be used with unit tests to prevent errors from', + '/// making message calls in a unit test.', + '///', + '/// See [$proxyApiOverridesClassName.${classMemberNamePrefix}reset] to set all overrides back to null.', + ]) + ..fields.addAll( + overridesClassConstructors(proxyApis), + ) + ..fields.addAll( + overridesClassStaticFields(proxyApis), + ) + ..fields.addAll(overridesClassStaticMethods(proxyApis)) + ..methods.add( + overridesClassResetMethod(proxyApis), + ), + ); + + final cb.DartEmitter emitter = cb.DartEmitter(useNullSafetySyntax: true); + indent.format(formatter.format('${proxyApiOverrides.accept(emitter)}')); +} diff --git a/packages/pigeon/lib/src/generator_tools.dart b/packages/pigeon/lib/src/generator_tools.dart index 8528dd70df8..51d2500e9de 100644 --- a/packages/pigeon/lib/src/generator_tools.dart +++ b/packages/pigeon/lib/src/generator_tools.dart @@ -15,7 +15,7 @@ import 'generator.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '25.5.0'; +const String pigeonVersion = '26.0.0'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart index 4f6b8593aed..214476f8f53 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart @@ -11,7 +11,7 @@ import 'dart:io' show Platform; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' - show ReadBuffer, WriteBuffer, immutable, protected; + show ReadBuffer, WriteBuffer, immutable, protected, visibleForTesting; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart' show WidgetsFlutterBinding; @@ -33,6 +33,286 @@ List wrapResponse( return [error.code, error.message, error.details]; } +/// Provides overrides for the constructors and static members of each proxy +/// API. +/// +/// This is only intended to be used with unit tests to prevent errors from +/// making message calls in a unit test. +/// +/// See [PigeonOverrides.pigeon_reset] to set all overrides back to null. +@visibleForTesting +class PigeonOverrides { + /// Overrides [ProxyApiTestClass.new]. + static ProxyApiTestClass Function({ + required bool aBool, + required int anInt, + required double aDouble, + required String aString, + required Uint8List aUint8List, + required List aList, + required Map aMap, + required ProxyApiTestEnum anEnum, + required ProxyApiSuperClass aProxyApi, + required bool Function( + ProxyApiTestClass pigeon_instance, + bool aBool, + ) flutterEchoBool, + required int Function( + ProxyApiTestClass pigeon_instance, + int anInt, + ) flutterEchoInt, + required double Function( + ProxyApiTestClass pigeon_instance, + double aDouble, + ) flutterEchoDouble, + required String Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoString, + required Uint8List Function( + ProxyApiTestClass pigeon_instance, + Uint8List aList, + ) flutterEchoUint8List, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoList, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoProxyApiList, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoMap, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoProxyApiMap, + required ProxyApiTestEnum Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum anEnum, + ) flutterEchoEnum, + required ProxyApiSuperClass Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass aProxyApi, + ) flutterEchoProxyApi, + required Future Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoAsyncString, + required bool boolParam, + required int intParam, + required double doubleParam, + required String stringParam, + required Uint8List aUint8ListParam, + required List listParam, + required Map mapParam, + required ProxyApiTestEnum enumParam, + required ProxyApiSuperClass proxyApiParam, + bool? aNullableBool, + int? aNullableInt, + double? aNullableDouble, + String? aNullableString, + Uint8List? aNullableUint8List, + List? aNullableList, + Map? aNullableMap, + ProxyApiTestEnum? aNullableEnum, + ProxyApiSuperClass? aNullableProxyApi, + void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod, + void Function(ProxyApiTestClass pigeon_instance)? flutterNoop, + Object? Function(ProxyApiTestClass pigeon_instance)? flutterThrowError, + void Function(ProxyApiTestClass pigeon_instance)? flutterThrowErrorFromVoid, + bool? Function( + ProxyApiTestClass pigeon_instance, + bool? aBool, + )? flutterEchoNullableBool, + int? Function( + ProxyApiTestClass pigeon_instance, + int? anInt, + )? flutterEchoNullableInt, + double? Function( + ProxyApiTestClass pigeon_instance, + double? aDouble, + )? flutterEchoNullableDouble, + String? Function( + ProxyApiTestClass pigeon_instance, + String? aString, + )? flutterEchoNullableString, + Uint8List? Function( + ProxyApiTestClass pigeon_instance, + Uint8List? aList, + )? flutterEchoNullableUint8List, + List? Function( + ProxyApiTestClass pigeon_instance, + List? aList, + )? flutterEchoNullableList, + Map? Function( + ProxyApiTestClass pigeon_instance, + Map? aMap, + )? flutterEchoNullableMap, + ProxyApiTestEnum? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum? anEnum, + )? flutterEchoNullableEnum, + ProxyApiSuperClass? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass? aProxyApi, + )? flutterEchoNullableProxyApi, + Future Function(ProxyApiTestClass pigeon_instance)? flutterNoopAsync, + bool? nullableBoolParam, + int? nullableIntParam, + double? nullableDoubleParam, + String? nullableStringParam, + Uint8List? nullableUint8ListParam, + List? nullableListParam, + Map? nullableMapParam, + ProxyApiTestEnum? nullableEnumParam, + ProxyApiSuperClass? nullableProxyApiParam, + })? proxyApiTestClass_new; + + /// Overrides [ProxyApiTestClass.namedConstructor]. + static ProxyApiTestClass Function({ + required bool aBool, + required int anInt, + required double aDouble, + required String aString, + required Uint8List aUint8List, + required List aList, + required Map aMap, + required ProxyApiTestEnum anEnum, + required ProxyApiSuperClass aProxyApi, + required bool Function( + ProxyApiTestClass pigeon_instance, + bool aBool, + ) flutterEchoBool, + required int Function( + ProxyApiTestClass pigeon_instance, + int anInt, + ) flutterEchoInt, + required double Function( + ProxyApiTestClass pigeon_instance, + double aDouble, + ) flutterEchoDouble, + required String Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoString, + required Uint8List Function( + ProxyApiTestClass pigeon_instance, + Uint8List aList, + ) flutterEchoUint8List, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoList, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoProxyApiList, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoMap, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoProxyApiMap, + required ProxyApiTestEnum Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum anEnum, + ) flutterEchoEnum, + required ProxyApiSuperClass Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass aProxyApi, + ) flutterEchoProxyApi, + required Future Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoAsyncString, + bool? aNullableBool, + int? aNullableInt, + double? aNullableDouble, + String? aNullableString, + Uint8List? aNullableUint8List, + List? aNullableList, + Map? aNullableMap, + ProxyApiTestEnum? aNullableEnum, + ProxyApiSuperClass? aNullableProxyApi, + void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod, + void Function(ProxyApiTestClass pigeon_instance)? flutterNoop, + Object? Function(ProxyApiTestClass pigeon_instance)? flutterThrowError, + void Function(ProxyApiTestClass pigeon_instance)? flutterThrowErrorFromVoid, + bool? Function( + ProxyApiTestClass pigeon_instance, + bool? aBool, + )? flutterEchoNullableBool, + int? Function( + ProxyApiTestClass pigeon_instance, + int? anInt, + )? flutterEchoNullableInt, + double? Function( + ProxyApiTestClass pigeon_instance, + double? aDouble, + )? flutterEchoNullableDouble, + String? Function( + ProxyApiTestClass pigeon_instance, + String? aString, + )? flutterEchoNullableString, + Uint8List? Function( + ProxyApiTestClass pigeon_instance, + Uint8List? aList, + )? flutterEchoNullableUint8List, + List? Function( + ProxyApiTestClass pigeon_instance, + List? aList, + )? flutterEchoNullableList, + Map? Function( + ProxyApiTestClass pigeon_instance, + Map? aMap, + )? flutterEchoNullableMap, + ProxyApiTestEnum? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum? anEnum, + )? flutterEchoNullableEnum, + ProxyApiSuperClass? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass? aProxyApi, + )? flutterEchoNullableProxyApi, + Future Function(ProxyApiTestClass pigeon_instance)? flutterNoopAsync, + })? proxyApiTestClass_namedConstructor; + + /// Overrides [ProxyApiSuperClass.new]. + static ProxyApiSuperClass Function()? proxyApiSuperClass_new; + + /// Overrides [ClassWithApiRequirement.new]. + static ClassWithApiRequirement Function()? classWithApiRequirement_new; + + /// Overrides [ProxyApiTestClass.staticAttachedField]. + static ProxyApiSuperClass? proxyApiTestClass_staticAttachedField; + + /// Overrides [ProxyApiTestClass.staticNoop]. + static Future Function()? proxyApiTestClass_staticNoop; + + /// Overrides [ProxyApiTestClass.echoStaticString]. + static Future Function(String)? proxyApiTestClass_echoStaticString; + + /// Overrides [ProxyApiTestClass.staticAsyncNoop]. + static Future Function()? proxyApiTestClass_staticAsyncNoop; + + /// Sets all overridden ProxyApi class members to null. + static void pigeon_reset() { + proxyApiTestClass_new = null; + proxyApiTestClass_namedConstructor = null; + proxyApiTestClass_staticAttachedField = null; + proxyApiTestClass_staticNoop = null; + proxyApiTestClass_echoStaticString = null; + proxyApiTestClass_staticAsyncNoop = null; + proxyApiSuperClass_new = null; + classWithApiRequirement_new = null; + } +} + /// An immutable object that serves as the base class for all ProxyApis and /// can provide functional copies of itself. /// @@ -453,7 +733,271 @@ class _PigeonCodec extends StandardMessageCodec { /// implement in platform_tests integration tests. class ProxyApiTestClass extends ProxyApiSuperClass implements ProxyApiInterface { - ProxyApiTestClass({ + factory ProxyApiTestClass({ + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + required bool aBool, + required int anInt, + required double aDouble, + required String aString, + required Uint8List aUint8List, + required List aList, + required Map aMap, + required ProxyApiTestEnum anEnum, + required ProxyApiSuperClass aProxyApi, + bool? aNullableBool, + int? aNullableInt, + double? aNullableDouble, + String? aNullableString, + Uint8List? aNullableUint8List, + List? aNullableList, + Map? aNullableMap, + ProxyApiTestEnum? aNullableEnum, + ProxyApiSuperClass? aNullableProxyApi, + void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod, + void Function(ProxyApiTestClass pigeon_instance)? flutterNoop, + Object? Function(ProxyApiTestClass pigeon_instance)? flutterThrowError, + void Function(ProxyApiTestClass pigeon_instance)? flutterThrowErrorFromVoid, + required bool Function( + ProxyApiTestClass pigeon_instance, + bool aBool, + ) flutterEchoBool, + required int Function( + ProxyApiTestClass pigeon_instance, + int anInt, + ) flutterEchoInt, + required double Function( + ProxyApiTestClass pigeon_instance, + double aDouble, + ) flutterEchoDouble, + required String Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoString, + required Uint8List Function( + ProxyApiTestClass pigeon_instance, + Uint8List aList, + ) flutterEchoUint8List, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoList, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoProxyApiList, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoMap, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoProxyApiMap, + required ProxyApiTestEnum Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum anEnum, + ) flutterEchoEnum, + required ProxyApiSuperClass Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass aProxyApi, + ) flutterEchoProxyApi, + bool? Function( + ProxyApiTestClass pigeon_instance, + bool? aBool, + )? flutterEchoNullableBool, + int? Function( + ProxyApiTestClass pigeon_instance, + int? anInt, + )? flutterEchoNullableInt, + double? Function( + ProxyApiTestClass pigeon_instance, + double? aDouble, + )? flutterEchoNullableDouble, + String? Function( + ProxyApiTestClass pigeon_instance, + String? aString, + )? flutterEchoNullableString, + Uint8List? Function( + ProxyApiTestClass pigeon_instance, + Uint8List? aList, + )? flutterEchoNullableUint8List, + List? Function( + ProxyApiTestClass pigeon_instance, + List? aList, + )? flutterEchoNullableList, + Map? Function( + ProxyApiTestClass pigeon_instance, + Map? aMap, + )? flutterEchoNullableMap, + ProxyApiTestEnum? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum? anEnum, + )? flutterEchoNullableEnum, + ProxyApiSuperClass? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass? aProxyApi, + )? flutterEchoNullableProxyApi, + Future Function(ProxyApiTestClass pigeon_instance)? flutterNoopAsync, + required Future Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoAsyncString, + required bool boolParam, + required int intParam, + required double doubleParam, + required String stringParam, + required Uint8List aUint8ListParam, + required List listParam, + required Map mapParam, + required ProxyApiTestEnum enumParam, + required ProxyApiSuperClass proxyApiParam, + bool? nullableBoolParam, + int? nullableIntParam, + double? nullableDoubleParam, + String? nullableStringParam, + Uint8List? nullableUint8ListParam, + List? nullableListParam, + Map? nullableMapParam, + ProxyApiTestEnum? nullableEnumParam, + ProxyApiSuperClass? nullableProxyApiParam, + }) { + if (PigeonOverrides.proxyApiTestClass_new != null) { + return PigeonOverrides.proxyApiTestClass_new!( + aBool: aBool, + anInt: anInt, + aDouble: aDouble, + aString: aString, + aUint8List: aUint8List, + aList: aList, + aMap: aMap, + anEnum: anEnum, + aProxyApi: aProxyApi, + aNullableBool: aNullableBool, + aNullableInt: aNullableInt, + aNullableDouble: aNullableDouble, + aNullableString: aNullableString, + aNullableUint8List: aNullableUint8List, + aNullableList: aNullableList, + aNullableMap: aNullableMap, + aNullableEnum: aNullableEnum, + aNullableProxyApi: aNullableProxyApi, + anInterfaceMethod: anInterfaceMethod, + flutterNoop: flutterNoop, + flutterThrowError: flutterThrowError, + flutterThrowErrorFromVoid: flutterThrowErrorFromVoid, + flutterEchoBool: flutterEchoBool, + flutterEchoInt: flutterEchoInt, + flutterEchoDouble: flutterEchoDouble, + flutterEchoString: flutterEchoString, + flutterEchoUint8List: flutterEchoUint8List, + flutterEchoList: flutterEchoList, + flutterEchoProxyApiList: flutterEchoProxyApiList, + flutterEchoMap: flutterEchoMap, + flutterEchoProxyApiMap: flutterEchoProxyApiMap, + flutterEchoEnum: flutterEchoEnum, + flutterEchoProxyApi: flutterEchoProxyApi, + flutterEchoNullableBool: flutterEchoNullableBool, + flutterEchoNullableInt: flutterEchoNullableInt, + flutterEchoNullableDouble: flutterEchoNullableDouble, + flutterEchoNullableString: flutterEchoNullableString, + flutterEchoNullableUint8List: flutterEchoNullableUint8List, + flutterEchoNullableList: flutterEchoNullableList, + flutterEchoNullableMap: flutterEchoNullableMap, + flutterEchoNullableEnum: flutterEchoNullableEnum, + flutterEchoNullableProxyApi: flutterEchoNullableProxyApi, + flutterNoopAsync: flutterNoopAsync, + flutterEchoAsyncString: flutterEchoAsyncString, + boolParam: boolParam, + intParam: intParam, + doubleParam: doubleParam, + stringParam: stringParam, + aUint8ListParam: aUint8ListParam, + listParam: listParam, + mapParam: mapParam, + enumParam: enumParam, + proxyApiParam: proxyApiParam, + nullableBoolParam: nullableBoolParam, + nullableIntParam: nullableIntParam, + nullableDoubleParam: nullableDoubleParam, + nullableStringParam: nullableStringParam, + nullableUint8ListParam: nullableUint8ListParam, + nullableListParam: nullableListParam, + nullableMapParam: nullableMapParam, + nullableEnumParam: nullableEnumParam, + nullableProxyApiParam: nullableProxyApiParam, + ); + } + return ProxyApiTestClass.pigeon_new( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + aBool: aBool, + anInt: anInt, + aDouble: aDouble, + aString: aString, + aUint8List: aUint8List, + aList: aList, + aMap: aMap, + anEnum: anEnum, + aProxyApi: aProxyApi, + aNullableBool: aNullableBool, + aNullableInt: aNullableInt, + aNullableDouble: aNullableDouble, + aNullableString: aNullableString, + aNullableUint8List: aNullableUint8List, + aNullableList: aNullableList, + aNullableMap: aNullableMap, + aNullableEnum: aNullableEnum, + aNullableProxyApi: aNullableProxyApi, + anInterfaceMethod: anInterfaceMethod, + flutterNoop: flutterNoop, + flutterThrowError: flutterThrowError, + flutterThrowErrorFromVoid: flutterThrowErrorFromVoid, + flutterEchoBool: flutterEchoBool, + flutterEchoInt: flutterEchoInt, + flutterEchoDouble: flutterEchoDouble, + flutterEchoString: flutterEchoString, + flutterEchoUint8List: flutterEchoUint8List, + flutterEchoList: flutterEchoList, + flutterEchoProxyApiList: flutterEchoProxyApiList, + flutterEchoMap: flutterEchoMap, + flutterEchoProxyApiMap: flutterEchoProxyApiMap, + flutterEchoEnum: flutterEchoEnum, + flutterEchoProxyApi: flutterEchoProxyApi, + flutterEchoNullableBool: flutterEchoNullableBool, + flutterEchoNullableInt: flutterEchoNullableInt, + flutterEchoNullableDouble: flutterEchoNullableDouble, + flutterEchoNullableString: flutterEchoNullableString, + flutterEchoNullableUint8List: flutterEchoNullableUint8List, + flutterEchoNullableList: flutterEchoNullableList, + flutterEchoNullableMap: flutterEchoNullableMap, + flutterEchoNullableEnum: flutterEchoNullableEnum, + flutterEchoNullableProxyApi: flutterEchoNullableProxyApi, + flutterNoopAsync: flutterNoopAsync, + flutterEchoAsyncString: flutterEchoAsyncString, + boolParam: boolParam, + intParam: intParam, + doubleParam: doubleParam, + stringParam: stringParam, + aUint8ListParam: aUint8ListParam, + listParam: listParam, + mapParam: mapParam, + enumParam: enumParam, + proxyApiParam: proxyApiParam, + nullableBoolParam: nullableBoolParam, + nullableIntParam: nullableIntParam, + nullableDoubleParam: nullableDoubleParam, + nullableStringParam: nullableStringParam, + nullableUint8ListParam: nullableUint8ListParam, + nullableListParam: nullableListParam, + nullableMapParam: nullableMapParam, + nullableEnumParam: nullableEnumParam, + nullableProxyApiParam: nullableProxyApiParam, + ); + } + + @protected + ProxyApiTestClass.pigeon_new({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, required this.aBool, @@ -589,7 +1133,217 @@ class ProxyApiTestClass extends ProxyApiSuperClass }(); } - ProxyApiTestClass.namedConstructor({ + factory ProxyApiTestClass.namedConstructor({ + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + required bool aBool, + required int anInt, + required double aDouble, + required String aString, + required Uint8List aUint8List, + required List aList, + required Map aMap, + required ProxyApiTestEnum anEnum, + required ProxyApiSuperClass aProxyApi, + bool? aNullableBool, + int? aNullableInt, + double? aNullableDouble, + String? aNullableString, + Uint8List? aNullableUint8List, + List? aNullableList, + Map? aNullableMap, + ProxyApiTestEnum? aNullableEnum, + ProxyApiSuperClass? aNullableProxyApi, + void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod, + void Function(ProxyApiTestClass pigeon_instance)? flutterNoop, + Object? Function(ProxyApiTestClass pigeon_instance)? flutterThrowError, + void Function(ProxyApiTestClass pigeon_instance)? flutterThrowErrorFromVoid, + required bool Function( + ProxyApiTestClass pigeon_instance, + bool aBool, + ) flutterEchoBool, + required int Function( + ProxyApiTestClass pigeon_instance, + int anInt, + ) flutterEchoInt, + required double Function( + ProxyApiTestClass pigeon_instance, + double aDouble, + ) flutterEchoDouble, + required String Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoString, + required Uint8List Function( + ProxyApiTestClass pigeon_instance, + Uint8List aList, + ) flutterEchoUint8List, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoList, + required List Function( + ProxyApiTestClass pigeon_instance, + List aList, + ) flutterEchoProxyApiList, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoMap, + required Map Function( + ProxyApiTestClass pigeon_instance, + Map aMap, + ) flutterEchoProxyApiMap, + required ProxyApiTestEnum Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum anEnum, + ) flutterEchoEnum, + required ProxyApiSuperClass Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass aProxyApi, + ) flutterEchoProxyApi, + bool? Function( + ProxyApiTestClass pigeon_instance, + bool? aBool, + )? flutterEchoNullableBool, + int? Function( + ProxyApiTestClass pigeon_instance, + int? anInt, + )? flutterEchoNullableInt, + double? Function( + ProxyApiTestClass pigeon_instance, + double? aDouble, + )? flutterEchoNullableDouble, + String? Function( + ProxyApiTestClass pigeon_instance, + String? aString, + )? flutterEchoNullableString, + Uint8List? Function( + ProxyApiTestClass pigeon_instance, + Uint8List? aList, + )? flutterEchoNullableUint8List, + List? Function( + ProxyApiTestClass pigeon_instance, + List? aList, + )? flutterEchoNullableList, + Map? Function( + ProxyApiTestClass pigeon_instance, + Map? aMap, + )? flutterEchoNullableMap, + ProxyApiTestEnum? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiTestEnum? anEnum, + )? flutterEchoNullableEnum, + ProxyApiSuperClass? Function( + ProxyApiTestClass pigeon_instance, + ProxyApiSuperClass? aProxyApi, + )? flutterEchoNullableProxyApi, + Future Function(ProxyApiTestClass pigeon_instance)? flutterNoopAsync, + required Future Function( + ProxyApiTestClass pigeon_instance, + String aString, + ) flutterEchoAsyncString, + }) { + if (PigeonOverrides.proxyApiTestClass_namedConstructor != null) { + return PigeonOverrides.proxyApiTestClass_namedConstructor!( + aBool: aBool, + anInt: anInt, + aDouble: aDouble, + aString: aString, + aUint8List: aUint8List, + aList: aList, + aMap: aMap, + anEnum: anEnum, + aProxyApi: aProxyApi, + aNullableBool: aNullableBool, + aNullableInt: aNullableInt, + aNullableDouble: aNullableDouble, + aNullableString: aNullableString, + aNullableUint8List: aNullableUint8List, + aNullableList: aNullableList, + aNullableMap: aNullableMap, + aNullableEnum: aNullableEnum, + aNullableProxyApi: aNullableProxyApi, + anInterfaceMethod: anInterfaceMethod, + flutterNoop: flutterNoop, + flutterThrowError: flutterThrowError, + flutterThrowErrorFromVoid: flutterThrowErrorFromVoid, + flutterEchoBool: flutterEchoBool, + flutterEchoInt: flutterEchoInt, + flutterEchoDouble: flutterEchoDouble, + flutterEchoString: flutterEchoString, + flutterEchoUint8List: flutterEchoUint8List, + flutterEchoList: flutterEchoList, + flutterEchoProxyApiList: flutterEchoProxyApiList, + flutterEchoMap: flutterEchoMap, + flutterEchoProxyApiMap: flutterEchoProxyApiMap, + flutterEchoEnum: flutterEchoEnum, + flutterEchoProxyApi: flutterEchoProxyApi, + flutterEchoNullableBool: flutterEchoNullableBool, + flutterEchoNullableInt: flutterEchoNullableInt, + flutterEchoNullableDouble: flutterEchoNullableDouble, + flutterEchoNullableString: flutterEchoNullableString, + flutterEchoNullableUint8List: flutterEchoNullableUint8List, + flutterEchoNullableList: flutterEchoNullableList, + flutterEchoNullableMap: flutterEchoNullableMap, + flutterEchoNullableEnum: flutterEchoNullableEnum, + flutterEchoNullableProxyApi: flutterEchoNullableProxyApi, + flutterNoopAsync: flutterNoopAsync, + flutterEchoAsyncString: flutterEchoAsyncString, + ); + } + return ProxyApiTestClass.pigeon_namedConstructor( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + aBool: aBool, + anInt: anInt, + aDouble: aDouble, + aString: aString, + aUint8List: aUint8List, + aList: aList, + aMap: aMap, + anEnum: anEnum, + aProxyApi: aProxyApi, + aNullableBool: aNullableBool, + aNullableInt: aNullableInt, + aNullableDouble: aNullableDouble, + aNullableString: aNullableString, + aNullableUint8List: aNullableUint8List, + aNullableList: aNullableList, + aNullableMap: aNullableMap, + aNullableEnum: aNullableEnum, + aNullableProxyApi: aNullableProxyApi, + anInterfaceMethod: anInterfaceMethod, + flutterNoop: flutterNoop, + flutterThrowError: flutterThrowError, + flutterThrowErrorFromVoid: flutterThrowErrorFromVoid, + flutterEchoBool: flutterEchoBool, + flutterEchoInt: flutterEchoInt, + flutterEchoDouble: flutterEchoDouble, + flutterEchoString: flutterEchoString, + flutterEchoUint8List: flutterEchoUint8List, + flutterEchoList: flutterEchoList, + flutterEchoProxyApiList: flutterEchoProxyApiList, + flutterEchoMap: flutterEchoMap, + flutterEchoProxyApiMap: flutterEchoProxyApiMap, + flutterEchoEnum: flutterEchoEnum, + flutterEchoProxyApi: flutterEchoProxyApi, + flutterEchoNullableBool: flutterEchoNullableBool, + flutterEchoNullableInt: flutterEchoNullableInt, + flutterEchoNullableDouble: flutterEchoNullableDouble, + flutterEchoNullableString: flutterEchoNullableString, + flutterEchoNullableUint8List: flutterEchoNullableUint8List, + flutterEchoNullableList: flutterEchoNullableList, + flutterEchoNullableMap: flutterEchoNullableMap, + flutterEchoNullableEnum: flutterEchoNullableEnum, + flutterEchoNullableProxyApi: flutterEchoNullableProxyApi, + flutterNoopAsync: flutterNoopAsync, + flutterEchoAsyncString: flutterEchoAsyncString, + ); + } + + @protected + ProxyApiTestClass.pigeon_namedConstructor({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, required this.aBool, @@ -1382,9 +2136,13 @@ class ProxyApiTestClass extends ProxyApiSuperClass late final ProxyApiSuperClass attachedField = pigeonVar_attachedField(); - static final ProxyApiSuperClass staticAttachedField = + static final ProxyApiSuperClass _staticAttachedField = pigeonVar_staticAttachedField(); + static ProxyApiSuperClass get staticAttachedField => + PigeonOverrides.proxyApiTestClass_staticAttachedField ?? + _staticAttachedField; + static void pigeon_setUpMessageHandlers({ bool pigeon_clearHandlers = false, BinaryMessenger? pigeon_binaryMessenger, @@ -4003,6 +4761,9 @@ class ProxyApiTestClass extends ProxyApiSuperClass BinaryMessenger? pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, }) async { + if (PigeonOverrides.proxyApiTestClass_staticNoop != null) { + return PigeonOverrides.proxyApiTestClass_staticNoop!(); + } final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); @@ -4036,6 +4797,9 @@ class ProxyApiTestClass extends ProxyApiSuperClass BinaryMessenger? pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, }) async { + if (PigeonOverrides.proxyApiTestClass_echoStaticString != null) { + return PigeonOverrides.proxyApiTestClass_echoStaticString!(aString); + } final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); @@ -4074,6 +4838,9 @@ class ProxyApiTestClass extends ProxyApiSuperClass BinaryMessenger? pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, }) async { + if (PigeonOverrides.proxyApiTestClass_staticAsyncNoop != null) { + return PigeonOverrides.proxyApiTestClass_staticAsyncNoop!(); + } final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = _PigeonInternalProxyApiBaseCodec( pigeon_instanceManager ?? PigeonInstanceManager.instance); @@ -4955,7 +5722,21 @@ class ProxyApiTestClass extends ProxyApiSuperClass /// ProxyApi to serve as a super class to the core ProxyApi class. class ProxyApiSuperClass extends PigeonInternalProxyApiBaseClass { - ProxyApiSuperClass({ + factory ProxyApiSuperClass({ + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + }) { + if (PigeonOverrides.proxyApiSuperClass_new != null) { + return PigeonOverrides.proxyApiSuperClass_new!(); + } + return ProxyApiSuperClass.pigeon_new( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } + + @protected + ProxyApiSuperClass.pigeon_new({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, }) { @@ -5219,7 +6000,21 @@ class ProxyApiInterface extends PigeonInternalProxyApiBaseClass { } class ClassWithApiRequirement extends PigeonInternalProxyApiBaseClass { - ClassWithApiRequirement({ + factory ClassWithApiRequirement({ + BinaryMessenger? pigeon_binaryMessenger, + PigeonInstanceManager? pigeon_instanceManager, + }) { + if (PigeonOverrides.classWithApiRequirement_new != null) { + return PigeonOverrides.classWithApiRequirement_new!(); + } + return ClassWithApiRequirement.pigeon_new( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } + + @protected + ClassWithApiRequirement.pigeon_new({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, }) { diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/proxy_api_overrides_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/proxy_api_overrides_test.dart new file mode 100644 index 00000000000..d3a1967d11b --- /dev/null +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/proxy_api_overrides_test.dart @@ -0,0 +1,65 @@ +// 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:flutter_test/flutter_test.dart'; +import 'package:shared_test_plugin_code/src/generated/proxy_api_tests.gen.dart'; + +void main() { + test('can override ProxyApi constructors', () { + PigeonOverrides.pigeon_reset(); + + final ProxyApiSuperClass instance = ProxyApiSuperClass.pigeon_detached(); + PigeonOverrides.proxyApiSuperClass_new = () => instance; + + expect(ProxyApiSuperClass(), instance); + }); + + test('can override ProxyApi static attached fields', () { + PigeonOverrides.pigeon_reset(); + + final ProxyApiSuperClass instance = ProxyApiSuperClass.pigeon_detached(); + PigeonOverrides.proxyApiTestClass_staticAttachedField = instance; + + expect(ProxyApiTestClass.staticAttachedField, instance); + }); + + test('can override ProxyApi static methods', () async { + PigeonOverrides.pigeon_reset(); + + PigeonOverrides.proxyApiTestClass_echoStaticString = (String value) async { + return value; + }; + + const String value = 'testString'; + expect(await ProxyApiTestClass.echoStaticString(value), value); + }); + + test('pigeon_reset sets constructor overrides to null', () { + PigeonOverrides.proxyApiSuperClass_new = + () => ProxyApiSuperClass.pigeon_detached(); + + PigeonOverrides.pigeon_reset(); + expect( + PigeonOverrides.proxyApiSuperClass_new, + isNull, + ); + }); + + test('pigeon_reset sets attached field overrides to null', () { + PigeonOverrides.proxyApiTestClass_staticAttachedField = + ProxyApiSuperClass.pigeon_detached(); + + PigeonOverrides.pigeon_reset(); + expect(PigeonOverrides.proxyApiTestClass_staticAttachedField, isNull); + }); + + test('pigeon_reset sets static method overrides to null', () { + PigeonOverrides.proxyApiTestClass_echoStaticString = (String value) async { + return value; + }; + + PigeonOverrides.pigeon_reset(); + expect(PigeonOverrides.proxyApiTestClass_echoStaticString, isNull); + }); +} diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index fc25e430e75..0c2d643267e 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: 25.5.0 # This must match the version in lib/src/generator_tools.dart +version: 26.0.0 # This must match the version in lib/src/generator_tools.dart environment: sdk: ^3.6.0 diff --git a/packages/pigeon/test/dart/proxy_api_test.dart b/packages/pigeon/test/dart/proxy_api_test.dart index ac72dfb07f1..d1bc8761065 100644 --- a/packages/pigeon/test/dart/proxy_api_test.dart +++ b/packages/pigeon/test/dart/proxy_api_test.dart @@ -98,7 +98,13 @@ void main() { expect( collapsedCode, contains( - r'Api.name({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, required this.someField, this.doSomethingElse, required Input input, })', + r'factory Api.name({ BinaryMessenger? pigeon_binaryMessenger, PigeonInstanceManager? pigeon_instanceManager, required int someField, String Function( Api pigeon_instance, Input input, )? doSomethingElse, required Input input, })', + ), + ); + expect( + collapsedCode, + contains( + r'Api.pigeon_name({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, required this.someField, this.doSomethingElse, required Input input, })', ), ); expect( @@ -459,7 +465,14 @@ void main() { expect( collapsedCode, contains( - r'Api({ super.pigeon_binaryMessenger, ' + r'factory Api({ BinaryMessenger? pigeon_binaryMessenger, ' + r'PigeonInstanceManager? pigeon_instanceManager, })', + ), + ); + expect( + collapsedCode, + contains( + r'Api.pigeon_new({ super.pigeon_binaryMessenger, ' r'super.pigeon_instanceManager, })', ), ); @@ -565,7 +578,20 @@ void main() { expect( collapsedCode, contains( - r'Api.name({ super.pigeon_binaryMessenger, ' + r'factory Api.name({ BinaryMessenger? pigeon_binaryMessenger, ' + r'PigeonInstanceManager? pigeon_instanceManager, ' + r'required int validType, ' + r'required AnEnum enumType, ' + r'required Api2 proxyApiType, ' + r'int? nullableValidType, ' + r'AnEnum? nullableEnumType, ' + r'Api2? nullableProxyApiType, })', + ), + ); + expect( + collapsedCode, + contains( + r'Api.pigeon_name({ super.pigeon_binaryMessenger, ' r'super.pigeon_instanceManager, ' r'required int validType, ' r'required AnEnum enumType, ' @@ -675,7 +701,20 @@ void main() { expect( collapsedCode, contains( - r'Api.name({ super.pigeon_binaryMessenger, ' + r'factory Api.name({ BinaryMessenger? pigeon_binaryMessenger, ' + r'PigeonInstanceManager? pigeon_instanceManager, ' + r'required int validType, ' + r'required AnEnum enumType, ' + r'required Api2 proxyApiType, ' + r'int? nullableValidType, ' + r'AnEnum? nullableEnumType, ' + r'Api2? nullableProxyApiType, })', + ), + ); + expect( + collapsedCode, + contains( + r'Api.pigeon_name({ super.pigeon_binaryMessenger, ' r'super.pigeon_instanceManager, ' r'required this.validType, ' r'required this.enumType, ' @@ -806,7 +845,11 @@ void main() { final String code = sink.toString(); expect(code, contains('class Api')); expect( - code, contains(r'static final Api2 aField = pigeonVar_aField();')); + code, + contains( + r'static Api2 get aField => PigeonOverrides.api_aField ?? _aField;')); + expect( + code, contains(r'static final Api2 _aField = pigeonVar_aField();')); expect(code, contains(r'static Api2 pigeonVar_aField()')); }); });