writeFlutterApi method
void
writeFlutterApi(
- ArkTSOptions generatorOptions,
- Root root,
- Indent indent,
- Api api, {
- required String dartPackageName,
override
Writes a single Flutter Api to indent
.
Implementation
@override
void writeFlutterApi(
ArkTSOptions generatorOptions, Root root, Indent indent, Api api,
{required String dartPackageName}) {
assert(api.location == ApiLocation.flutter);
if (getCodecClasses(api, root).isNotEmpty) {
_writeCodec(indent, api, root);
}
const List<String> generatedMessages = <String>[
' Generated class from Pigeon that represents Flutter messages that can be called from ArkTS.'
];
addDocumentationComments(indent, api.documentationComments, _docCommentSpec,
generatorComments: generatedMessages);
indent.write('export class ${api.name} ');
indent.addScoped('{', '}', () {
indent.writeln('binaryMessenger: BinaryMessenger;');
indent.newln();
indent.write('constructor(binaryMessenger: BinaryMessenger) ');
indent.addScoped('{', '}', () {
indent.writeln('this.binaryMessenger = binaryMessenger;');
});
indent.newln();
final String codecName = _getCodecName(api);
indent.writeln('/** The codec used by ${api.name}. */');
indent.write('static getCodec(): MessageCodec<Object> ');
indent.addScoped('{', '}', () {
indent.write('return ');
if (getCodecClasses(api, root).isNotEmpty) {
indent.addln('$codecName.INSTANCE;');
} else {
indent.addln('new $_standardMessageCodec();');
}
});
indent.newln();
/// Returns an argument name that can be used in a context where it is possible to collide
/// and append `.index` to enums.
String getEnumSafeArgumentExpression(int count, NamedType argument) {
if (isEnum(root, argument.type)) {
return argument.type.isNullable
? '${_getArgumentName(count, argument)}Arg == null ? null : ${_getArgumentName(count, argument)}Arg.index'
: '${_getArgumentName(count, argument)}Arg.index';
}
return '${_getArgumentName(count, argument)}Arg';
}
for (final Method func in api.methods) {
final String channelName = makeChannelName(api, func, dartPackageName);
final String returnType = func.returnType.isVoid
? 'void'
: _arkTSTypeForDartType(func.returnType);
String sendArgument;
addDocumentationComments(
indent, func.documentationComments, _docCommentSpec);
if (func.arguments.isEmpty) {
indent.write('${func.name}(callback: Reply<$returnType>):void ');
sendArgument = 'null';
} else {
final Iterable<String> argTypes = func.arguments
.map((NamedType e) => _arkTSTypeForDartType(e.type));
final Iterable<String> argNames =
indexMap(func.arguments, _getSafeArgumentName);
final Iterable<String> enumSafeArgNames =
indexMap(func.arguments, getEnumSafeArgumentExpression);
sendArgument = '[${argNames.join(', ')}]';
final String argsSignature =
map2(argTypes, argNames, (String x, String y) => '$y: $x')
.join(',');
indent.write(
'${func.name}($argsSignature, callback: Reply<$returnType>) ');
}
indent.addScoped('{', '}', () {
const String channel = 'channel';
indent.writeln('let $channel: BasicMessageChannel<Object> = ');
indent.nest(2, () {
indent.writeln('new BasicMessageChannel<Object>(');
indent.nest(2, () {
indent.writeln(
'this.binaryMessenger, "$channelName", ${api.name}.getCodec());');
});
});
indent.writeln('$channel.send(');
indent.nest(2, () {
indent.writeln('$sendArgument,');
indent.write('channelReply => ');
if (func.returnType.isVoid) {
indent.addln('callback.reply(null));');
} else {
indent.addScoped('{', '});', () {
const String output = 'output';
if (func.returnType.baseName == 'number') {
indent.writeln(
'let $output: $returnType = channelReply == null ? null : channelReply as number;');
} else if (isEnum(root, func.returnType)) {
indent.writeln(
'let $output: $returnType = channelReply == null ? null : $returnType[channelReply as number];');
} else {
indent.writeln(
'let $output: $returnType = ${_cast('channelReply', artTSType: returnType)};');
}
indent.writeln('callback.reply($output);');
});
}
});
});
}
});
}