-
Notifications
You must be signed in to change notification settings - Fork 6k
Add Locale.fromSubtags and support for scriptCode. #6518
Changes from all commits
e042526
4013600
813998d
fe5e110
fb72be0
c6a8b96
af40b72
488cf31
829af35
c749663
04c52e9
58bfdc6
bc4cc07
a8b2797
d6f06f5
8948502
20e8bd7
9911dfd
cb81b55
5e0def8
9f6e3e0
97ab4fe
5f625ae
3b87068
df46762
57b068e
6f07e8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,9 +116,11 @@ class WindowPadding { | |
| } | ||
| } | ||
|
|
||
| /// An identifier used to select a user's language and formatting preferences, | ||
| /// consisting of a language and a country. This is a subset of locale | ||
| /// identifiers as defined by BCP 47. | ||
| /// An identifier used to select a user's language and formatting preferences. | ||
| /// | ||
| /// This represents a [Unicode Language | ||
| /// Identifier](https://www.unicode.org/reports/tr35/#Unicode_language_identifier) | ||
| /// (i.e. without Locale extensions), except variants are not supported. | ||
| /// | ||
| /// Locales are canonicalized according to the "preferred value" entries in the | ||
| /// [IANA Language Subtag | ||
|
|
@@ -145,16 +147,58 @@ class Locale { | |
| /// The primary language subtag must not be null. The region subtag is | ||
| /// optional. | ||
| /// | ||
| /// The values are _case sensitive_, and should match the case of the relevant | ||
| /// subtags in the [IANA Language Subtag | ||
| /// Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry). | ||
| /// Typically this means the primary language subtag should be lowercase and | ||
| /// the region subtag should be uppercase. | ||
| const Locale(this._languageCode, [ this._countryCode ]) : assert(_languageCode != null), assert(_languageCode != ''); | ||
| /// The subtag values are _case sensitive_ and must be one of the valid | ||
| /// subtags according to CLDR supplemental data: | ||
| /// [language](http://unicode.org/cldr/latest/common/validity/language.xml), | ||
| /// [region](http://unicode.org/cldr/latest/common/validity/region.xml). The | ||
| /// primary language subtag must be at least two and at most eight lowercase | ||
| /// letters, but not four letters. The region region subtag must be two | ||
| /// uppercase letters or three digits. See the [Unicode Language | ||
| /// Identifier](https://www.unicode.org/reports/tr35/#Unicode_language_identifier) | ||
| /// specification. | ||
| /// | ||
| /// Validity is not checked by default, but some methods may throw away | ||
| /// invalid data. | ||
| /// | ||
| /// See also: | ||
| /// | ||
| /// * [new Locale.fromSubtags], which also allows a [scriptCode] to be | ||
| /// specified. | ||
| const Locale( | ||
| this._languageCode, [ | ||
| this._countryCode, | ||
| ]) : assert(_languageCode != null), | ||
| assert(_languageCode != ''), | ||
| scriptCode = null, | ||
| assert(_countryCode != ''); | ||
|
|
||
| /// Creates a new Locale object. | ||
| /// | ||
| /// The keyword arguments specify the subtags of the Locale. | ||
| /// | ||
| /// The subtag values are _case sensitive_ and must be valid subtags according | ||
| /// to CLDR supplemental data: | ||
| /// [language](http://unicode.org/cldr/latest/common/validity/language.xml), | ||
| /// [script](http://unicode.org/cldr/latest/common/validity/script.xml) and | ||
| /// [region](http://unicode.org/cldr/latest/common/validity/region.xml) for | ||
| /// each of languageCode, scriptCode and countryCode respectively. | ||
| /// | ||
| /// Validity is not checked by default, but some methods may throw away | ||
| /// invalid data. | ||
| const Locale.fromSubtags({ | ||
| String languageCode = 'und', | ||
| this.scriptCode, | ||
| String countryCode, | ||
| }) : assert(languageCode != null), | ||
| assert(languageCode != ''), | ||
| _languageCode = languageCode, | ||
| assert(scriptCode != ''), | ||
| assert(countryCode != ''), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's add this assert to the other constructor too while we're at it
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With this I then manage to bring us back to the unit test that I disliked:
The existing Locale constructor is being tested to support both So: in-scope or out of scope for this Pull Request to change existing behaviour? I'm happy to consider this via a follow-up change too...
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's fine to remove support for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added the assert and removed what should have been a failing unit test, though I'm not sure how to actually trigger a failure. Looks like asserts are dropped (frontend_server.dart.snapshot requires no-asserts). From an attempt to add --enable-asserts to the dart invocation for locale_test.dart: I'd need to look into how one might tweak the snapshot later. |
||
| _countryCode = countryCode; | ||
|
|
||
| /// The primary language subtag for the locale. | ||
| /// | ||
| /// This must not be null. | ||
| /// This must not be null. It may be 'und', representing 'undefined'. | ||
| /// | ||
| /// This is expected to be string registered in the [IANA Language Subtag | ||
| /// Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry) | ||
|
|
@@ -166,10 +210,19 @@ class Locale { | |
| /// Locale('he')` and `const Locale('iw')` are equal, and both have the | ||
| /// [languageCode] `he`, because `iw` is a deprecated language subtag that was | ||
| /// replaced by the subtag `he`. | ||
| String get languageCode => _canonicalizeLanguageCode(_languageCode); | ||
| /// | ||
| /// This must be a valid Unicode Language subtag as listed in [Unicode CLDR | ||
| /// supplemental | ||
| /// data](http://unicode.org/cldr/latest/common/validity/language.xml). | ||
hugovdm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// | ||
| /// See also: | ||
| /// | ||
| /// * [new Locale.fromSubtags], which describes the conventions for creating | ||
| /// [Locale] objects. | ||
| String get languageCode => _replaceDeprecatedLanguageSubtag(_languageCode); | ||
| final String _languageCode; | ||
|
|
||
| static String _canonicalizeLanguageCode(String languageCode) { | ||
| static String _replaceDeprecatedLanguageSubtag(String languageCode) { | ||
| // This switch statement is generated by //flutter/tools/gen_locale.dart | ||
| // Mappings generated for language subtag registry as of 2018-08-08. | ||
| switch (languageCode) { | ||
|
|
@@ -255,9 +308,23 @@ class Locale { | |
| } | ||
| } | ||
|
|
||
| /// The script subtag for the locale. | ||
| /// | ||
| /// This may be null, indicating that there is no specified script subtag. | ||
| /// | ||
| /// This must be a valid Unicode Language Identifier script subtag as listed | ||
| /// in [Unicode CLDR supplemental | ||
| /// data](http://unicode.org/cldr/latest/common/validity/script.xml). | ||
| /// | ||
| /// See also: | ||
| /// | ||
| /// * [new Locale.fromSubtags], which describes the conventions for creating | ||
| /// [Locale] objects. | ||
| final String scriptCode; | ||
|
|
||
| /// The region subtag for the locale. | ||
| /// | ||
| /// This can be null. | ||
| /// This may be null, indicating that there is no specified region subtag. | ||
| /// | ||
| /// This is expected to be string registered in the [IANA Language Subtag | ||
| /// Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry) | ||
|
|
@@ -269,10 +336,15 @@ class Locale { | |
| /// 'DE')` and `const Locale('de', 'DD')` are equal, and both have the | ||
| /// [countryCode] `DE`, because `DD` is a deprecated language subtag that was | ||
| /// replaced by the subtag `DE`. | ||
| String get countryCode => _canonicalizeRegionCode(_countryCode); | ||
| /// | ||
| /// See also: | ||
| /// | ||
| /// * [new Locale.fromSubtags], which describes the conventions for creating | ||
| /// [Locale] objects. | ||
| String get countryCode => _replaceDeprecatedRegionSubtag(_countryCode); | ||
| final String _countryCode; | ||
|
|
||
| static String _canonicalizeRegionCode(String regionCode) { | ||
| static String _replaceDeprecatedRegionSubtag(String regionCode) { | ||
| // This switch statement is generated by //flutter/tools/gen_locale.dart | ||
| // Mappings generated for language subtag registry as of 2018-08-08. | ||
| switch (regionCode) { | ||
|
|
@@ -294,23 +366,21 @@ class Locale { | |
| return false; | ||
| final Locale typedOther = other; | ||
| return languageCode == typedOther.languageCode | ||
| && scriptCode == typedOther.scriptCode | ||
| && countryCode == typedOther.countryCode; | ||
| } | ||
|
|
||
| @override | ||
| int get hashCode { | ||
| int result = 373; | ||
| result = 37 * result + languageCode.hashCode; | ||
| if (_countryCode != null) | ||
| result = 37 * result + countryCode.hashCode; | ||
| return result; | ||
| } | ||
| int get hashCode => hashValues(languageCode, scriptCode, countryCode); | ||
|
|
||
| @override | ||
| String toString() { | ||
hugovdm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (_countryCode == null) | ||
| return languageCode; | ||
| return '${languageCode}_$countryCode'; | ||
| final StringBuffer out = StringBuffer(languageCode); | ||
| if (scriptCode != null) | ||
| out.write('_$scriptCode'); | ||
| if (_countryCode != null) | ||
| out.write('_$countryCode'); | ||
| return out.toString(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.