Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * This provides classes to represent the internal structure of the | 6 * This provides classes to represent the internal structure of the |
| 7 * arguments to `Intl.message`. It is used when parsing sources to extract | 7 * arguments to `Intl.message`. It is used when parsing sources to extract |
| 8 * messages or to generate code for message substitution. Normal programs | 8 * messages or to generate code for message substitution. Normal programs |
| 9 * using Intl would not import this library. | 9 * using Intl would not import this library. |
| 10 * | 10 * |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 (eachArg) => eachArg is NamedExpression && | 82 (eachArg) => eachArg is NamedExpression && |
| 83 eachArg.name.label.name == 'name', | 83 eachArg.name.label.name == 'name', |
| 84 orElse: () => null); | 84 orElse: () => null); |
| 85 if (messageName == null) { | 85 if (messageName == null) { |
| 86 return "The 'name' argument for Intl.message must be specified"; | 86 return "The 'name' argument for Intl.message must be specified"; |
| 87 } | 87 } |
| 88 if (messageName.expression is! SimpleStringLiteral) { | 88 if (messageName.expression is! SimpleStringLiteral) { |
| 89 return "The 'name' argument for Intl.message must be a simple string " | 89 return "The 'name' argument for Intl.message must be a simple string " |
| 90 "literal."; | 90 "literal."; |
| 91 } | 91 } |
| 92 if (outerName != null && outerName != messageName.expression.value) { | |
| 93 return "The 'name' argument for Intl.message must match " | |
| 94 "the name of the containing function (" | |
| 95 "'${messageName.expression.value}' vs. '$outerName')"; | |
| 96 } | |
| 92 var simpleArguments = arguments.where( | 97 var simpleArguments = arguments.where( |
| 93 (each) => each is NamedExpression | 98 (each) => each is NamedExpression |
| 94 && ["desc", "name"].contains(each.name.label.name)); | 99 && ["desc", "name"].contains(each.name.label.name)); |
| 95 var values = simpleArguments.map((each) => each.expression).toList(); | 100 var values = simpleArguments.map((each) => each.expression).toList(); |
| 96 for (var arg in values) { | 101 for (var arg in values) { |
| 97 if (arg is! SimpleStringLiteral) { | 102 if (arg is! SimpleStringLiteral) { |
| 98 return "Intl.message argument '$arg' must be " | 103 return "Intl.message argument '$arg' must be " |
| 99 "a simple string literal"; | 104 "a simple string literal"; |
| 100 } | 105 } |
| 101 } | 106 } |
| 107 return null; | |
| 102 } | 108 } |
| 103 | 109 |
| 104 /** | 110 /** |
| 105 * Turn a value, typically read from a translation file or created out of an | 111 * Turn a value, typically read from a translation file or created out of an |
| 106 * AST for a source program, into the appropriate | 112 * AST for a source program, into the appropriate |
| 107 * subclass. We expect to get literal Strings, variable substitutions | 113 * subclass. We expect to get literal Strings, variable substitutions |
| 108 * represented by integers, things that are already MessageChunks and | 114 * represented by integers, things that are already MessageChunks and |
| 109 * lists of the same. | 115 * lists of the same. |
| 110 */ | 116 */ |
| 111 static Message from(value, Message parent) { | 117 static Message from(value, Message parent) { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 * When generating code, we store translations for each locale | 350 * When generating code, we store translations for each locale |
| 345 * associated with the original message. | 351 * associated with the original message. |
| 346 */ | 352 */ |
| 347 Map<String, String> translations = new Map(); | 353 Map<String, String> translations = new Map(); |
| 348 | 354 |
| 349 /** | 355 /** |
| 350 * If the message was not given a name, we use the entire message string as | 356 * If the message was not given a name, we use the entire message string as |
| 351 * the name. | 357 * the name. |
| 352 */ | 358 */ |
| 353 String get name => _name == null ? computeName() : _name; | 359 String get name => _name == null ? computeName() : _name; |
| 354 void set name(x) {_name = x;} | 360 set name(String newName) { _name = newName; } |
|
Emily Fortuna
2014/02/24 18:38:23
I'd be inclined to leave the "void" in this line,
Alan Knight
2014/02/24 18:46:44
I got dinged before in a review for having that, s
| |
| 355 | 361 |
| 356 String computeName() => name = expanded((msg, chunk) => ""); | 362 String computeName() => name = expanded((msg, chunk) => ""); |
| 357 | 363 |
| 358 /** | 364 /** |
| 359 * Return the full message, with any interpolation expressions transformed | 365 * Return the full message, with any interpolation expressions transformed |
| 360 * by [f] and all the results concatenated. The chunk argument to [f] may be | 366 * by [f] and all the results concatenated. The chunk argument to [f] may be |
| 361 * either a String, an int or an object representing a more complex | 367 * either a String, an int or an object representing a more complex |
| 362 * message entity. | 368 * message entity. |
| 363 * See [messagePieces]. | 369 * See [messagePieces]. |
| 364 */ | 370 */ |
| 365 String expanded([Function f = _nullTransform]) => | 371 String expanded([Function f = _nullTransform]) => |
| 366 messagePieces.map((chunk) => f(this, chunk)).join(""); | 372 messagePieces.map((chunk) => f(this, chunk)).join(""); |
| 367 | 373 |
| 368 /** | 374 /** |
| 369 * Record the translation for this message in the given locale, after | 375 * Record the translation for this message in the given locale, after |
| 370 * suitably escaping it. | 376 * suitably escaping it. |
| 371 */ | 377 */ |
| 372 String addTranslation(String locale, Message translated) { | 378 void addTranslation(String locale, Message translated) { |
| 373 translated.parent = this; | 379 translated.parent = this; |
| 374 translations[locale] = translated.toCode(); | 380 translations[locale] = translated.toCode(); |
| 375 } | 381 } |
| 376 | 382 |
| 377 toCode() => throw | 383 toCode() => throw |
| 378 new UnsupportedError("MainMessage.toCode requires a locale"); | 384 new UnsupportedError("MainMessage.toCode requires a locale"); |
| 379 | 385 |
| 380 /** | 386 /** |
| 381 * Generate code for this message, expecting it to be part of a map | 387 * Generate code for this message, expecting it to be part of a map |
| 382 * keyed by name with values the function that calls Intl.message. | 388 * keyed by name with values the function that calls Intl.message. |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 669 out.write('('); | 675 out.write('('); |
| 670 out.write(mainArgument); | 676 out.write(mainArgument); |
| 671 var args = codeAttributeNames; | 677 var args = codeAttributeNames; |
| 672 out.write(", {"); | 678 out.write(", {"); |
| 673 args.fold(out, (buffer, arg) => buffer..write( | 679 args.fold(out, (buffer, arg) => buffer..write( |
| 674 "'$arg': '${this[arg].toCode()}', ")); | 680 "'$arg': '${this[arg].toCode()}', ")); |
| 675 out.write("})}"); | 681 out.write("})}"); |
| 676 return out.toString(); | 682 return out.toString(); |
| 677 } | 683 } |
| 678 } | 684 } |
| OLD | NEW |