Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Unified Diff: pkg/intl/lib/message_lookup_by_library.dart

Issue 12733003: Adds facilities for extracting Intl.message calls and generating code from translations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes from review comments, also made tests more robust, removed scheduled_test dependency Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/intl/lib/message_lookup_by_library.dart
diff --git a/pkg/intl/lib/message_lookup_by_library.dart b/pkg/intl/lib/message_lookup_by_library.dart
new file mode 100644
index 0000000000000000000000000000000000000000..5aba08481bc8eb5386d4bd03a0f618b7ca15eb50
--- /dev/null
+++ b/pkg/intl/lib/message_lookup_by_library.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Message/plural format library with locale support. This can have different
+ * implementations based on the mechanism for finding the localized versions
+ * of messages. This version expects them to be in a library named e.g.
+ * 'messages_en_US'. The prefix is set in the [initializeMessages] call, which
+ * must be made for a locale before any lookups can be done.
+ *
+ * See Intl class comment or `tests/message_format_test.dart` for more examples.
+ */
+library message_lookup_by_library;
+
+import 'dart:async';
+import 'intl.dart';
+import 'src/intl_helpers.dart';
+
+/**
+ * This is a message lookup mechanism that delegates to one of a collection
+ * of individual [MessageLookupByLibrary] instances.
+ */
+class CompositeMessageLookup {
+ /** A map from locale names to the corresponding lookups. */
+ Map<String, MessageLookupByLibrary> availableMessages = new Map();
+
+ /** Return true if we have a message lookup for [localeName]. */
+ bool localeExists(localeName) => availableMessages.containsKey(localeName);
+
+ /**
+ * Look up the message with the given [name] and [locale] and return
+ * the translated version with the values in [args] interpolated.
+ * 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]) {
+ 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.
+ var verifiedLocale =
+ Intl.verifiedLocale(
+ actualLocale,
+ localeExists,
+ onFailure: (locale)=>locale);
+ var messages = availableMessages[verifiedLocale];
+ if (messages == null) return message_str;
+ return messages.
+ lookupMessage(message_str, desc, examples, locale, name, args);
+ }
+
+ /**
+ * If we do not already have a locale for [localeName] then
+ * [findLocale] will be called and the result stored as the lookup
+ * mechanism for that locale.
+ */
+ addLocale(String localeName, Function findLocale) {
+ if (localeExists(localeName)) return;
+ var newLocale = findLocale(localeName);
+ if (newLocale != null) {
+ availableMessages[localeName] = newLocale;
+ }
+ }
+}
+
+/**
+ * This provides an abstract class for messages looked up in generated code.
+ * Each locale will have a separate subclass of this class with its set of
+ * messages. See generate_localized.dart.
+ */
+abstract class MessageLookupByLibrary {
+ /** Prevent infinite recursion when looking up the message. */
+ bool _lookupInProgress = false;
+
+ /**
+ * Return true if the locale exists, or if it is null. Null is treated
+ * as meaning that we use the default locale.
+ */
+ bool localeExists(localeName);
+
+ /**
+ * Return the localized version of a message. We are passed the original
+ * version of the message, which consists of a
+ * [message_str] that will be translated, and which may be interpolated
+ * based on one or more variables, a [desc] providing a description of usage
+ * for the [message_str], and a map of [examples] for each data element to be
+ * substituted into the message.
+ *
+ * For example, if message="Hello, $name", then
+ * examples = {'name': 'Sparky'}. If not using the user's default locale, or
+ * if the locale is not easily detectable, explicitly pass [locale].
+ *
+ * The values of [desc] and [examples] are not used at run-time but are only
+ * made available to the translators, so they MUST be simple Strings available
+ * at compile time: no String interpolation or concatenation.
+ * The expected usage of this is inside a function that takes as parameters
+ * the variables used in the interpolated string.
+ *
+ * Ultimately, the information about the enclosing function and its arguments
+ * 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]) {
+ // If we don't have a name, return the original, and if we have
+ // been recursively invoked, also just return message_str. This
+ // happens because the replacement functions also call Intl.message,
+ // so we assume that when _lookupInProgress is true that we're
+ // already translated.
+ if (name == null || _lookupInProgress) return message_str;
+ _lookupInProgress = true;
+ // Try to apply the function holding the translated version. If there
+ // is an exception, use the original [message_str] as the result.
+ var result = message_str;
+ try {
+ var function = this[name];
+ if (function != null) result = Function.apply(function, args);
+ } finally {
+ _lookupInProgress = false;
+ }
+ return result;
+ }
+
+ /** Return our message with the given name */
+ operator [](String messageName) => messages[messageName];
+
+ /**
+ * Subclasses should override this to return a list of their message
+ * functions.
+ */
+ Map<String, Function> get messages;
+
+ /** Subclasses should override this to return their locale, e.g. 'en_US' */
+ String get localeName;
+
+ toString() => localeName;
+}

Powered by Google App Engine
This is Rietveld 408576698