in packages/pigeon/lib/dart_generator.dart [236:358]
void _writeFlutterApi(
DartOptions opt,
Indent indent,
Api api,
Root root, {
String Function(Method)? channelNameFunc,
bool isMockHandler = false,
}) {
assert(api.location == ApiLocation.flutter);
final String codecName = _getCodecName(api);
_writeCodec(indent, codecName, api, root);
final String nullTag = opt.isNullSafe ? '?' : '';
final String unwrapOperator = opt.isNullSafe ? '!' : '';
indent.write('abstract class ${api.name} ');
indent.scoped('{', '}', () {
indent.writeln('static const MessageCodec<Object?> codec = $codecName();');
indent.addln('');
for (final Method func in api.methods) {
final bool isAsync = func.isAsynchronous;
final String returnType = isAsync
? 'Future<${_addGenericTypes(func.returnType, nullTag)}>'
: _addGenericTypes(func.returnType, nullTag);
final String argSignature = _getMethodArgumentsSignature(
func,
_getArgumentName,
nullTag,
);
indent.writeln('$returnType ${func.name}($argSignature);');
}
indent.write(
'static void setup(${api.name}$nullTag api, {BinaryMessenger$nullTag binaryMessenger}) ');
indent.scoped('{', '}', () {
for (final Method func in api.methods) {
indent.write('');
indent.scoped('{', '}', () {
indent.writeln(
'final BasicMessageChannel<Object$nullTag> channel = BasicMessageChannel<Object$nullTag>(',
);
final String channelName = channelNameFunc == null
? makeChannelName(api, func)
: channelNameFunc(func);
indent.nest(2, () {
indent.writeln(
'\'$channelName\', codec, binaryMessenger: binaryMessenger);',
);
});
final String messageHandlerSetter =
isMockHandler ? 'setMockMessageHandler' : 'setMessageHandler';
indent.write('if (api == null) ');
indent.scoped('{', '}', () {
indent.writeln('channel.$messageHandlerSetter(null);');
}, addTrailingNewline: false);
indent.add(' else ');
indent.scoped('{', '}', () {
indent.write(
'channel.$messageHandlerSetter((Object$nullTag message) async ',
);
indent.scoped('{', '});', () {
final String returnType =
_addGenericTypes(func.returnType, nullTag);
final bool isAsync = func.isAsynchronous;
final String emptyReturnStatement = isMockHandler
? 'return <Object$nullTag, Object$nullTag>{};'
: func.returnType.isVoid
? 'return;'
: 'return null;';
String call;
if (func.arguments.isEmpty) {
indent.writeln('// ignore message');
call = 'api.${func.name}()';
} else {
indent.writeln(
'assert(message != null, \'Argument for $channelName was null.\');',
);
const String argsArray = 'args';
indent.writeln(
'final List<Object$nullTag> $argsArray = (message as List<Object$nullTag>$nullTag)$unwrapOperator;');
String argNameFunc(int index, NamedType type) =>
_getSafeArgumentName(index, type);
enumerate(func.arguments, (int count, NamedType arg) {
final String argType = _addGenericTypes(arg.type, nullTag);
final String argName = argNameFunc(count, arg);
final String genericArgType =
_makeGenericTypeArguments(arg.type, nullTag);
final String castCall =
_makeGenericCastCall(arg.type, nullTag);
indent.writeln(
'final $argType$nullTag $argName = ($argsArray[$count] as $genericArgType$nullTag)${castCall.isEmpty ? '' : '$nullTag$castCall'};');
indent.writeln(
'assert($argName != null, \'Argument for $channelName was null, expected non-null $argType.\');');
});
final Iterable<String> argNames =
indexMap(func.arguments, argNameFunc);
call =
'api.${func.name}(${argNames.map<String>((String x) => '$x$unwrapOperator').join(', ')})';
}
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 returnStatement = isMockHandler
? 'return <Object$nullTag, Object$nullTag>{\'${Keys.result}\': $returnExpression};'
: 'return $returnExpression;';
indent.writeln(returnStatement);
}
});
});
});
}
});
});
}