diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 6e05728aa341..d403f0802a1c 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 16.0.1 + +* Adds support for `ProxyApi` generation only for Dart. + ## 16.0.0 * [java] Adds `VoidResult` type for `Void` returns. diff --git a/packages/pigeon/example/app/lib/src/messages.g.dart b/packages/pigeon/example/app/lib/src/messages.g.dart index 59213e4ef2bb..961e9c5856b5 100644 --- a/packages/pigeon/example/app/lib/src/messages.g.dart +++ b/packages/pigeon/example/app/lib/src/messages.g.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/lib/ast.dart b/packages/pigeon/lib/ast.dart index 9d79a781afbd..7b0e32511fae 100644 --- a/packages/pigeon/lib/ast.dart +++ b/packages/pigeon/lib/ast.dart @@ -29,7 +29,10 @@ class Method extends Node { required this.name, required this.returnType, required this.parameters, + required this.location, + this.required = false, this.isAsynchronous = false, + this.isStatic = false, this.offset, this.objcSelector = '', this.swiftFunction = '', @@ -68,6 +71,18 @@ class Method extends Node { /// For example: [" List of documentation comments, separated by line.", ...] List documentationComments; + /// Where the implementation of this method is located, host or Flutter. + ApiLocation location; + + /// Whether this method is required to be implemented. + /// + /// This flag is typically used to determine whether a callback method for + /// a `ProxyApi` is nullable or not. + bool required; + + /// Whether this is a static method of a ProxyApi. + bool isStatic; + @override String toString() { final String objcSelectorStr = @@ -78,29 +93,185 @@ class Method extends Node { } } -/// Represents a collection of [Method]s that are hosted on a given [location]. -class Api extends Node { +/// Represents a collection of [Method]s that are implemented on the platform +/// side. +class AstHostApi extends Api { + /// Parametric constructor for [AstHostApi]. + AstHostApi({ + required super.name, + required super.methods, + super.documentationComments = const [], + this.dartHostTestHandler, + }); + + /// The name of the Dart test interface to generate to help with testing. + String? dartHostTestHandler; + + @override + String toString() { + return '(HostApi name:$name methods:$methods documentationComments:$documentationComments dartHostTestHandler:$dartHostTestHandler)'; + } +} + +/// Represents a collection of [Method]s that are hosted on the Flutter side. +class AstFlutterApi extends Api { + /// Parametric constructor for [AstFlutterApi]. + AstFlutterApi({ + required super.name, + required super.methods, + super.documentationComments = const [], + }); + + @override + String toString() { + return '(FlutterApi name:$name methods:$methods documentationComments:$documentationComments)'; + } +} + +/// Represents an API that wraps a native class. +class AstProxyApi extends Api { + /// Parametric constructor for [AstProxyApi]. + AstProxyApi({ + required super.name, + required super.methods, + super.documentationComments = const [], + required this.constructors, + required this.fields, + this.superClassName, + this.interfacesNames = const {}, + }); + + /// List of constructors inside the API. + final List constructors; + + /// List of fields inside the API. + List fields; + + /// Name of the class this class considers the super class. + final String? superClassName; + + /// Name of the classes this class considers to be implemented. + final Set interfacesNames; + + /// Methods implemented in the host platform language. + Iterable get hostMethods => methods.where( + (Method method) => method.location == ApiLocation.host, + ); + + /// Methods implemented in Flutter. + Iterable get flutterMethods => methods.where( + (Method method) => method.location == ApiLocation.flutter, + ); + + /// All fields that are attached. + /// + /// See [attached]. + Iterable get attachedFields => fields.where( + (Field field) => field.isAttached, + ); + + /// All fields that are not attached. + /// + /// See [attached]. + Iterable get unattachedFields => fields.where( + (Field field) => !field.isAttached, + ); + + @override + String toString() { + return '(ProxyApi name:$name methods:$methods documentationComments:$documentationComments superClassName:$superClassName interfacesNames:$interfacesNames)'; + } +} + +/// Represents a constructor for an API. +class Constructor extends Node { + /// Parametric constructor for [Constructor]. + Constructor({ + required this.name, + required this.parameters, + this.offset, + this.swiftFunction = '', + this.documentationComments = const [], + }); + + /// The name of the method. + String name; + + /// The parameters passed into the [Constructor]. + List parameters; + + /// The offset in the source file where the field appears. + int? offset; + + /// An override for the generated swift function signature (ex. "divideNumber(_:by:)"). + String swiftFunction; + + /// List of documentation comments, separated by line. + /// + /// Lines should not include the comment marker itself, but should include any + /// leading whitespace, so that any indentation in the original comment is preserved. + /// For example: [" List of documentation comments, separated by line.", ...] + List documentationComments; + + @override + String toString() { + final String swiftFunctionStr = + swiftFunction.isEmpty ? '' : ' swiftFunction:$swiftFunction'; + return '(Constructor name:$name parameters:$parameters $swiftFunctionStr documentationComments:$documentationComments)'; + } +} + +/// Represents a field of an API. +class Field extends NamedType { + /// Constructor for [Field]. + Field({ + required super.name, + required super.type, + super.offset, + super.documentationComments, + this.isAttached = false, + this.isStatic = false, + }) : assert(!isStatic || isAttached); + + /// Whether this is an attached field for a [AstProxyApi]. + /// + /// See [attached]. + final bool isAttached; + + /// Whether this is a static field of a [AstProxyApi]. + /// + /// A static field must also be attached. See [attached]. + final bool isStatic; + + /// Returns a copy of [Parameter] instance with new attached [TypeDeclaration]. + @override + Field copyWithType(TypeDeclaration type) { + return Field( + name: name, + type: type, + offset: offset, + documentationComments: documentationComments, + isAttached: isAttached, + isStatic: isStatic, + ); + } +} + +/// Represents a collection of [Method]s. +sealed class Api extends Node { /// Parametric constructor for [Api]. Api({ required this.name, - required this.location, required this.methods, - this.dartHostTestHandler, this.documentationComments = const [], }); /// The name of the API. String name; - /// Where the API's implementation is located, host or Flutter. - ApiLocation location; - /// List of methods inside the API. List methods; - /// The name of the Dart test interface to generate to help with testing. - String? dartHostTestHandler; - /// List of documentation comments, separated by line. /// /// Lines should not include the comment marker itself, but should include any @@ -110,7 +281,7 @@ class Api extends Node { @override String toString() { - return '(Api name:$name location:$location methods:$methods documentationComments:$documentationComments)'; + return '(Api name:$name methods:$methods documentationComments:$documentationComments)'; } } @@ -123,6 +294,7 @@ class TypeDeclaration { required this.isNullable, this.associatedEnum, this.associatedClass, + this.associatedProxyApi, this.typeArguments = const [], }); @@ -132,6 +304,7 @@ class TypeDeclaration { isNullable = false, associatedEnum = null, associatedClass = null, + associatedProxyApi = null, typeArguments = const []; /// The base name of the [TypeDeclaration] (ex 'Foo' to 'Foo?'). @@ -158,6 +331,12 @@ class TypeDeclaration { /// Associated [Class], if any. final Class? associatedClass; + /// Associated [AstProxyApi], if any. + final AstProxyApi? associatedProxyApi; + + /// Whether the [TypeDeclaration] has an [associatedProxyApi]. + bool get isProxyApi => associatedProxyApi != null; + @override int get hashCode { // This has to be implemented because TypeDeclaration is used as a Key to a @@ -207,11 +386,21 @@ class TypeDeclaration { ); } + /// Returns duplicated `TypeDeclaration` with attached `associatedProxyApi` value. + TypeDeclaration copyWithProxyApi(AstProxyApi proxyApiDefinition) { + return TypeDeclaration( + baseName: baseName, + isNullable: isNullable, + associatedProxyApi: proxyApiDefinition, + typeArguments: typeArguments, + ); + } + @override String toString() { final String typeArgumentsStr = typeArguments.isEmpty ? '' : 'typeArguments:$typeArguments'; - return '(TypeDeclaration baseName:$baseName isNullable:$isNullable$typeArgumentsStr isEnum:$isEnum isClass:$isClass)'; + return '(TypeDeclaration baseName:$baseName isNullable:$isNullable$typeArgumentsStr isEnum:$isEnum isClass:$isClass isProxyApi:$isProxyApi)'; } } diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 5247f424052e..b9cb140f39d5 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart'; + import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; @@ -175,7 +177,7 @@ class CppHeaderGenerator extends StructuredGenerator { indent, anEnum.documentationComments, _docCommentSpec); indent.write('enum class ${anEnum.name} '); indent.addScoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { + anEnum.members.forEachIndexed((int index, EnumMember member) { addDocumentationComments( indent, member.documentationComments, _docCommentSpec); indent.writeln( @@ -191,14 +193,21 @@ class CppHeaderGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final bool hasHostApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.host); - final bool hasFlutterApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.flutter); + final bool hasHostApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); + final bool hasFlutterApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); _writeFlutterError(indent); if (hasHostApi) { - _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); + _writeErrorOr( + indent, + friends: root.apis + .where((Api api) => api is AstFlutterApi || api is AstHostApi) + .map((Api api) => api.name), + ); } if (hasFlutterApi) { // Nothing yet. @@ -291,7 +300,8 @@ class CppHeaderGenerator extends StructuredGenerator { indent.writeln('friend class ${friend.name};'); } } - for (final Api api in root.apis) { + for (final Api api in root.apis + .where((Api api) => api is AstFlutterApi || api is AstHostApi)) { // TODO(gaaclarke): Find a way to be more precise with our // friendships. indent.writeln('friend class ${api.name};'); @@ -317,10 +327,9 @@ class CppHeaderGenerator extends StructuredGenerator { CppOptions generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.flutter); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(generatorOptions, root, indent, api); } @@ -349,7 +358,7 @@ class CppHeaderGenerator extends StructuredGenerator { return _flutterApiArgumentType(hostType); }); final Iterable argNames = - indexMap(func.parameters, _getArgumentName); + func.parameters.mapIndexed(_getArgumentName); final List parameters = [ ...map2(argTypes, argNames, (String x, String y) => '$x $y'), ..._flutterApiCallbackParameters(returnType), @@ -370,10 +379,9 @@ class CppHeaderGenerator extends StructuredGenerator { CppOptions generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.host); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(generatorOptions, root, indent, api); } @@ -775,9 +783,10 @@ class CppSourceGenerator extends StructuredGenerator { returnType: classDefinition.name, parameters: ['const EncodableList& list'], body: () { const String instanceVariable = 'decoded'; - final Iterable<_IndexedField> indexedFields = indexMap( - getFieldsInSerializationOrder(classDefinition), - (int index, NamedType field) => _IndexedField(index, field)); + final Iterable<_IndexedField> indexedFields = + getFieldsInSerializationOrder(classDefinition).mapIndexed( + (int index, NamedType field) => _IndexedField(index, field)); + final Iterable<_IndexedField> nullableFields = indexedFields .where((_IndexedField field) => field.field.type.isNullable); final Iterable<_IndexedField> nonNullableFields = indexedFields @@ -823,10 +832,9 @@ class CppSourceGenerator extends StructuredGenerator { CppOptions generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.flutter); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(generatorOptions, root, indent, api); } @@ -852,7 +860,7 @@ class CppSourceGenerator extends StructuredGenerator { // Determine the input parameter list, saved in a structured form for later // use as platform channel call arguments. final Iterable<_HostNamedType> hostParameters = - indexMap(func.parameters, (int i, NamedType arg) { + func.parameters.mapIndexed((int i, NamedType arg) { final HostDatatype hostType = getFieldHostDatatype(arg, _shortBaseCppTypeForBuiltinDartType); return _HostNamedType(_getSafeArgumentName(i, arg), hostType, arg.type); @@ -937,10 +945,9 @@ class CppSourceGenerator extends StructuredGenerator { CppOptions generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.host); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(generatorOptions, root, indent, api); } @@ -981,7 +988,7 @@ class CppSourceGenerator extends StructuredGenerator { indent.writeln( 'const auto& args = std::get(message);'); - enumerate(method.parameters, (int index, NamedType arg) { + method.parameters.forEachIndexed((int index, NamedType arg) { final HostDatatype hostType = getHostDatatype( arg.type, (TypeDeclaration x) => @@ -1678,7 +1685,7 @@ void _writeFunction( indent.add('(${parameters.first})'); } else { indent.addScoped('(', null, () { - enumerate(parameters, (int index, final String param) { + parameters.forEachIndexed((int index, final String param) { if (index == parameters.length - 1) { indent.write('$param)'); } else { diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 52e2d0e68d95..9b9ea5afbe12 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -2,6 +2,9 @@ // 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 'package:path/path.dart' as path; import 'ast.dart'; @@ -94,7 +97,7 @@ class DartGenerator extends StructuredGenerator { indent.writeln('// ${getGeneratedCodeWarning()}'); indent.writeln('// $seeAlsoWarning'); indent.writeln( - '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers', + '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types', ); indent.newln(); } @@ -111,9 +114,19 @@ class DartGenerator extends StructuredGenerator { "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", ); indent.newln(); - indent.writeln( - "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); + if (root.apis.any((Api api) => api is AstProxyApi)) { + indent.writeln( + "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer, immutable, protected;"); + } else { + indent.writeln( + "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); + } indent.writeln("import 'package:flutter/services.dart';"); + if (root.apis.any((Api api) => api is AstProxyApi)) { + indent.writeln( + "import 'package:flutter/widgets.dart' show WidgetsFlutterBinding;", + ); + } } @override @@ -288,8 +301,8 @@ $resultAt != null indent.writeln('result as List;'); indent.write('return ${classDefinition.name}'); indent.addScoped('(', ');', () { - enumerate(getFieldsInSerializationOrder(classDefinition), - (int index, final NamedType field) { + getFieldsInSerializationOrder(classDefinition) + .forEachIndexed((int index, final NamedType field) { indent.write('${field.name}: '); writeValueDecode(field, index); indent.addln(','); @@ -312,12 +325,11 @@ $resultAt != null DartOptions generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { String Function(Method)? channelNameFunc, bool isMockHandler = false, required String dartPackageName, }) { - assert(api.location == ApiLocation.flutter); String codecName = _standardMessageCodec; if (getCodecClasses(api, root).isNotEmpty) { codecName = _getCodecName(api); @@ -344,7 +356,9 @@ $resultAt != null final String returnType = isAsync ? 'Future<${_addGenericTypesNullable(func.returnType)}>' : _addGenericTypesNullable(func.returnType); - final String argSignature = _getMethodParameterSignature(func); + final String argSignature = _getMethodParameterSignature( + func.parameters, + ); indent.writeln('$returnType ${func.name}($argSignature);'); indent.newln(); } @@ -352,115 +366,17 @@ $resultAt != null 'static void setup(${api.name}? api, {BinaryMessenger? binaryMessenger}) '); indent.addScoped('{', '}', () { for (final Method func in api.methods) { - indent.write(''); - indent.addScoped('{', '}', () { - indent.writeln( - 'final BasicMessageChannel ${_varNamePrefix}channel = BasicMessageChannel(', - ); - final String channelName = channelNameFunc == null + _writeFlutterMethodMessageHandler( + indent, + name: func.name, + parameters: func.parameters, + returnType: func.returnType, + channelName: channelNameFunc == null ? makeChannelName(api, func, dartPackageName) - : channelNameFunc(func); - indent.nest(2, () { - indent.writeln("'$channelName', $_pigeonChannelCodec,"); - indent.writeln( - 'binaryMessenger: binaryMessenger);', - ); - }); - final String messageHandlerSetterWithOpeningParentheses = isMockHandler - ? '_testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(${_varNamePrefix}channel, ' - : '${_varNamePrefix}channel.setMessageHandler('; - indent.write('if (api == null) '); - indent.addScoped('{', '}', () { - indent.writeln( - '${messageHandlerSetterWithOpeningParentheses}null);'); - }, addTrailingNewline: false); - indent.add(' else '); - indent.addScoped('{', '}', () { - indent.write( - '$messageHandlerSetterWithOpeningParentheses(Object? message) async ', - ); - indent.addScoped('{', '});', () { - final String returnType = - _addGenericTypesNullable(func.returnType); - final bool isAsync = func.isAsynchronous; - const String emptyReturnStatement = - 'return wrapResponse(empty: true);'; - String call; - if (func.parameters.isEmpty) { - call = 'api.${func.name}()'; - } else { - indent.writeln('assert(message != null,'); - indent.writeln("'Argument for $channelName was null.');"); - const String argsArray = 'args'; - indent.writeln( - 'final List $argsArray = (message as List?)!;'); - String argNameFunc(int index, NamedType type) => - _getSafeArgumentName(index, type); - enumerate(func.parameters, (int count, NamedType arg) { - final String argType = _addGenericTypes(arg.type); - final String argName = argNameFunc(count, arg); - final String genericArgType = - _makeGenericTypeArguments(arg.type); - final String castCall = _makeGenericCastCall(arg.type); - - final String leftHandSide = 'final $argType? $argName'; - if (arg.type.isEnum) { - indent.writeln( - '$leftHandSide = $argsArray[$count] == null ? null : $argType.values[$argsArray[$count]! as int];'); - } else { - indent.writeln( - '$leftHandSide = ($argsArray[$count] as $genericArgType?)${castCall.isEmpty ? '' : '?$castCall'};'); - } - if (!arg.type.isNullable) { - indent.writeln('assert($argName != null,'); - indent.writeln( - " 'Argument for $channelName was null, expected non-null $argType.');"); - } - }); - final Iterable argNames = - indexMap(func.parameters, (int index, Parameter field) { - final String name = _getSafeArgumentName(index, field); - return '${field.isNamed ? '${field.name}: ' : ''}$name${field.type.isNullable ? '' : '!'}'; - }); - call = 'api.${func.name}(${argNames.join(', ')})'; - } - indent.writeScoped('try {', '} ', () { - if (func.returnType.isVoid) { - if (isAsync) { - indent.writeln('await $call;'); - } else { - indent.writeln('$call;'); - } - indent.writeln(emptyReturnStatement); - } else { - if (isAsync) { - indent.writeln('final $returnType output = await $call;'); - } else { - indent.writeln('final $returnType output = $call;'); - } - - const String returnExpression = 'output'; - final String nullability = - func.returnType.isNullable ? '?' : ''; - final String valueExtraction = - func.returnType.isEnum ? '$nullability.index' : ''; - final String returnStatement = isMockHandler - ? 'return [$returnExpression$valueExtraction];' - : 'return wrapResponse(result: $returnExpression$valueExtraction);'; - indent.writeln(returnStatement); - } - }, addTrailingNewline: false); - indent.addScoped('on PlatformException catch (e) {', '}', () { - indent.writeln('return wrapResponse(error: e);'); - }, addTrailingNewline: false); - - indent.writeScoped('catch (e) {', '}', () { - indent.writeln( - "return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));"); - }); - }); - }); - }); + : channelNameFunc(func), + isMockHandler: isMockHandler, + isAsynchronous: func.isAsynchronous, + ); } }); }); @@ -488,10 +404,9 @@ $resultAt != null DartOptions generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.host); String codecName = _standardMessageCodec; if (getCodecClasses(api, root).isNotEmpty) { codecName = _getCodecName(api); @@ -521,92 +436,1264 @@ final BinaryMessenger? ${_varNamePrefix}binaryMessenger; } else { first = false; } - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - String argSignature = ''; - String sendArgument = 'null'; - if (func.parameters.isNotEmpty) { - final Iterable argExpressions = - indexMap(func.parameters, (int index, NamedType type) { - final String name = _getParameterName(index, type); - if (type.type.isEnum) { - return '$name${type.type.isNullable ? '?' : ''}.index'; - } else { - return name; - } - }); - sendArgument = '[${argExpressions.join(', ')}]'; - argSignature = _getMethodParameterSignature(func); - } - indent.write( - 'Future<${_addGenericTypesNullable(func.returnType)}> ${func.name}($argSignature) async ', + _writeHostMethod( + indent, + name: func.name, + parameters: func.parameters, + returnType: func.returnType, + documentationComments: func.documentationComments, + channelName: makeChannelName(api, func, dartPackageName), ); - indent.addScoped('{', '}', () { - indent.writeln( - "const String ${_varNamePrefix}channelName = '${makeChannelName(api, func, dartPackageName)}';"); - indent.writeScoped( - 'final BasicMessageChannel ${_varNamePrefix}channel = BasicMessageChannel(', - ');', () { - indent.writeln('${_varNamePrefix}channelName,'); - indent.writeln('$_pigeonChannelCodec,'); - indent - .writeln('binaryMessenger: ${_varNamePrefix}binaryMessenger,'); - }); - final String returnType = _makeGenericTypeArguments(func.returnType); - final String genericCastCall = _makeGenericCastCall(func.returnType); - const String accessor = '${_varNamePrefix}replyList[0]'; - // Avoid warnings from pointlessly casting to `Object?`. - final String nullablyTypedAccessor = - returnType == 'Object' ? accessor : '($accessor as $returnType?)'; - final String nullHandler = func.returnType.isNullable - ? (genericCastCall.isEmpty ? '' : '?') - : '!'; - String returnStatement = 'return'; - if (func.returnType.isEnum) { - if (func.returnType.isNullable) { - returnStatement = - '$returnStatement ($accessor as int?) == null ? null : $returnType.values[$accessor! as int]'; - } else { - returnStatement = - '$returnStatement $returnType.values[$accessor! as int]'; - } - } else if (!func.returnType.isVoid) { - returnStatement = - '$returnStatement $nullablyTypedAccessor$nullHandler$genericCastCall'; - } - returnStatement = '$returnStatement;'; + } + }); + } - indent.format(''' -final List? ${_varNamePrefix}replyList = -\t\tawait ${_varNamePrefix}channel.send($sendArgument) as List?; -if (${_varNamePrefix}replyList == null) { -\tthrow _createConnectionError(${_varNamePrefix}channelName); -} else if (${_varNamePrefix}replyList.length > 1) { -\tthrow PlatformException( -\t\tcode: ${_varNamePrefix}replyList[0]! as String, -\t\tmessage: ${_varNamePrefix}replyList[1] as String?, -\t\tdetails: ${_varNamePrefix}replyList[2], -\t);'''); - // On iOS we can return nil from functions to accommodate error - // handling. Returning a nil value and not returning an error is an - // exception. - if (!func.returnType.isNullable && !func.returnType.isVoid) { - indent.format(''' -} else if (${_varNamePrefix}replyList[0] == null) { -\tthrow PlatformException( -\t\tcode: 'null-error', -\t\tmessage: 'Host platform returned null value for non-null return value.', -\t);'''); - } - indent.format(''' -} else { -\t$returnStatement -}'''); - }); + @override + void writeInstanceManager( + DartOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + _writeProxyApiBaseClass(indent); + + const String proxyApiBaseClassName = '${classNamePrefix}ProxyApiBaseClass'; + final Iterable apiHandlerSetups = + root.apis.whereType().map( + (AstProxyApi api) { + return '${api.name}.${classMemberNamePrefix}setUpMessageHandlers(${classMemberNamePrefix}instanceManager: instanceManager);'; + }, + ); + indent.format(''' +/// Maintains instances used to communicate with the native objects they +/// represent. +/// +/// Added instances are stored as weak references and their copies are stored +/// as strong references to maintain access to their variables and callback +/// methods. Both are stored with the same identifier. +/// +/// When a weak referenced instance becomes inaccessible, +/// [onWeakReferenceRemoved] is called with its associated identifier. +/// +/// If an instance is retrieved and has the possibility to be used, +/// (e.g. calling [getInstanceWithWeakReference]) a copy of the strong reference +/// is added as a weak reference with the same identifier. This prevents a +/// scenario where the weak referenced instance was released and then later +/// returned by the host platform. +class $instanceManagerClassName { + /// Constructs a [$instanceManagerClassName]. + $instanceManagerClassName({required void Function(int) onWeakReferenceRemoved}) { + this.onWeakReferenceRemoved = (int identifier) { + _weakInstances.remove(identifier); + onWeakReferenceRemoved(identifier); + }; + _finalizer = Finalizer(this.onWeakReferenceRemoved); + } + + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously by the host platform. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + static const int _maxDartCreatedIdentifier = 65536; + + /// The default [$instanceManagerClassName] used by ProxyApis. + /// + /// On creation, this manager makes a call to clear the native + /// InstanceManager. This is to prevent identifier conflicts after a host + /// restart. + static final $instanceManagerClassName instance = _initInstance(); + + // Expando is used because it doesn't prevent its keys from becoming + // inaccessible. This allows the manager to efficiently retrieve an identifier + // of an instance without holding a strong reference to that instance. + // + // It also doesn't use `==` to search for identifiers, which would lead to an + // infinite loop when comparing an object to its copy. (i.e. which was caused + // by calling instanceManager.getIdentifier() inside of `==` while this was a + // HashMap). + final Expando _identifiers = Expando(); + final Map> _weakInstances = + >{}; + final Map _strongInstances = {}; + late final Finalizer _finalizer; + int _nextIdentifier = 0; + + /// Called when a weak referenced instance is removed by [removeWeakReference] + /// or becomes inaccessible. + late final void Function(int) onWeakReferenceRemoved; + + static $instanceManagerClassName _initInstance() { + WidgetsFlutterBinding.ensureInitialized(); + final _${instanceManagerClassName}Api api = _${instanceManagerClassName}Api(); + // Clears the native `$instanceManagerClassName` on the initial use of the Dart one. + api.clear(); + final $instanceManagerClassName instanceManager = $instanceManagerClassName( + onWeakReferenceRemoved: (int identifier) { + api.removeStrongReference(identifier); + }, + ); + _${instanceManagerClassName}Api.setUpMessageHandlers(instanceManager: instanceManager); + ${apiHandlerSetups.join('\n\t\t')} + return instanceManager; + } + + /// Adds a new instance that was instantiated by Dart. + /// + /// In other words, Dart wants to add a new instance that will represent + /// an object that will be instantiated on the host platform. + /// + /// Throws assertion error if the instance has already been added. + /// + /// Returns the randomly generated id of the [instance] added. + int addDartCreatedInstance($proxyApiBaseClassName instance) { + final int identifier = _nextUniqueIdentifier(); + _addInstanceWithIdentifier(instance, identifier); + return identifier; + } + + /// Removes the instance, if present, and call [onWeakReferenceRemoved] with + /// its identifier. + /// + /// Returns the identifier associated with the removed instance. Otherwise, + /// `null` if the instance was not found in this manager. + /// + /// This does not remove the strong referenced instance associated with + /// [instance]. This can be done with [remove]. + int? removeWeakReference($proxyApiBaseClassName instance) { + final int? identifier = getIdentifier(instance); + if (identifier == null) { + return null; + } + + _identifiers[instance] = null; + _finalizer.detach(instance); + onWeakReferenceRemoved(identifier); + + return identifier; + } + + /// Removes [identifier] and its associated strongly referenced instance, if + /// present, from the manager. + /// + /// Returns the strong referenced instance associated with [identifier] before + /// it was removed. Returns `null` if [identifier] was not associated with + /// any strong reference. + /// + /// This does not remove the weak referenced instance associated with + /// [identifier]. This can be done with [removeWeakReference]. + T? remove(int identifier) { + return _strongInstances.remove(identifier) as T?; + } + + /// Retrieves the instance associated with identifier. + /// + /// The value returned is chosen from the following order: + /// + /// 1. A weakly referenced instance associated with identifier. + /// 2. If the only instance associated with identifier is a strongly + /// referenced instance, a copy of the instance is added as a weak reference + /// with the same identifier. Returning the newly created copy. + /// 3. If no instance is associated with identifier, returns null. + /// + /// This method also expects the host `InstanceManager` to have a strong + /// reference to the instance the identifier is associated with. + T? getInstanceWithWeakReference(int identifier) { + final $proxyApiBaseClassName? weakInstance = _weakInstances[identifier]?.target; + + if (weakInstance == null) { + final $proxyApiBaseClassName? strongInstance = _strongInstances[identifier]; + if (strongInstance != null) { + final $proxyApiBaseClassName copy = strongInstance.${classMemberNamePrefix}copy(); + _identifiers[copy] = identifier; + _weakInstances[identifier] = WeakReference<$proxyApiBaseClassName>(copy); + _finalizer.attach(copy, identifier, detach: copy); + return copy as T; } + return strongInstance as T?; + } + + return weakInstance as T; + } + + /// Retrieves the identifier associated with instance. + int? getIdentifier($proxyApiBaseClassName instance) { + return _identifiers[instance]; + } + + /// Adds a new instance that was instantiated by the host platform. + /// + /// In other words, the host platform wants to add a new instance that + /// represents an object on the host platform. Stored with [identifier]. + /// + /// Throws assertion error if the instance or its identifier has already been + /// added. + /// + /// Returns unique identifier of the [instance] added. + void addHostCreatedInstance($proxyApiBaseClassName instance, int identifier) { + _addInstanceWithIdentifier(instance, identifier); + } + + void _addInstanceWithIdentifier($proxyApiBaseClassName instance, int identifier) { + assert(!containsIdentifier(identifier)); + assert(getIdentifier(instance) == null); + assert(identifier >= 0); + + _identifiers[instance] = identifier; + _weakInstances[identifier] = WeakReference<$proxyApiBaseClassName>(instance); + _finalizer.attach(instance, identifier, detach: instance); + + final $proxyApiBaseClassName copy = instance.${classMemberNamePrefix}copy(); + _identifiers[copy] = identifier; + _strongInstances[identifier] = copy; + } + + /// Whether this manager contains the given [identifier]. + bool containsIdentifier(int identifier) { + return _weakInstances.containsKey(identifier) || + _strongInstances.containsKey(identifier); + } + + int _nextUniqueIdentifier() { + late int identifier; + do { + identifier = _nextIdentifier; + _nextIdentifier = (_nextIdentifier + 1) % _maxDartCreatedIdentifier; + } while (containsIdentifier(identifier)); + return identifier; + } +} +'''); + } + + @override + void writeInstanceManagerApi( + DartOptions generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) { + const String apiName = '${instanceManagerClassName}Api'; + final String removeStrongReferenceName = makeChannelNameWithStrings( + apiName: apiName, + methodName: 'removeStrongReference', + dartPackageName: dartPackageName, + ); + final String clearName = makeChannelNameWithStrings( + apiName: apiName, + methodName: 'clear', + dartPackageName: dartPackageName, + ); + + indent.writeln(''' +/// Generated API for managing the Dart and native `$instanceManagerClassName`s. +class _$apiName { + /// Constructor for [_$apiName ]. + _$apiName({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec $_pigeonChannelCodec = + StandardMessageCodec(); + + static void setUpMessageHandlers({ + BinaryMessenger? binaryMessenger, + $instanceManagerClassName? instanceManager, + }) { + const String channelName = + r'$removeStrongReferenceName'; + final BasicMessageChannel channel = BasicMessageChannel( + channelName, + $_pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); + channel.setMessageHandler((Object? message) async { + assert( + message != null, + 'Argument for \$channelName was null.', + ); + final int? identifier = message as int?; + assert( + identifier != null, + r'Argument for \$channelName, expected non-null int.', + ); + (instanceManager ?? $instanceManagerClassName.instance).remove(identifier!); + return; }); } + Future removeStrongReference(int identifier) async { + const String channelName = + r'$removeStrongReferenceName'; + final BasicMessageChannel channel = BasicMessageChannel( + channelName, + $_pigeonChannelCodec, + binaryMessenger: _binaryMessenger, + ); + final List? replyList = + await channel.send(identifier) as List?; + if (replyList == null) { + throw _createConnectionError(channelName); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + /// Clear the native `$instanceManagerClassName`. + /// + /// This is typically called after a hot restart. + Future clear() async { + const String channelName = + r'$clearName'; + final BasicMessageChannel channel = BasicMessageChannel( + channelName, + $_pigeonChannelCodec, + binaryMessenger: _binaryMessenger, + ); + final List? replyList = await channel.send(null) as List?; + if (replyList == null) { + throw _createConnectionError(channelName); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } +}'''); + } + + @override + void writeProxyApiBaseCodec( + DartOptions generatorOptions, + Root root, + Indent indent, + ) { + const String codecName = '_${classNamePrefix}ProxyApiBaseCodec'; + + indent.writeln(''' +class $codecName extends StandardMessageCodec { + const $codecName(this.instanceManager); + + final $instanceManagerClassName instanceManager; + + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is ${classNamePrefix}ProxyApiBaseClass) { + buffer.putUint8(128); + writeValue(buffer, instanceManager.getIdentifier(value)); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return instanceManager + .getInstanceWithWeakReference(readValue(buffer)! as int); + default: + return super.readValueOfType(type, buffer); + } + } +} +'''); + } + + @override + void writeProxyApi( + DartOptions generatorOptions, + Root root, + Indent indent, + AstProxyApi api, { + required String dartPackageName, + }) { + const String codecName = '_${classNamePrefix}ProxyApiBaseCodec'; + + // Each api has an private codec instance used by every host method. + // constructor, or non-static field. + final String codecInstanceName = '${_varNamePrefix}codec${api.name}'; + + final Iterable allProxyApis = + root.apis.whereType(); + + // A list of ProxyApis where each `extends` the API that follows it. + final List superClassApisChain = + recursiveGetSuperClassApisChain( + api, + allProxyApis, + ); + + // The proxy api this api `extends` if it exists. + final AstProxyApi? superClassApi = + superClassApisChain.isNotEmpty ? superClassApisChain.first : null; + + // All ProxyApis this API `implements` and all the interfaces those APIs + // `implements`. + final Set interfacesApis = recursiveFindAllInterfacesApis( + api, + allProxyApis, + ); + + // All methods inherited from interfaces and the interfaces of interfaces. + final List interfacesMethods = []; + for (final AstProxyApi proxyApi in interfacesApis) { + interfacesMethods.addAll(proxyApi.methods); + } + + // 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`. + final List superClassFlutterMethods = []; + if (superClassApi != null) { + for (final AstProxyApi proxyApi in superClassApisChain) { + superClassFlutterMethods.addAll(proxyApi.flutterMethods); + } + + final Set superClassInterfacesApis = + recursiveFindAllInterfacesApis( + superClassApi, + allProxyApis, + ); + for (final AstProxyApi proxyApi in superClassInterfacesApis) { + superClassFlutterMethods.addAll(proxyApi.methods); + } + } + + // Ast class used by code_builder. + final cb.Class proxyApi = cb.Class( + (cb.ClassBuilder builder) => builder + ..name = api.name + ..extend = superClassApi != null + ? cb.refer(superClassApi.name) + : cb.refer('${classNamePrefix}ProxyApiBaseClass') + ..implements.addAll([ + if (api.interfacesNames.isNotEmpty) + ...api.interfacesNames.map((String name) => cb.refer(name)) + ]) + ..docs.addAll(asDocumentationComments( + api.documentationComments, + _docCommentSpec, + )) + ..constructors.addAll(_proxyApiConstructors( + api.constructors, + apiName: api.name, + dartPackageName: dartPackageName, + codecName: codecName, + codecInstanceName: codecInstanceName, + superClassApi: superClassApi, + unattachedFields: api.unattachedFields, + superClassFlutterMethods: superClassFlutterMethods, + interfacesMethods: interfacesMethods, + flutterMethods: api.flutterMethods, + )) + ..fields.addAll(_proxyApiFields( + unattachedFields: api.unattachedFields, + attachedFields: api.attachedFields, + apiName: api.name, + dartPackageName: dartPackageName, + codecInstanceName: codecInstanceName, + codecName: codecName, + interfacesApis: interfacesApis, + flutterMethods: api.flutterMethods, + referencesCodecInstance: api.hostMethods.isNotEmpty || + api.constructors.isNotEmpty || + api.attachedFields.any((Field field) => !field.isStatic), + )) + ..methods.addAll(_proxyApiMethods( + hostMethods: api.hostMethods, + flutterMethods: api.flutterMethods, + superClassFlutterMethods: superClassFlutterMethods, + apiName: api.name, + dartPackageName: dartPackageName, + codecInstanceName: codecInstanceName, + codecName: codecName, + unattachedFields: api.unattachedFields, + attachedFields: api.attachedFields, + interfacesApis: interfacesApis, + hasCallbackConstructor: api.methods + .followedBy(superClassFlutterMethods) + .followedBy(interfacesMethods) + .every( + (Method method) { + return method.location != ApiLocation.flutter || !method.required; + }, + ), + )), + ); + + final cb.DartEmitter emitter = cb.DartEmitter(useNullSafetySyntax: true); + indent.write(DartFormatter().format('${proxyApi.accept(emitter)}')); + } + + Iterable _proxyApiConstructors( + Iterable constructors, { + required String apiName, + required String dartPackageName, + required String codecName, + required String codecInstanceName, + required AstProxyApi? superClassApi, + required Iterable unattachedFields, + required Iterable superClassFlutterMethods, + required Iterable interfacesMethods, + required Iterable flutterMethods, + }) { + 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 = '${classMemberNamePrefix}instanceManager' + ..named = true + ..toSuper = true, + ); + return [ + // All constructors for this api defined in the pigeon file. + ...constructors.map( + (Constructor constructor) => cb.Constructor( + (cb.ConstructorBuilder builder) { + final String channelName = makeChannelNameWithStrings( + apiName: apiName, + methodName: constructor.name.isNotEmpty + ? constructor.name + : '${classMemberNamePrefix}defaultConstructor', + dartPackageName: dartPackageName, + ); + builder + ..name = constructor.name.isNotEmpty ? constructor.name : null + ..docs.addAll(asDocumentationComments( + constructor.documentationComments, + _docCommentSpec, + )) + ..optionalParameters.addAll( + [ + binaryMessengerParameter, + instanceManagerParameter, + for (final Field 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 superClassFlutterMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..toSuper = true + ..required = method.required, + ), + for (final Method method in interfacesMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..toThis = true + ..required = method.required, + ), + for (final Method method in flutterMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..toThis = true + ..required = method.required, + ), + ...constructor.parameters.mapIndexed( + (int index, NamedType parameter) => cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = _getParameterName(index, parameter) + ..type = cb.refer( + _addGenericTypesNullable(parameter.type), + ) + ..named = true + ..required = !parameter.type.isNullable, + ), + ) + ], + ) + ..initializers.addAll( + [ + if (superClassApi != null) + const cb.Code('super.${classMemberNamePrefix}detached()') + ], + ) + ..body = cb.Block( + (cb.BlockBuilder builder) { + final StringBuffer messageCallSink = StringBuffer(); + _writeHostMethodMessageCall( + Indent(messageCallSink), + channelName: channelName, + parameters: [ + Parameter( + name: '${_varNamePrefix}instanceIdentifier', + type: const TypeDeclaration( + baseName: 'int', isNullable: false), + ), + ...unattachedFields.map( + (Field field) => Parameter( + name: field.name, + type: field.type, + ), + ), + ...constructor.parameters, + ], + returnType: const TypeDeclaration.voidDeclaration(), + ); + builder.statements.addAll([ + const cb.Code( + 'final int ${_varNamePrefix}instanceIdentifier = ${classMemberNamePrefix}instanceManager.addDartCreatedInstance(this);', + ), + cb.Code('final $codecName $_pigeonChannelCodec =\n' + ' $codecInstanceName;'), + cb.Code( + 'final BinaryMessenger? ${_varNamePrefix}binaryMessenger = ${binaryMessengerParameter.name};', + ), + const cb.Code('() async {'), + cb.Code(messageCallSink.toString()), + const cb.Code('}();'), + ]); + }, + ); + }, + ), + ), + // The detached constructor present for every ProxyApi. This constructor + // doesn't include a host method call to create a new native class + // instance. It is mainly used when the native side once to create a Dart + // instance and when the `InstanceManager` wants to create a copy for + // garbage collection. + cb.Constructor( + (cb.ConstructorBuilder builder) => builder + ..name = '${classMemberNamePrefix}detached' + ..docs.addAll([ + '/// Constructs $apiName without creating the associated native object.', + '///', + '/// This should only be used by subclasses created by this library or to', + '/// create copies.', + ]) + ..optionalParameters.addAll([ + binaryMessengerParameter, + instanceManagerParameter, + for (final Field 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 superClassFlutterMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..toSuper = true + ..required = method.required, + ), + for (final Method method in interfacesMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..toThis = true + ..required = method.required, + ), + for (final Method method in flutterMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..named = true + ..toThis = true + ..required = method.required, + ), + ]) + ..initializers.addAll([ + if (superClassApi != null) + const cb.Code('super.${classMemberNamePrefix}detached()'), + ]), + ), + ]; + } + + Iterable _proxyApiFields({ + required Iterable unattachedFields, + required Iterable attachedFields, + required String apiName, + required String dartPackageName, + required String codecInstanceName, + required String codecName, + required Iterable interfacesApis, + required Iterable flutterMethods, + required bool referencesCodecInstance, + }) { + return [ + if (referencesCodecInstance) + cb.Field( + (cb.FieldBuilder builder) => builder + ..name = codecInstanceName + ..type = cb.refer(codecName) + ..late = true + ..modifier = cb.FieldModifier.final$ + ..assignment = + cb.Code('$codecName(${classMemberNamePrefix}instanceManager)'), + ), + for (final Field field in unattachedFields) + cb.Field( + (cb.FieldBuilder builder) => builder + ..name = field.name + ..type = cb.refer(_addGenericTypesNullable(field.type)) + ..modifier = cb.FieldModifier.final$ + ..docs.addAll(asDocumentationComments( + field.documentationComments, + _docCommentSpec, + )), + ), + for (final Method method in flutterMethods) + cb.Field( + (cb.FieldBuilder builder) => builder + ..name = method.name + ..modifier = cb.FieldModifier.final$ + ..docs.addAll(asDocumentationComments( + [ + ...method.documentationComments, + ...[ + if (method.documentationComments.isNotEmpty) '', + 'Dart:', + 'For the associated Native object to be automatically garbage collected,', + "it is required that the implementation of this `Function` doesn't have a", + 'strong reference to the encapsulating class instance. When this `Function`', + 'references a non-local variable, it is strongly recommended to access it', + 'from a `WeakReference`:', + '', + '```dart', + 'final WeakReference weakMyVariable = WeakReference(myVariable);', + 'final $apiName instance = $apiName(', + ' ${method.name}: ($apiName ${classMemberNamePrefix}instance, ...) {', + ' print(weakMyVariable?.target);', + ' },', + ');', + '```', + '', + 'Alternatively, `$instanceManagerClassName.removeWeakReference` can be used to', + 'release the associated Native object manually.', + ], + ], + _docCommentSpec, + )) + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = _refer( + _addGenericTypesNullable(method.returnType), + isFuture: method.isAsynchronous, + ) + ..isNullable = !method.required + ..requiredParameters.addAll([ + cb.refer('$apiName ${classMemberNamePrefix}instance'), + ...method.parameters.mapIndexed( + (int index, NamedType parameter) { + return cb.refer( + '${_addGenericTypesNullable(parameter.type)} ${_getParameterName(index, parameter)}', + ); + }, + ), + ]), + ), + ), + for (final AstProxyApi proxyApi in interfacesApis) + for (final Method method in proxyApi.methods) + cb.Field( + (cb.FieldBuilder builder) => builder + ..name = method.name + ..modifier = cb.FieldModifier.final$ + ..annotations.add(cb.refer('override')) + ..docs.addAll(asDocumentationComments( + method.documentationComments, _docCommentSpec)) + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = _refer( + _addGenericTypesNullable(method.returnType), + isFuture: method.isAsynchronous, + ) + ..isNullable = !method.required + ..requiredParameters.addAll([ + cb.refer('${proxyApi.name} instance'), + ...method.parameters + .mapIndexed((int index, NamedType parameter) { + return cb.refer( + '${_addGenericTypesNullable(parameter.type)} ${_getParameterName(index, parameter)}', + ); + }), + ]), + ), + ), + for (final Field field in attachedFields) + cb.Field( + (cb.FieldBuilder builder) => builder + ..name = field.name + ..type = cb.refer(_addGenericTypesNullable(field.type)) + ..modifier = cb.FieldModifier.final$ + ..static = field.isStatic + ..late = !field.isStatic + ..docs.addAll(asDocumentationComments( + field.documentationComments, + _docCommentSpec, + )) + ..assignment = cb.Code('$_varNamePrefix${field.name}()'), + ), + ]; + } + + Iterable _proxyApiMethods({ + required Iterable hostMethods, + required Iterable flutterMethods, + required Iterable superClassFlutterMethods, + required String apiName, + required String dartPackageName, + required String codecInstanceName, + required String codecName, + required Iterable unattachedFields, + required Iterable attachedFields, + required Iterable interfacesApis, + required bool hasCallbackConstructor, + }) { + return [ + // Flutter methods message handler `*setUpMessageHandlers()` + cb.Method.returnsVoid( + (cb.MethodBuilder builder) => builder + ..name = '${classMemberNamePrefix}setUpMessageHandlers' + ..returns = cb.refer('void') + ..static = true + ..optionalParameters.addAll([ + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}clearHandlers' + ..type = cb.refer('bool') + ..named = true + ..defaultTo = const cb.Code('false'), + ), + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}binaryMessenger' + ..named = true + ..type = cb.refer('BinaryMessenger?'), + ), + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}instanceManager' + ..named = true + ..type = cb.refer('$instanceManagerClassName?'), + ), + if (hasCallbackConstructor) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}newInstance' + ..named = true + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = cb.refer(apiName) + ..isNullable = true + ..requiredParameters.addAll( + unattachedFields.mapIndexed( + (int index, Field field) { + return cb.refer( + '${_addGenericTypesNullable(field.type)} ${_getParameterName(index, field)}', + ); + }, + ), + ), + ), + ), + for (final Method method in flutterMethods) + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = method.name + ..type = cb.FunctionType( + (cb.FunctionTypeBuilder builder) => builder + ..returnType = _refer( + _addGenericTypesNullable(method.returnType), + isFuture: method.isAsynchronous, + ) + ..isNullable = true + ..requiredParameters.addAll([ + cb.refer('$apiName ${classMemberNamePrefix}instance'), + ...method.parameters.mapIndexed( + (int index, NamedType parameter) { + return cb.refer( + '${_addGenericTypesNullable(parameter.type)} ${_getParameterName(index, parameter)}', + ); + }, + ), + ]), + ), + ), + ]) + ..body = cb.Block.of([ + cb.Code( + 'final $codecName $_pigeonChannelCodec = $codecName(${classMemberNamePrefix}instanceManager ?? $instanceManagerClassName.instance);', + ), + const cb.Code( + 'final BinaryMessenger? binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', + ), + if (hasCallbackConstructor) + ...cb.Block((cb.BlockBuilder builder) { + final StringBuffer messageHandlerSink = StringBuffer(); + const String methodName = '${classMemberNamePrefix}newInstance'; + _writeFlutterMethodMessageHandler( + Indent(messageHandlerSink), + name: methodName, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}instanceIdentifier', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ...unattachedFields.map( + (Field field) => Parameter( + name: field.name, + type: field.type, + ), + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + channelName: makeChannelNameWithStrings( + apiName: apiName, + methodName: methodName, + dartPackageName: dartPackageName, + ), + isMockHandler: false, + isAsynchronous: false, + nullHandlerExpression: + '${classMemberNamePrefix}clearHandlers', + onCreateApiCall: ( + String methodName, + Iterable parameters, + Iterable safeArgumentNames, + ) { + final String argsAsNamedParams = map2( + parameters, + safeArgumentNames, + (Parameter parameter, String safeArgName) { + return '${parameter.name}: $safeArgName,\n'; + }, + ).skip(1).join(); + return '(${classMemberNamePrefix}instanceManager ?? $instanceManagerClassName.instance)\n' + ' .addHostCreatedInstance(\n' + ' $methodName?.call(${safeArgumentNames.skip(1).join(',')}) ??\n' + ' $apiName.${classMemberNamePrefix}detached(' + ' ${classMemberNamePrefix}binaryMessenger: ${classMemberNamePrefix}binaryMessenger,\n' + ' ${classMemberNamePrefix}instanceManager: ${classMemberNamePrefix}instanceManager,\n' + ' $argsAsNamedParams\n' + ' ),\n' + ' ${safeArgumentNames.first},\n' + ')'; + }, + ); + builder.statements.add(cb.Code(messageHandlerSink.toString())); + }).statements, + ...flutterMethods.fold>( + [], + (List list, Method method) { + final StringBuffer messageHandlerSink = StringBuffer(); + _writeFlutterMethodMessageHandler( + Indent(messageHandlerSink), + name: method.name, + parameters: [ + Parameter( + name: '${classMemberNamePrefix}instance', + type: TypeDeclaration( + baseName: apiName, + isNullable: false, + ), + ), + ...method.parameters, + ], + returnType: TypeDeclaration( + baseName: method.returnType.baseName, + isNullable: + !method.required || method.returnType.isNullable, + typeArguments: method.returnType.typeArguments, + associatedEnum: method.returnType.associatedEnum, + associatedClass: method.returnType.associatedClass, + associatedProxyApi: method.returnType.associatedProxyApi, + ), + channelName: makeChannelNameWithStrings( + apiName: apiName, + methodName: method.name, + dartPackageName: dartPackageName, + ), + isMockHandler: false, + isAsynchronous: method.isAsynchronous, + nullHandlerExpression: + '${classMemberNamePrefix}clearHandlers', + onCreateApiCall: ( + String methodName, + Iterable parameters, + Iterable safeArgumentNames, + ) { + final String nullability = method.required ? '' : '?'; + return '($methodName ?? ${safeArgumentNames.first}.$methodName)$nullability.call(${safeArgumentNames.join(',')})'; + }, + ); + return list..add(cb.Code(messageHandlerSink.toString())); + }, + ), + ]), + ), + for (final Field field in attachedFields) + cb.Method( + (cb.MethodBuilder builder) { + final String type = _addGenericTypesNullable(field.type); + const String instanceName = '${_varNamePrefix}instance'; + const String identifierInstanceName = + '${_varNamePrefix}instanceIdentifier'; + builder + ..name = '$_varNamePrefix${field.name}' + ..static = field.isStatic + ..returns = cb.refer(type) + ..body = cb.Block( + (cb.BlockBuilder builder) { + final StringBuffer messageCallSink = StringBuffer(); + _writeHostMethodMessageCall( + Indent(messageCallSink), + channelName: makeChannelNameWithStrings( + apiName: apiName, + methodName: field.name, + dartPackageName: dartPackageName, + ), + parameters: [ + if (!field.isStatic) + Parameter( + name: 'this', + type: TypeDeclaration( + baseName: apiName, + isNullable: false, + ), + ), + Parameter( + name: identifierInstanceName, + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ); + builder.statements.addAll([ + if (!field.isStatic) ...[ + cb.Code( + 'final $type $instanceName = $type.${classMemberNamePrefix}detached(\n' + ' pigeon_binaryMessenger: pigeon_binaryMessenger,\n' + ' pigeon_instanceManager: pigeon_instanceManager,\n' + ');', + ), + cb.Code('final $codecName $_pigeonChannelCodec =\n' + ' $codecInstanceName;'), + const cb.Code( + 'final BinaryMessenger? ${_varNamePrefix}binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', + ), + const cb.Code( + 'final int $identifierInstanceName = ${classMemberNamePrefix}instanceManager.addDartCreatedInstance($instanceName);', + ), + ] else ...[ + cb.Code( + 'final $type $instanceName = $type.${classMemberNamePrefix}detached();', + ), + cb.Code( + 'final $codecName $_pigeonChannelCodec = $codecName($instanceManagerClassName.instance);', + ), + const cb.Code( + 'final BinaryMessenger ${_varNamePrefix}binaryMessenger = ServicesBinding.instance.defaultBinaryMessenger;', + ), + const cb.Code( + 'final int $identifierInstanceName = $instanceManagerClassName.instance.addDartCreatedInstance($instanceName);', + ), + ], + const cb.Code('() async {'), + cb.Code(messageCallSink.toString()), + const cb.Code('}();'), + const cb.Code('return $instanceName;'), + ]); + }, + ); + }, + ), + for (final Method method in hostMethods) + cb.Method( + (cb.MethodBuilder builder) => builder + ..name = method.name + ..static = method.isStatic + ..modifier = cb.MethodModifier.async + ..docs.addAll(asDocumentationComments( + method.documentationComments, + _docCommentSpec, + )) + ..returns = _refer( + _addGenericTypesNullable(method.returnType), + isFuture: true, + ) + ..requiredParameters.addAll( + method.parameters.mapIndexed( + (int index, NamedType parameter) => cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = _getParameterName(index, parameter) + ..type = cb.refer( + _addGenericTypesNullable(parameter.type), + ), + ), + ), + ) + ..optionalParameters.addAll([ + if (method.isStatic) ...[ + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}binaryMessenger' + ..type = cb.refer('BinaryMessenger?') + ..named = true, + ), + cb.Parameter( + (cb.ParameterBuilder builder) => builder + ..name = '${classMemberNamePrefix}instanceManager' + ..type = cb.refer('$instanceManagerClassName?'), + ), + ], + ]) + ..body = cb.Block( + (cb.BlockBuilder builder) { + final StringBuffer messageCallSink = StringBuffer(); + _writeHostMethodMessageCall( + Indent(messageCallSink), + channelName: makeChannelNameWithStrings( + apiName: apiName, + methodName: method.name, + dartPackageName: dartPackageName, + ), + parameters: [ + if (!method.isStatic) + Parameter( + name: 'this', + type: TypeDeclaration( + baseName: apiName, + isNullable: false, + ), + ), + ...method.parameters, + ], + returnType: method.returnType, + ); + builder.statements.addAll([ + if (!method.isStatic) + cb.Code('final $codecName $_pigeonChannelCodec =\n' + ' $codecInstanceName;') + else + cb.Code( + 'final $codecName $_pigeonChannelCodec = $codecName(${classMemberNamePrefix}instanceManager ?? $instanceManagerClassName.instance);', + ), + const cb.Code( + 'final BinaryMessenger? ${_varNamePrefix}binaryMessenger = ${classMemberNamePrefix}binaryMessenger;', + ), + cb.Code(messageCallSink.toString()), + ]); + }, + ), + ), + cb.Method( + (cb.MethodBuilder builder) => builder + ..name = '${classMemberNamePrefix}copy' + ..returns = cb.refer(apiName) + ..annotations.add(cb.refer('override')) + ..body = cb.Block.of([ + cb + .refer('$apiName.${classMemberNamePrefix}detached') + .call( + [], + { + '${classMemberNamePrefix}binaryMessenger': + cb.refer('${classMemberNamePrefix}binaryMessenger'), + '${classMemberNamePrefix}instanceManager': + cb.refer('${classMemberNamePrefix}instanceManager'), + for (final Field field in unattachedFields) + field.name: cb.refer(field.name), + for (final Method method in superClassFlutterMethods) + method.name: cb.refer(method.name), + for (final AstProxyApi proxyApi in interfacesApis) + for (final Method method in proxyApi.methods) + method.name: cb.refer(method.name), + for (final Method method in flutterMethods) + method.name: cb.refer(method.name), + }, + ) + .returned + .statement, + ]), + ), + ]; + } + + // The base class of all generated ProxyApis. + void _writeProxyApiBaseClass(Indent indent) { + const String className = '${classNamePrefix}ProxyApiBaseClass'; + const String messengerVarName = '${classMemberNamePrefix}binaryMessenger'; + const String instanceManagerVarName = + '${classMemberNamePrefix}instanceManager'; + indent.writeln(''' +/// An immutable object that serves as the base class for all ProxyApis and +/// can provide functional copies of itself. +/// +/// All implementers are expected to be [immutable] as defined by the annotation +/// and override [${classMemberNamePrefix}copy] returning an instance of itself. +@immutable +abstract class $className { + /// Construct a [$className]. + $className({ + this.$messengerVarName, + $instanceManagerClassName? $instanceManagerVarName, + }) : $instanceManagerVarName = + $instanceManagerVarName ?? $instanceManagerClassName.instance; + + /// Sends and receives binary data across the Flutter platform barrier. + /// + /// If it is null, the default BinaryMessenger will be used, which routes to + /// the host platform. + final BinaryMessenger? $messengerVarName; + + /// Maintains instances stored to communicate with native language objects. + final $instanceManagerClassName $instanceManagerVarName; + + /// Instantiates and returns a functionally identical object to oneself. + /// + /// Outside of tests, this method should only ever be called by + /// [$instanceManagerClassName]. + /// + /// Subclasses should always override their parent's implementation of this + /// method. + @protected + $className ${classMemberNamePrefix}copy(); +} +'''); + } + /// Generates Dart source code for test support libraries based on the given AST /// represented by [root], outputting the code to [sink]. [sourceOutPath] is the /// path of the generated dart code to be tested. [testOutPath] is where the @@ -641,12 +1728,10 @@ if (${_varNamePrefix}replyList == null) { indent.writeln("import 'package:$dartOutputPackageName/$path';"); } for (final Api api in root.apis) { - if (api.location == ApiLocation.host && api.dartHostTestHandler != null) { - final Api mockApi = Api( + if (api is AstHostApi && api.dartHostTestHandler != null) { + final AstFlutterApi mockApi = AstFlutterApi( name: api.dartHostTestHandler!, methods: api.methods, - location: ApiLocation.flutter, - dartHostTestHandler: api.dartHostTestHandler, documentationComments: api.documentationComments, ); writeFlutterApi( @@ -696,15 +1781,18 @@ if (${_varNamePrefix}replyList == null) { Indent indent, { required String dartPackageName, }) { - final bool hasHostApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.host); - final bool hasFlutterApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.flutter); + final bool hasHostApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); + final bool hasFlutterApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); + final bool hasProxyApi = root.apis.any((Api api) => api is AstProxyApi); - if (hasHostApi) { + if (hasHostApi || hasProxyApi) { _writeCreateConnectionError(indent); } - if (hasFlutterApi) { + if (hasFlutterApi || hasProxyApi) { _writeWrapResponse(generatorOptions, root, indent); } } @@ -736,6 +1824,249 @@ PlatformException _createConnectionError(String channelName) { \t); }'''); } + + void _writeHostMethod( + Indent indent, { + required String name, + required Iterable parameters, + required TypeDeclaration returnType, + required List documentationComments, + required String channelName, + }) { + addDocumentationComments(indent, documentationComments, _docCommentSpec); + String argSignature = ''; + if (parameters.isNotEmpty) { + argSignature = _getMethodParameterSignature(parameters); + } + indent.write( + 'Future<${_addGenericTypesNullable(returnType)}> $name($argSignature) async ', + ); + indent.addScoped('{', '}', () { + _writeHostMethodMessageCall( + indent, + channelName: channelName, + parameters: parameters, + returnType: returnType, + ); + }); + } + + void _writeHostMethodMessageCall( + Indent indent, { + required String channelName, + required Iterable parameters, + required TypeDeclaration returnType, + }) { + String sendArgument = 'null'; + if (parameters.isNotEmpty) { + final Iterable argExpressions = + parameters.mapIndexed((int index, NamedType type) { + final String name = _getParameterName(index, type); + if (type.type.isEnum) { + return '$name${type.type.isNullable ? '?' : ''}.index'; + } else { + return name; + } + }); + sendArgument = '[${argExpressions.join(', ')}]'; + } + + indent + .writeln("const String ${_varNamePrefix}channelName = '$channelName';"); + indent.writeScoped( + 'final BasicMessageChannel ${_varNamePrefix}channel = BasicMessageChannel(', + ');', () { + indent.writeln('${_varNamePrefix}channelName,'); + indent.writeln('$_pigeonChannelCodec,'); + indent.writeln('binaryMessenger: ${_varNamePrefix}binaryMessenger,'); + }); + final String returnTypeName = _makeGenericTypeArguments(returnType); + final String genericCastCall = _makeGenericCastCall(returnType); + const String accessor = '${_varNamePrefix}replyList[0]'; + // Avoid warnings from pointlessly casting to `Object?`. + final String nullablyTypedAccessor = returnTypeName == 'Object' + ? accessor + : '($accessor as $returnTypeName?)'; + final String nullHandler = + returnType.isNullable ? (genericCastCall.isEmpty ? '' : '?') : '!'; + String returnStatement = 'return'; + if (returnType.isEnum) { + if (returnType.isNullable) { + returnStatement = + '$returnStatement ($accessor as int?) == null ? null : $returnTypeName.values[$accessor! as int]'; + } else { + returnStatement = + '$returnStatement $returnTypeName.values[$accessor! as int]'; + } + } else if (!returnType.isVoid) { + returnStatement = + '$returnStatement $nullablyTypedAccessor$nullHandler$genericCastCall'; + } + returnStatement = '$returnStatement;'; + + indent.format(''' +final List? ${_varNamePrefix}replyList = +\t\tawait ${_varNamePrefix}channel.send($sendArgument) as List?; +if (${_varNamePrefix}replyList == null) { +\tthrow _createConnectionError(${_varNamePrefix}channelName); +} else if (${_varNamePrefix}replyList.length > 1) { +\tthrow PlatformException( +\t\tcode: ${_varNamePrefix}replyList[0]! as String, +\t\tmessage: ${_varNamePrefix}replyList[1] as String?, +\t\tdetails: ${_varNamePrefix}replyList[2], +\t);'''); + // On iOS we can return nil from functions to accommodate error + // handling. Returning a nil value and not returning an error is an + // exception. + if (!returnType.isNullable && !returnType.isVoid) { + indent.format(''' +} else if (${_varNamePrefix}replyList[0] == null) { +\tthrow PlatformException( +\t\tcode: 'null-error', +\t\tmessage: 'Host platform returned null value for non-null return value.', +\t);'''); + } + indent.format(''' +} else { +\t$returnStatement +}'''); + } + + void _writeFlutterMethodMessageHandler( + Indent indent, { + required String name, + required Iterable parameters, + required TypeDeclaration returnType, + required String channelName, + required bool isMockHandler, + required bool isAsynchronous, + String nullHandlerExpression = 'api == null', + String Function(String methodName, Iterable parameters, + Iterable safeArgumentNames) + onCreateApiCall = _createFlutterApiMethodCall, + }) { + indent.write(''); + indent.addScoped('{', '}', () { + indent.writeln( + 'final BasicMessageChannel ${_varNamePrefix}channel = BasicMessageChannel(', + ); + indent.nest(2, () { + indent.writeln("'$channelName', $_pigeonChannelCodec,"); + indent.writeln( + 'binaryMessenger: binaryMessenger);', + ); + }); + final String messageHandlerSetterWithOpeningParentheses = isMockHandler + ? '_testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(${_varNamePrefix}channel, ' + : '${_varNamePrefix}channel.setMessageHandler('; + indent.write('if ($nullHandlerExpression) '); + indent.addScoped('{', '}', () { + indent.writeln('${messageHandlerSetterWithOpeningParentheses}null);'); + }, addTrailingNewline: false); + indent.add(' else '); + indent.addScoped('{', '}', () { + indent.write( + '$messageHandlerSetterWithOpeningParentheses(Object? message) async ', + ); + indent.addScoped('{', '});', () { + final String returnTypeString = _addGenericTypesNullable(returnType); + final bool isAsync = isAsynchronous; + const String emptyReturnStatement = + 'return wrapResponse(empty: true);'; + String call; + if (parameters.isEmpty) { + call = 'api.$name()'; + } else { + indent.writeln('assert(message != null,'); + indent.writeln("'Argument for $channelName was null.');"); + const String argsArray = 'args'; + indent.writeln( + 'final List $argsArray = (message as List?)!;'); + String argNameFunc(int index, NamedType type) => + _getSafeArgumentName(index, type); + parameters.forEachIndexed((int count, NamedType arg) { + final String argType = _addGenericTypes(arg.type); + final String argName = argNameFunc(count, arg); + final String genericArgType = _makeGenericTypeArguments(arg.type); + final String castCall = _makeGenericCastCall(arg.type); + + final String leftHandSide = 'final $argType? $argName'; + if (arg.type.isEnum) { + indent.writeln( + '$leftHandSide = $argsArray[$count] == null ? null : $argType.values[$argsArray[$count]! as int];'); + } else { + indent.writeln( + '$leftHandSide = ($argsArray[$count] as $genericArgType?)${castCall.isEmpty ? '' : '?$castCall'};'); + } + if (!arg.type.isNullable) { + indent.writeln('assert($argName != null,'); + indent.writeln( + " 'Argument for $channelName was null, expected non-null $argType.');"); + } + }); + final Iterable argNames = + parameters.mapIndexed((int index, Parameter field) { + final String name = _getSafeArgumentName(index, field); + return '${field.isNamed ? '${field.name}: ' : ''}$name${field.type.isNullable ? '' : '!'}'; + }); + call = onCreateApiCall(name, parameters, argNames); + } + indent.writeScoped('try {', '} ', () { + if (returnType.isVoid) { + if (isAsync) { + indent.writeln('await $call;'); + } else { + indent.writeln('$call;'); + } + indent.writeln(emptyReturnStatement); + } else { + if (isAsync) { + indent.writeln('final $returnTypeString output = await $call;'); + } else { + indent.writeln('final $returnTypeString output = $call;'); + } + + const String returnExpression = 'output'; + final String nullability = returnType.isNullable ? '?' : ''; + final String valueExtraction = + returnType.isEnum ? '$nullability.index' : ''; + final String returnStatement = isMockHandler + ? 'return [$returnExpression$valueExtraction];' + : 'return wrapResponse(result: $returnExpression$valueExtraction);'; + indent.writeln(returnStatement); + } + }, addTrailingNewline: false); + indent.addScoped('on PlatformException catch (e) {', '}', () { + indent.writeln('return wrapResponse(error: e);'); + }, addTrailingNewline: false); + + indent.writeScoped('catch (e) {', '}', () { + indent.writeln( + "return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));"); + }); + }); + }); + }); + } + + static String _createFlutterApiMethodCall( + String methodName, + Iterable parameters, + Iterable safeArgumentNames, + ) { + return 'api.$methodName(${safeArgumentNames.join(', ')})'; + } +} + +cb.Reference _refer( + String symbol, { + bool isFuture = false, + bool isNullable = false, +}) { + final String nullability = isNullable ? '?' : ''; + return cb.refer( + isFuture ? 'Future<$symbol$nullability>' : '$symbol$nullability', + ); } String _escapeForDartSingleQuotedString(String raw) { @@ -762,7 +2093,8 @@ void _writeCodec(Indent indent, String codecName, Api api, Root root) { indent.writeln('@override'); indent.write('void writeValue(WriteBuffer buffer, Object? value) '); indent.addScoped('{', '}', () { - enumerate(codecClasses, (int index, final EnumeratedClass customClass) { + codecClasses + .forEachIndexed((int index, final EnumeratedClass customClass) { final String ifValue = 'if (value is ${customClass.name}) '; if (index == 0) { indent.write(''); @@ -824,20 +2156,20 @@ String _getParameterName(int count, NamedType field) => /// Generates the parameters code for [func] /// Example: (func, _getParameterName) -> 'String? foo, int bar' -String _getMethodParameterSignature(Method func) { +String _getMethodParameterSignature(Iterable parameters) { String signature = ''; - if (func.parameters.isEmpty) { + if (parameters.isEmpty) { return signature; } - final List requiredPositionalParams = func.parameters + final List requiredPositionalParams = parameters .where((Parameter p) => p.isPositional && !p.isOptional) .toList(); - final List optionalPositionalParams = func.parameters + final List optionalPositionalParams = parameters .where((Parameter p) => p.isPositional && p.isOptional) .toList(); final List namedParams = - func.parameters.where((Parameter p) => !p.isPositional).toList(); + parameters.where((Parameter p) => !p.isPositional).toList(); String getParameterString(Parameter p) { final String required = p.isRequired && !p.isPositional ? 'required ' : ''; diff --git a/packages/pigeon/lib/functional.dart b/packages/pigeon/lib/functional.dart index 8e23950e9e70..59e477783c3a 100644 --- a/packages/pigeon/lib/functional.dart +++ b/packages/pigeon/lib/functional.dart @@ -2,26 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// A [map] function that calls the function with an enumeration as well as the -/// value. -Iterable indexMap( - Iterable iterable, U Function(int index, T value) func) sync* { - int index = 0; - for (final T value in iterable) { - yield func(index, value); - ++index; - } -} - -/// Performs like [forEach] but invokes [func] with an enumeration. -void enumerate(Iterable iterable, void Function(int, T) func) { - int count = 0; - for (final T value in iterable) { - func(count, value); - ++count; - } -} - /// A [map] function that takes in 2 iterables. The [Iterable]s must be of /// equal length. Iterable map2( diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 1bd083078745..3711fd28dbe3 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -63,6 +63,24 @@ abstract class StructuredGenerator extends Generator { dartPackageName: dartPackageName, ); + if (root.apis.any((Api api) => api is AstProxyApi)) { + writeInstanceManager( + generatorOptions, + root, + indent, + dartPackageName: dartPackageName, + ); + + writeInstanceManagerApi( + generatorOptions, + root, + indent, + dartPackageName: dartPackageName, + ); + + writeProxyApiBaseCodec(generatorOptions, root, indent); + } + writeEnums( generatorOptions, root, @@ -224,22 +242,31 @@ abstract class StructuredGenerator extends Generator { required String dartPackageName, }) { for (final Api api in root.apis) { - if (api.location == ApiLocation.host) { - writeHostApi( - generatorOptions, - root, - indent, - api, - dartPackageName: dartPackageName, - ); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi( - generatorOptions, - root, - indent, - api, - dartPackageName: dartPackageName, - ); + switch (api) { + case AstHostApi(): + writeHostApi( + generatorOptions, + root, + indent, + api, + dartPackageName: dartPackageName, + ); + case AstFlutterApi(): + writeFlutterApi( + generatorOptions, + root, + indent, + api, + dartPackageName: dartPackageName, + ); + case AstProxyApi(): + writeProxyApi( + generatorOptions, + root, + indent, + api, + dartPackageName: dartPackageName, + ); } } } @@ -249,7 +276,7 @@ abstract class StructuredGenerator extends Generator { T generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { required String dartPackageName, }); @@ -258,7 +285,49 @@ abstract class StructuredGenerator extends Generator { T generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }); + + /// Writes the implementation of an `InstanceManager` to [indent]. + void writeInstanceManager( + T generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) {} + + /// Writes the implementation of the API for the `InstanceManager` to + /// [indent]. + void writeInstanceManagerApi( + T generatorOptions, + Root root, + Indent indent, { + required String dartPackageName, + }) {} + + /// Writes the base codec to be used by all ProxyApis. + /// + /// This codec should use `128` as the identifier for objects that exist in + /// an `InstanceManager`. The write implementation should convert an instance + /// to an identifier. The read implementation should covert the identifier + /// to an instance. + /// + /// This will serve as the default codec for all ProxyApis. If a ProxyApi + /// needs to create its own codec (it has methods/fields/constructor that use + /// a data class) it should extend this codec and not `StandardMessageCodec`. + void writeProxyApiBaseCodec( + T generatorOptions, + Root root, + Indent indent, + ) {} + + /// Writes a single Proxy Api to [indent]. + void writeProxyApi( + T generatorOptions, + Root root, + Indent indent, + AstProxyApi api, { + required String dartPackageName, + }) {} } diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index ba32f720a2a0..f3fe858fe525 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 = '16.0.0'; +const String pigeonVersion = '16.0.1'; /// Read all the content from [stdin] to a String. String readStdin() { @@ -164,9 +164,22 @@ class Indent { } } -/// Create the generated channel name for a [func] on a [api]. -String makeChannelName(Api api, Method func, String dartPackageName) { - return 'dev.flutter.pigeon.$dartPackageName.${api.name}.${func.name}'; +/// Create the generated channel name for a [method] on an [api]. +String makeChannelName(Api api, Method method, String dartPackageName) { + return makeChannelNameWithStrings( + apiName: api.name, + methodName: method.name, + dartPackageName: dartPackageName, + ); +} + +/// Create the generated channel name for a method on an api. +String makeChannelNameWithStrings({ + required String apiName, + required String methodName, + required String dartPackageName, +}) { + return 'dev.flutter.pigeon.$dartPackageName.$apiName.$methodName'; } // TODO(tarrinneal): Determine whether HostDataType is needed. @@ -282,6 +295,24 @@ String getGeneratedCodeWarning() { /// String to be printed after `getGeneratedCodeWarning()'s warning`. const String seeAlsoWarning = 'See also: https://pub.dev/packages/pigeon'; +/// Prefix for utility classes generated for ProxyApis. +/// +/// This lowers the chances of variable name collisions with user defined +/// parameters. +const String classNamePrefix = 'Pigeon_'; + +/// Name for the generated InstanceManager for ProxyApis. +/// +/// This lowers the chances of variable name collisions with user defined +/// parameters. +const String instanceManagerClassName = '${classNamePrefix}InstanceManager'; + +/// Prefix for class member names not defined by the user. +/// +/// This lowers the chances of variable name collisions with user defined +/// parameters. +const String classMemberNamePrefix = 'pigeon_'; + /// Collection of keys used in dictionaries across generators. class Keys { /// The key in the result hash for the 'result' value. @@ -313,37 +344,6 @@ void addLines(Indent indent, Iterable lines, {String? linePrefix}) { } } -/// Recursively merges [modification] into [base]. -/// -/// In other words, whenever there is a conflict over the value of a key path, -/// [modification]'s value for that key path is selected. -Map mergeMaps( - Map base, - Map modification, -) { - final Map result = {}; - for (final MapEntry entry in modification.entries) { - if (base.containsKey(entry.key)) { - final Object entryValue = entry.value; - if (entryValue is Map) { - assert(base[entry.key] is Map); - result[entry.key] = - mergeMaps((base[entry.key] as Map?)!, entryValue); - } else { - result[entry.key] = entry.value; - } - } else { - result[entry.key] = entry.value; - } - } - for (final MapEntry entry in base.entries) { - if (!result.containsKey(entry.key)) { - result[entry.key] = entry.value; - } - } - return result; -} - /// A class name that is enumerated. class EnumeratedClass { /// Constructor. @@ -510,6 +510,23 @@ void addDocumentationComments( DocumentCommentSpecification commentSpec, { List generatorComments = const [], }) { + asDocumentationComments( + comments, + commentSpec, + generatorComments: generatorComments, + ).forEach(indent.writeln); +} + +/// Formats documentation comments and adds them to current Indent. +/// +/// The [comments] list is meant for comments written in the input dart file. +/// The [generatorComments] list is meant for comments added by the generators. +/// Include white space for all tokens when called, no assumptions are made. +Iterable asDocumentationComments( + Iterable comments, + DocumentCommentSpecification commentSpec, { + List generatorComments = const [], +}) sync* { final List allComments = [ ...comments, if (comments.isNotEmpty && generatorComments.isNotEmpty) '', @@ -518,24 +535,20 @@ void addDocumentationComments( String currentLineOpenToken = commentSpec.openCommentToken; if (allComments.length > 1) { if (commentSpec.closeCommentToken != '') { - indent.writeln(commentSpec.openCommentToken); + yield commentSpec.openCommentToken; currentLineOpenToken = commentSpec.blockContinuationToken; } for (String line in allComments) { if (line.isNotEmpty && line[0] != ' ') { line = ' $line'; } - indent.writeln( - '$currentLineOpenToken$line', - ); + yield '$currentLineOpenToken$line'; } if (commentSpec.closeCommentToken != '') { - indent.writeln(commentSpec.closeCommentToken); + yield commentSpec.closeCommentToken; } } else if (allComments.length == 1) { - indent.writeln( - '$currentLineOpenToken${allComments.first}${commentSpec.closeCommentToken}', - ); + yield '$currentLineOpenToken${allComments.first}${commentSpec.closeCommentToken}'; } } @@ -609,6 +622,88 @@ enum FileType { na, } +/// Recursively search for all the interfaces apis from a list of names of +/// interfaces. +/// +/// This method assumes that all interfaces names can be found in +/// [allProxyApis]. Otherwise, throws an [ArgumentError]. +Set recursiveFindAllInterfacesApis( + AstProxyApi api, + Iterable allProxyApis, +) { + final Set interfacesApis = {}; + + for (final AstProxyApi proxyApi in allProxyApis) { + if (api.interfacesNames.contains(proxyApi.name)) { + interfacesApis.add(proxyApi); + } + } + + if (interfacesApis.length != api.interfacesNames.length) { + throw ArgumentError( + 'Could not find a ProxyApi for every interface name: ' + '${api.interfacesNames}, ${allProxyApis.map((Api api) => api.name)}', + ); + } + + for (final AstProxyApi proxyApi in Set.from(interfacesApis)) { + interfacesApis.addAll( + recursiveFindAllInterfacesApis(proxyApi, allProxyApis), + ); + } + + return interfacesApis; +} + +/// Creates a list of ProxyApis where each `extends` the ProxyApi that follows +/// it. +/// +/// Returns an empty list if [proxyApi] does not extend a ProxyApi. +/// +/// This method assumes the super classes of each ProxyApi doesn't create a +/// loop. Throws a [ArgumentError] if a loop is found. +/// +/// This method also assumes that all super class names can be found in +/// [allProxyApis]. Otherwise, throws an [ArgumentError]. +List recursiveGetSuperClassApisChain( + AstProxyApi proxyApi, + Iterable allProxyApis, +) { + final List proxyApis = []; + + String? currentProxyApiName = proxyApi.superClassName; + while (currentProxyApiName != null) { + if (proxyApis.length > allProxyApis.length) { + final Iterable apiNames = proxyApis.map( + (AstProxyApi api) => api.name, + ); + throw ArgumentError( + 'Loop found when processing super classes for a ProxyApi: ' + '${proxyApi.name},${apiNames.join(',')}', + ); + } + + AstProxyApi? nextProxyApi; + for (final AstProxyApi node in allProxyApis) { + if (currentProxyApiName == node.name) { + nextProxyApi = node; + proxyApis.add(node); + } + } + + if (nextProxyApi == null) { + throw ArgumentError( + 'Could not find a ProxyApi for every super class name: ' + '$currentProxyApiName, ${allProxyApis.map((Api api) => api.name)}', + ); + } + + currentProxyApiName = nextProxyApi.superClassName; + } + + return proxyApis; +} + /// Options for [Generator]s that have multiple output file types. /// /// Specifies which file to write as well as wraps all language options. diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 43b42c40e909..7a8a0fc65552 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart'; + import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; @@ -183,7 +185,7 @@ class JavaGenerator extends StructuredGenerator { indent.write('public enum ${anEnum.name} '); indent.addScoped('{', '}', () { - enumerate(anEnum.members, (int index, final EnumMember member) { + anEnum.members.forEachIndexed((int index, final EnumMember member) { addDocumentationComments( indent, member.documentationComments, _docCommentSpec); indent.writeln( @@ -369,8 +371,8 @@ class JavaGenerator extends StructuredGenerator { const String result = 'pigeonResult'; indent.writeln( '${classDefinition.name} $result = new ${classDefinition.name}();'); - enumerate(getFieldsInSerializationOrder(classDefinition), - (int index, final NamedType field) { + getFieldsInSerializationOrder(classDefinition) + .forEachIndexed((int index, final NamedType field) { final String fieldVariable = field.name; final String setter = _makeSetter(field); indent.writeln('Object $fieldVariable = list.get($index);'); @@ -400,7 +402,7 @@ class JavaGenerator extends StructuredGenerator { JavaOptions generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { required String dartPackageName, }) { /// Returns an argument name that can be used in a context where it is possible to collide @@ -414,7 +416,6 @@ class JavaGenerator extends StructuredGenerator { return '${_getArgumentName(count, argument)}Arg'; } - assert(api.location == ApiLocation.flutter); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(indent, api, root); } @@ -463,9 +464,9 @@ class JavaGenerator extends StructuredGenerator { final Iterable argTypes = func.parameters .map((NamedType e) => _nullsafeJavaTypeForDartType(e.type)); final Iterable argNames = - indexMap(func.parameters, _getSafeArgumentName); + func.parameters.mapIndexed(_getSafeArgumentName); final Iterable enumSafeArgNames = - indexMap(func.parameters, getEnumSafeArgumentExpression); + func.parameters.mapIndexed(getEnumSafeArgumentExpression); if (func.parameters.length == 1) { sendArgument = 'new ArrayList(Collections.singletonList(${enumSafeArgNames.first}))'; @@ -556,9 +557,9 @@ class JavaGenerator extends StructuredGenerator { required String dartPackageName, }) { if (root.apis.any((Api api) => - api.location == ApiLocation.host && + api is AstHostApi && api.methods.any((Method it) => it.isAsynchronous) || - api.location == ApiLocation.flutter)) { + api is AstFlutterApi)) { indent.newln(); _writeResultInterfaces(indent); } @@ -577,10 +578,9 @@ class JavaGenerator extends StructuredGenerator { JavaOptions generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.host); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(indent, api, root); } @@ -713,7 +713,7 @@ class JavaGenerator extends StructuredGenerator { if (method.parameters.isNotEmpty) { indent.writeln( 'ArrayList args = (ArrayList) message;'); - enumerate(method.parameters, (int index, NamedType arg) { + method.parameters.forEachIndexed((int index, NamedType arg) { // The StandardMessageCodec can give us [Integer, Long] for // a Dart 'int'. To keep things simple we just use 64bit // longs in Pigeon with Java. @@ -979,10 +979,12 @@ protected static ArrayList wrapError(@NonNull Throwable exception) { Indent indent, { required String dartPackageName, }) { - final bool hasHostApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.host); - final bool hasFlutterApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.flutter); + final bool hasHostApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); + final bool hasFlutterApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); indent.newln(); _writeErrorClass(indent); diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 88ffb487406e..d0a0ccb06cec 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart'; + import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; @@ -124,7 +126,7 @@ class KotlinGenerator extends StructuredGenerator { indent, anEnum.documentationComments, _docCommentSpec); indent.write('enum class ${anEnum.name}(val raw: Int) '); indent.addScoped('{', '}', () { - enumerate(anEnum.members, (int index, final EnumMember member) { + anEnum.members.forEachIndexed((int index, final EnumMember member) { addDocumentationComments( indent, member.documentationComments, _docCommentSpec); indent.write('${member.name.toUpperCase()}($index)'); @@ -240,8 +242,8 @@ class KotlinGenerator extends StructuredGenerator { indent.write('fun fromList(list: List): $className '); indent.addScoped('{', '}', () { - enumerate(getFieldsInSerializationOrder(classDefinition), - (int index, final NamedType field) { + getFieldsInSerializationOrder(classDefinition) + .forEachIndexed((int index, final NamedType field) { final String listValue = 'list[$index]'; final String fieldType = _kotlinTypeForDartType(field.type); @@ -307,7 +309,7 @@ class KotlinGenerator extends StructuredGenerator { required String dartPackageName, }) { if (root.apis.any((Api api) => - api.location == ApiLocation.host && + api is AstHostApi && api.methods.any((Method it) => it.isAsynchronous))) { indent.newln(); } @@ -325,10 +327,9 @@ class KotlinGenerator extends StructuredGenerator { KotlinOptions generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.flutter); final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; if (isCustomCodec) { _writeCodec(indent, api, root); @@ -376,9 +377,8 @@ class KotlinGenerator extends StructuredGenerator { final Iterable argTypes = func.parameters .map((NamedType e) => _nullsafeKotlinTypeForDartType(e.type)); final Iterable argNames = - indexMap(func.parameters, _getSafeArgumentName); - final Iterable enumSafeArgNames = indexMap( - func.parameters, + func.parameters.mapIndexed(_getSafeArgumentName); + final Iterable enumSafeArgNames = func.parameters.mapIndexed( (int count, NamedType type) => _getEnumSafeArgumentExpression(count, type)); sendArgument = 'listOf(${enumSafeArgNames.join(', ')})'; @@ -448,11 +448,9 @@ class KotlinGenerator extends StructuredGenerator { KotlinOptions generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.host); - final String apiName = api.name; final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; @@ -551,7 +549,8 @@ class KotlinGenerator extends StructuredGenerator { final List methodArguments = []; if (method.parameters.isNotEmpty) { indent.writeln('val args = message as List'); - enumerate(method.parameters, (int index, NamedType arg) { + method.parameters + .forEachIndexed((int index, NamedType arg) { final String argName = _getSafeArgumentName(index, arg); final String argIndex = 'args[$index]'; indent.writeln( @@ -742,10 +741,12 @@ class KotlinGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final bool hasHostApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.host); - final bool hasFlutterApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.flutter); + final bool hasHostApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); + final bool hasFlutterApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); if (hasHostApi) { _writeWrapResult(indent); diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 903957d083c2..378393b46dc0 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart'; + import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; @@ -149,7 +151,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { indent.write('typedef NS_ENUM(NSUInteger, $enumName) '); indent.addScoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { + anEnum.members.forEachIndexed((int index, final EnumMember member) { addDocumentationComments( indent, member.documentationComments, _docCommentSpec); // Capitalized first letter to ensure Swift compatibility @@ -572,8 +574,8 @@ class ObjcSourceGenerator extends StructuredGenerator { indent.addScoped('{', '}', () { const String resultName = 'pigeonResult'; indent.writeln('$className *$resultName = [[$className alloc] init];'); - enumerate(getFieldsInSerializationOrder(classDefinition), - (int index, final NamedType field) { + getFieldsInSerializationOrder(classDefinition) + .forEachIndexed((int index, final NamedType field) { final bool isEnumType = field.type.isEnum; final String valueGetter = _listGetter('list', field, index, generatorOptions.prefix); @@ -617,10 +619,9 @@ class ObjcSourceGenerator extends StructuredGenerator { ObjcOptions generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.flutter); final String apiName = _className(generatorOptions.prefix, api.name); _writeCodecAndGetter(generatorOptions, root, indent, api); @@ -649,10 +650,9 @@ class ObjcSourceGenerator extends StructuredGenerator { ObjcOptions generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.host); final String apiName = _className(generatorOptions.prefix, api.name); _writeCodecAndGetter(generatorOptions, root, indent, api); @@ -702,10 +702,12 @@ class ObjcSourceGenerator extends StructuredGenerator { Indent indent, { required String dartPackageName, }) { - final bool hasHostApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.host); - final bool hasFlutterApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.flutter); + final bool hasHostApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); + final bool hasFlutterApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); if (hasHostApi) { _writeWrapError(indent); @@ -858,7 +860,7 @@ static FlutterError *createConnectionError(NSString *channelName) { final Iterable selectorComponents = _getSelectorComponents(func, lastSelectorComponent); final Iterable argNames = - indexMap(func.parameters, _getSafeArgName); + func.parameters.mapIndexed(_getSafeArgName); final String callSignature = map2(selectorComponents.take(argNames.length), argNames, (String selectorComponent, String argName) { @@ -1453,7 +1455,7 @@ String _makeObjcSignature({ (int _, NamedType e) => e.type.isNullable && e.type.isEnum ? '${e.name}Boxed' : e.name; final Iterable argNames = - followedByOne(indexMap(func.parameters, argNameFunc), lastArgName); + followedByOne(func.parameters.mapIndexed(argNameFunc), lastArgName); final Iterable selectorComponents = _getSelectorComponents(func, lastArgName); final Iterable argTypes = followedByOne( diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index e114af93caa4..56dc43ed5b21 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -22,6 +22,7 @@ import 'package:analyzer/dart/ast/visitor.dart' as dart_ast_visitor; import 'package:analyzer/error/error.dart' show AnalysisError; import 'package:args/args.dart'; import 'package:collection/collection.dart' as collection; +import 'package:collection/collection.dart'; import 'package:path/path.dart' as path; import 'ast.dart'; @@ -39,9 +40,44 @@ class _Asynchronous { const _Asynchronous(); } +class _Attached { + const _Attached(); +} + +class _Static { + const _Static(); +} + /// Metadata to annotate a Api method as asynchronous const Object async = _Asynchronous(); +/// Metadata to annotate the field of a ProxyApi as an Attached Field. +/// +/// Attached fields provide a synchronous [AstProxyApi] instance as a field +/// for another [AstProxyApi]. +/// +/// Attached fields: +/// * Must be nonnull. +/// * Must be a ProxyApi type. +/// * Must be a ProxyApi that contains any fields. +/// * Must be a ProxyApi that does not have a required Flutter method. +/// +/// Example generated code: +/// +/// ```dart +/// class MyProxyApi { +/// final MyOtherProxyApi myField = __pigeon_myField(). +/// } +/// ``` +/// +/// The field provides access to the value synchronously, but the native +/// instance is stored in the native `InstanceManager` asynchronously. Similar +/// to how constructors are implemented. +const Object attached = _Attached(); + +/// Metadata to annotate an method or an Attached Field of a ProxyApi as static. +const Object static = _Static(); + /// Metadata annotation used to configure how Pigeon will generate code. class ConfigurePigeon { /// Constructor for ConfigurePigeon. @@ -88,6 +124,30 @@ class FlutterApi { const FlutterApi(); } +/// Metadata to annotate a Pigeon API that wraps a native class. +/// +/// The abstract class with this annotation groups a collection of Dart↔host +/// constructors, fields, methods and host↔Dart methods used to wrap a native +/// class. +/// +/// The generated Dart class acts as a proxy to a native type and +/// maintains instances automatically with an `InstanceManager`. The generated +/// host language class implements methods to interact with class instances +/// or static methods. +class ProxyApi { + /// Parametric constructor for [ProxyApi]. + const ProxyApi({this.superClass}); + + /// The proxy api that is a super class to this one. + /// + /// This provides an alternative to calling `extends` on a class since this + /// requires calling the super class constructor. + /// + /// Note that using this instead of `extends` can cause unexpected conflicts + /// with inherited method names. + final Type? superClass; +} + /// Metadata to annotation methods to control the selector used for objc output. /// The number of components in the provided selector must match the number of /// arguments in the annotated method. @@ -787,7 +847,16 @@ List _validateAst(Root root, String source) { } } } + for (final Api api in root.apis) { + if (api is AstProxyApi) { + result.addAll(_validateProxyApi( + api, + source, + customClasses: customClasses.toSet(), + proxyApis: root.apis.whereType().toSet(), + )); + } for (final Method method in api.methods) { for (final Parameter param in method.parameters) { if (param.type.baseName.isEmpty) { @@ -809,7 +878,7 @@ List _validateAst(Root root, String source) { lineNumber: _calculateLineNumberNullable(source, param.offset), )); } - if (api.location == ApiLocation.flutter) { + if (api is AstFlutterApi) { if (!param.isPositional) { result.add(Error( message: @@ -847,7 +916,7 @@ List _validateAst(Root root, String source) { } } if (method.taskQueueType != TaskQueueType.serial && - api.location != ApiLocation.host) { + method.location == ApiLocation.flutter) { result.add(Error( message: 'Unsupported TaskQueue specification on ${method.name}', lineNumber: _calculateLineNumberNullable(source, method.offset), @@ -859,6 +928,275 @@ List _validateAst(Root root, String source) { return result; } +List _validateProxyApi( + AstProxyApi api, + String source, { + required Set customClasses, + required Set proxyApis, +}) { + final List result = []; + + bool isDataClass(NamedType type) => + customClasses.contains(type.type.baseName); + bool isProxyApi(NamedType type) => proxyApis.any( + (AstProxyApi api) => api.name == type.type.baseName, + ); + Error unsupportedDataClassError(NamedType type) { + return Error( + message: 'ProxyApis do not support data classes: ${type.type.baseName}.', + lineNumber: _calculateLineNumberNullable(source, type.offset), + ); + } + + // Validate super class is another ProxyApi + final String? superClassName = api.superClassName; + if (api.superClassName != null && + !proxyApis.any((AstProxyApi api) => api.name == superClassName)) { + result.add(Error( + message: + 'Super class of ${api.name} is not marked as a @ProxyApi: $superClassName', + )); + } + + // Validate all interfaces are other ProxyApis + for (final String interfaceName in api.interfacesNames) { + if (!proxyApis.any((AstProxyApi api) => api.name == interfaceName)) { + result.add(Error( + message: + 'Interface of ${api.name} is not marked as a @ProxyApi: $interfaceName', + )); + } + } + + List? superClassChain; + try { + superClassChain = recursiveGetSuperClassApisChain(api, proxyApis); + } catch (error) { + result.add(Error(message: error.toString())); + } + + // Validate that the api does not inherit a non attached field from its super class. + if (superClassChain != null && + superClassChain.isNotEmpty && + superClassChain.first.unattachedFields.isNotEmpty) { + result.add(Error( + message: + 'Non attached fields can not be inherited. Non attached field found for parent class ${api.unattachedFields.first.name}', + lineNumber: _calculateLineNumberNullable( + source, + api.unattachedFields.first.offset, + ), + )); + } + + for (final AstProxyApi proxyApi in proxyApis) { + // Validate this api is not used as an attached field while either: + // 1. Having an unattached field. + // 2. Having a required Flutter method. + final bool hasUnattachedField = api.unattachedFields.isNotEmpty; + final bool hasRequiredFlutterMethod = + api.flutterMethods.any((Method method) => method.required); + if (hasUnattachedField || hasRequiredFlutterMethod) { + for (final Field field in proxyApi.attachedFields) { + if (field.type.baseName == api.name) { + if (hasUnattachedField) { + result.add(Error( + message: + 'ProxyApis with fields can not be used as attached fields: ${field.name}', + lineNumber: _calculateLineNumberNullable( + source, + field.offset, + ), + )); + } + if (hasRequiredFlutterMethod) { + result.add(Error( + message: + 'ProxyApis with required callback methods can not be used as attached fields: ${field.name}', + lineNumber: _calculateLineNumberNullable( + source, + field.offset, + ), + )); + } + } + } + } + + // Validate this api isn't used as an interface and contains anything except + // Flutter methods. + final bool isValidInterfaceProxyApi = api.hostMethods.isEmpty && + api.constructors.isEmpty && + api.fields.isEmpty; + if (!isValidInterfaceProxyApi) { + for (final String interfaceName in proxyApi.interfacesNames) { + if (interfaceName == api.name) { + result.add(Error( + message: + 'ProxyApis used as interfaces can only have callback methods: ${proxyApi.name}', + )); + } + } + } + } + + // Validate constructor parameters + for (final Constructor constructor in api.constructors) { + for (final Parameter parameter in constructor.parameters) { + if (isDataClass(parameter)) { + result.add(unsupportedDataClassError(parameter)); + } + + if (api.fields.any((Field field) => field.name == parameter.name) || + api.flutterMethods + .any((Method method) => method.name == parameter.name)) { + result.add(Error( + message: + 'Parameter names must not share a name with a field or callback method in constructor "${constructor.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } + + if (parameter.type.baseName.isEmpty) { + result.add(Error( + message: + 'Parameters must specify their type in constructor "${constructor.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } else if (parameter.name.startsWith('__pigeon_')) { + result.add(Error( + message: + 'Parameter name must not begin with "__pigeon_" in constructor "${constructor.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } else if (parameter.name == 'pigeonChannelCodec') { + result.add(Error( + message: + 'Parameter name must not be "pigeonChannelCodec" in constructor "${constructor.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } else if (parameter.name.startsWith(classNamePrefix)) { + result.add(Error( + message: + 'Parameter name must not begin with "$classNamePrefix" in constructor "${constructor.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } else if (parameter.name.startsWith(classMemberNamePrefix)) { + result.add(Error( + message: + 'Parameter name must not begin with "$classMemberNamePrefix" in constructor "${constructor.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } + } + if (constructor.swiftFunction.isNotEmpty) { + final RegExp signatureRegex = + RegExp('\\w+ *\\((\\w+:){${constructor.parameters.length}}\\)'); + if (!signatureRegex.hasMatch(constructor.swiftFunction)) { + result.add(Error( + message: + 'Invalid constructor signature, expected ${constructor.parameters.length} parameters.', + lineNumber: _calculateLineNumberNullable(source, constructor.offset), + )); + } + } + } + + // Validate method parameters + for (final Method method in api.methods) { + for (final Parameter parameter in method.parameters) { + if (isDataClass(parameter)) { + result.add(unsupportedDataClassError(parameter)); + } + + if (parameter.name.startsWith(classNamePrefix)) { + result.add(Error( + message: + 'Parameter name must not begin with "$classNamePrefix" in method "${method.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } else if (parameter.name.startsWith(classMemberNamePrefix)) { + result.add(Error( + message: + 'Parameter name must not begin with "$classMemberNamePrefix" in method "${method.name}" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, parameter.offset), + )); + } + } + + if (method.location == ApiLocation.flutter && method.isStatic) { + result.add(Error( + message: 'Static callback methods are not supported: ${method.name}.', + lineNumber: _calculateLineNumberNullable(source, method.offset), + )); + } + } + + // Validate fields + for (final Field field in api.fields) { + if (isDataClass(field)) { + result.add(unsupportedDataClassError(field)); + } else if (field.isStatic) { + if (!isProxyApi(field)) { + result.add(Error( + message: + 'Static fields are considered attached fields and must be a ProxyApi: ${field.type.baseName}.', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } else if (field.type.isNullable) { + result.add(Error( + message: + 'Static fields are considered attached fields and must not be nullable: ${field.type.baseName}.', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } + } else if (field.isAttached) { + if (!isProxyApi(field)) { + result.add(Error( + message: + 'Attached fields must be a ProxyApi: ${field.type.baseName}.', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } + if (field.type.isNullable) { + result.add(Error( + message: + 'Attached fields must not be nullable: ${field.type.baseName}.', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } + } + + if (field.name.startsWith('__pigeon_')) { + result.add(Error( + message: + 'Field name must not begin with "__pigeon_" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } else if (field.name == 'pigeonChannelCodec') { + result.add(Error( + message: + 'Field name must not be "pigeonChannelCodec" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } else if (field.name.startsWith(classNamePrefix)) { + result.add(Error( + message: + 'Field name must not begin with "$classNamePrefix" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } else if (field.name.startsWith(classMemberNamePrefix)) { + result.add(Error( + message: + 'Field name must not begin with "$classMemberNamePrefix" in API: "${api.name}"', + lineNumber: _calculateLineNumberNullable(source, field.offset), + )); + } + } + + return result; +} + class _FindInitializer extends dart_ast_visitor.RecursiveAstVisitor { dart_ast.Expression? initializer; @override @@ -927,6 +1265,10 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { !referencedEnums .map((Enum e) => e.name) .contains(element.key.baseName) && + !_apis + .whereType() + .map((AstProxyApi e) => e.name) + .contains(element.key.baseName) && !validTypes.contains(element.key.baseName) && !element.key.isVoid && element.key.baseName != 'dynamic' && @@ -943,7 +1285,9 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { for (final Class classDefinition in referencedClasses) { final List fields = []; for (final NamedType field in classDefinition.fields) { - fields.add(field.copyWithType(_attachClassesAndEnums(field.type))); + fields.add(field.copyWithType( + _attachClassesEnumsAndProxyApis(field.type), + )); } classDefinition.fields = fields; } @@ -952,10 +1296,31 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { for (final Method func in api.methods) { final List paramList = []; for (final Parameter param in func.parameters) { - paramList.add(param.copyWithType(_attachClassesAndEnums(param.type))); + paramList.add(param.copyWithType( + _attachClassesEnumsAndProxyApis(param.type), + )); } func.parameters = paramList; - func.returnType = _attachClassesAndEnums(func.returnType); + func.returnType = _attachClassesEnumsAndProxyApis(func.returnType); + } + if (api is AstProxyApi) { + for (final Constructor constructor in api.constructors) { + final List paramList = []; + for (final Parameter param in constructor.parameters) { + paramList.add( + param.copyWithType(_attachClassesEnumsAndProxyApis(param.type)), + ); + } + constructor.parameters = paramList; + } + + final List fieldList = []; + for (final Field field in api.fields) { + fieldList.add(field.copyWithType( + _attachClassesEnumsAndProxyApis(field.type), + )); + } + api.fields = fieldList; } } @@ -968,15 +1333,21 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { ); } - TypeDeclaration _attachClassesAndEnums(TypeDeclaration type) { + TypeDeclaration _attachClassesEnumsAndProxyApis(TypeDeclaration type) { final Enum? assocEnum = _enums.firstWhereOrNull( (Enum enumDefinition) => enumDefinition.name == type.baseName); final Class? assocClass = _classes.firstWhereOrNull( (Class classDefinition) => classDefinition.name == type.baseName); + final AstProxyApi? assocProxyApi = + _apis.whereType().firstWhereOrNull( + (Api apiDefinition) => apiDefinition.name == type.baseName, + ); if (assocClass != null) { return type.copyWithClass(assocClass); } else if (assocEnum != null) { return type.copyWithEnum(assocEnum); + } else if (assocProxyApi != null) { + return type.copyWithProxyApi(assocProxyApi); } return type; } @@ -1003,6 +1374,8 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { return expression.value!; } else if (expression is dart_ast.BooleanLiteral) { return expression.value; + } else if (expression is dart_ast.SimpleIdentifier) { + return expression.name; } else if (expression is dart_ast.ListLiteral) { final List list = []; for (final dart_ast.CollectionElement element in expression.elements) { @@ -1016,6 +1389,19 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { } } return list; + } else if (expression is dart_ast.SetOrMapLiteral) { + final Set set = {}; + for (final dart_ast.CollectionElement element in expression.elements) { + if (element is dart_ast.Expression) { + set.add(_expressionToMap(element)); + } else { + _errors.add(Error( + message: 'expected Expression but found $element', + lineNumber: _calculateLineNumber(source, element.offset), + )); + } + } + return set; } else { _errors.add(Error( message: @@ -1081,19 +1467,57 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { } } } - _currentApi = Api( + + _currentApi = AstHostApi( name: node.name.lexeme, - location: ApiLocation.host, methods: [], dartHostTestHandler: dartHostTestHandler, documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); } else if (_hasMetadata(node.metadata, 'FlutterApi')) { - _currentApi = Api( + _currentApi = AstFlutterApi( + name: node.name.lexeme, + methods: [], + documentationComments: + _documentationCommentsParser(node.documentationComment?.tokens), + ); + } else if (_hasMetadata(node.metadata, 'ProxyApi')) { + final dart_ast.Annotation proxyApiAnnotation = node.metadata.firstWhere( + (dart_ast.Annotation element) => element.name.name == 'ProxyApi', + ); + + final Map annotationMap = {}; + for (final dart_ast.Expression expression + in proxyApiAnnotation.arguments!.arguments) { + if (expression is dart_ast.NamedExpression) { + annotationMap[expression.name.label.name] = + _expressionToMap(expression.expression); + } + } + + final String? superClassName = annotationMap['superClass'] as String?; + if (superClassName != null && node.extendsClause != null) { + _errors.add( + Error( + message: + 'ProxyApis should either set the super class in the annotation OR use extends: ("${node.name.lexeme}").', + lineNumber: _calculateLineNumber(source, node.offset), + ), + ); + } + + _currentApi = AstProxyApi( name: node.name.lexeme, - location: ApiLocation.flutter, methods: [], + constructors: [], + fields: [], + superClassName: + superClassName ?? node.extendsClause?.superclass.name2.lexeme, + interfacesNames: node.implementsClause?.interfaces + .map((dart_ast.NamedType type) => type.name2.lexeme) + .toSet() ?? + {}, documentationComments: _documentationCommentsParser(node.documentationComment?.tokens), ); @@ -1204,6 +1628,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { final List arguments = parameters.parameters.map(formalParameterToPigeonParameter).toList(); final bool isAsynchronous = _hasMetadata(node.metadata, 'async'); + final bool isStatic = _hasMetadata(node.metadata, 'static'); final String objcSelector = _findMetadata(node.metadata, 'ObjCSelector') ?.arguments ?.arguments @@ -1243,6 +1668,13 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { typeAnnotationsToTypeArguments(returnType.typeArguments), isNullable: returnType.question != null), parameters: arguments, + required: true, + isStatic: isStatic, + location: switch (_currentApi!) { + AstHostApi() => ApiLocation.host, + AstProxyApi() => ApiLocation.host, + AstFlutterApi() => ApiLocation.flutter, + }, isAsynchronous: isAsynchronous, objcSelector: objcSelector, swiftFunction: swiftFunction, @@ -1298,8 +1730,8 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { @override Object? visitFieldDeclaration(dart_ast.FieldDeclaration node) { + final dart_ast.TypeAnnotation? type = node.fields.type; if (_currentClass != null) { - final dart_ast.TypeAnnotation? type = node.fields.type; if (node.isStatic) { _errors.add(Error( message: @@ -1335,6 +1767,88 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { message: 'Expected a named type but found "$node".', lineNumber: _calculateLineNumber(source, node.offset))); } + } else if (_currentApi is AstProxyApi) { + final bool isStatic = _hasMetadata(node.metadata, 'static'); + if (type is dart_ast.GenericFunctionType) { + final List parameters = type.parameters.parameters + .map(formalParameterToPigeonParameter) + .toList(); + final String swiftFunction = + _findMetadata(node.metadata, 'SwiftFunction') + ?.arguments + ?.arguments + .first + .asNullable() + ?.value ?? + ''; + final dart_ast.ArgumentList? taskQueueArguments = + _findMetadata(node.metadata, 'TaskQueue')?.arguments; + final String? taskQueueTypeName = taskQueueArguments == null + ? null + : getFirstChildOfType(taskQueueArguments) + ?.expression + .asNullable() + ?.name; + final TaskQueueType taskQueueType = + _stringToEnum(TaskQueueType.values, taskQueueTypeName) ?? + TaskQueueType.serial; + + // Methods without named return types aren't supported. + final dart_ast.TypeAnnotation returnType = type.returnType!; + returnType as dart_ast.NamedType; + + _currentApi!.methods.add( + Method( + name: node.fields.variables[0].name.lexeme, + returnType: TypeDeclaration( + baseName: _getNamedTypeQualifiedName(returnType), + typeArguments: + typeAnnotationsToTypeArguments(returnType.typeArguments), + isNullable: returnType.question != null, + ), + location: ApiLocation.flutter, + required: type.question == null, + isStatic: isStatic, + parameters: parameters, + isAsynchronous: _hasMetadata(node.metadata, 'async'), + swiftFunction: swiftFunction, + offset: node.offset, + taskQueueType: taskQueueType, + documentationComments: + _documentationCommentsParser(node.documentationComment?.tokens), + ), + ); + } else if (type is dart_ast.NamedType) { + final _FindInitializer findInitializerVisitor = _FindInitializer(); + node.visitChildren(findInitializerVisitor); + if (findInitializerVisitor.initializer != null) { + _errors.add(Error( + message: + 'Initialization isn\'t supported for fields in ProxyApis ("$node"), just use nullable types with no initializer (example "int? x;").', + lineNumber: _calculateLineNumber(source, node.offset))); + } else { + final dart_ast.TypeArgumentList? typeArguments = type.typeArguments; + (_currentApi as AstProxyApi?)!.fields.add( + Field( + type: TypeDeclaration( + baseName: _getNamedTypeQualifiedName(type), + isNullable: type.question != null, + typeArguments: typeAnnotationsToTypeArguments( + typeArguments, + ), + ), + name: node.fields.variables[0].name.lexeme, + isAttached: + _hasMetadata(node.metadata, 'attached') || isStatic, + isStatic: isStatic, + offset: node.offset, + documentationComments: _documentationCommentsParser( + node.documentationComment?.tokens, + ), + ), + ); + } + } } else if (_currentApi != null) { _errors.add(Error( message: 'Fields aren\'t supported in Pigeon API classes ("$node").', @@ -1346,7 +1860,30 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor { @override Object? visitConstructorDeclaration(dart_ast.ConstructorDeclaration node) { - if (_currentApi != null) { + if (_currentApi is AstProxyApi) { + final dart_ast.FormalParameterList parameters = node.parameters; + final List arguments = + parameters.parameters.map(formalParameterToPigeonParameter).toList(); + final String swiftFunction = _findMetadata(node.metadata, 'SwiftFunction') + ?.arguments + ?.arguments + .first + .asNullable() + ?.value ?? + ''; + + (_currentApi as AstProxyApi?)!.constructors.add( + Constructor( + name: node.name?.lexeme ?? '', + parameters: arguments, + swiftFunction: swiftFunction, + offset: node.offset, + documentationComments: _documentationCommentsParser( + node.documentationComment?.tokens, + ), + ), + ); + } else if (_currentApi != null) { _errors.add(Error( message: 'Constructors aren\'t supported in API classes ("$node").', lineNumber: _calculateLineNumber(source, node.offset))); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index ae869426e620..36d0c0d8dbea 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart'; + import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; @@ -100,7 +102,7 @@ import FlutterMacOS indent.write('enum ${anEnum.name}: Int '); indent.addScoped('{', '}', () { - enumerate(anEnum.members, (int index, final EnumMember member) { + anEnum.members.forEachIndexed((int index, final EnumMember member) { addDocumentationComments( indent, member.documentationComments, _docCommentSpec); indent.writeln('case ${_camelCase(member.name)} = $index'); @@ -191,8 +193,8 @@ import FlutterMacOS indent.write('static func fromList(_ list: [Any?]) -> $className? '); indent.addScoped('{', '}', () { - enumerate(getFieldsInSerializationOrder(classDefinition), - (int index, final NamedType field) { + getFieldsInSerializationOrder(classDefinition) + .forEachIndexed((int index, final NamedType field) { final String listValue = 'list[$index]'; _writeDecodeCasting( @@ -236,7 +238,7 @@ import FlutterMacOS required String dartPackageName, }) { if (root.apis.any((Api api) => - api.location == ApiLocation.host && + api is AstHostApi && api.methods.any((Method it) => it.isAsynchronous))) { indent.newln(); } @@ -256,11 +258,9 @@ import FlutterMacOS SwiftOptions generatorOptions, Root root, Indent indent, - Api api, { + AstFlutterApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.flutter); - /// Returns an argument name that can be used in a context where it is possible to collide. String getEnumSafeArgumentExpression( Root root, int count, NamedType argument) { @@ -380,11 +380,9 @@ import FlutterMacOS SwiftOptions generatorOptions, Root root, Indent indent, - Api api, { + AstHostApi api, { required String dartPackageName, }) { - assert(api.location == ApiLocation.host); - final String apiName = api.name; final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; @@ -473,8 +471,8 @@ import FlutterMacOS final List methodArgument = []; if (components.arguments.isNotEmpty) { indent.writeln('let args = message as! [Any?]'); - enumerate(components.arguments, - (int index, _SwiftFunctionArgument arg) { + components.arguments + .forEachIndexed((int index, _SwiftFunctionArgument arg) { final String argName = _getSafeArgumentName(index, arg.namedType); final String argIndex = 'args[$index]'; @@ -802,10 +800,12 @@ private func nilOrValue(_ value: Any?) -> T? { Indent indent, { required String dartPackageName, }) { - final bool hasHostApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.host); - final bool hasFlutterApi = root.apis.any((Api api) => - api.methods.isNotEmpty && api.location == ApiLocation.flutter); + final bool hasHostApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); + final bool hasFlutterApi = root.apis + .whereType() + .any((Api api) => api.methods.isNotEmpty); if (hasHostApi) { _writeWrapResult(indent); @@ -906,12 +906,12 @@ String _getMethodSignature(Method func) { } else { final Iterable argTypes = func.parameters .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); - final Iterable argLabels = indexMap(components.arguments, - (int index, _SwiftFunctionArgument argument) { + final Iterable argLabels = components.arguments + .mapIndexed((int index, _SwiftFunctionArgument argument) { return argument.label ?? _getArgumentName(index, argument.namedType); }); final Iterable argNames = - indexMap(func.parameters, _getSafeArgumentName); + func.parameters.mapIndexed(_getSafeArgumentName); final String argsSignature = map3(argTypes, argLabels, argNames, (String type, String label, String name) => '$label $name: $type') .join(', '); diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index a0c6a3ccf29f..0a98f5b95128 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -699,3 +699,460 @@ class TestMessage { // ignore: always_specify_types, strict_raw_type List? testList; } + +/// The core interface that each host language plugin must implement in +/// platform_test integration tests. +@ProxyApi() +abstract class ProxyIntegrationCoreApi extends ProxyApiSuperClass + implements ProxyApiInterface { + ProxyIntegrationCoreApi( + // ignore: avoid_unused_constructor_parameters + bool boolParam, + // ignore: avoid_unused_constructor_parameters + int intParam, + // ignore: avoid_unused_constructor_parameters + double doubleParam, + // ignore: avoid_unused_constructor_parameters + String stringParam, + // ignore: avoid_unused_constructor_parameters + Uint8List aUint8ListParam, + // ignore: avoid_unused_constructor_parameters + List listParam, + // ignore: avoid_unused_constructor_parameters + Map mapParam, + // ignore: avoid_unused_constructor_parameters + AnEnum enumParam, + // ignore: avoid_unused_constructor_parameters + ProxyApiSuperClass proxyApiParam, + // ignore: avoid_unused_constructor_parameters + bool? nullableBoolParam, + // ignore: avoid_unused_constructor_parameters + int? nullableIntParam, + // ignore: avoid_unused_constructor_parameters + double? nullableDoubleParam, + // ignore: avoid_unused_constructor_parameters + String? nullableStringParam, + // ignore: avoid_unused_constructor_parameters + Uint8List? nullableUint8ListParam, + // ignore: avoid_unused_constructor_parameters + List? nullableListParam, + // ignore: avoid_unused_constructor_parameters + Map? nullableMapParam, + // ignore: avoid_unused_constructor_parameters + AnEnum? nullableEnumParam, + // ignore: avoid_unused_constructor_parameters + ProxyApiSuperClass? nullableProxyApiParam, + ); + + late bool aBool; + late int anInt; + late double aDouble; + late String aString; + late Uint8List aUint8List; + late List aList; + late Map aMap; + late AnEnum anEnum; + late ProxyApiSuperClass aProxyApi; + + late bool? aNullableBool; + late int? aNullableInt; + late double? aNullableDouble; + late String? aNullableString; + late Uint8List? aNullableUint8List; + late List? aNullableList; + late Map? aNullableMap; + late AnEnum? aNullableEnum; + late ProxyApiSuperClass? aNullableProxyApi; + + @attached + late ProxyApiSuperClass attachedField; + + @static + late ProxyApiSuperClass staticAttachedField; + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + late void Function()? flutterNoop; + + /// Responds with an error from an async function returning a value. + late Object? Function()? flutterThrowError; + + /// Responds with an error from an async void function. + late void Function()? flutterThrowErrorFromVoid; + + // ========== Non-nullable argument/return type tests ========== + + /// Returns the passed boolean, to test serialization and deserialization. + late bool Function(bool aBool)? flutterEchoBool; + + /// Returns the passed int, to test serialization and deserialization. + late int Function(int anInt)? flutterEchoInt; + + /// Returns the passed double, to test serialization and deserialization. + late double Function(double aDouble)? flutterEchoDouble; + + /// Returns the passed string, to test serialization and deserialization. + late String Function(String aString)? flutterEchoString; + + /// Returns the passed byte list, to test serialization and deserialization. + late Uint8List Function(Uint8List aList)? flutterEchoUint8List; + + /// Returns the passed list, to test serialization and deserialization. + late List Function(List aList)? flutterEchoList; + + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + late List Function( + List aList)? flutterEchoProxyApiList; + + /// Returns the passed map, to test serialization and deserialization. + late Map Function(Map aMap)? + flutterEchoMap; + + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + late Map Function( + Map aMap)? flutterEchoProxyApiMap; + + /// Returns the passed enum to test serialization and deserialization. + late AnEnum Function(AnEnum anEnum)? flutterEchoEnum; + + /// Returns the passed ProxyApi to test serialization and deserialization. + late ProxyApiSuperClass Function(ProxyApiSuperClass aProxyApi)? + flutterEchoProxyApi; + + // ========== Nullable argument/return type tests ========== + + /// Returns the passed boolean, to test serialization and deserialization. + late bool? Function(bool? aBool)? flutterEchoNullableBool; + + /// Returns the passed int, to test serialization and deserialization. + late int? Function(int? anInt)? flutterEchoNullableInt; + + /// Returns the passed double, to test serialization and deserialization. + late double? Function(double? aDouble)? flutterEchoNullableDouble; + + /// Returns the passed string, to test serialization and deserialization. + late String? Function(String? aString)? flutterEchoNullableString; + + /// Returns the passed byte list, to test serialization and deserialization. + late Uint8List? Function(Uint8List? aList)? flutterEchoNullableUint8List; + + /// Returns the passed list, to test serialization and deserialization. + late List? Function(List? aList)? flutterEchoNullableList; + + /// Returns the passed map, to test serialization and deserialization. + late Map? Function(Map? aMap)? + flutterEchoNullableMap; + + /// Returns the passed enum to test serialization and deserialization. + late AnEnum? Function(AnEnum? anEnum)? flutterEchoNullableEnum; + + /// Returns the passed ProxyApi to test serialization and deserialization. + late ProxyApiSuperClass? Function(ProxyApiSuperClass? aProxyApi)? + flutterEchoNullableProxyApi; + + // ========== Async tests ========== + // These are minimal since async FlutterApi only changes Dart generation. + // Currently they aren't integration tested, but having them here ensures + // analysis coverage. + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + @async + late void Function()? flutterNoopAsync; + + /// Returns the passed in generic Object asynchronously. + @async + late String Function(String aString)? flutterEchoAsyncString; + + // ========== Synchronous host method tests ========== + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + void noop(); + + /// Returns an error, to test error handling. + Object? throwError(); + + /// Returns an error from a void function, to test error handling. + void throwErrorFromVoid(); + + /// Returns a Flutter error, to test error handling. + Object? throwFlutterError(); + + /// Returns passed in int. + int echoInt(int anInt); + + /// Returns passed in double. + double echoDouble(double aDouble); + + /// Returns the passed in boolean. + bool echoBool(bool aBool); + + /// Returns the passed in string. + String echoString(String aString); + + /// Returns the passed in Uint8List. + Uint8List echoUint8List(Uint8List aUint8List); + + /// Returns the passed in generic Object. + Object echoObject(Object anObject); + + /// Returns the passed list, to test serialization and deserialization. + List echoList(List aList); + + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + List echoProxyApiList( + List aList, + ); + + /// Returns the passed map, to test serialization and deserialization. + Map echoMap(Map aMap); + + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + Map echoProxyApiMap( + Map aMap, + ); + + /// Returns the passed enum to test serialization and deserialization. + AnEnum echoEnum(AnEnum anEnum); + + /// Returns the passed ProxyApi to test serialization and deserialization. + ProxyApiSuperClass echoProxyApi(ProxyApiSuperClass aProxyApi); + + // ========== Synchronous host nullable method tests ========== + + /// Returns passed in int. + int? echoNullableInt(int? aNullableInt); + + /// Returns passed in double. + double? echoNullableDouble(double? aNullableDouble); + + /// Returns the passed in boolean. + bool? echoNullableBool(bool? aNullableBool); + + /// Returns the passed in string. + String? echoNullableString(String? aNullableString); + + /// Returns the passed in Uint8List. + Uint8List? echoNullableUint8List(Uint8List? aNullableUint8List); + + /// Returns the passed in generic Object. + Object? echoNullableObject(Object? aNullableObject); + + /// Returns the passed list, to test serialization and deserialization. + List? echoNullableList(List? aNullableList); + + /// Returns the passed map, to test serialization and deserialization. + Map? echoNullableMap(Map? aNullableMap); + + AnEnum? echoNullableEnum(AnEnum? aNullableEnum); + + /// Returns the passed ProxyApi to test serialization and deserialization. + ProxyApiSuperClass? echoNullableProxyApi( + ProxyApiSuperClass? aNullableProxyApi, + ); + + // ========== Asynchronous method tests ========== + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + @async + void noopAsync(); + + /// Returns passed in int asynchronously. + @async + int echoAsyncInt(int anInt); + + /// Returns passed in double asynchronously. + @async + double echoAsyncDouble(double aDouble); + + /// Returns the passed in boolean asynchronously. + @async + bool echoAsyncBool(bool aBool); + + /// Returns the passed string asynchronously. + @async + String echoAsyncString(String aString); + + /// Returns the passed in Uint8List asynchronously. + @async + Uint8List echoAsyncUint8List(Uint8List aUint8List); + + /// Returns the passed in generic Object asynchronously. + @async + Object echoAsyncObject(Object anObject); + + /// Returns the passed list, to test asynchronous serialization and deserialization. + @async + List echoAsyncList(List aList); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + Map echoAsyncMap(Map aMap); + + /// Returns the passed enum, to test asynchronous serialization and deserialization. + @async + AnEnum echoAsyncEnum(AnEnum anEnum); + + /// Responds with an error from an async function returning a value. + @async + Object? throwAsyncError(); + + /// Responds with an error from an async void function. + @async + void throwAsyncErrorFromVoid(); + + /// Responds with a Flutter error from an async function returning a value. + @async + Object? throwAsyncFlutterError(); + + /// Returns passed in int asynchronously. + @async + int? echoAsyncNullableInt(int? anInt); + + /// Returns passed in double asynchronously. + @async + double? echoAsyncNullableDouble(double? aDouble); + + /// Returns the passed in boolean asynchronously. + @async + bool? echoAsyncNullableBool(bool? aBool); + + /// Returns the passed string asynchronously. + @async + String? echoAsyncNullableString(String? aString); + + /// Returns the passed in Uint8List asynchronously. + @async + Uint8List? echoAsyncNullableUint8List(Uint8List? aUint8List); + + /// Returns the passed in generic Object asynchronously. + @async + Object? echoAsyncNullableObject(Object? anObject); + + /// Returns the passed list, to test asynchronous serialization and deserialization. + @async + List? echoAsyncNullableList(List? aList); + + /// Returns the passed map, to test asynchronous serialization and deserialization. + @async + Map? echoAsyncNullableMap(Map? aMap); + + /// Returns the passed enum, to test asynchronous serialization and deserialization. + @async + AnEnum? echoAsyncNullableEnum(AnEnum? anEnum); + + // ========== Static method test ========== + + @static + void staticNoop(); + + @static + String echoStaticString(String aString); + + @static + @async + void staticAsyncNoop(); + + // ========== Flutter methods test wrappers ========== + + @async + void callFlutterNoop(); + + @async + Object? callFlutterThrowError(); + + @async + void callFlutterThrowErrorFromVoid(); + + @async + bool callFlutterEchoBool(bool aBool); + + @async + int callFlutterEchoInt(int anInt); + + @async + double callFlutterEchoDouble(double aDouble); + + @async + String callFlutterEchoString(String aString); + + @async + Uint8List callFlutterEchoUint8List(Uint8List aUint8List); + + @async + List callFlutterEchoList(List aList); + + @async + List callFlutterEchoProxyApiList( + List aList); + + @async + Map callFlutterEchoMap(Map aMap); + + @async + Map callFlutterEchoProxyApiMap( + Map aMap); + + @async + AnEnum callFlutterEchoEnum(AnEnum anEnum); + + @async + ProxyApiSuperClass callFlutterEchoProxyApi(ProxyApiSuperClass aProxyApi); + + @async + bool? callFlutterEchoNullableBool(bool? aBool); + + @async + int? callFlutterEchoNullableInt(int? anInt); + + @async + double? callFlutterEchoNullableDouble(double? aDouble); + + @async + String? callFlutterEchoNullableString(String? aString); + + @async + Uint8List? callFlutterEchoNullableUint8List(Uint8List? aUint8List); + + @async + List? callFlutterEchoNullableList(List? aList); + + @async + Map? callFlutterEchoNullableMap( + Map? aMap, + ); + + @async + AnEnum? callFlutterEchoNullableEnum(AnEnum? anEnum); + + @async + ProxyApiSuperClass? callFlutterEchoNullableProxyApi( + ProxyApiSuperClass? aProxyApi, + ); + + @async + void callFlutterNoopAsync(); + + @async + String callFlutterEchoAsyncString(String aString); +} + +/// ProxyApi to serve as a super class to the core ProxyApi interface. +@ProxyApi() +abstract class ProxyApiSuperClass { + ProxyApiSuperClass(); + + void aSuperMethod(); +} + +/// ProxyApi to serve as an interface to the core ProxyApi interface. +@ProxyApi() +abstract class ProxyApiInterface { + late void Function()? anInterfaceMethod; +} diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart index 7222e263b32b..91dee132ceba 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/background_platform_channels.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index 6815f461c943..8d83750e71fc 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -4,13 +4,15 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/foundation.dart' + show ReadBuffer, WriteBuffer, immutable, protected; import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart' show WidgetsFlutterBinding; PlatformException _createConnectionError(String channelName) { return PlatformException( @@ -30,6 +32,365 @@ List wrapResponse( return [error.code, error.message, error.details]; } +/// An immutable object that serves as the base class for all ProxyApis and +/// can provide functional copies of itself. +/// +/// All implementers are expected to be [immutable] as defined by the annotation +/// and override [pigeon_copy] returning an instance of itself. +@immutable +abstract class Pigeon_ProxyApiBaseClass { + /// Construct a [Pigeon_ProxyApiBaseClass]. + Pigeon_ProxyApiBaseClass({ + this.pigeon_binaryMessenger, + Pigeon_InstanceManager? pigeon_instanceManager, + }) : pigeon_instanceManager = + pigeon_instanceManager ?? Pigeon_InstanceManager.instance; + + /// Sends and receives binary data across the Flutter platform barrier. + /// + /// If it is null, the default BinaryMessenger will be used, which routes to + /// the host platform. + final BinaryMessenger? pigeon_binaryMessenger; + + /// Maintains instances stored to communicate with native language objects. + final Pigeon_InstanceManager pigeon_instanceManager; + + /// Instantiates and returns a functionally identical object to oneself. + /// + /// Outside of tests, this method should only ever be called by + /// [Pigeon_InstanceManager]. + /// + /// Subclasses should always override their parent's implementation of this + /// method. + @protected + Pigeon_ProxyApiBaseClass pigeon_copy(); +} + +/// Maintains instances used to communicate with the native objects they +/// represent. +/// +/// Added instances are stored as weak references and their copies are stored +/// as strong references to maintain access to their variables and callback +/// methods. Both are stored with the same identifier. +/// +/// When a weak referenced instance becomes inaccessible, +/// [onWeakReferenceRemoved] is called with its associated identifier. +/// +/// If an instance is retrieved and has the possibility to be used, +/// (e.g. calling [getInstanceWithWeakReference]) a copy of the strong reference +/// is added as a weak reference with the same identifier. This prevents a +/// scenario where the weak referenced instance was released and then later +/// returned by the host platform. +class Pigeon_InstanceManager { + /// Constructs a [Pigeon_InstanceManager]. + Pigeon_InstanceManager({required void Function(int) onWeakReferenceRemoved}) { + this.onWeakReferenceRemoved = (int identifier) { + _weakInstances.remove(identifier); + onWeakReferenceRemoved(identifier); + }; + _finalizer = Finalizer(this.onWeakReferenceRemoved); + } + + // Identifiers are locked to a specific range to avoid collisions with objects + // created simultaneously by the host platform. + // Host uses identifiers >= 2^16 and Dart is expected to use values n where, + // 0 <= n < 2^16. + static const int _maxDartCreatedIdentifier = 65536; + + /// The default [Pigeon_InstanceManager] used by ProxyApis. + /// + /// On creation, this manager makes a call to clear the native + /// InstanceManager. This is to prevent identifier conflicts after a host + /// restart. + static final Pigeon_InstanceManager instance = _initInstance(); + + // Expando is used because it doesn't prevent its keys from becoming + // inaccessible. This allows the manager to efficiently retrieve an identifier + // of an instance without holding a strong reference to that instance. + // + // It also doesn't use `==` to search for identifiers, which would lead to an + // infinite loop when comparing an object to its copy. (i.e. which was caused + // by calling instanceManager.getIdentifier() inside of `==` while this was a + // HashMap). + final Expando _identifiers = Expando(); + final Map> _weakInstances = + >{}; + final Map _strongInstances = + {}; + late final Finalizer _finalizer; + int _nextIdentifier = 0; + + /// Called when a weak referenced instance is removed by [removeWeakReference] + /// or becomes inaccessible. + late final void Function(int) onWeakReferenceRemoved; + + static Pigeon_InstanceManager _initInstance() { + WidgetsFlutterBinding.ensureInitialized(); + final _Pigeon_InstanceManagerApi api = _Pigeon_InstanceManagerApi(); + // Clears the native `Pigeon_InstanceManager` on the initial use of the Dart one. + api.clear(); + final Pigeon_InstanceManager instanceManager = Pigeon_InstanceManager( + onWeakReferenceRemoved: (int identifier) { + api.removeStrongReference(identifier); + }, + ); + _Pigeon_InstanceManagerApi.setUpMessageHandlers( + instanceManager: instanceManager); + ProxyIntegrationCoreApi.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + ProxyApiSuperClass.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + ProxyApiInterface.pigeon_setUpMessageHandlers( + pigeon_instanceManager: instanceManager); + return instanceManager; + } + + /// Adds a new instance that was instantiated by Dart. + /// + /// In other words, Dart wants to add a new instance that will represent + /// an object that will be instantiated on the host platform. + /// + /// Throws assertion error if the instance has already been added. + /// + /// Returns the randomly generated id of the [instance] added. + int addDartCreatedInstance(Pigeon_ProxyApiBaseClass instance) { + final int identifier = _nextUniqueIdentifier(); + _addInstanceWithIdentifier(instance, identifier); + return identifier; + } + + /// Removes the instance, if present, and call [onWeakReferenceRemoved] with + /// its identifier. + /// + /// Returns the identifier associated with the removed instance. Otherwise, + /// `null` if the instance was not found in this manager. + /// + /// This does not remove the strong referenced instance associated with + /// [instance]. This can be done with [remove]. + int? removeWeakReference(Pigeon_ProxyApiBaseClass instance) { + final int? identifier = getIdentifier(instance); + if (identifier == null) { + return null; + } + + _identifiers[instance] = null; + _finalizer.detach(instance); + onWeakReferenceRemoved(identifier); + + return identifier; + } + + /// Removes [identifier] and its associated strongly referenced instance, if + /// present, from the manager. + /// + /// Returns the strong referenced instance associated with [identifier] before + /// it was removed. Returns `null` if [identifier] was not associated with + /// any strong reference. + /// + /// This does not remove the weak referenced instance associated with + /// [identifier]. This can be done with [removeWeakReference]. + T? remove(int identifier) { + return _strongInstances.remove(identifier) as T?; + } + + /// Retrieves the instance associated with identifier. + /// + /// The value returned is chosen from the following order: + /// + /// 1. A weakly referenced instance associated with identifier. + /// 2. If the only instance associated with identifier is a strongly + /// referenced instance, a copy of the instance is added as a weak reference + /// with the same identifier. Returning the newly created copy. + /// 3. If no instance is associated with identifier, returns null. + /// + /// This method also expects the host `InstanceManager` to have a strong + /// reference to the instance the identifier is associated with. + T? getInstanceWithWeakReference( + int identifier) { + final Pigeon_ProxyApiBaseClass? weakInstance = + _weakInstances[identifier]?.target; + + if (weakInstance == null) { + final Pigeon_ProxyApiBaseClass? strongInstance = + _strongInstances[identifier]; + if (strongInstance != null) { + final Pigeon_ProxyApiBaseClass copy = strongInstance.pigeon_copy(); + _identifiers[copy] = identifier; + _weakInstances[identifier] = + WeakReference(copy); + _finalizer.attach(copy, identifier, detach: copy); + return copy as T; + } + return strongInstance as T?; + } + + return weakInstance as T; + } + + /// Retrieves the identifier associated with instance. + int? getIdentifier(Pigeon_ProxyApiBaseClass instance) { + return _identifiers[instance]; + } + + /// Adds a new instance that was instantiated by the host platform. + /// + /// In other words, the host platform wants to add a new instance that + /// represents an object on the host platform. Stored with [identifier]. + /// + /// Throws assertion error if the instance or its identifier has already been + /// added. + /// + /// Returns unique identifier of the [instance] added. + void addHostCreatedInstance( + Pigeon_ProxyApiBaseClass instance, int identifier) { + _addInstanceWithIdentifier(instance, identifier); + } + + void _addInstanceWithIdentifier( + Pigeon_ProxyApiBaseClass instance, int identifier) { + assert(!containsIdentifier(identifier)); + assert(getIdentifier(instance) == null); + assert(identifier >= 0); + + _identifiers[instance] = identifier; + _weakInstances[identifier] = + WeakReference(instance); + _finalizer.attach(instance, identifier, detach: instance); + + final Pigeon_ProxyApiBaseClass copy = instance.pigeon_copy(); + _identifiers[copy] = identifier; + _strongInstances[identifier] = copy; + } + + /// Whether this manager contains the given [identifier]. + bool containsIdentifier(int identifier) { + return _weakInstances.containsKey(identifier) || + _strongInstances.containsKey(identifier); + } + + int _nextUniqueIdentifier() { + late int identifier; + do { + identifier = _nextIdentifier; + _nextIdentifier = (_nextIdentifier + 1) % _maxDartCreatedIdentifier; + } while (containsIdentifier(identifier)); + return identifier; + } +} + +/// Generated API for managing the Dart and native `Pigeon_InstanceManager`s. +class _Pigeon_InstanceManagerApi { + /// Constructor for [_Pigeon_InstanceManagerApi ]. + _Pigeon_InstanceManagerApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + StandardMessageCodec(); + + static void setUpMessageHandlers({ + BinaryMessenger? binaryMessenger, + Pigeon_InstanceManager? instanceManager, + }) { + const String channelName = + r'dev.flutter.pigeon.pigeon_integration_tests.Pigeon_InstanceManagerApi.removeStrongReference'; + final BasicMessageChannel channel = BasicMessageChannel( + channelName, + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); + channel.setMessageHandler((Object? message) async { + assert( + message != null, + 'Argument for $channelName was null.', + ); + final int? identifier = message as int?; + assert( + identifier != null, + r'Argument for $channelName, expected non-null int.', + ); + (instanceManager ?? Pigeon_InstanceManager.instance).remove(identifier!); + return; + }); + } + + Future removeStrongReference(int identifier) async { + const String channelName = + r'dev.flutter.pigeon.pigeon_integration_tests.Pigeon_InstanceManagerApi.removeStrongReference'; + final BasicMessageChannel channel = BasicMessageChannel( + channelName, + pigeonChannelCodec, + binaryMessenger: _binaryMessenger, + ); + final List? replyList = + await channel.send(identifier) as List?; + if (replyList == null) { + throw _createConnectionError(channelName); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + /// Clear the native `Pigeon_InstanceManager`. + /// + /// This is typically called after a hot restart. + Future clear() async { + const String channelName = + r'dev.flutter.pigeon.pigeon_integration_tests.Pigeon_InstanceManagerApi.clear'; + final BasicMessageChannel channel = BasicMessageChannel( + channelName, + pigeonChannelCodec, + binaryMessenger: _binaryMessenger, + ); + final List? replyList = await channel.send(null) as List?; + if (replyList == null) { + throw _createConnectionError(channelName); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } +} + +class _Pigeon_ProxyApiBaseCodec extends StandardMessageCodec { + const _Pigeon_ProxyApiBaseCodec(this.instanceManager); + + final Pigeon_InstanceManager instanceManager; + + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is Pigeon_ProxyApiBaseClass) { + buffer.putUint8(128); + writeValue(buffer, instanceManager.getIdentifier(value)); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return instanceManager + .getInstanceWithWeakReference(readValue(buffer)! as int); + default: + return super.readValueOfType(type, buffer); + } + } +} + enum AnEnum { one, two, @@ -3446,3 +3807,4650 @@ abstract class FlutterSmallApi { } } } + +/// The core interface that each host language plugin must implement in +/// platform_test integration tests. +class ProxyIntegrationCoreApi extends ProxyApiSuperClass + implements ProxyApiInterface { + ProxyIntegrationCoreApi({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.aBool, + required this.anInt, + required this.aDouble, + required this.aString, + required this.aUint8List, + required this.aList, + required this.aMap, + required this.anEnum, + required this.aProxyApi, + this.aNullableBool, + this.aNullableInt, + this.aNullableDouble, + this.aNullableString, + this.aNullableUint8List, + this.aNullableList, + this.aNullableMap, + this.aNullableEnum, + this.aNullableProxyApi, + this.anInterfaceMethod, + this.flutterNoop, + this.flutterThrowError, + this.flutterThrowErrorFromVoid, + this.flutterEchoBool, + this.flutterEchoInt, + this.flutterEchoDouble, + this.flutterEchoString, + this.flutterEchoUint8List, + this.flutterEchoList, + this.flutterEchoProxyApiList, + this.flutterEchoMap, + this.flutterEchoProxyApiMap, + this.flutterEchoEnum, + this.flutterEchoProxyApi, + this.flutterEchoNullableBool, + this.flutterEchoNullableInt, + this.flutterEchoNullableDouble, + this.flutterEchoNullableString, + this.flutterEchoNullableUint8List, + this.flutterEchoNullableList, + this.flutterEchoNullableMap, + this.flutterEchoNullableEnum, + this.flutterEchoNullableProxyApi, + this.flutterNoopAsync, + this.flutterEchoAsyncString, + required bool boolParam, + required int intParam, + required double doubleParam, + required String stringParam, + required Uint8List aUint8ListParam, + required List listParam, + required Map mapParam, + required AnEnum enumParam, + required ProxyApiSuperClass proxyApiParam, + bool? nullableBoolParam, + int? nullableIntParam, + double? nullableDoubleParam, + String? nullableStringParam, + Uint8List? nullableUint8ListParam, + List? nullableListParam, + Map? nullableMapParam, + AnEnum? nullableEnumParam, + ProxyApiSuperClass? nullableProxyApiParam, + }) : super.pigeon_detached() { + final int __pigeon_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + () async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_defaultConstructor'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([ + __pigeon_instanceIdentifier, + aBool, + anInt, + aDouble, + aString, + aUint8List, + aList, + aMap, + anEnum.index, + aProxyApi, + aNullableBool, + aNullableInt, + aNullableDouble, + aNullableString, + aNullableUint8List, + aNullableList, + aNullableMap, + aNullableEnum?.index, + aNullableProxyApi, + boolParam, + intParam, + doubleParam, + stringParam, + aUint8ListParam, + listParam, + mapParam, + enumParam.index, + proxyApiParam, + nullableBoolParam, + nullableIntParam, + nullableDoubleParam, + nullableStringParam, + nullableUint8ListParam, + nullableListParam, + nullableMapParam, + nullableEnumParam?.index, + nullableProxyApiParam + ]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs ProxyIntegrationCoreApi without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies. + ProxyIntegrationCoreApi.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + required this.aBool, + required this.anInt, + required this.aDouble, + required this.aString, + required this.aUint8List, + required this.aList, + required this.aMap, + required this.anEnum, + required this.aProxyApi, + this.aNullableBool, + this.aNullableInt, + this.aNullableDouble, + this.aNullableString, + this.aNullableUint8List, + this.aNullableList, + this.aNullableMap, + this.aNullableEnum, + this.aNullableProxyApi, + this.anInterfaceMethod, + this.flutterNoop, + this.flutterThrowError, + this.flutterThrowErrorFromVoid, + this.flutterEchoBool, + this.flutterEchoInt, + this.flutterEchoDouble, + this.flutterEchoString, + this.flutterEchoUint8List, + this.flutterEchoList, + this.flutterEchoProxyApiList, + this.flutterEchoMap, + this.flutterEchoProxyApiMap, + this.flutterEchoEnum, + this.flutterEchoProxyApi, + this.flutterEchoNullableBool, + this.flutterEchoNullableInt, + this.flutterEchoNullableDouble, + this.flutterEchoNullableString, + this.flutterEchoNullableUint8List, + this.flutterEchoNullableList, + this.flutterEchoNullableMap, + this.flutterEchoNullableEnum, + this.flutterEchoNullableProxyApi, + this.flutterNoopAsync, + this.flutterEchoAsyncString, + }) : super.pigeon_detached(); + + late final _Pigeon_ProxyApiBaseCodec __pigeon_codecProxyIntegrationCoreApi = + _Pigeon_ProxyApiBaseCodec(pigeon_instanceManager); + + final bool aBool; + + final int anInt; + + final double aDouble; + + final String aString; + + final Uint8List aUint8List; + + final List aList; + + final Map aMap; + + final AnEnum anEnum; + + final ProxyApiSuperClass aProxyApi; + + final bool? aNullableBool; + + final int? aNullableInt; + + final double? aNullableDouble; + + final String? aNullableString; + + final Uint8List? aNullableUint8List; + + final List? aNullableList; + + final Map? aNullableMap; + + final AnEnum? aNullableEnum; + + final ProxyApiSuperClass? aNullableProxyApi; + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterNoop: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final void Function(ProxyIntegrationCoreApi pigeon_instance)? flutterNoop; + + /// Responds with an error from an async function returning a value. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterThrowError: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Object? Function(ProxyIntegrationCoreApi pigeon_instance)? + flutterThrowError; + + /// Responds with an error from an async void function. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterThrowErrorFromVoid: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final void Function(ProxyIntegrationCoreApi pigeon_instance)? + flutterThrowErrorFromVoid; + + /// Returns the passed boolean, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoBool: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final bool Function( + ProxyIntegrationCoreApi pigeon_instance, + bool aBool, + )? flutterEchoBool; + + /// Returns the passed int, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoInt: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final int Function( + ProxyIntegrationCoreApi pigeon_instance, + int anInt, + )? flutterEchoInt; + + /// Returns the passed double, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoDouble: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final double Function( + ProxyIntegrationCoreApi pigeon_instance, + double aDouble, + )? flutterEchoDouble; + + /// Returns the passed string, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoString: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final String Function( + ProxyIntegrationCoreApi pigeon_instance, + String aString, + )? flutterEchoString; + + /// Returns the passed byte list, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoUint8List: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Uint8List Function( + ProxyIntegrationCoreApi pigeon_instance, + Uint8List aList, + )? flutterEchoUint8List; + + /// Returns the passed list, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoList: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final List Function( + ProxyIntegrationCoreApi pigeon_instance, + List aList, + )? flutterEchoList; + + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoProxyApiList: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final List Function( + ProxyIntegrationCoreApi pigeon_instance, + List aList, + )? flutterEchoProxyApiList; + + /// Returns the passed map, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoMap: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Map Function( + ProxyIntegrationCoreApi pigeon_instance, + Map aMap, + )? flutterEchoMap; + + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoProxyApiMap: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Map Function( + ProxyIntegrationCoreApi pigeon_instance, + Map aMap, + )? flutterEchoProxyApiMap; + + /// Returns the passed enum to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoEnum: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final AnEnum Function( + ProxyIntegrationCoreApi pigeon_instance, + AnEnum anEnum, + )? flutterEchoEnum; + + /// Returns the passed ProxyApi to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoProxyApi: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final ProxyApiSuperClass Function( + ProxyIntegrationCoreApi pigeon_instance, + ProxyApiSuperClass aProxyApi, + )? flutterEchoProxyApi; + + /// Returns the passed boolean, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableBool: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final bool? Function( + ProxyIntegrationCoreApi pigeon_instance, + bool? aBool, + )? flutterEchoNullableBool; + + /// Returns the passed int, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableInt: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final int? Function( + ProxyIntegrationCoreApi pigeon_instance, + int? anInt, + )? flutterEchoNullableInt; + + /// Returns the passed double, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableDouble: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final double? Function( + ProxyIntegrationCoreApi pigeon_instance, + double? aDouble, + )? flutterEchoNullableDouble; + + /// Returns the passed string, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableString: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final String? Function( + ProxyIntegrationCoreApi pigeon_instance, + String? aString, + )? flutterEchoNullableString; + + /// Returns the passed byte list, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableUint8List: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Uint8List? Function( + ProxyIntegrationCoreApi pigeon_instance, + Uint8List? aList, + )? flutterEchoNullableUint8List; + + /// Returns the passed list, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableList: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final List? Function( + ProxyIntegrationCoreApi pigeon_instance, + List? aList, + )? flutterEchoNullableList; + + /// Returns the passed map, to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableMap: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Map? Function( + ProxyIntegrationCoreApi pigeon_instance, + Map? aMap, + )? flutterEchoNullableMap; + + /// Returns the passed enum to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableEnum: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final AnEnum? Function( + ProxyIntegrationCoreApi pigeon_instance, + AnEnum? anEnum, + )? flutterEchoNullableEnum; + + /// Returns the passed ProxyApi to test serialization and deserialization. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoNullableProxyApi: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final ProxyApiSuperClass? Function( + ProxyIntegrationCoreApi pigeon_instance, + ProxyApiSuperClass? aProxyApi, + )? flutterEchoNullableProxyApi; + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterNoopAsync: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Future Function(ProxyIntegrationCoreApi pigeon_instance)? + flutterNoopAsync; + + /// Returns the passed in generic Object asynchronously. + /// + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyIntegrationCoreApi instance = ProxyIntegrationCoreApi( + /// flutterEchoAsyncString: (ProxyIntegrationCoreApi pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final Future Function( + ProxyIntegrationCoreApi pigeon_instance, + String aString, + )? flutterEchoAsyncString; + + @override + final void Function(ProxyApiInterface instance)? anInterfaceMethod; + + late final ProxyApiSuperClass attachedField = __pigeon_attachedField(); + + static final ProxyApiSuperClass staticAttachedField = + __pigeon_staticAttachedField(); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + Pigeon_InstanceManager? pigeon_instanceManager, + ProxyIntegrationCoreApi Function( + bool aBool, + int anInt, + double aDouble, + String aString, + Uint8List aUint8List, + List aList, + Map aMap, + AnEnum anEnum, + ProxyApiSuperClass aProxyApi, + bool? aNullableBool, + int? aNullableInt, + double? aNullableDouble, + String? aNullableString, + Uint8List? aNullableUint8List, + List? aNullableList, + Map? aNullableMap, + AnEnum? aNullableEnum, + ProxyApiSuperClass? aNullableProxyApi, + )? pigeon_newInstance, + void Function(ProxyIntegrationCoreApi pigeon_instance)? flutterNoop, + Object? Function(ProxyIntegrationCoreApi pigeon_instance)? + flutterThrowError, + void Function(ProxyIntegrationCoreApi pigeon_instance)? + flutterThrowErrorFromVoid, + bool Function( + ProxyIntegrationCoreApi pigeon_instance, + bool aBool, + )? flutterEchoBool, + int Function( + ProxyIntegrationCoreApi pigeon_instance, + int anInt, + )? flutterEchoInt, + double Function( + ProxyIntegrationCoreApi pigeon_instance, + double aDouble, + )? flutterEchoDouble, + String Function( + ProxyIntegrationCoreApi pigeon_instance, + String aString, + )? flutterEchoString, + Uint8List Function( + ProxyIntegrationCoreApi pigeon_instance, + Uint8List aList, + )? flutterEchoUint8List, + List Function( + ProxyIntegrationCoreApi pigeon_instance, + List aList, + )? flutterEchoList, + List Function( + ProxyIntegrationCoreApi pigeon_instance, + List aList, + )? flutterEchoProxyApiList, + Map Function( + ProxyIntegrationCoreApi pigeon_instance, + Map aMap, + )? flutterEchoMap, + Map Function( + ProxyIntegrationCoreApi pigeon_instance, + Map aMap, + )? flutterEchoProxyApiMap, + AnEnum Function( + ProxyIntegrationCoreApi pigeon_instance, + AnEnum anEnum, + )? flutterEchoEnum, + ProxyApiSuperClass Function( + ProxyIntegrationCoreApi pigeon_instance, + ProxyApiSuperClass aProxyApi, + )? flutterEchoProxyApi, + bool? Function( + ProxyIntegrationCoreApi pigeon_instance, + bool? aBool, + )? flutterEchoNullableBool, + int? Function( + ProxyIntegrationCoreApi pigeon_instance, + int? anInt, + )? flutterEchoNullableInt, + double? Function( + ProxyIntegrationCoreApi pigeon_instance, + double? aDouble, + )? flutterEchoNullableDouble, + String? Function( + ProxyIntegrationCoreApi pigeon_instance, + String? aString, + )? flutterEchoNullableString, + Uint8List? Function( + ProxyIntegrationCoreApi pigeon_instance, + Uint8List? aList, + )? flutterEchoNullableUint8List, + List? Function( + ProxyIntegrationCoreApi pigeon_instance, + List? aList, + )? flutterEchoNullableList, + Map? Function( + ProxyIntegrationCoreApi pigeon_instance, + Map? aMap, + )? flutterEchoNullableMap, + AnEnum? Function( + ProxyIntegrationCoreApi pigeon_instance, + AnEnum? anEnum, + )? flutterEchoNullableEnum, + ProxyApiSuperClass? Function( + ProxyIntegrationCoreApi pigeon_instance, + ProxyApiSuperClass? aProxyApi, + )? flutterEchoNullableProxyApi, + Future Function(ProxyIntegrationCoreApi pigeon_instance)? + flutterNoopAsync, + Future Function( + ProxyIntegrationCoreApi pigeon_instance, + String aString, + )? flutterEchoAsyncString, + }) { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + _Pigeon_ProxyApiBaseCodec( + pigeon_instanceManager ?? Pigeon_InstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null int.'); + final bool? arg_aBool = (args[1] as bool?); + assert(arg_aBool != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null bool.'); + final int? arg_anInt = (args[2] as int?); + assert(arg_anInt != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null int.'); + final double? arg_aDouble = (args[3] as double?); + assert(arg_aDouble != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null double.'); + final String? arg_aString = (args[4] as String?); + assert(arg_aString != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null String.'); + final Uint8List? arg_aUint8List = (args[5] as Uint8List?); + assert(arg_aUint8List != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null Uint8List.'); + final List? arg_aList = + (args[6] as List?)?.cast(); + assert(arg_aList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null List.'); + final Map? arg_aMap = + (args[7] as Map?)?.cast(); + assert(arg_aMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null Map.'); + final AnEnum? arg_anEnum = + args[8] == null ? null : AnEnum.values[args[8]! as int]; + assert(arg_anEnum != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null AnEnum.'); + final ProxyApiSuperClass? arg_aProxyApi = + (args[9] as ProxyApiSuperClass?); + assert(arg_aProxyApi != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.pigeon_newInstance was null, expected non-null ProxyApiSuperClass.'); + final bool? arg_aNullableBool = (args[10] as bool?); + final int? arg_aNullableInt = (args[11] as int?); + final double? arg_aNullableDouble = (args[12] as double?); + final String? arg_aNullableString = (args[13] as String?); + final Uint8List? arg_aNullableUint8List = (args[14] as Uint8List?); + final List? arg_aNullableList = + (args[15] as List?)?.cast(); + final Map? arg_aNullableMap = + (args[16] as Map?)?.cast(); + final AnEnum? arg_aNullableEnum = + args[17] == null ? null : AnEnum.values[args[17]! as int]; + final ProxyApiSuperClass? arg_aNullableProxyApi = + (args[18] as ProxyApiSuperClass?); + try { + (pigeon_instanceManager ?? Pigeon_InstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call( + arg_aBool!, + arg_anInt!, + arg_aDouble!, + arg_aString!, + arg_aUint8List!, + arg_aList!, + arg_aMap!, + arg_anEnum!, + arg_aProxyApi!, + arg_aNullableBool, + arg_aNullableInt, + arg_aNullableDouble, + arg_aNullableString, + arg_aNullableUint8List, + arg_aNullableList, + arg_aNullableMap, + arg_aNullableEnum, + arg_aNullableProxyApi) ?? + ProxyIntegrationCoreApi.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + aBool: arg_aBool!, + anInt: arg_anInt!, + aDouble: arg_aDouble!, + aString: arg_aString!, + aUint8List: arg_aUint8List!, + aList: arg_aList!, + aMap: arg_aMap!, + anEnum: arg_anEnum!, + aProxyApi: arg_aProxyApi!, + aNullableBool: arg_aNullableBool, + aNullableInt: arg_aNullableInt, + aNullableDouble: arg_aNullableDouble, + aNullableString: arg_aNullableString, + aNullableUint8List: arg_aNullableUint8List, + aNullableList: arg_aNullableList, + aNullableMap: arg_aNullableMap, + aNullableEnum: arg_aNullableEnum, + aNullableProxyApi: arg_aNullableProxyApi, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterNoop', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterNoop was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterNoop was null, expected non-null ProxyIntegrationCoreApi.'); + try { + (flutterNoop ?? arg_pigeon_instance!.flutterNoop) + ?.call(arg_pigeon_instance!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterThrowError', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterThrowError was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterThrowError was null, expected non-null ProxyIntegrationCoreApi.'); + try { + final Object? output = + (flutterThrowError ?? arg_pigeon_instance!.flutterThrowError) + ?.call(arg_pigeon_instance!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterThrowErrorFromVoid', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterThrowErrorFromVoid was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterThrowErrorFromVoid was null, expected non-null ProxyIntegrationCoreApi.'); + try { + (flutterThrowErrorFromVoid ?? + arg_pigeon_instance!.flutterThrowErrorFromVoid) + ?.call(arg_pigeon_instance!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoBool', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoBool was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoBool was null, expected non-null ProxyIntegrationCoreApi.'); + final bool? arg_aBool = (args[1] as bool?); + assert(arg_aBool != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoBool was null, expected non-null bool.'); + try { + final bool? output = + (flutterEchoBool ?? arg_pigeon_instance!.flutterEchoBool) + ?.call(arg_pigeon_instance!, arg_aBool!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoInt', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoInt was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoInt was null, expected non-null ProxyIntegrationCoreApi.'); + final int? arg_anInt = (args[1] as int?); + assert(arg_anInt != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoInt was null, expected non-null int.'); + try { + final int? output = + (flutterEchoInt ?? arg_pigeon_instance!.flutterEchoInt) + ?.call(arg_pigeon_instance!, arg_anInt!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoDouble', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoDouble was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoDouble was null, expected non-null ProxyIntegrationCoreApi.'); + final double? arg_aDouble = (args[1] as double?); + assert(arg_aDouble != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoDouble was null, expected non-null double.'); + try { + final double? output = + (flutterEchoDouble ?? arg_pigeon_instance!.flutterEchoDouble) + ?.call(arg_pigeon_instance!, arg_aDouble!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoString', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoString was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoString was null, expected non-null ProxyIntegrationCoreApi.'); + final String? arg_aString = (args[1] as String?); + assert(arg_aString != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoString was null, expected non-null String.'); + try { + final String? output = + (flutterEchoString ?? arg_pigeon_instance!.flutterEchoString) + ?.call(arg_pigeon_instance!, arg_aString!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoUint8List', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoUint8List was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoUint8List was null, expected non-null ProxyIntegrationCoreApi.'); + final Uint8List? arg_aList = (args[1] as Uint8List?); + assert(arg_aList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoUint8List was null, expected non-null Uint8List.'); + try { + final Uint8List? output = (flutterEchoUint8List ?? + arg_pigeon_instance!.flutterEchoUint8List) + ?.call(arg_pigeon_instance!, arg_aList!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoList', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoList was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoList was null, expected non-null ProxyIntegrationCoreApi.'); + final List? arg_aList = + (args[1] as List?)?.cast(); + assert(arg_aList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoList was null, expected non-null List.'); + try { + final List? output = + (flutterEchoList ?? arg_pigeon_instance!.flutterEchoList) + ?.call(arg_pigeon_instance!, arg_aList!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiList', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiList was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiList was null, expected non-null ProxyIntegrationCoreApi.'); + final List? arg_aList = + (args[1] as List?)?.cast(); + assert(arg_aList != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiList was null, expected non-null List.'); + try { + final List? output = + (flutterEchoProxyApiList ?? + arg_pigeon_instance!.flutterEchoProxyApiList) + ?.call(arg_pigeon_instance!, arg_aList!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoMap', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoMap was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoMap was null, expected non-null ProxyIntegrationCoreApi.'); + final Map? arg_aMap = + (args[1] as Map?)?.cast(); + assert(arg_aMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoMap was null, expected non-null Map.'); + try { + final Map? output = + (flutterEchoMap ?? arg_pigeon_instance!.flutterEchoMap) + ?.call(arg_pigeon_instance!, arg_aMap!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiMap', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiMap was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiMap was null, expected non-null ProxyIntegrationCoreApi.'); + final Map? arg_aMap = + (args[1] as Map?) + ?.cast(); + assert(arg_aMap != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApiMap was null, expected non-null Map.'); + try { + final Map? output = + (flutterEchoProxyApiMap ?? + arg_pigeon_instance!.flutterEchoProxyApiMap) + ?.call(arg_pigeon_instance!, arg_aMap!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoEnum', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoEnum was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoEnum was null, expected non-null ProxyIntegrationCoreApi.'); + final AnEnum? arg_anEnum = + args[1] == null ? null : AnEnum.values[args[1]! as int]; + assert(arg_anEnum != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoEnum was null, expected non-null AnEnum.'); + try { + final AnEnum? output = + (flutterEchoEnum ?? arg_pigeon_instance!.flutterEchoEnum) + ?.call(arg_pigeon_instance!, arg_anEnum!); + return wrapResponse(result: output?.index); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApi', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApi was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApi was null, expected non-null ProxyIntegrationCoreApi.'); + final ProxyApiSuperClass? arg_aProxyApi = + (args[1] as ProxyApiSuperClass?); + assert(arg_aProxyApi != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoProxyApi was null, expected non-null ProxyApiSuperClass.'); + try { + final ProxyApiSuperClass? output = (flutterEchoProxyApi ?? + arg_pigeon_instance!.flutterEchoProxyApi) + ?.call(arg_pigeon_instance!, arg_aProxyApi!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableBool', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableBool was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableBool was null, expected non-null ProxyIntegrationCoreApi.'); + final bool? arg_aBool = (args[1] as bool?); + try { + final bool? output = (flutterEchoNullableBool ?? + arg_pigeon_instance!.flutterEchoNullableBool) + ?.call(arg_pigeon_instance!, arg_aBool); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableInt', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableInt was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableInt was null, expected non-null ProxyIntegrationCoreApi.'); + final int? arg_anInt = (args[1] as int?); + try { + final int? output = (flutterEchoNullableInt ?? + arg_pigeon_instance!.flutterEchoNullableInt) + ?.call(arg_pigeon_instance!, arg_anInt); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableDouble', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableDouble was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableDouble was null, expected non-null ProxyIntegrationCoreApi.'); + final double? arg_aDouble = (args[1] as double?); + try { + final double? output = (flutterEchoNullableDouble ?? + arg_pigeon_instance!.flutterEchoNullableDouble) + ?.call(arg_pigeon_instance!, arg_aDouble); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableString', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableString was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableString was null, expected non-null ProxyIntegrationCoreApi.'); + final String? arg_aString = (args[1] as String?); + try { + final String? output = (flutterEchoNullableString ?? + arg_pigeon_instance!.flutterEchoNullableString) + ?.call(arg_pigeon_instance!, arg_aString); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableUint8List', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableUint8List was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableUint8List was null, expected non-null ProxyIntegrationCoreApi.'); + final Uint8List? arg_aList = (args[1] as Uint8List?); + try { + final Uint8List? output = (flutterEchoNullableUint8List ?? + arg_pigeon_instance!.flutterEchoNullableUint8List) + ?.call(arg_pigeon_instance!, arg_aList); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableList', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableList was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableList was null, expected non-null ProxyIntegrationCoreApi.'); + final List? arg_aList = + (args[1] as List?)?.cast(); + try { + final List? output = (flutterEchoNullableList ?? + arg_pigeon_instance!.flutterEchoNullableList) + ?.call(arg_pigeon_instance!, arg_aList); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableMap', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableMap was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableMap was null, expected non-null ProxyIntegrationCoreApi.'); + final Map? arg_aMap = + (args[1] as Map?)?.cast(); + try { + final Map? output = (flutterEchoNullableMap ?? + arg_pigeon_instance!.flutterEchoNullableMap) + ?.call(arg_pigeon_instance!, arg_aMap); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableEnum', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableEnum was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableEnum was null, expected non-null ProxyIntegrationCoreApi.'); + final AnEnum? arg_anEnum = + args[1] == null ? null : AnEnum.values[args[1]! as int]; + try { + final AnEnum? output = (flutterEchoNullableEnum ?? + arg_pigeon_instance!.flutterEchoNullableEnum) + ?.call(arg_pigeon_instance!, arg_anEnum); + return wrapResponse(result: output?.index); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableProxyApi', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableProxyApi was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoNullableProxyApi was null, expected non-null ProxyIntegrationCoreApi.'); + final ProxyApiSuperClass? arg_aProxyApi = + (args[1] as ProxyApiSuperClass?); + try { + final ProxyApiSuperClass? output = (flutterEchoNullableProxyApi ?? + arg_pigeon_instance!.flutterEchoNullableProxyApi) + ?.call(arg_pigeon_instance!, arg_aProxyApi); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterNoopAsync', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterNoopAsync was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterNoopAsync was null, expected non-null ProxyIntegrationCoreApi.'); + try { + await (flutterNoopAsync ?? arg_pigeon_instance!.flutterNoopAsync) + ?.call(arg_pigeon_instance!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoAsyncString', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoAsyncString was null.'); + final List args = (message as List?)!; + final ProxyIntegrationCoreApi? arg_pigeon_instance = + (args[0] as ProxyIntegrationCoreApi?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoAsyncString was null, expected non-null ProxyIntegrationCoreApi.'); + final String? arg_aString = (args[1] as String?); + assert(arg_aString != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.flutterEchoAsyncString was null, expected non-null String.'); + try { + final String? output = await (flutterEchoAsyncString ?? + arg_pigeon_instance!.flutterEchoAsyncString) + ?.call(arg_pigeon_instance!, arg_aString!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + ProxyApiSuperClass __pigeon_attachedField() { + final ProxyApiSuperClass __pigeon_instance = + ProxyApiSuperClass.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + final int __pigeon_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(__pigeon_instance); + () async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.attachedField'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, __pigeon_instanceIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + }(); + return __pigeon_instance; + } + + static ProxyApiSuperClass __pigeon_staticAttachedField() { + final ProxyApiSuperClass __pigeon_instance = + ProxyApiSuperClass.pigeon_detached(); + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + _Pigeon_ProxyApiBaseCodec(Pigeon_InstanceManager.instance); + final BinaryMessenger __pigeon_binaryMessenger = + ServicesBinding.instance.defaultBinaryMessenger; + final int __pigeon_instanceIdentifier = Pigeon_InstanceManager.instance + .addDartCreatedInstance(__pigeon_instance); + () async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.staticAttachedField'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([__pigeon_instanceIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + }(); + return __pigeon_instance; + } + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + Future noop() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.noop'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Returns an error, to test error handling. + Future throwError() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.throwError'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return __pigeon_replyList[0]; + } + } + + /// Returns an error from a void function, to test error handling. + Future throwErrorFromVoid() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.throwErrorFromVoid'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Returns a Flutter error, to test error handling. + Future throwFlutterError() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.throwFlutterError'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return __pigeon_replyList[0]; + } + } + + /// Returns passed in int. + Future echoInt(int anInt) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, anInt]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as int?)!; + } + } + + /// Returns passed in double. + Future echoDouble(double aDouble) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aDouble]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as double?)!; + } + } + + /// Returns the passed in boolean. + Future echoBool(bool aBool) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aBool]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + /// Returns the passed in string. + Future echoString(String aString) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as String?)!; + } + } + + /// Returns the passed in Uint8List. + Future echoUint8List(Uint8List aUint8List) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoUint8List'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aUint8List]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Uint8List?)!; + } + } + + /// Returns the passed in generic Object. + Future echoObject(Object anObject) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoObject'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anObject]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return __pigeon_replyList[0]!; + } + } + + /// Returns the passed list, to test serialization and deserialization. + Future> echoList(List aList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as List?)!.cast(); + } + } + + /// Returns the passed list with ProxyApis, to test serialization and + /// deserialization. + Future> echoProxyApiList( + List aList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoProxyApiList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as List?)! + .cast(); + } + } + + /// Returns the passed map, to test serialization and deserialization. + Future> echoMap(Map aMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Map?)! + .cast(); + } + } + + /// Returns the passed map with ProxyApis, to test serialization and + /// deserialization. + Future> echoProxyApiMap( + Map aMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoProxyApiMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Map?)! + .cast(); + } + } + + /// Returns the passed enum to test serialization and deserialization. + Future echoEnum(AnEnum anEnum) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoEnum'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anEnum.index]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return AnEnum.values[__pigeon_replyList[0]! as int]; + } + } + + /// Returns the passed ProxyApi to test serialization and deserialization. + Future echoProxyApi(ProxyApiSuperClass aProxyApi) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoProxyApi'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aProxyApi]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as ProxyApiSuperClass?)!; + } + } + + /// Returns passed in int. + Future echoNullableInt(int? aNullableInt) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableInt]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?); + } + } + + /// Returns passed in double. + Future echoNullableDouble(double? aNullableDouble) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableDouble]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as double?); + } + } + + /// Returns the passed in boolean. + Future echoNullableBool(bool? aNullableBool) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableBool]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as bool?); + } + } + + /// Returns the passed in string. + Future echoNullableString(String? aNullableString) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as String?); + } + } + + /// Returns the passed in Uint8List. + Future echoNullableUint8List( + Uint8List? aNullableUint8List) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableUint8List'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableUint8List]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as Uint8List?); + } + } + + /// Returns the passed in generic Object. + Future echoNullableObject(Object? aNullableObject) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableObject'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableObject]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return __pigeon_replyList[0]; + } + } + + /// Returns the passed list, to test serialization and deserialization. + Future?> echoNullableList(List? aNullableList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as List?)?.cast(); + } + } + + /// Returns the passed map, to test serialization and deserialization. + Future?> echoNullableMap( + Map? aNullableMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as Map?) + ?.cast(); + } + } + + Future echoNullableEnum(AnEnum? aNullableEnum) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableEnum'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableEnum?.index]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?) == null + ? null + : AnEnum.values[__pigeon_replyList[0]! as int]; + } + } + + /// Returns the passed ProxyApi to test serialization and deserialization. + Future echoNullableProxyApi( + ProxyApiSuperClass? aNullableProxyApi) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoNullableProxyApi'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aNullableProxyApi]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as ProxyApiSuperClass?); + } + } + + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + Future noopAsync() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.noopAsync'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Returns passed in int asynchronously. + Future echoAsyncInt(int anInt) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, anInt]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as int?)!; + } + } + + /// Returns passed in double asynchronously. + Future echoAsyncDouble(double aDouble) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aDouble]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as double?)!; + } + } + + /// Returns the passed in boolean asynchronously. + Future echoAsyncBool(bool aBool) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aBool]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + /// Returns the passed string asynchronously. + Future echoAsyncString(String aString) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as String?)!; + } + } + + /// Returns the passed in Uint8List asynchronously. + Future echoAsyncUint8List(Uint8List aUint8List) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncUint8List'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aUint8List]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Uint8List?)!; + } + } + + /// Returns the passed in generic Object asynchronously. + Future echoAsyncObject(Object anObject) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncObject'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anObject]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return __pigeon_replyList[0]!; + } + } + + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future> echoAsyncList(List aList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as List?)!.cast(); + } + } + + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future> echoAsyncMap(Map aMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Map?)! + .cast(); + } + } + + /// Returns the passed enum, to test asynchronous serialization and deserialization. + Future echoAsyncEnum(AnEnum anEnum) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncEnum'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anEnum.index]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return AnEnum.values[__pigeon_replyList[0]! as int]; + } + } + + /// Responds with an error from an async function returning a value. + Future throwAsyncError() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.throwAsyncError'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return __pigeon_replyList[0]; + } + } + + /// Responds with an error from an async void function. + Future throwAsyncErrorFromVoid() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.throwAsyncErrorFromVoid'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Responds with a Flutter error from an async function returning a value. + Future throwAsyncFlutterError() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.throwAsyncFlutterError'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return __pigeon_replyList[0]; + } + } + + /// Returns passed in int asynchronously. + Future echoAsyncNullableInt(int? anInt) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, anInt]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?); + } + } + + /// Returns passed in double asynchronously. + Future echoAsyncNullableDouble(double? aDouble) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aDouble]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as double?); + } + } + + /// Returns the passed in boolean asynchronously. + Future echoAsyncNullableBool(bool? aBool) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aBool]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as bool?); + } + } + + /// Returns the passed string asynchronously. + Future echoAsyncNullableString(String? aString) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as String?); + } + } + + /// Returns the passed in Uint8List asynchronously. + Future echoAsyncNullableUint8List(Uint8List? aUint8List) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableUint8List'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aUint8List]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as Uint8List?); + } + } + + /// Returns the passed in generic Object asynchronously. + Future echoAsyncNullableObject(Object? anObject) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableObject'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anObject]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return __pigeon_replyList[0]; + } + } + + /// Returns the passed list, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableList(List? aList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as List?)?.cast(); + } + } + + /// Returns the passed map, to test asynchronous serialization and deserialization. + Future?> echoAsyncNullableMap( + Map? aMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as Map?) + ?.cast(); + } + } + + /// Returns the passed enum, to test asynchronous serialization and deserialization. + Future echoAsyncNullableEnum(AnEnum? anEnum) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoAsyncNullableEnum'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anEnum?.index]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?) == null + ? null + : AnEnum.values[__pigeon_replyList[0]! as int]; + } + } + + static Future staticNoop({ + BinaryMessenger? pigeon_binaryMessenger, + Pigeon_InstanceManager? pigeon_instanceManager, + }) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + _Pigeon_ProxyApiBaseCodec( + pigeon_instanceManager ?? Pigeon_InstanceManager.instance); + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.staticNoop'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + static Future echoStaticString( + String aString, { + BinaryMessenger? pigeon_binaryMessenger, + Pigeon_InstanceManager? pigeon_instanceManager, + }) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + _Pigeon_ProxyApiBaseCodec( + pigeon_instanceManager ?? Pigeon_InstanceManager.instance); + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.echoStaticString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([aString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as String?)!; + } + } + + static Future staticAsyncNoop({ + BinaryMessenger? pigeon_binaryMessenger, + Pigeon_InstanceManager? pigeon_instanceManager, + }) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + _Pigeon_ProxyApiBaseCodec( + pigeon_instanceManager ?? Pigeon_InstanceManager.instance); + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.staticAsyncNoop'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + Future callFlutterNoop() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterNoop'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + Future callFlutterThrowError() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterThrowError'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return __pigeon_replyList[0]; + } + } + + Future callFlutterThrowErrorFromVoid() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterThrowErrorFromVoid'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + Future callFlutterEchoBool(bool aBool) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aBool]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future callFlutterEchoInt(int anInt) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, anInt]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as int?)!; + } + } + + Future callFlutterEchoDouble(double aDouble) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aDouble]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as double?)!; + } + } + + Future callFlutterEchoString(String aString) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as String?)!; + } + } + + Future callFlutterEchoUint8List(Uint8List aUint8List) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoUint8List'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aUint8List]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Uint8List?)!; + } + } + + Future> callFlutterEchoList(List aList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as List?)!.cast(); + } + } + + Future> callFlutterEchoProxyApiList( + List aList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoProxyApiList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as List?)! + .cast(); + } + } + + Future> callFlutterEchoMap( + Map aMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Map?)! + .cast(); + } + } + + Future> callFlutterEchoProxyApiMap( + Map aMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoProxyApiMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Map?)! + .cast(); + } + } + + Future callFlutterEchoEnum(AnEnum anEnum) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoEnum'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anEnum.index]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return AnEnum.values[__pigeon_replyList[0]! as int]; + } + } + + Future callFlutterEchoProxyApi( + ProxyApiSuperClass aProxyApi) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoProxyApi'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aProxyApi]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as ProxyApiSuperClass?)!; + } + } + + Future callFlutterEchoNullableBool(bool? aBool) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aBool]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as bool?); + } + } + + Future callFlutterEchoNullableInt(int? anInt) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, anInt]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?); + } + } + + Future callFlutterEchoNullableDouble(double? aDouble) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aDouble]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as double?); + } + } + + Future callFlutterEchoNullableString(String? aString) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as String?); + } + } + + Future callFlutterEchoNullableUint8List( + Uint8List? aUint8List) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableUint8List'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aUint8List]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as Uint8List?); + } + } + + Future?> callFlutterEchoNullableList( + List? aList) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aList]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as List?)?.cast(); + } + } + + Future?> callFlutterEchoNullableMap( + Map? aMap) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableMap'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aMap]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as Map?) + ?.cast(); + } + } + + Future callFlutterEchoNullableEnum(AnEnum? anEnum) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableEnum'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, anEnum?.index]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?) == null + ? null + : AnEnum.values[__pigeon_replyList[0]! as int]; + } + } + + Future callFlutterEchoNullableProxyApi( + ProxyApiSuperClass? aProxyApi) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoNullableProxyApi'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([this, aProxyApi]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as ProxyApiSuperClass?); + } + } + + Future callFlutterNoopAsync() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterNoopAsync'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + Future callFlutterEchoAsyncString(String aString) async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyIntegrationCoreApi; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyIntegrationCoreApi.callFlutterEchoAsyncString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this, aString]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as String?)!; + } + } + + @override + ProxyIntegrationCoreApi pigeon_copy() { + return ProxyIntegrationCoreApi.pigeon_detached( + 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, + ); + } +} + +/// ProxyApi to serve as a super class to the core ProxyApi interface. +class ProxyApiSuperClass extends Pigeon_ProxyApiBaseClass { + ProxyApiSuperClass({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }) { + final int __pigeon_instanceIdentifier = + pigeon_instanceManager.addDartCreatedInstance(this); + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyApiSuperClass; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + () async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_defaultConstructor'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([__pigeon_instanceIdentifier]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + }(); + } + + /// Constructs ProxyApiSuperClass without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies. + ProxyApiSuperClass.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + }); + + late final _Pigeon_ProxyApiBaseCodec __pigeon_codecProxyApiSuperClass = + _Pigeon_ProxyApiBaseCodec(pigeon_instanceManager); + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + Pigeon_InstanceManager? pigeon_instanceManager, + ProxyApiSuperClass Function()? pigeon_newInstance, + }) { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + _Pigeon_ProxyApiBaseCodec( + pigeon_instanceManager ?? Pigeon_InstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? Pigeon_InstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + ProxyApiSuperClass.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + Future aSuperMethod() async { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + __pigeon_codecProxyApiSuperClass; + final BinaryMessenger? __pigeon_binaryMessenger = pigeon_binaryMessenger; + const String __pigeon_channelName = + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiSuperClass.aSuperMethod'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([this]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + @override + ProxyApiSuperClass pigeon_copy() { + return ProxyApiSuperClass.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ); + } +} + +/// ProxyApi to serve as an interface to the core ProxyApi interface. +class ProxyApiInterface extends Pigeon_ProxyApiBaseClass { + /// Constructs ProxyApiInterface without creating the associated native object. + /// + /// This should only be used by subclasses created by this library or to + /// create copies. + ProxyApiInterface.pigeon_detached({ + super.pigeon_binaryMessenger, + super.pigeon_instanceManager, + this.anInterfaceMethod, + }); + + /// Dart: + /// For the associated Native object to be automatically garbage collected, + /// it is required that the implementation of this `Function` doesn't have a + /// strong reference to the encapsulating class instance. When this `Function` + /// references a non-local variable, it is strongly recommended to access it + /// from a `WeakReference`: + /// + /// ```dart + /// final WeakReference weakMyVariable = WeakReference(myVariable); + /// final ProxyApiInterface instance = ProxyApiInterface( + /// anInterfaceMethod: (ProxyApiInterface pigeon_instance, ...) { + /// print(weakMyVariable?.target); + /// }, + /// ); + /// ``` + /// + /// Alternatively, `Pigeon_InstanceManager.removeWeakReference` can be used to + /// release the associated Native object manually. + final void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod; + + static void pigeon_setUpMessageHandlers({ + bool pigeon_clearHandlers = false, + BinaryMessenger? pigeon_binaryMessenger, + Pigeon_InstanceManager? pigeon_instanceManager, + ProxyApiInterface Function()? pigeon_newInstance, + void Function(ProxyApiInterface pigeon_instance)? anInterfaceMethod, + }) { + final _Pigeon_ProxyApiBaseCodec pigeonChannelCodec = + _Pigeon_ProxyApiBaseCodec( + pigeon_instanceManager ?? Pigeon_InstanceManager.instance); + final BinaryMessenger? binaryMessenger = pigeon_binaryMessenger; + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance was null.'); + final List args = (message as List?)!; + final int? arg_pigeon_instanceIdentifier = (args[0] as int?); + assert(arg_pigeon_instanceIdentifier != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.pigeon_newInstance was null, expected non-null int.'); + try { + (pigeon_instanceManager ?? Pigeon_InstanceManager.instance) + .addHostCreatedInstance( + pigeon_newInstance?.call() ?? + ProxyApiInterface.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + ), + arg_pigeon_instanceIdentifier!, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel< + Object?>( + 'dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod', + pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (pigeon_clearHandlers) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod was null.'); + final List args = (message as List?)!; + final ProxyApiInterface? arg_pigeon_instance = + (args[0] as ProxyApiInterface?); + assert(arg_pigeon_instance != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.ProxyApiInterface.anInterfaceMethod was null, expected non-null ProxyApiInterface.'); + try { + (anInterfaceMethod ?? arg_pigeon_instance!.anInterfaceMethod) + ?.call(arg_pigeon_instance!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + } + + @override + ProxyApiInterface pigeon_copy() { + return ProxyApiInterface.pigeon_detached( + pigeon_binaryMessenger: pigeon_binaryMessenger, + pigeon_instanceManager: pigeon_instanceManager, + anInterfaceMethod: anInterfaceMethod, + ); + } +} diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart index 8354d159d33e..f465bf2b765c 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/enum.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart index 73f100cf28b6..99cbf7fa3711 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/flutter_unittests.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart index cc7b8b53c360..04dbc6d43a2a 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/message.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart index bec054b4be49..19455117087d 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/multiple_arity.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart index 7279e85c40ea..be9c48422aef 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/non_null_fields.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart index ecf7c7f7e970..bc18ccd0ada0 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/null_fields.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart index dd1665a463c1..d5c2bb3f63df 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/nullable_returns.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart index 72c115d65278..b1f618a72b6e 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/primitive.gen.dart @@ -4,7 +4,7 @@ // // Autogenerated from Pigeon, do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers, camel_case_types import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart new file mode 100644 index 000000000000..3d3de761a977 --- /dev/null +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -0,0 +1,168 @@ +// 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. + +// This file specifically tests the test Pigeon_InstanceManager generated by core_tests. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_test_plugin_code/src/generated/core_tests.gen.dart'; + +void main() { + group('InstanceManager', () { + test('addHostCreatedInstance', () { + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (_) {}); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addHostCreatedInstance(object, 0); + + expect(instanceManager.getIdentifier(object), 0); + expect( + instanceManager.getInstanceWithWeakReference(0), + object, + ); + }); + + test('addHostCreatedInstance prevents already used objects and ids', () { + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (_) {}); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addHostCreatedInstance(object, 0); + + expect( + () => instanceManager.addHostCreatedInstance(object, 0), + throwsAssertionError, + ); + + expect( + () => instanceManager.addHostCreatedInstance( + CopyableObject(pigeon_instanceManager: instanceManager), + 0, + ), + throwsAssertionError, + ); + }); + + test('addFlutterCreatedInstance', () { + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (_) {}); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addDartCreatedInstance(object); + + final int? instanceId = instanceManager.getIdentifier(object); + expect(instanceId, isNotNull); + expect( + instanceManager.getInstanceWithWeakReference(instanceId!), + object, + ); + }); + + test('removeWeakReference', () { + int? weakInstanceId; + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (int instanceId) { + weakInstanceId = instanceId; + }); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addHostCreatedInstance(object, 0); + + expect(instanceManager.removeWeakReference(object), 0); + expect( + instanceManager.getInstanceWithWeakReference(0), + isA(), + ); + expect(weakInstanceId, 0); + }); + + test('removeWeakReference removes only weak reference', () { + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (_) {}); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addHostCreatedInstance(object, 0); + + expect(instanceManager.removeWeakReference(object), 0); + final CopyableObject copy = instanceManager.getInstanceWithWeakReference( + 0, + )!; + expect(identical(object, copy), isFalse); + }); + + test('removeStrongReference', () { + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (_) {}); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addHostCreatedInstance(object, 0); + instanceManager.removeWeakReference(object); + expect(instanceManager.remove(0), isA()); + expect(instanceManager.containsIdentifier(0), isFalse); + }); + + test('removeStrongReference removes only strong reference', () { + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (_) {}); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addHostCreatedInstance(object, 0); + expect(instanceManager.remove(0), isA()); + expect( + instanceManager.getInstanceWithWeakReference(0), + object, + ); + }); + + test('getInstance can add a new weak reference', () { + final Pigeon_InstanceManager instanceManager = + Pigeon_InstanceManager(onWeakReferenceRemoved: (_) {}); + + final CopyableObject object = CopyableObject( + pigeon_instanceManager: instanceManager, + ); + + instanceManager.addHostCreatedInstance(object, 0); + instanceManager.removeWeakReference(object); + + final CopyableObject newWeakCopy = + instanceManager.getInstanceWithWeakReference( + 0, + )!; + expect(identical(object, newWeakCopy), isFalse); + }); + }); +} + +class CopyableObject extends Pigeon_ProxyApiBaseClass { + // ignore: non_constant_identifier_names + CopyableObject({super.pigeon_instanceManager}); + + @override + // ignore: non_constant_identifier_names + CopyableObject pigeon_copy() { + return CopyableObject(pigeon_instanceManager: pigeon_instanceManager); + } +} diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index c820df9256f8..904aaebdd965 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: 16.0.0 # This must match the version in lib/generator_tools.dart +version: 16.0.1 # This must match the version in lib/generator_tools.dart environment: sdk: ">=3.0.0 <4.0.0" @@ -10,7 +10,9 @@ environment: dependencies: analyzer: ">=5.13.0 <7.0.0" args: ^2.1.0 + code_builder: ^4.8.0 collection: ^1.15.0 + dart_style: ^2.3.4 meta: ^1.7.0 path: ^1.8.0 yaml: ^3.1.1 diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index cbd290b42fa3..af7865815d3a 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -25,7 +25,7 @@ final Enum emptyEnum = Enum( void main() { test('gen one api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', parameters: [ @@ -37,6 +37,8 @@ void main() { ), name: 'input') ], + required: true, + location: ApiLocation.host, returnType: TypeDeclaration( baseName: 'Output', isNullable: false, @@ -101,7 +103,7 @@ void main() { test('naming follows style', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', parameters: [ @@ -113,6 +115,7 @@ void main() { ), name: 'someInput') ], + location: ApiLocation.host, returnType: TypeDeclaration( baseName: 'Output', isNullable: false, @@ -179,9 +182,10 @@ void main() { test('FlutterError fields are private with public accessors', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: const TypeDeclaration( @@ -230,9 +234,10 @@ void main() { test('Error field is private with public accessors', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: const TypeDeclaration( @@ -273,9 +278,10 @@ void main() { test('Spaces before {', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -350,9 +356,10 @@ void main() { test('include blocks follow style', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: const TypeDeclaration( @@ -423,9 +430,10 @@ void main() { test('namespaces follows style', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: const TypeDeclaration( @@ -478,9 +486,10 @@ void main() { test('data classes handle nullable fields', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -661,9 +670,10 @@ void main() { test('data classes handle non-nullable fields', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -804,9 +814,10 @@ void main() { test('host nullable return types map correctly', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'returnNullableBool', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'bool', @@ -815,6 +826,7 @@ void main() { ), Method( name: 'returnNullableInt', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'int', @@ -823,6 +835,7 @@ void main() { ), Method( name: 'returnNullableString', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'String', @@ -831,6 +844,7 @@ void main() { ), Method( name: 'returnNullableList', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'List', @@ -845,6 +859,7 @@ void main() { ), Method( name: 'returnNullableMap', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'Map', @@ -863,6 +878,7 @@ void main() { ), Method( name: 'returnNullableDataClass', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'ReturnData', @@ -921,9 +937,10 @@ void main() { test('host non-nullable return types map correctly', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'returnBool', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'bool', @@ -932,6 +949,7 @@ void main() { ), Method( name: 'returnInt', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'int', @@ -940,6 +958,7 @@ void main() { ), Method( name: 'returnString', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'String', @@ -948,6 +967,7 @@ void main() { ), Method( name: 'returnList', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'List', @@ -962,6 +982,7 @@ void main() { ), Method( name: 'returnMap', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration( baseName: 'Map', @@ -980,6 +1001,7 @@ void main() { ), Method( name: 'returnDataClass', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'ReturnData', @@ -1024,9 +1046,10 @@ void main() { test('host nullable arguments map correctly', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( name: 'aBool', @@ -1179,9 +1202,10 @@ void main() { test('host non-nullable arguments map correctly', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( name: 'aBool', @@ -1329,9 +1353,10 @@ void main() { test('flutter nullable arguments map correctly', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'aBool', @@ -1488,9 +1513,10 @@ void main() { test('flutter non-nullable arguments map correctly', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'aBool', @@ -1621,9 +1647,10 @@ void main() { test('host API argument extraction uses references', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( name: 'anArg', @@ -1661,9 +1688,10 @@ void main() { test('enum argument', () { final Root root = Root( apis: [ - Api(name: 'Bar', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Bar', methods: [ Method( name: 'bar', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1705,13 +1733,13 @@ void main() { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, documentationComments: [comments[count++]], methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), documentationComments: [comments[count++]], parameters: [ @@ -1785,12 +1813,12 @@ void main() { test("doesn't create codecs if no custom datatypes", () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1827,9 +1855,10 @@ void main() { test('creates custom codecs if custom datatypes present', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -1884,9 +1913,10 @@ void main() { test('Does not send unwrapped EncodableLists', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( name: 'aBool', @@ -1966,15 +1996,17 @@ void main() { test('does not keep unowned references in async handlers', () { final Root root = Root(apis: [ - Api(name: 'HostApi', location: ApiLocation.host, methods: [ + AstHostApi(name: 'HostApi', methods: [ Method( name: 'noop', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration.voidDeclaration(), isAsynchronous: true, ), Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: const TypeDeclaration( @@ -1988,15 +2020,17 @@ void main() { isAsynchronous: true, ), ]), - Api(name: 'FlutterApi', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'FlutterApi', methods: [ Method( name: 'noop', + location: ApiLocation.flutter, parameters: [], returnType: const TypeDeclaration.voidDeclaration(), isAsynchronous: true, ), Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: const TypeDeclaration( @@ -2038,12 +2072,12 @@ void main() { test('connection error contains channel name', () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index 83a6556c7fab..24fb50f39026 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -85,9 +85,10 @@ void main() { test('gen one host api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -137,9 +138,10 @@ void main() { test('host multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -170,9 +172,10 @@ void main() { test('flutter multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -305,9 +308,10 @@ void main() { test('flutterApi', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -358,9 +362,10 @@ void main() { test('host void', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -398,9 +403,10 @@ void main() { test('flutter void return', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -441,9 +447,10 @@ void main() { test('flutter void argument', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -477,9 +484,10 @@ void main() { test('flutter enum argument with enum class', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -531,9 +539,10 @@ void main() { test('primitive enum host', () { final Root root = Root(apis: [ - Api(name: 'Bar', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Bar', methods: [ Method( name: 'bar', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -567,9 +576,10 @@ void main() { test('flutter non-nullable enum argument with enum class', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -620,9 +630,10 @@ void main() { test('host void argument', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -655,42 +666,40 @@ void main() { test('mock dart handler', () { final Root root = Root(apis: [ - Api( - name: 'Api', + AstHostApi(name: 'Api', dartHostTestHandler: 'ApiMock', methods: [ + Method( + name: 'doSomething', location: ApiLocation.host, - dartHostTestHandler: 'ApiMock', - methods: [ - Method( - name: 'doSomething', - parameters: [ - Parameter( - type: TypeDeclaration( - baseName: 'Input', - isNullable: false, - associatedClass: emptyClass, - ), - name: '') - ], - returnType: TypeDeclaration( - baseName: 'Output', - isNullable: false, - associatedClass: emptyClass, - ), - ), - Method( - name: 'voidReturner', - parameters: [ - Parameter( - type: TypeDeclaration( - baseName: 'Input', - isNullable: false, - associatedClass: emptyClass, - ), - name: '') - ], - returnType: const TypeDeclaration.voidDeclaration(), - ) - ]) + parameters: [ + Parameter( + type: TypeDeclaration( + baseName: 'Input', + isNullable: false, + associatedClass: emptyClass, + ), + name: '') + ], + returnType: TypeDeclaration( + baseName: 'Output', + isNullable: false, + associatedClass: emptyClass, + ), + ), + Method( + name: 'voidReturner', + location: ApiLocation.host, + parameters: [ + Parameter( + type: TypeDeclaration( + baseName: 'Input', + isNullable: false, + associatedClass: emptyClass, + ), + name: '') + ], + returnType: const TypeDeclaration.voidDeclaration(), + ) + ]) ], classes: [ Class(name: 'Input', fields: [ NamedType( @@ -748,9 +757,10 @@ void main() { test('gen one async Flutter Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -803,9 +813,10 @@ void main() { test('gen one async Flutter Api with void return', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -853,9 +864,10 @@ void main() { test('gen one async Host Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -906,9 +918,10 @@ void main() { test('async host void argument', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -1027,9 +1040,10 @@ void main() { test('host generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1061,9 +1075,10 @@ void main() { test('flutter generics argument with void return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1095,9 +1110,10 @@ void main() { test('host generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -1129,9 +1145,10 @@ void main() { test('flutter generics argument non void return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -1173,9 +1190,10 @@ void main() { test('return nullable host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1202,9 +1220,10 @@ void main() { test('return nullable collection host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'List', isNullable: true, @@ -1236,9 +1255,10 @@ void main() { test('return nullable async host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1266,9 +1286,10 @@ void main() { test('return nullable flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1295,9 +1316,10 @@ void main() { test('return nullable async flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1325,9 +1347,10 @@ void main() { test('platform error for return nil on nonnull', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: false, @@ -1356,9 +1379,10 @@ void main() { test('nullable argument host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1388,9 +1412,10 @@ void main() { test('nullable argument flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1420,9 +1445,10 @@ void main() { test('named argument flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1502,13 +1528,13 @@ name: foobar final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, documentationComments: [comments[count++]], methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), documentationComments: [comments[count++]], parameters: [ @@ -1577,12 +1603,12 @@ name: foobar test("doesn't create codecs if no custom datatypes", () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1615,9 +1641,10 @@ name: foobar test('creates custom codecs if custom datatypes present', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -1668,13 +1695,13 @@ name: foobar test('host test code handles enums', () { final Root root = Root( apis: [ - Api( + AstHostApi( name: 'Api', - location: ApiLocation.host, dartHostTestHandler: 'ApiMock', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1721,9 +1748,10 @@ name: foobar test('connection error contains channel name', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'method', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration(baseName: 'Output', isNullable: false), @@ -1746,4 +1774,973 @@ name: foobar contains( '\'Unable to establish connection on channel: "\$channelName".\'')); }); + + group('ProxyApi', () { + test('one api', () { + final Root root = Root(apis: [ + AstProxyApi(name: 'Api', constructors: [ + Constructor(name: 'name', parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ), + ]), + ], fields: [ + Field( + name: 'someField', + type: const TypeDeclaration( + baseName: 'int', + isNullable: false, + ), + ) + ], methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ) + ], + returnType: const TypeDeclaration( + baseName: 'String', + isNullable: false, + ), + ), + Method( + name: 'doSomethingElse', + location: ApiLocation.flutter, + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'Input', + isNullable: false, + ), + name: 'input', + ) + ], + returnType: const TypeDeclaration( + baseName: 'String', + isNullable: 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(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + + // Instance Manager + expect(code, contains(r'class Pigeon_InstanceManager')); + expect(code, contains(r'class _Pigeon_InstanceManagerApi')); + + // Base Api class + expect( + code, + contains(r'abstract class Pigeon_ProxyApiBaseClass'), + ); + + // Codec and class + expect(code, contains('class _Pigeon_ProxyApiBaseCodec')); + expect(code, contains(r'class Api extends Pigeon_ProxyApiBaseClass')); + + // Constructors + expect( + collapsedCode, + contains( + r'Api.name({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, required this.someField, this.doSomethingElse, required Input input, })', + ), + ); + expect( + code, + contains( + r'Api.pigeon_detached', + ), + ); + + // Field + expect(code, contains('final int someField;')); + + // Dart -> Host method + expect(code, contains('Future doSomething(Input input)')); + + // Host -> Dart method + expect(code, contains(r'static void pigeon_setUpMessageHandlers({')); + expect( + collapsedCode, + contains( + 'final String Function( Api pigeon_instance, Input input, )? doSomethingElse;', + ), + ); + + // Copy method + expect(code, contains(r'Api pigeon_copy(')); + }); + + group('inheritance', () { + test('extends', () { + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + superClassName: 'Api2', + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ) + ], 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(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(code, contains(r'class Api extends Api2')); + expect( + collapsedCode, + contains( + r'Api.pigeon_detached({ super.pigeon_binaryMessenger, super.pigeon_instanceManager, }) : super.pigeon_detached();', + ), + ); + }); + + test('implements', () { + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + interfacesNames: {'Api2'}, + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ) + ], 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( + r'class Api extends Pigeon_ProxyApiBaseClass implements Api2', + ), + ); + }); + + test('implements 2 ProxyApis', () { + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + interfacesNames: {'Api2', 'Api3'}, + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + AstProxyApi( + name: 'Api3', + constructors: [], + fields: [], + methods: [], + ), + ], 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( + r'class Api extends Pigeon_ProxyApiBaseClass implements Api2, Api3', + ), + ); + }); + + test('implements inherits flutter method', () { + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [], + interfacesNames: {'Api2'}, + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [ + Method( + name: 'aFlutterMethod', + returnType: const TypeDeclaration.voidDeclaration(), + parameters: [], + location: ApiLocation.flutter, + ), + Method( + name: 'aNullableFlutterMethod', + returnType: const TypeDeclaration.voidDeclaration(), + parameters: [], + location: ApiLocation.flutter, + required: true, + ), + ], + ), + ], 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(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect( + code, + contains( + r'class Api extends Pigeon_ProxyApiBaseClass implements Api2', + ), + ); + expect( + collapsedCode, + contains( + r'Api.pigeon_detached({ super.pigeon_binaryMessenger, ' + r'super.pigeon_instanceManager, ' + r'this.aFlutterMethod, ' + r'required this.aNullableFlutterMethod, })', + ), + ); + }); + }); + + group('Constructors', () { + test('empty name and no params constructor', () { + final Root root = Root( + apis: [ + AstProxyApi(name: 'Api', constructors: [ + Constructor( + name: '', + parameters: [], + ) + ], fields: [], methods: []), + ], + 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(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(code, contains('class Api')); + expect( + collapsedCode, + contains( + r'Api({ super.pigeon_binaryMessenger, ' + r'super.pigeon_instanceManager, })', + ), + ); + expect( + collapsedCode, + contains( + r"const String __pigeon_channelName = 'dev.flutter.pigeon.test_package.Api.pigeon_defaultConstructor';", + ), + ); + expect( + collapsedCode, + contains( + r'__pigeon_channel .send([__pigeon_instanceIdentifier])', + ), + ); + }); + + test('multiple params constructor', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi(name: 'Api', constructors: [ + Constructor( + name: 'name', + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + ) + ], fields: [], methods: []), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const DartGenerator generator = DartGenerator(); + generator.generate( + const DartOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(code, contains('class Api')); + expect( + collapsedCode, + contains( + r'Api.name({ super.pigeon_binaryMessenger, ' + r'super.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'__pigeon_channel.send([ ' + r'__pigeon_instanceIdentifier, ' + r'validType, enumType.index, proxyApiType, ' + r'nullableValidType, nullableEnumType?.index, nullableProxyApiType ])', + ), + ); + }); + }); + + group('Fields', () { + test('constructor with fields', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [ + Constructor( + name: 'name', + parameters: [], + ) + ], + fields: [ + Field( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Field( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Field( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Field( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Field( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Field( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + methods: [], + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const DartGenerator generator = DartGenerator(); + generator.generate( + const DartOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(code, contains('class Api')); + expect( + collapsedCode, + contains( + r'Api.name({ super.pigeon_binaryMessenger, ' + r'super.pigeon_instanceManager, ' + r'required this.validType, ' + r'required this.enumType, ' + r'required this.proxyApiType, ' + r'this.nullableValidType, ' + r'this.nullableEnumType, ' + r'this.nullableProxyApiType, })', + ), + ); + expect( + collapsedCode, + contains( + r'__pigeon_channel.send([ ' + r'__pigeon_instanceIdentifier, ' + r'validType, enumType.index, proxyApiType, ' + r'nullableValidType, nullableEnumType?.index, nullableProxyApiType ])', + ), + ); + expect( + code, + contains(r'final int validType;'), + ); + expect( + code, + contains(r'final AnEnum enumType;'), + ); + expect( + code, + contains(r'final Api2 proxyApiType;'), + ); + expect( + code, + contains(r'final int? nullableValidType;'), + ); + expect( + code, + contains(r'final AnEnum? nullableEnumType;'), + ); + expect( + code, + contains(r'final Api2? nullableProxyApiType;'), + ); + }); + + test('attached field', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [ + Field( + name: 'aField', + isAttached: true, + type: TypeDeclaration( + baseName: 'Api2', + isNullable: false, + associatedProxyApi: api2, + ), + ), + ], + methods: [], + ), + api2, + ], + 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('class Api')); + expect(code, contains(r'late final Api2 aField = __pigeon_aField();')); + expect(code, contains(r'Api2 __pigeon_aField()')); + }); + + test('static attached field', () { + final AstProxyApi api2 = AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [ + Field( + name: 'aField', + isStatic: true, + isAttached: true, + type: TypeDeclaration( + baseName: 'Api2', + isNullable: false, + associatedProxyApi: api2, + ), + ), + ], + methods: [], + ), + api2, + ], + 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('class Api')); + expect( + code, contains(r'static final Api2 aField = __pigeon_aField();')); + expect(code, contains(r'static Api2 __pigeon_aField()')); + }); + }); + + group('Host methods', () { + test('multiple params method', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ), + ], + ), + AstProxyApi( + name: 'Api2', + constructors: [], + fields: [], + methods: [], + ), + ], + classes: [], + enums: [anEnum], + ); + final StringBuffer sink = StringBuffer(); + const DartGenerator generator = DartGenerator(); + generator.generate( + const DartOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(code, contains('class Api')); + expect( + collapsedCode, + contains( + r'Future doSomething( int validType, AnEnum enumType, ' + r'Api2 proxyApiType, int? nullableValidType, ' + r'AnEnum? nullableEnumType, Api2? nullableProxyApiType, )', + ), + ); + expect( + collapsedCode, + contains( + r'await __pigeon_channel.send([ this, validType, ' + r'enumType.index, proxyApiType, nullableValidType, ' + r'nullableEnumType?.index, nullableProxyApiType ])', + ), + ); + }); + + test('static method', () { + final Root root = Root( + apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.host, + isStatic: true, + parameters: [], + returnType: const TypeDeclaration.voidDeclaration(), + ), + ], + ), + ], + 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(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(code, contains('class Api')); + expect( + collapsedCode, + contains( + r'static Future doSomething({ BinaryMessenger? pigeon_binaryMessenger, ' + r'Pigeon_InstanceManager? pigeon_instanceManager, })', + ), + ); + expect( + collapsedCode, + contains(r'await __pigeon_channel.send(null)'), + ); + }); + }); + + group('Flutter methods', () { + test('multiple params flutter method', () { + final Enum anEnum = Enum( + name: 'AnEnum', + members: [EnumMember(name: 'one')], + ); + final Root root = Root(apis: [ + AstProxyApi( + name: 'Api', + constructors: [], + fields: [], + methods: [ + Method( + name: 'doSomething', + location: ApiLocation.flutter, + parameters: [ + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'int', + ), + name: 'validType', + ), + Parameter( + type: TypeDeclaration( + isNullable: false, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'enumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: false, + baseName: 'Api2', + ), + name: 'proxyApiType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'int', + ), + name: 'nullableValidType', + ), + Parameter( + type: TypeDeclaration( + isNullable: true, + baseName: 'AnEnum', + associatedEnum: anEnum, + ), + name: 'nullableEnumType', + ), + Parameter( + type: const TypeDeclaration( + isNullable: true, + baseName: 'Api2', + ), + name: 'nullableProxyApiType', + ), + ], + returnType: const TypeDeclaration.voidDeclaration(), + ) + ]) + ], classes: [], enums: [ + anEnum + ]); + final StringBuffer sink = StringBuffer(); + const DartGenerator generator = DartGenerator(); + generator.generate( + const DartOptions(), + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final String code = sink.toString(); + final String collapsedCode = _collapseNewlineAndIndentation(code); + expect(code, contains('class Api')); + expect( + collapsedCode, + contains( + r'final void Function( Api pigeon_instance, int validType, ' + r'AnEnum enumType, Api2 proxyApiType, int? nullableValidType, ' + r'AnEnum? nullableEnumType, Api2? nullableProxyApiType, )? ' + r'doSomething;', + ), + ); + expect( + collapsedCode, + contains( + r'void Function( Api pigeon_instance, int validType, AnEnum enumType, ' + r'Api2 proxyApiType, int? nullableValidType, ' + r'AnEnum? nullableEnumType, Api2? nullableProxyApiType, )? ' + r'doSomething'), + ); + expect( + code, + contains(r'final Api? arg_pigeon_instance = (args[0] as Api?);'), + ); + expect( + code, + contains(r'final int? arg_validType = (args[1] as int?);'), + ); + expect( + collapsedCode, + contains( + r'final AnEnum? arg_enumType = args[2] == null ? ' + r'null : AnEnum.values[args[2]! as int];', + ), + ); + expect( + code, + contains(r'final Api2? arg_proxyApiType = (args[3] as Api2?);'), + ); + expect( + code, + contains(r'final int? arg_nullableValidType = (args[4] as int?);'), + ); + expect( + collapsedCode, + contains( + r'final AnEnum? arg_nullableEnumType = args[5] == null ? ' + r'null : AnEnum.values[args[5]! as int];', + ), + ); + expect( + collapsedCode, + contains( + r'(doSomething ?? arg_pigeon_instance!.doSomething)?.call( arg_pigeon_instance!, ' + r'arg_validType!, arg_enumType!, arg_proxyApiType!, ' + r'arg_nullableValidType, arg_nullableEnumType, ' + r'arg_nullableProxyApiType);', + ), + ); + }); + }); + }); +} + +/// Replaces a new line and the indentation with a single white space +/// +/// This +/// +/// ```dart +/// void method( +/// int param1, +/// int param2, +/// ) +/// ``` +/// +/// converts to +/// +/// ```dart +/// void method( int param1, int param2, ) +/// ``` +String _collapseNewlineAndIndentation(String string) { + final StringBuffer result = StringBuffer(); + for (final String line in string.split('\n')) { + result.write('${line.trimLeft()} '); + } + return result.toString().trim(); } diff --git a/packages/pigeon/test/functional_test.dart b/packages/pigeon/test/functional_test.dart index 1c2079ccae4d..ade909799aca 100644 --- a/packages/pigeon/test/functional_test.dart +++ b/packages/pigeon/test/functional_test.dart @@ -6,34 +6,6 @@ import 'package:pigeon/functional.dart'; import 'package:test/test.dart'; void main() { - test('indexMap', () { - final List items = ['a', 'b', 'c']; - final List result = - indexMap(items, (int index, String value) => value + index.toString()) - .toList(); - expect(result[0], 'a0'); - expect(result[1], 'b1'); - expect(result[2], 'c2'); - }); - - test('enumerate', () { - final List items = ['a', 'b', 'c']; - int saw = 0; - enumerate(items, (int index, String value) { - if (index == 0) { - expect(value, 'a'); - saw |= 0x1; - } else if (index == 1) { - expect(value, 'b'); - saw |= 0x2; - } else if (index == 2) { - expect(value, 'c'); - saw |= 0x4; - } - }); - expect(saw, 0x7); - }); - test('map2', () { final List result = map2([3, 5, 7], [1, 2, 3], (int x, int y) => x * y).toList(); diff --git a/packages/pigeon/test/generator_tools_test.dart b/packages/pigeon/test/generator_tools_test.dart index 4570ac633aaa..68a2cb0861fa 100644 --- a/packages/pigeon/test/generator_tools_test.dart +++ b/packages/pigeon/test/generator_tools_test.dart @@ -6,37 +6,6 @@ import 'package:pigeon/ast.dart'; import 'package:pigeon/generator_tools.dart'; import 'package:test/test.dart'; -bool _equalSet(Set x, Set y) { - if (x.length != y.length) { - return false; - } - for (final T object in x) { - if (!y.contains(object)) { - return false; - } - } - return true; -} - -bool _equalMaps(Map x, Map y) { - if (!_equalSet(x.keys.toSet(), y.keys.toSet())) { - return false; - } - for (final String key in x.keys) { - final Object xValue = x[key]!; - if (xValue is Map) { - if (!_equalMaps(xValue, (y[key] as Map?)!)) { - return false; - } - } else { - if (xValue != y[key]) { - return false; - } - } - } - return true; -} - final Class emptyClass = Class(name: 'className', fields: [ NamedType( name: 'namedTypeName', @@ -50,38 +19,11 @@ final Enum emptyEnum = Enum( ); void main() { - test('test merge maps', () { - final Map source = { - '1': '1', - '2': { - '1': '1', - '3': '3', - }, - '3': '3', // not modified - }; - final Map modification = { - '1': '2', // modify - '2': { - '2': '2', // added - }, - }; - final Map expected = { - '1': '2', - '2': { - '1': '1', - '2': '2', - '3': '3', - }, - '3': '3', - }; - expect(_equalMaps(expected, mergeMaps(source, modification)), isTrue); - }); - test('get codec classes from argument type arguments', () { - final Api api = - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + final Api api = AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -123,10 +65,10 @@ void main() { }); test('get codec classes from return value type arguments', () { - final Api api = - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + final Api api = AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -168,10 +110,10 @@ void main() { }); test('get codec classes from all arguments', () { - final Api api = - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + final Api api = AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -216,9 +158,10 @@ void main() { test('getCodecClasses: nested type arguments', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'foo', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -272,12 +215,12 @@ void main() { test('getCodecClasses: with Object', () { final Root root = Root(apis: [ - Api( + AstFlutterApi( name: 'Api1', - location: ApiLocation.flutter, methods: [ Method( name: 'foo', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -311,12 +254,12 @@ void main() { test('getCodecClasses: unique entries', () { final Root root = Root(apis: [ - Api( + AstFlutterApi( name: 'Api1', - location: ApiLocation.flutter, methods: [ Method( name: 'foo', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -330,12 +273,12 @@ void main() { ) ], ), - Api( + AstFlutterApi( name: 'Api2', - location: ApiLocation.host, methods: [ Method( name: 'foo', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -372,4 +315,97 @@ void main() { expect(dartPackageName, 'pigeon'); }); + + test('recursiveGetSuperClassApisChain', () { + final AstProxyApi api = AstProxyApi( + name: 'Api', + methods: [], + constructors: [], + fields: [], + superClassName: 'Api2', + ); + final AstProxyApi superClassApi = AstProxyApi( + name: 'Api2', + methods: [], + constructors: [], + fields: [], + superClassName: 'Api3', + ); + final AstProxyApi superClassOfSuperClassApi = AstProxyApi( + name: 'Api3', + methods: [], + constructors: [], + fields: [], + ); + + final List apiChain = recursiveGetSuperClassApisChain( + api, + [superClassOfSuperClassApi, api, superClassApi], + ); + + expect( + apiChain, + containsAllInOrder([ + superClassApi, + superClassOfSuperClassApi, + ]), + ); + }); + + test('recursiveFindAllInterfacesApis', () { + final AstProxyApi api = AstProxyApi( + name: 'Api', + methods: [], + constructors: [], + fields: [], + interfacesNames: {'Api2', 'Api3'}, + ); + final AstProxyApi interfaceApi = AstProxyApi( + name: 'Api2', + methods: [], + constructors: [], + fields: [], + interfacesNames: {'Api4', 'Api5'}, + ); + final AstProxyApi interfaceApi2 = AstProxyApi( + name: 'Api3', + methods: [], + constructors: [], + fields: [], + interfacesNames: {'Api5'}, + ); + final AstProxyApi interfaceOfInterfaceApi = AstProxyApi( + name: 'Api4', + methods: [], + constructors: [], + fields: [], + ); + final AstProxyApi interfaceOfInterfaceApi2 = AstProxyApi( + name: 'Api5', + methods: [], + constructors: [], + fields: [], + ); + + final Set allInterfaces = recursiveFindAllInterfacesApis( + api, + [ + api, + interfaceApi, + interfaceApi2, + interfaceOfInterfaceApi, + interfaceOfInterfaceApi2, + ], + ); + + expect( + allInterfaces, + containsAll([ + interfaceApi, + interfaceApi2, + interfaceOfInterfaceApi, + interfaceOfInterfaceApi2, + ]), + ); + }); } diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index cba2d702255c..97cbfe8b4d09 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -123,9 +123,10 @@ void main() { test('gen one host api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -265,9 +266,10 @@ void main() { test('gen one flutter api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -318,9 +320,10 @@ void main() { test('gen host void api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -359,9 +362,10 @@ void main() { test('gen flutter void return api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -403,9 +407,10 @@ void main() { test('gen host void argument api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -440,9 +445,10 @@ void main() { test('gen flutter void argument api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -578,9 +584,10 @@ void main() { test('gen one async Host Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -639,9 +646,10 @@ void main() { test('gen one async Flutter Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -745,9 +753,10 @@ void main() { test('primitive enum host', () { final Root root = Root(apis: [ - Api(name: 'Bar', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Bar', methods: [ Method( name: 'bar', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -875,9 +884,10 @@ void main() { test('host generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -910,9 +920,10 @@ void main() { test('flutter generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -945,9 +956,10 @@ void main() { test('host generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -977,9 +989,10 @@ void main() { test('flutter generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -1010,9 +1023,10 @@ void main() { test('flutter int return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration(baseName: 'int', isNullable: false), parameters: [], @@ -1041,9 +1055,10 @@ void main() { test('host multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -1082,9 +1097,10 @@ void main() { test('if host argType is Object not cast', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'objectTest', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -1110,9 +1126,10 @@ void main() { test('flutter multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -1152,9 +1169,10 @@ void main() { test('flutter single args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'send', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -1184,9 +1202,10 @@ void main() { test('return nullable host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1213,9 +1232,10 @@ void main() { test('return nullable host async', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1244,9 +1264,10 @@ void main() { test('nullable argument host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1277,9 +1298,10 @@ void main() { test('nullable argument flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1313,9 +1335,10 @@ void main() { test('background platform channel', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1415,13 +1438,13 @@ void main() { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'api', - location: ApiLocation.flutter, documentationComments: [comments[count++]], methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), documentationComments: [comments[count++]], parameters: [ @@ -1496,12 +1519,12 @@ void main() { test("doesn't create codecs if no custom datatypes", () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1535,9 +1558,10 @@ void main() { test('creates custom codecs if custom datatypes present', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -1587,8 +1611,7 @@ void main() { }); test('creates api error class for custom errors', () { - final Api api = - Api(name: 'Api', location: ApiLocation.host, methods: []); + final Api api = AstHostApi(name: 'Api', methods: []); final Root root = Root( apis: [api], classes: [], @@ -1610,12 +1633,12 @@ void main() { test('connection error contains channel name', () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index f51c68b32bcc..e680e3ac66d2 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -140,9 +140,10 @@ void main() { test('primitive enum host', () { final Root root = Root(apis: [ - Api(name: 'Bar', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Bar', methods: [ Method( name: 'bar', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -176,9 +177,10 @@ void main() { test('gen one host api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -405,9 +407,10 @@ void main() { test('gen one flutter api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -462,9 +465,10 @@ void main() { test('gen host void api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -505,9 +509,10 @@ void main() { test('gen flutter void return api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -550,9 +555,10 @@ void main() { test('gen host void argument api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -590,9 +596,10 @@ void main() { test('gen flutter void argument api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -732,9 +739,10 @@ void main() { test('gen one async Host Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -790,9 +798,10 @@ void main() { test('gen one async Flutter Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -979,9 +988,10 @@ void main() { test('host generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1015,9 +1025,10 @@ void main() { test('flutter generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1051,9 +1062,10 @@ void main() { test('host generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -1084,9 +1096,10 @@ void main() { test('flutter generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -1116,9 +1129,10 @@ void main() { test('host multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -1159,9 +1173,10 @@ void main() { test('flutter multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -1203,9 +1218,10 @@ void main() { test('return nullable host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1232,9 +1248,10 @@ void main() { test('return nullable host async', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1262,9 +1279,10 @@ void main() { test('nullable argument host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1298,9 +1316,10 @@ void main() { test('nullable argument flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1333,9 +1352,10 @@ void main() { test('nonnull fields', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -1389,13 +1409,13 @@ void main() { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'api', - location: ApiLocation.flutter, documentationComments: [comments[count++]], methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), documentationComments: [comments[count++]], parameters: [ @@ -1470,12 +1490,12 @@ void main() { test("doesn't create codecs if no custom datatypes", () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1509,9 +1529,10 @@ void main() { test('creates custom codecs if custom datatypes present', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -1563,10 +1584,11 @@ void main() { test('creates api error class for custom errors', () { final Method method = Method( name: 'doSomething', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: []); - final Api api = Api( - name: 'SomeApi', location: ApiLocation.host, methods: [method]); + final AstHostApi api = + AstHostApi(name: 'SomeApi', methods: [method]); final Root root = Root( apis: [api], classes: [], @@ -1593,12 +1615,12 @@ void main() { test('connection error contains channel name', () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1639,12 +1661,12 @@ void main() { test('gen host uses default error class', () { final Root root = Root( apis: [ - Api( + AstHostApi( name: 'Api', - location: ApiLocation.host, methods: [ Method( name: 'method', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1678,12 +1700,12 @@ void main() { test('gen flutter uses default error class', () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1717,12 +1739,12 @@ void main() { test('gen host uses error class', () { final Root root = Root( apis: [ - Api( + AstHostApi( name: 'Api', - location: ApiLocation.host, methods: [ Method( name: 'method', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1759,12 +1781,12 @@ void main() { test('gen flutter uses error class', () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index f77f186ac8df..267747e1e913 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -188,9 +188,10 @@ void main() { test('primitive enum host', () { final Root root = Root(apis: [ - Api(name: 'Bar', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Bar', methods: [ Method( name: 'bar', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -251,9 +252,10 @@ void main() { test('validate nullable primitive enum', () { final Root root = Root(apis: [ - Api(name: 'Bar', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Bar', methods: [ Method( name: 'bar', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -328,9 +330,10 @@ void main() { test('gen one api header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -383,9 +386,10 @@ void main() { test('gen one api source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -656,9 +660,10 @@ void main() { test('prefix nested class header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -711,9 +716,10 @@ void main() { test('prefix nested class source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -766,9 +772,10 @@ void main() { test('gen flutter api header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -821,9 +828,10 @@ void main() { test('gen flutter api source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -872,9 +880,10 @@ void main() { test('gen host void header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -913,9 +922,10 @@ void main() { test('gen host void source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -956,9 +966,10 @@ void main() { test('gen flutter void return header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -997,9 +1008,10 @@ void main() { test('gen flutter void return source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -1039,9 +1051,10 @@ void main() { test('gen host void arg header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -1076,9 +1089,10 @@ void main() { test('gen host void arg source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -1113,9 +1127,10 @@ void main() { test('gen flutter void arg header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -1153,9 +1168,10 @@ void main() { test('gen flutter void arg source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -1281,9 +1297,10 @@ void main() { test('gen map argument with object', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1317,9 +1334,10 @@ void main() { test('async void (input) HostApi header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -1367,9 +1385,10 @@ void main() { test('async output(input) HostApi header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -1421,9 +1440,10 @@ void main() { test('async output(void) HostApi header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -1462,9 +1482,10 @@ void main() { test('async void (void) HostApi header', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration.voidDeclaration(), isAsynchronous: true) @@ -1493,9 +1514,10 @@ void main() { test('async output(input) HostApi source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -1547,9 +1569,10 @@ void main() { test('async void (input) HostApi source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -1597,9 +1620,10 @@ void main() { test('async void (void) HostApi source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: const TypeDeclaration.voidDeclaration(), isAsynchronous: true) @@ -1628,9 +1652,10 @@ void main() { test('async output(void) HostApi source', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -1755,9 +1780,10 @@ void main() { test('host generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1818,9 +1844,10 @@ void main() { test('flutter generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1878,9 +1905,10 @@ void main() { test('host nested generic argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1926,9 +1954,10 @@ void main() { test('host generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -1983,9 +2012,10 @@ void main() { test('flutter generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -2040,9 +2070,10 @@ void main() { test('host multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -2110,9 +2141,10 @@ void main() { test('host multiple args async', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -2180,9 +2212,10 @@ void main() { test('flutter multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -2245,25 +2278,48 @@ void main() { Root getDivideRoot(ApiLocation location) => Root( apis: [ - Api(name: 'Api', location: location, methods: [ - Method( - name: 'divide', - objcSelector: 'divideValue:by:', - parameters: [ - Parameter( - type: const TypeDeclaration( - baseName: 'int', isNullable: false), - name: 'x', - ), - Parameter( - type: const TypeDeclaration( - baseName: 'int', isNullable: false), - name: 'y', - ), - ], - returnType: const TypeDeclaration( - baseName: 'double', isNullable: false)) - ]) + switch (location) { + ApiLocation.host => AstHostApi(name: 'Api', methods: [ + Method( + name: 'divide', + location: location, + objcSelector: 'divideValue:by:', + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'int', isNullable: false), + name: 'x', + ), + Parameter( + type: const TypeDeclaration( + baseName: 'int', isNullable: false), + name: 'y', + ), + ], + returnType: const TypeDeclaration( + baseName: 'double', isNullable: false)) + ]), + ApiLocation.flutter => AstFlutterApi(name: 'Api', methods: [ + Method( + name: 'divide', + location: location, + objcSelector: 'divideValue:by:', + parameters: [ + Parameter( + type: const TypeDeclaration( + baseName: 'int', isNullable: false), + name: 'x', + ), + Parameter( + type: const TypeDeclaration( + baseName: 'int', isNullable: false), + name: 'y', + ), + ], + returnType: const TypeDeclaration( + baseName: 'double', isNullable: false)) + ]), + } ], classes: [], enums: [], @@ -2378,9 +2434,10 @@ void main() { test('return nullable flutter header', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -2414,9 +2471,10 @@ void main() { test('return nullable flutter source', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -2447,9 +2505,10 @@ void main() { test('return nullable host header', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -2480,9 +2539,10 @@ void main() { test('nullable argument host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -2537,9 +2597,10 @@ void main() { test('nullable argument flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -2593,9 +2654,10 @@ void main() { test('background platform channel', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -2644,13 +2706,13 @@ void main() { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'api', - location: ApiLocation.flutter, documentationComments: [comments[count++]], methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), documentationComments: [comments[count++]], parameters: [ @@ -2725,12 +2787,12 @@ void main() { test("doesn't create codecs if no custom datatypes", () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -2767,9 +2829,10 @@ void main() { test('creates custom codecs if custom datatypes present', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -2825,12 +2888,12 @@ void main() { test('connection error contains channel name', () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 5d60f92bf69d..7998733664ab 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -313,7 +313,7 @@ abstract class AFlutterApi { expect(results.errors.length, equals(0)); expect(results.root.apis.length, equals(1)); expect(results.root.apis[0].name, equals('AFlutterApi')); - expect(results.root.apis[0].location, equals(ApiLocation.flutter)); + expect(results.root.apis[0], isA()); }); test('void host api', () { @@ -370,8 +370,10 @@ abstract class ApiWithMockDartClass { final ParseResults results = parseSource(code); expect(results.errors.length, equals(0)); expect(results.root.apis.length, equals(1)); - expect(results.root.apis[0].dartHostTestHandler, - equals('ApiWithMockDartClassMock')); + expect( + (results.root.apis[0] as AstHostApi).dartHostTestHandler, + equals('ApiWithMockDartClassMock'), + ); }); test('only visible from nesting', () { diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 4c07b784eb74..e43dc8efed62 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -84,9 +84,10 @@ void main() { test('primitive enum host', () { final Root root = Root(apis: [ - Api(name: 'Bar', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Bar', methods: [ Method( name: 'bar', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -120,9 +121,10 @@ void main() { test('gen one host api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -248,9 +250,10 @@ void main() { test('gen one flutter api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -302,9 +305,10 @@ void main() { test('gen host void api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -343,9 +347,10 @@ void main() { test('gen flutter void return api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -385,9 +390,10 @@ void main() { test('gen host void argument api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -423,9 +429,10 @@ void main() { test('gen flutter void argument api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [], returnType: TypeDeclaration( baseName: 'Output', @@ -560,9 +567,10 @@ void main() { test('gen one async Host Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -615,9 +623,10 @@ void main() { test('gen one async Flutter Api', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -798,9 +807,10 @@ void main() { test('host generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -833,9 +843,10 @@ void main() { test('flutter generics argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -868,9 +879,10 @@ void main() { test('host generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -901,9 +913,10 @@ void main() { test('flutter generics return', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration( baseName: 'List', isNullable: false, @@ -936,9 +949,10 @@ void main() { test('host multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.host, parameters: [ Parameter( name: 'x', @@ -979,9 +993,10 @@ void main() { test('flutter multiple args', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'add', + location: ApiLocation.flutter, parameters: [ Parameter( name: 'x', @@ -1023,9 +1038,10 @@ void main() { test('return nullable host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1052,9 +1068,10 @@ void main() { test('return nullable host async', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration( baseName: 'int', isNullable: true, @@ -1085,9 +1102,10 @@ void main() { test('nullable argument host', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.host, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1121,9 +1139,10 @@ void main() { test('nullable argument flutter', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doit', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1156,9 +1175,10 @@ void main() { test('nonnull fields', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.host, parameters: [ Parameter( type: TypeDeclaration( @@ -1210,13 +1230,13 @@ void main() { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'api', - location: ApiLocation.flutter, documentationComments: [comments[count++]], methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), documentationComments: [comments[count++]], parameters: [ @@ -1287,12 +1307,12 @@ void main() { test("doesn't create codecs if no custom datatypes", () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( @@ -1325,9 +1345,10 @@ void main() { test('creates custom codecs if custom datatypes present', () { final Root root = Root(apis: [ - Api(name: 'Api', location: ApiLocation.flutter, methods: [ + AstFlutterApi(name: 'Api', methods: [ Method( name: 'doSomething', + location: ApiLocation.flutter, parameters: [ Parameter( type: TypeDeclaration( @@ -1379,9 +1400,10 @@ void main() { test('swift function signature', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'set', + location: ApiLocation.host, parameters: [ Parameter( type: const TypeDeclaration( @@ -1422,9 +1444,10 @@ void main() { test('swift function signature with same name argument', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'set', + location: ApiLocation.host, parameters: [ Parameter( type: const TypeDeclaration( @@ -1458,9 +1481,10 @@ void main() { test('swift function signature with no arguments', () { final Root root = Root( apis: [ - Api(name: 'Api', location: ApiLocation.host, methods: [ + AstHostApi(name: 'Api', methods: [ Method( name: 'clear', + location: ApiLocation.host, parameters: [], swiftFunction: 'removeAll()', returnType: const TypeDeclaration.voidDeclaration(), @@ -1486,12 +1510,12 @@ void main() { test('connection error contains channel name', () { final Root root = Root( apis: [ - Api( + AstFlutterApi( name: 'Api', - location: ApiLocation.flutter, methods: [ Method( name: 'method', + location: ApiLocation.flutter, returnType: const TypeDeclaration.voidDeclaration(), parameters: [ Parameter( diff --git a/script/configs/allowed_unpinned_deps.yaml b/script/configs/allowed_unpinned_deps.yaml index fe4c138b0a63..84ff94a1101b 100644 --- a/script/configs/allowed_unpinned_deps.yaml +++ b/script/configs/allowed_unpinned_deps.yaml @@ -25,9 +25,11 @@ - build_config - build_runner - build_test +- code_builder - collection - convert - crypto +- dart_style - fake_async - ffi - gcloud