Skip to content

Commit 9ad2327

Browse files
[pigeon] Updates PigeonInstanceMangerApi to use the shared api channel code in Dart (flutter#6831)
This is in response to flutter/packages#6371 (comment)
1 parent 910fabb commit 9ad2327

File tree

7 files changed

+315
-163
lines changed

7 files changed

+315
-163
lines changed

packages/pigeon/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 19.0.1
2+
3+
* [dart] Updates `PigeonInstanceMangerApi` to use the shared api channel code.
4+
15
## 19.0.0
26

37
* **Breaking Change** [swift] Removes `FlutterError` in favor of `PigeonError`.

packages/pigeon/lib/dart/templates.dart

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -215,113 +215,6 @@ class $instanceManagerClassName {
215215
''';
216216
}
217217

218-
/// Creates the `InstanceManagerApi` with the passed string values.
219-
String instanceManagerApiTemplate({
220-
required String dartPackageName,
221-
required String pigeonChannelCodecVarName,
222-
}) {
223-
const String apiName = '${instanceManagerClassName}Api';
224-
225-
final String removeStrongReferenceName = makeChannelNameWithStrings(
226-
apiName: apiName,
227-
methodName: 'removeStrongReference',
228-
dartPackageName: dartPackageName,
229-
);
230-
231-
final String clearName = makeChannelNameWithStrings(
232-
apiName: apiName,
233-
methodName: 'clear',
234-
dartPackageName: dartPackageName,
235-
);
236-
237-
return '''
238-
/// Generated API for managing the Dart and native `$instanceManagerClassName`s.
239-
class _$apiName {
240-
/// Constructor for [_$apiName].
241-
_$apiName({BinaryMessenger? binaryMessenger})
242-
: _binaryMessenger = binaryMessenger;
243-
244-
final BinaryMessenger? _binaryMessenger;
245-
246-
static const MessageCodec<Object?> $pigeonChannelCodecVarName =
247-
StandardMessageCodec();
248-
249-
static void setUpMessageHandlers({
250-
BinaryMessenger? binaryMessenger,
251-
$instanceManagerClassName? instanceManager,
252-
}) {
253-
const String channelName =
254-
r'$removeStrongReferenceName';
255-
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
256-
channelName,
257-
$pigeonChannelCodecVarName,
258-
binaryMessenger: binaryMessenger,
259-
);
260-
channel.setMessageHandler((Object? message) async {
261-
assert(
262-
message != null,
263-
'Argument for \$channelName was null.',
264-
);
265-
final int? identifier = message as int?;
266-
assert(
267-
identifier != null,
268-
r'Argument for \$channelName, expected non-null int.',
269-
);
270-
(instanceManager ?? $instanceManagerClassName.instance).remove(identifier!);
271-
return;
272-
});
273-
}
274-
275-
Future<void> removeStrongReference(int identifier) async {
276-
const String channelName =
277-
r'$removeStrongReferenceName';
278-
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
279-
channelName,
280-
$pigeonChannelCodecVarName,
281-
binaryMessenger: _binaryMessenger,
282-
);
283-
final List<Object?>? replyList =
284-
await channel.send(identifier) as List<Object?>?;
285-
if (replyList == null) {
286-
throw _createConnectionError(channelName);
287-
} else if (replyList.length > 1) {
288-
throw PlatformException(
289-
code: replyList[0]! as String,
290-
message: replyList[1] as String?,
291-
details: replyList[2],
292-
);
293-
} else {
294-
return;
295-
}
296-
}
297-
298-
/// Clear the native `$instanceManagerClassName`.
299-
///
300-
/// This is typically called after a hot restart.
301-
Future<void> clear() async {
302-
const String channelName =
303-
r'$clearName';
304-
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
305-
channelName,
306-
$pigeonChannelCodecVarName,
307-
binaryMessenger: _binaryMessenger,
308-
);
309-
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
310-
if (replyList == null) {
311-
throw _createConnectionError(channelName);
312-
} else if (replyList.length > 1) {
313-
throw PlatformException(
314-
code: replyList[0]! as String,
315-
message: replyList[1] as String?,
316-
details: replyList[2],
317-
);
318-
} else {
319-
return;
320-
}
321-
}
322-
}''';
323-
}
324-
325218
/// The base class for all ProxyApis.
326219
///
327220
/// All Dart classes generated as a ProxyApi extends this one.

packages/pigeon/lib/dart_generator.dart

Lines changed: 199 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ $resultAt != null
362362
name: func.name,
363363
parameters: func.parameters,
364364
returnType: func.returnType,
365+
addSuffixVariable: true,
365366
channelName: channelNameFunc == null
366367
? makeChannelName(api, func, dartPackageName)
367368
: channelNameFunc(func),
@@ -468,11 +469,204 @@ final BinaryMessenger? ${_varNamePrefix}binaryMessenger;
468469
Indent indent, {
469470
required String dartPackageName,
470471
}) {
472+
const String apiName = '${instanceManagerClassName}Api';
473+
474+
final cb.Parameter binaryMessengerParameter = cb.Parameter(
475+
(cb.ParameterBuilder builder) => builder
476+
..name = 'binaryMessenger'
477+
..type = cb.refer('BinaryMessenger?')
478+
..named = true,
479+
);
480+
481+
final cb.Field binaryMessengerField = cb.Field(
482+
(cb.FieldBuilder builder) => builder
483+
..name = '${varNamePrefix}binaryMessenger'
484+
..type = cb.refer('BinaryMessenger?')
485+
..modifier = cb.FieldModifier.final$,
486+
);
487+
488+
final String removeStrongReferenceName = makeChannelNameWithStrings(
489+
apiName: apiName,
490+
methodName: 'removeStrongReference',
491+
dartPackageName: dartPackageName,
492+
);
493+
494+
final cb.Class instanceManagerApi = cb.Class(
495+
(cb.ClassBuilder builder) => builder
496+
..name = '_$apiName'
497+
..docs.add(
498+
'/// Generated API for managing the Dart and native `$instanceManagerClassName`s.',
499+
)
500+
..constructors.add(
501+
cb.Constructor(
502+
(cb.ConstructorBuilder builder) {
503+
builder
504+
..docs.add('/// Constructor for [_$apiName].')
505+
..optionalParameters.add(binaryMessengerParameter)
506+
..initializers.add(
507+
cb.Code(
508+
'${binaryMessengerField.name} = ${binaryMessengerParameter.name}',
509+
),
510+
);
511+
},
512+
),
513+
)
514+
..fields.addAll(
515+
<cb.Field>[
516+
binaryMessengerField,
517+
cb.Field(
518+
(cb.FieldBuilder builder) {
519+
builder
520+
..name = _pigeonChannelCodec
521+
..type = cb.refer('MessageCodec<Object?>')
522+
..static = true
523+
..modifier = cb.FieldModifier.constant
524+
..assignment = const cb.Code('StandardMessageCodec()');
525+
},
526+
)
527+
],
528+
)
529+
..methods.add(
530+
cb.Method(
531+
(cb.MethodBuilder builder) {
532+
builder
533+
..name = 'setUpMessageHandlers'
534+
..static = true
535+
..returns = cb.refer('void')
536+
..optionalParameters.addAll(<cb.Parameter>[
537+
cb.Parameter(
538+
(cb.ParameterBuilder builder) => builder
539+
..name = '${classMemberNamePrefix}clearHandlers'
540+
..type = cb.refer('bool')
541+
..named = true
542+
..defaultTo = const cb.Code('false'),
543+
),
544+
binaryMessengerParameter,
545+
cb.Parameter(
546+
(cb.ParameterBuilder builder) => builder
547+
..name = 'instanceManager'
548+
..named = true
549+
..type = cb.refer('$instanceManagerClassName?'),
550+
),
551+
])
552+
..body = cb.Block.of(
553+
cb.Block(
554+
(cb.BlockBuilder builder) {
555+
final StringBuffer messageHandlerSink = StringBuffer();
556+
_writeFlutterMethodMessageHandler(
557+
Indent(messageHandlerSink),
558+
name: 'removeStrongReferenceName',
559+
parameters: <Parameter>[
560+
Parameter(
561+
name: 'identifier',
562+
type: const TypeDeclaration(
563+
baseName: 'int',
564+
isNullable: false,
565+
),
566+
)
567+
],
568+
returnType: const TypeDeclaration.voidDeclaration(),
569+
channelName: removeStrongReferenceName,
570+
isMockHandler: false,
571+
isAsynchronous: false,
572+
nullHandlerExpression:
573+
'${classMemberNamePrefix}clearHandlers',
574+
onCreateApiCall: (
575+
String methodName,
576+
Iterable<Parameter> parameters,
577+
Iterable<String> safeArgumentNames,
578+
) {
579+
return '(instanceManager ?? $instanceManagerClassName.instance).remove(${safeArgumentNames.single})';
580+
},
581+
);
582+
builder.statements.add(
583+
cb.Code(messageHandlerSink.toString()),
584+
);
585+
},
586+
).statements,
587+
);
588+
},
589+
),
590+
)
591+
..methods.addAll(
592+
<cb.Method>[
593+
cb.Method(
594+
(cb.MethodBuilder builder) {
595+
builder
596+
..name = 'removeStrongReference'
597+
..returns = cb.refer('Future<void>')
598+
..modifier = cb.MethodModifier.async
599+
..requiredParameters.add(
600+
cb.Parameter(
601+
(cb.ParameterBuilder builder) => builder
602+
..name = 'identifier'
603+
..type = cb.refer('int'),
604+
),
605+
)
606+
..body = cb.Block(
607+
(cb.BlockBuilder builder) {
608+
final StringBuffer messageCallSink = StringBuffer();
609+
_writeHostMethodMessageCall(
610+
Indent(messageCallSink),
611+
addSuffixVariable: false,
612+
channelName: removeStrongReferenceName,
613+
parameters: <Parameter>[
614+
Parameter(
615+
name: 'identifier',
616+
type: const TypeDeclaration(
617+
baseName: 'int',
618+
isNullable: false,
619+
),
620+
),
621+
],
622+
returnType: const TypeDeclaration.voidDeclaration(),
623+
);
624+
builder.statements.addAll(<cb.Code>[
625+
cb.Code(messageCallSink.toString()),
626+
]);
627+
},
628+
);
629+
},
630+
),
631+
cb.Method(
632+
(cb.MethodBuilder builder) {
633+
builder
634+
..name = 'clear'
635+
..returns = cb.refer('Future<void>')
636+
..modifier = cb.MethodModifier.async
637+
..docs.addAll(<String>[
638+
'/// Clear the native `$instanceManagerClassName`.',
639+
'///',
640+
'/// This is typically called after a hot restart.',
641+
])
642+
..body = cb.Block(
643+
(cb.BlockBuilder builder) {
644+
final StringBuffer messageCallSink = StringBuffer();
645+
_writeHostMethodMessageCall(
646+
Indent(messageCallSink),
647+
addSuffixVariable: false,
648+
channelName: makeChannelNameWithStrings(
649+
apiName: apiName,
650+
methodName: 'clear',
651+
dartPackageName: dartPackageName,
652+
),
653+
parameters: <Parameter>[],
654+
returnType: const TypeDeclaration.voidDeclaration(),
655+
);
656+
builder.statements.addAll(<cb.Code>[
657+
cb.Code(messageCallSink.toString()),
658+
]);
659+
},
660+
);
661+
},
662+
),
663+
],
664+
),
665+
);
666+
667+
final cb.DartEmitter emitter = cb.DartEmitter(useNullSafetySyntax: true);
471668
indent.format(
472-
instanceManagerApiTemplate(
473-
dartPackageName: dartPackageName,
474-
pigeonChannelCodecVarName: _pigeonChannelCodec,
475-
),
669+
DartFormatter().format('${instanceManagerApi.accept(emitter)}'),
476670
);
477671
}
478672

@@ -859,7 +1053,7 @@ if (${varNamePrefix}replyList == null) {
8591053
);
8601054
indent.nest(2, () {
8611055
final String channelSuffix =
862-
addSuffixVariable ? '' : r'$messageChannelSuffix';
1056+
addSuffixVariable ? r'$messageChannelSuffix' : '';
8631057
indent.writeln("'$channelName$channelSuffix', $_pigeonChannelCodec,");
8641058
indent.writeln(
8651059
'binaryMessenger: binaryMessenger);',
@@ -1451,7 +1645,6 @@ if (${varNamePrefix}replyList == null) {
14511645
_writeFlutterMethodMessageHandler(
14521646
Indent(messageHandlerSink),
14531647
name: methodName,
1454-
addSuffixVariable: true,
14551648
parameters: <Parameter>[
14561649
Parameter(
14571650
name: '${classMemberNamePrefix}instanceIdentifier',
@@ -1507,7 +1700,6 @@ if (${varNamePrefix}replyList == null) {
15071700
_writeFlutterMethodMessageHandler(
15081701
Indent(messageHandlerSink),
15091702
name: method.name,
1510-
addSuffixVariable: true,
15111703
parameters: <Parameter>[
15121704
Parameter(
15131705
name: '${classMemberNamePrefix}instance',

packages/pigeon/lib/generator_tools.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'ast.dart';
1313
/// The current version of pigeon.
1414
///
1515
/// This must match the version in pubspec.yaml.
16-
const String pigeonVersion = '19.0.0';
16+
const String pigeonVersion = '19.0.1';
1717

1818
/// Prefix for all local variables in methods.
1919
///

0 commit comments

Comments
 (0)