Improvements to compiled size of generated messages with dart2js, loosen pubspec for fixnum
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 02055b1..d5438cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
## 0.12.5
* Parse Eras in DateFormat.
+ * Update pubspec.yaml to allow newer version of fixnum.
+ * Improvements to the compiled size of generated messages code with dart2js.
## 0.12.4+2
* update analyzer to '<0.27.0'
diff --git a/README.md b/README.md
index e1fcfc0..2573df8 100644
--- a/README.md
+++ b/README.md
@@ -123,13 +123,13 @@
name: "greetingMessage",
args: [name],
desc: "Greet the user as they first open the application",
- examples: {'name': "Emily"});
+ examples: const {'name': "Emily"});
print(greetingMessage('Dan'));
There is one special class of complex expressions allowed in the
message string, for plurals and genders.
- remainingEmailsMessage(int howMany, String userName) =>
+ remainingEmailsMessage(int howMany, String userName) =>
Intl.message(
"${Intl.plural(howMany,
zero: 'There are no emails left for $userName.',
@@ -138,7 +138,7 @@
name: "remainingEmailsMessage",
args: [howMany, userName],
desc: "How many emails remain after archiving.",
- examples: {'howMany': 42, 'userName': 'Fred'});
+ examples: const {'howMany': 42, 'userName': 'Fred'});
print(remainingEmailsMessage(1, "Fred"));
@@ -146,7 +146,7 @@
be at the top-level, we can also omit the [Intl.message][Intl.message] call and
provide its parameters to the [Intl.plural][Intl.plural] call instead.
- remainingEmailsMessage(int howMany, String userName) =>
+ remainingEmailsMessage(int howMany, String userName) =>
Intl.plural(
howMany,
zero: 'There are no emails left for $userName.',
@@ -155,12 +155,12 @@
name: "remainingEmailsMessage",
args: [howMany, userName],
desc: "How many emails remain after archiving.",
- examples: {'howMany': 42, 'userName': 'Fred'});
+ examples: const {'howMany': 42, 'userName': 'Fred'});
Similarly, there is an [Intl.gender][Intl.gender] message, and plurals
and genders can be nested.
- notOnlineMessage(String userName, String userGender) =>
+ notOnlineMessage(String userName, String userGender) =>
Intl.gender(
userGender,
male: '$userName is unavailable because he is not online.',
@@ -169,7 +169,7 @@
name: "notOnlineMessage",
args: [userName, userGender],
desc: "The user is not available to hangout.",
- examples: {{'userGender': 'male', 'userName': 'Fred'},
+ examples: const {{'userGender': 'male', 'userName': 'Fred'},
{'userGender': 'female', 'userName' : 'Alice'}});
It's recommended to use complete sentences in the sub-messages to keep
@@ -179,7 +179,7 @@
When your program contains messages that need translation, these must
be extracted from the program source, sent to human translators, and the
-results need to be incorporated.
+results need to be incorporated.
To extract messages, run the `extract_to_arb.dart` program.
@@ -190,14 +190,14 @@
all of these programs. an [ARB]
(https://code.google.com/p/arb/wiki/ApplicationResourceBundleSpecification)
format file which can be used for input to translation tools like
-[Google Translator Toolkit](https://translate.google.com/toolkit/)
+[Google Translator Toolkit](https://translate.google.com/toolkit/)
The resulting translations can be used to generate a set of libraries
using the `generate_from_arb.dart` program.
This expects to receive a series of files, one per
-locale.
+locale.
- pub run intl:generate_from_arb --generated_file_prefix=<prefix>
+ pub run intl:generate_from_arb --generated_file_prefix=<prefix>
<my_dart_files> <translated_ARB_files>
This will generate Dart libraries, one per locale, which contain the
diff --git a/lib/generate_localized.dart b/lib/generate_localized.dart
index 80ab958..e5c1bc3 100644
--- a/lib/generate_localized.dart
+++ b/lib/generate_localized.dart
@@ -125,21 +125,29 @@
usableTranslations.sort((a, b) =>
a.originalMessages.first.name.compareTo(b.originalMessages.first.name));
for (var translation in usableTranslations) {
- for (var original in translation.originalMessages) {
+ // Some messages we generate as methods in this class. Simpler ones
+ // we inline in the map from names to messages.
+ var messagesThatNeedMethods =
+ translation.originalMessages.where((each) => _hasArguments(each));
+ for (var original in messagesThatNeedMethods) {
result
..write(" ")
..write(original.toCodeForLocale(locale))
..write("\n\n");
}
}
- result.write("\n final messages = const {\n");
+ // Some gyrations to prevent parts of the deferred libraries from being
+ // inlined into the main one, defeating the space savings. Issue 24356
+ result.write(
+"""
+ final messages = _notInlinedMessages(_notInlinedMessages);
+ static _notInlinedMessages(_) => {
+""");
var entries = usableTranslations
.expand((translation) => translation.originalMessages)
- .map((original) => original.name)
- .map((name) => " \"$name\" : $name");
- result
- ..write(entries.join(",\n"))
- ..write("\n };\n}");
+ .map((original) =>
+ ' "${original.name}" : ${_mapReference(original, locale)}');
+ result..write(entries.join(",\n"))..write("\n };\n}");
// To preserve compatibility, we don't use the canonical version of the locale
// in the file name.
@@ -148,6 +156,26 @@
new File(filename).writeAsStringSync(result.toString());
}
+bool _hasArguments(MainMessage message) => message.arguments.length != 0;
+
+/**
+ * Simple messages are printed directly in the map of message names to
+ * functions as a call that returns a lambda. e.g.
+ *
+ * "foo" : simpleMessage("This is foo"),
+ *
+ * This is helpful for the compiler.
+ **/
+String _mapReference(MainMessage original, String locale) {
+ if (!_hasArguments(original)) {
+ // No parameters, can be printed simply.
+ return 'MessageLookupByLibrary.simpleMessage("'
+ '${original.translations[locale]}")';
+ } else {
+ return original.name;
+ }
+}
+
/**
* This returns the mostly constant string used in
* [generateIndividualMessageFile] for the beginning of the file,
diff --git a/lib/intl.dart b/lib/intl.dart
index d952691..10381db 100644
--- a/lib/intl.dart
+++ b/lib/intl.dart
@@ -50,7 +50,7 @@
* name: 'today',
* args: [date],
* desc: 'Indicate the current date',
- * examples: {'date' : 'June 8, 2012'});
+ * examples: const {'date' : 'June 8, 2012'});
* print(today(new DateTime.now().toString());
*
* howManyPeople(numberOfPeople, place) => Intl.plural(
@@ -60,7 +60,7 @@
* name: 'msg',
* args: [numberOfPeople, place],
* desc: 'Description of how many people are seen in a place.',
- * examples: {'numberOfPeople': 3, 'place': 'London'});
+ * examples: const {'numberOfPeople': 3, 'place': 'London'});
*
* Calling `howManyPeople(2, 'Athens');` would
* produce "I see 2 other people in Athens." as output in the default locale.
@@ -153,7 +153,7 @@
* name: "hello",
* args: [yourName],
* desc: "Say hello",
- * examples = {"yourName": "Sparky"}.
+ * examples = const {"yourName": "Sparky"}.
* The source code will be processed via the analyzer to extract out the
* message data, so only a subset of valid Dart code is accepted. In
* particular, everything must be literal and cannot refer to variables
@@ -172,9 +172,12 @@
*/
static String message(String message_str, {String desc: '',
Map<String, String> examples: const {}, String locale, String name,
- List<String> args, String meaning}) {
- return messageLookup.lookupMessage(
- message_str, desc, examples, locale, name, args, meaning);
+ List<String> args, String meaning}) =>
+ _message(message_str, locale, name, args);
+
+ /** Omit the compile-time only parameters so dart2js can see to drop them. */
+ static _message(String message_str, String locale, String name, List args) {
+ return messageLookup.lookupMessage(message_str, locale, name, args);
}
/**
diff --git a/lib/message_lookup_by_library.dart b/lib/message_lookup_by_library.dart
index 3b668d4..c6ca92e 100644
--- a/lib/message_lookup_by_library.dart
+++ b/lib/message_lookup_by_library.dart
@@ -32,9 +32,8 @@
* If nothing is found, return [message_str]. The [desc] and [examples]
* parameters are ignored
*/
- String lookupMessage(String message_str, [final String desc = '',
- final Map examples = const {}, String locale, String name,
- List<String> args, String meaning]) {
+ String lookupMessage(String message_str, String locale,
+ String name, List args) {
var actualLocale = (locale == null) ? Intl.getCurrentLocale() : locale;
// For this usage, if the locale doesn't exist for messages, just return
// it and we'll fall back to the original version.
@@ -42,8 +41,8 @@
onFailure: (locale) => locale);
var messages = availableMessages[verifiedLocale];
if (messages == null) return message_str;
- return messages.lookupMessage(
- message_str, desc, examples, locale, name, args, meaning);
+ return messages.
+ lookupMessage(message_str, locale, name, args);
}
/**
@@ -90,9 +89,7 @@
* will be extracted automatically but for the time being it must be passed
* explicitly in the [name] and [args] arguments.
*/
- String lookupMessage(String message_str, [final String desc = '',
- final Map examples = const {}, String locale, String name,
- List<String> args, String meaning]) {
+ String lookupMessage(String message_str, String locale, String name, List args) {
if (name == null) return message_str;
var function = this[name];
return function == null ? message_str : Function.apply(function, args);
@@ -111,4 +108,10 @@
String get localeName;
toString() => localeName;
+
+ /**
+ * Return a function that returns the given string.
+ * An optimization for dart2js, used from the generated code.
+ */
+ static simpleMessage(translatedString) => () => translatedString;
}
diff --git a/lib/src/intl_helpers.dart b/lib/src/intl_helpers.dart
index f88ff8e..bf085a7 100644
--- a/lib/src/intl_helpers.dart
+++ b/lib/src/intl_helpers.dart
@@ -24,9 +24,8 @@
operator [](String key) =>
(key == 'en_US') ? fallbackData : _throwException();
- String lookupMessage(String message_str, [final String desc = '',
- final Map examples = const {}, String locale, String name,
- List<String> args, String meaning]) => message_str;
+ String lookupMessage(String message_str, String locale,
+ String name, List args) => message_str;
List get keys => _throwException();
diff --git a/pubspec.yaml b/pubspec.yaml
index 24bdeea..6c58b37 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -12,7 +12,7 @@
path: '>=0.9.0 <2.0.0'
petitparser: '>=1.1.3 <2.0.0'
dev_dependencies:
- fixnum: '>=0.9.0 <0.10.0'
+ fixnum: '>=0.9.0 <0.11.0'
unittest: '>=0.10.0 <0.12.0'
transformers:
- $dart2js: