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

Side by Side Diff: src/js/i18n.js

Issue 2717613005: [intl] Fix NumberFormat options handling spec compliance issues (Closed)
Patch Set: Run the local test262 tests Created 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ECMAScript 402 API implementation. 5 // ECMAScript 402 API implementation.
6 6
7 /** 7 /**
8 * Intl object is a single object that has some named properties, 8 * Intl object is a single object that has some named properties,
9 * all of which are constructors. 9 * all of which are constructors.
10 */ 10 */
(...skipping 14 matching lines...) Expand all
25 var GlobalIntlNumberFormat = GlobalIntl.NumberFormat; 25 var GlobalIntlNumberFormat = GlobalIntl.NumberFormat;
26 var GlobalIntlCollator = GlobalIntl.Collator; 26 var GlobalIntlCollator = GlobalIntl.Collator;
27 var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator; 27 var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator;
28 var GlobalNumber = global.Number; 28 var GlobalNumber = global.Number;
29 var GlobalRegExp = global.RegExp; 29 var GlobalRegExp = global.RegExp;
30 var GlobalString = global.String; 30 var GlobalString = global.String;
31 var IntlFallbackSymbol = utils.ImportNow("intl_fallback_symbol"); 31 var IntlFallbackSymbol = utils.ImportNow("intl_fallback_symbol");
32 var InstallFunctions = utils.InstallFunctions; 32 var InstallFunctions = utils.InstallFunctions;
33 var InstallGetter = utils.InstallGetter; 33 var InstallGetter = utils.InstallGetter;
34 var InternalArray = utils.InternalArray; 34 var InternalArray = utils.InternalArray;
35 var MaxSimple;
35 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty"); 36 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty");
36 var OverrideFunction = utils.OverrideFunction; 37 var OverrideFunction = utils.OverrideFunction;
37 var patternSymbol = utils.ImportNow("intl_pattern_symbol"); 38 var patternSymbol = utils.ImportNow("intl_pattern_symbol");
38 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol"); 39 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol");
39 var SetFunctionName = utils.SetFunctionName; 40 var SetFunctionName = utils.SetFunctionName;
40 var StringSubstr = GlobalString.prototype.substr; 41 var StringSubstr = GlobalString.prototype.substr;
41 var StringSubstring = GlobalString.prototype.substring; 42 var StringSubstring = GlobalString.prototype.substring;
42 43
43 utils.Import(function(from) { 44 utils.Import(function(from) {
44 ArrayJoin = from.ArrayJoin; 45 ArrayJoin = from.ArrayJoin;
45 ArrayPush = from.ArrayPush; 46 ArrayPush = from.ArrayPush;
47 MaxSimple = from.MaxSimple;
46 }); 48 });
47 49
48 // Utilities for definitions 50 // Utilities for definitions
49 51
50 function InstallFunction(object, name, func) { 52 function InstallFunction(object, name, func) {
51 InstallFunctions(object, DONT_ENUM, [name, func]); 53 InstallFunctions(object, DONT_ENUM, [name, func]);
52 } 54 }
53 55
54 56
55 /** 57 /**
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 var language = '(' + alpha + '{2,3}(-' + extLang + ')?|' + alpha + '{4}|' + 929 var language = '(' + alpha + '{2,3}(-' + extLang + ')?|' + alpha + '{4}|' +
928 alpha + '{5,8})'; 930 alpha + '{5,8})';
929 var langTag = language + '(-' + script + ')?(-' + region + ')?(-' + 931 var langTag = language + '(-' + script + ')?(-' + region + ')?(-' +
930 variant + ')*(-' + extension + ')*(-' + privateUse + ')?'; 932 variant + ')*(-' + extension + ')*(-' + privateUse + ')?';
931 933
932 var languageTag = 934 var languageTag =
933 '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$'; 935 '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$';
934 LANGUAGE_TAG_RE = new GlobalRegExp(languageTag, 'i'); 936 LANGUAGE_TAG_RE = new GlobalRegExp(languageTag, 'i');
935 } 937 }
936 938
937 var resolvedAccessor = {
938 get() {
939 %IncrementUseCounter(kIntlResolved);
940 return this[resolvedSymbol];
941 },
942 set(value) {
943 this[resolvedSymbol] = value;
944 }
945 };
946
947 // ECMA 402 section 8.2.1 939 // ECMA 402 section 8.2.1
948 InstallFunction(GlobalIntl, 'getCanonicalLocales', function(locales) { 940 InstallFunction(GlobalIntl, 'getCanonicalLocales', function(locales) {
949 return makeArray(canonicalizeLocaleList(locales)); 941 return makeArray(canonicalizeLocaleList(locales));
950 } 942 }
951 ); 943 );
952 944
953 /** 945 /**
954 * Initializes the given object so it's a valid Collator instance. 946 * Initializes the given object so it's a valid Collator instance.
955 * Useful for subclassing. 947 * Useful for subclassing.
956 */ 948 */
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 value = TO_NUMBER(value); 1127 value = TO_NUMBER(value);
1136 if (NUMBER_IS_NAN(value) || value < min || value > max) { 1128 if (NUMBER_IS_NAN(value) || value < min || value > max) {
1137 throw %make_range_error(kPropertyValueOutOfRange, property); 1129 throw %make_range_error(kPropertyValueOutOfRange, property);
1138 } 1130 }
1139 return %math_floor(value); 1131 return %math_floor(value);
1140 } 1132 }
1141 1133
1142 return fallback; 1134 return fallback;
1143 } 1135 }
1144 1136
1145 var patternAccessor = { 1137 // ECMA 402 #sec-setnfdigitoptions
1146 get() { 1138 // SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault )
1147 %IncrementUseCounter(kIntlPattern); 1139 function SetNumberFormatDigitOptions(internalOptions, options,
1148 return this[patternSymbol]; 1140 mnfdDefault, mxfdDefault) {
1149 }, 1141 // Digit ranges.
1150 set(value) { 1142 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
1151 this[patternSymbol] = value; 1143 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
1144
1145 var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20,
1146 mnfdDefault);
1147 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
1148
1149 var mxfdActualDefault = MaxSimple(mnfd, mxfdDefault);
1150
1151 var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20,
1152 mxfdActualDefault);
1153
1154 defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
1155
1156 var mnsd = options['minimumSignificantDigits'];
1157 var mxsd = options['maximumSignificantDigits'];
1158 if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) {
1159 mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 1);
1160 defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
1161
1162 mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
1163 defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
1152 } 1164 }
1153 }; 1165 }
1154 1166
1155 /** 1167 /**
1156 * Initializes the given object so it's a valid NumberFormat instance. 1168 * Initializes the given object so it's a valid NumberFormat instance.
1157 * Useful for subclassing. 1169 * Useful for subclassing.
1158 */ 1170 */
1159 function CreateNumberFormat(locales, options) { 1171 function CreateNumberFormat(locales, options) {
1160 if (IS_UNDEFINED(options)) { 1172 if (IS_UNDEFINED(options)) {
1161 options = {}; 1173 options = {};
1162 } 1174 }
1163 1175
1164 var getOption = getGetOption(options, 'numberformat'); 1176 var getOption = getGetOption(options, 'numberformat');
1165 1177
1166 var locale = resolveLocale('numberformat', locales, options); 1178 var locale = resolveLocale('numberformat', locales, options);
1167 1179
1168 var internalOptions = {}; 1180 var internalOptions = {};
1169 defineWEProperty(internalOptions, 'style', getOption( 1181 defineWEProperty(internalOptions, 'style', getOption(
1170 'style', 'string', ['decimal', 'percent', 'currency'], 'decimal')); 1182 'style', 'string', ['decimal', 'percent', 'currency'], 'decimal'));
1171 1183
1172 var currency = getOption('currency', 'string'); 1184 var currency = getOption('currency', 'string');
1173 if (!IS_UNDEFINED(currency) && !isWellFormedCurrencyCode(currency)) { 1185 if (!IS_UNDEFINED(currency) && !isWellFormedCurrencyCode(currency)) {
1174 throw %make_range_error(kInvalidCurrencyCode, currency); 1186 throw %make_range_error(kInvalidCurrencyCode, currency);
1175 } 1187 }
1176 1188
1177 if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) { 1189 if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) {
1178 throw %make_type_error(kCurrencyCode); 1190 throw %make_type_error(kCurrencyCode);
1179 } 1191 }
1180 1192
1193 var mnfdDefault, mxfdDefault;
1194
1181 var currencyDisplay = getOption( 1195 var currencyDisplay = getOption(
1182 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol'); 1196 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
1183 if (internalOptions.style === 'currency') { 1197 if (internalOptions.style === 'currency') {
1184 defineWEProperty(internalOptions, 'currency', %StringToUpperCaseI18N(currenc y)); 1198 defineWEProperty(internalOptions, 'currency', %StringToUpperCaseI18N(currenc y));
1185 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay); 1199 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay);
1200
1201 mnfdDefault = mxfdDefault = %CurrencyDigits(internalOptions.currency);
1202 } else {
1203 mnfdDefault = 0;
1204 mxfdDefault = internalOptions.style === 'percent' ? 0 : 3;
1186 } 1205 }
1187 1206
1188 // Digit ranges. 1207 SetNumberFormatDigitOptions(internalOptions, options, mnfdDefault,
1189 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1); 1208 mxfdDefault);
1190 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
1191
1192 var mnfd = options['minimumFractionDigits'];
1193 var mxfd = options['maximumFractionDigits'];
1194 if (!IS_UNDEFINED(mnfd) || internalOptions.style !== 'currency') {
1195 mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
1196 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
1197 }
1198
1199 if (!IS_UNDEFINED(mxfd) || internalOptions.style !== 'currency') {
1200 var min_mxfd = internalOptions.style === 'percent' ? 0 : 3;
1201 mnfd = IS_UNDEFINED(mnfd) ? 0 : mnfd;
1202 var fallback_limit = (mnfd > min_mxfd) ? mnfd : min_mxfd;
1203 mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, fallback_ limit);
1204 defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
1205 }
1206
1207 var mnsd = options['minimumSignificantDigits'];
1208 var mxsd = options['maximumSignificantDigits'];
1209 if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) {
1210 mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 1);
1211 defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
1212
1213 mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
1214 defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
1215 }
1216 1209
1217 // Grouping. 1210 // Grouping.
1218 defineWEProperty(internalOptions, 'useGrouping', getOption( 1211 defineWEProperty(internalOptions, 'useGrouping', getOption(
1219 'useGrouping', 'boolean', UNDEFINED, true)); 1212 'useGrouping', 'boolean', UNDEFINED, true));
1220 1213
1221 // ICU prefers options to be passed using -u- extension key/values for 1214 // ICU prefers options to be passed using -u- extension key/values for
1222 // number format, so we need to build that. 1215 // number format, so we need to build that.
1223 var extensionMap = parseExtension(locale.extension); 1216 var extensionMap = parseExtension(locale.extension);
1224 1217
1225 /** 1218 /**
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after
2173 2166
2174 utils.Export(function(to) { 2167 utils.Export(function(to) {
2175 to.FormatDateToParts = FormatDateToParts; 2168 to.FormatDateToParts = FormatDateToParts;
2176 to.ToLowerCaseI18N = ToLowerCaseI18N; 2169 to.ToLowerCaseI18N = ToLowerCaseI18N;
2177 to.ToUpperCaseI18N = ToUpperCaseI18N; 2170 to.ToUpperCaseI18N = ToUpperCaseI18N;
2178 to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N; 2171 to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N;
2179 to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N; 2172 to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N;
2180 }); 2173 });
2181 2174
2182 }) 2175 })
OLDNEW
« no previous file with comments | « src/i18n.cc ('k') | src/runtime/runtime.h » ('j') | src/runtime/runtime-i18n.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698