createI18nMessage method

Expression createI18nMessage(
  1. I18nMessage message
)

Generates code to internationalize message.

Returns an expression that evaluates to the internationalized message. May reuse an existing generated expression if a duplicate message has already been created.

Implementation

o.Expression createI18nMessage(I18nMessage message) {
  if (_i18nMessages.containsKey(message)) {
    return _i18nMessages[message]!;
  }
  final args = [
    _textExpression(message),
    o.NamedExpr('desc', o.literal(message.metadata.description)),
    if (message.metadata.locale != null)
      o.NamedExpr('locale', o.literal(message.metadata.locale)),
    if (message.metadata.meaning != null)
      o.NamedExpr('meaning', o.literal(message.metadata.meaning)),
    if (message.metadata.skip) o.NamedExpr('skip', o.literal(true)),
  ];
  final i18n = o.importExpr(Identifiers.Intl);
  final name = '_message_${_i18nMessages.length}';
  o.Expression messageExpression;
  if (message.containsHtml) {
    // A message with arguments is generated as a static method.
    // These are passed to `args` in `Intl.message()`.
    final messageArgs = <o.ReadVarExpr>[];
    // These are passed to `examples` in `Intl.message()`.
    final messageExamples = <List<dynamic>>[];
    final messageExamplesType = o.MapType(null, [o.TypeModifier.Const]);
    // These are the arguments used to invoke the generated method.
    final methodArgs = <o.LiteralExpr>[];
    // These are the parameters of the generated method.
    final methodParameters = <o.FnParam>[];
    for (final parameter in message.args.keys) {
      final argument = o.literal(message.args[parameter]);
      messageArgs.add(o.variable(parameter));
      messageExamples.add([parameter, argument]);
      methodArgs.add(argument);
      methodParameters.add(o.FnParam(parameter, o.STRING_TYPE));
    }
    args
      ..add(o.NamedExpr('name', o.literal('${className}_$name')))
      ..add(o.NamedExpr('args', o.literalArr(messageArgs)))
      ..add(o.NamedExpr(
        'examples',
        o.literalMap(messageExamples, messageExamplesType),
      ));
    final value = i18n.callMethod('message', args);
    final method = o.ClassMethod(
      name,
      methodParameters,
      [o.ReturnStatement(value)],
      o.STRING_TYPE,
      [o.StmtModifier.Static, o.StmtModifier.Private],
    );
    methods.add(method);
    // A hack to invoke a static class method.
    messageExpression = o.InvokeFunctionExpr(
      o.ReadStaticMemberExpr(name),
      methodArgs,
      [],
      type: o.STRING_TYPE,
    );
  } else {
    // A message with no arguments is generated as a static final field.
    final value = i18n.callMethod('message', args);
    final item = storage.allocate(
      name,
      outputType: o.STRING_TYPE,
      initializer: value,
      modifiers: const [
        o.StmtModifier.Static,
        o.StmtModifier.Final,
        o.StmtModifier.Private,
      ],
    );
    messageExpression = storage.buildReadExpr(item);
  }
  return _i18nMessages[message] = messageExpression;
}