Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How would I do Intl.message in this system? #24

Open
alanknight-wk opened this issue Jul 19, 2021 · 3 comments
Open

How would I do Intl.message in this system? #24

alanknight-wk opened this issue Jul 19, 2021 · 3 comments

Comments

@alanknight-wk
Copy link

One of the long-standing irritations in Intl is the redundant information that has to be passed. e.g. a simple call ooks like

String foo(String a, String b) => Intl.message('text with $a and $b', desc: 'arbitrary example', name: 'foo', args: [a, b], examples: const {'a': 'thing one', 'b': 'thing two'});

This is processed in two phases.

  • There's a build(-ish) time extraction that parses the text and extracts the information for translators. The description and examples are only used at this time, and even the main text is only used at this time for production purposes. In development it's also used before any translations are available.
  • At runtime the name is required as a lookup key for the translation text to use, and the args are required so that they can be interpolated into the translated text. This information is already available in the function definition, but not at run-time.

With transformers, developers could omit name and args and have them filled in automatically. It would be nice to be able to do the same with macros. So it seems like

  • An additional annotation for each message? Or is it possible to run a class-level or library level macro that would find all the messages within it.
  • More significantly, it's not clear to me how I could provide additional arguments into a method body. I haven't tried to implement it, just looked over the documentation, but I don't see a mechanism, and I don't see a mechanical rewrite that would fix it. About the only thing I can see is if you rewrote the whole statement into an annotation (can these anootations have parameters or a declaration that would be disregarded, e.g.
    @intlMessage(['a', 'b'], r'text with $a and $b', 'arbitrary example', {'a': 'thing one', 'b': thing two'}
    or
   @intlMessage
   String _payNoAttentionTofoo(String a, String b) => Intl.message('text with $a and $b', desc: 'arbitrary example', examples: const {'a': 'thing one', 'b': 'thing two'});

which would then produce foo. Neither of these seems great.

@jakemac53
Copy link
Owner

jakemac53 commented Jul 21, 2021

I think the way you would need to do this in the current system is with the annotation, yes. I would opt for a variant of the first solution probably, something like this:

@IntlMessage(r'text with $a and $b', 'arbitrary example', {'a': 'thing one', 'b': 'thing two'})
external String foo(String a, String b);

We are considering allowing statement level macros also, which would be a bit nicer, possibly allowing something like this:

String foo(String a, String b) =>
  intlMessage('text with $a and $b', 'arbitrary example', {'a': 'thing one', 'b': thing two'});

The advantage would be allowing you to use the actual string interpolation in the user code instead of a weird raw string.

This intlMessage thing looks like a function but would actually be a macro, and it would be able to effectively replace itself with any expression it likes, and its arguments would be provided as code blocks, which it could effectively splat into that resulting expression however it chooses. It would also be to introspect on the parent scope (function or method in this case) in order to generate the code (in this case the name and args).

@TimWhiting
Copy link
Contributor

Statement level macros would fix a lot of the limitations I see with the current approach. Glad it's being considered!

@alanknight-wk
Copy link
Author

Yes, the statement level macros does sound very promising. And more like what "macro" means in other systems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants