From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- js/src/builtin/intl/PluralRules.js | 440 +++++++++++++++++++++++++++++++++++++ 1 file changed, 440 insertions(+) create mode 100644 js/src/builtin/intl/PluralRules.js (limited to 'js/src/builtin/intl/PluralRules.js') diff --git a/js/src/builtin/intl/PluralRules.js b/js/src/builtin/intl/PluralRules.js new file mode 100644 index 0000000000..1dbf6656df --- /dev/null +++ b/js/src/builtin/intl/PluralRules.js @@ -0,0 +1,440 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * PluralRules internal properties. + * + * 9.1 Internal slots of Service Constructors + * 16.2.3 Properties of the Intl.PluralRules Constructor, Internal slots + * + * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + */ +var pluralRulesInternalProperties = { + localeData: pluralRulesLocaleData, + relevantExtensionKeys: [], +}; + +function pluralRulesLocaleData() { + // PluralRules don't support any extension keys. + return {}; +} + +/** + * 16.1.2 InitializePluralRules ( pluralRules, locales, options ) + * + * Compute an internal properties object from |lazyPluralRulesData|. + * + * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + */ +function resolvePluralRulesInternals(lazyPluralRulesData) { + assert(IsObject(lazyPluralRulesData), "lazy data not an object?"); + + var internalProps = std_Object_create(null); + + var PluralRules = pluralRulesInternalProperties; + + // Compute effective locale. + + // Step 9. + var localeData = PluralRules.localeData; + + // Step 10. + var r = ResolveLocale( + "PluralRules", + lazyPluralRulesData.requestedLocales, + lazyPluralRulesData.opt, + PluralRules.relevantExtensionKeys, + localeData + ); + + // Step 11. + internalProps.locale = r.locale; + + // Step 7. + internalProps.type = lazyPluralRulesData.type; + + // Step 8. SetNumberFormatDigitOptions, step 6. + internalProps.minimumIntegerDigits = lazyPluralRulesData.minimumIntegerDigits; + + // Step 8. SetNumberFormatDigitOptions, step 14. + internalProps.roundingIncrement = lazyPluralRulesData.roundingIncrement; + + // Step 8. SetNumberFormatDigitOptions, step 15. + internalProps.roundingMode = lazyPluralRulesData.roundingMode; + + // Step 8. SetNumberFormatDigitOptions, step 16. + internalProps.trailingZeroDisplay = lazyPluralRulesData.trailingZeroDisplay; + + // Step 8. SetNumberFormatDigitOptions, steps 25-26. + if ("minimumFractionDigits" in lazyPluralRulesData) { + assert( + "maximumFractionDigits" in lazyPluralRulesData, + "min/max frac digits mismatch" + ); + internalProps.minimumFractionDigits = + lazyPluralRulesData.minimumFractionDigits; + internalProps.maximumFractionDigits = + lazyPluralRulesData.maximumFractionDigits; + } + + // Step 8. SetNumberFormatDigitOptions, steps 24 and 26. + if ("minimumSignificantDigits" in lazyPluralRulesData) { + assert( + "maximumSignificantDigits" in lazyPluralRulesData, + "min/max sig digits mismatch" + ); + internalProps.minimumSignificantDigits = + lazyPluralRulesData.minimumSignificantDigits; + internalProps.maximumSignificantDigits = + lazyPluralRulesData.maximumSignificantDigits; + } + + // Step 8. SetNumberFormatDigitOptions, steps 26-30. + internalProps.roundingPriority = lazyPluralRulesData.roundingPriority; + + // `pluralCategories` is lazily computed on first access. + internalProps.pluralCategories = null; + + return internalProps; +} + +/** + * Returns an object containing the PluralRules internal properties of |obj|. + */ +function getPluralRulesInternals(obj) { + assert(IsObject(obj), "getPluralRulesInternals called with non-object"); + assert( + intl_GuardToPluralRules(obj) !== null, + "getPluralRulesInternals called with non-PluralRules" + ); + + var internals = getIntlObjectInternals(obj); + assert( + internals.type === "PluralRules", + "bad type escaped getIntlObjectInternals" + ); + + var internalProps = maybeInternalProperties(internals); + if (internalProps) { + return internalProps; + } + + internalProps = resolvePluralRulesInternals(internals.lazyData); + setInternalProperties(internals, internalProps); + return internalProps; +} + +/** + * 16.1.2 InitializePluralRules ( pluralRules, locales, options ) + * + * Initializes an object as a PluralRules. + * + * This method is complicated a moderate bit by its implementing initialization + * as a *lazy* concept. Everything that must happen now, does -- but we defer + * all the work we can until the object is actually used as a PluralRules. + * This later work occurs in |resolvePluralRulesInternals|; steps not noted + * here occur there. + * + * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + */ +function InitializePluralRules(pluralRules, locales, options) { + assert(IsObject(pluralRules), "InitializePluralRules called with non-object"); + assert( + intl_GuardToPluralRules(pluralRules) !== null, + "InitializePluralRules called with non-PluralRules" + ); + + // Lazy PluralRules data has the following structure: + // + // { + // requestedLocales: List of locales, + // type: "cardinal" / "ordinal", + // + // opt: // opt object computer in InitializePluralRules + // { + // localeMatcher: "lookup" / "best fit", + // } + // + // minimumIntegerDigits: integer ∈ [1, 21], + // + // // optional, mutually exclusive with the significant-digits option + // minimumFractionDigits: integer ∈ [0, 100], + // maximumFractionDigits: integer ∈ [0, 100], + // + // // optional, mutually exclusive with the fraction-digits option + // minimumSignificantDigits: integer ∈ [1, 21], + // maximumSignificantDigits: integer ∈ [1, 21], + // + // roundingPriority: "auto" / "lessPrecision" / "morePrecision", + // + // trailingZeroDisplay: "auto" / "stripIfInteger", + // + // roundingIncrement: integer ∈ (1, 2, 5, + // 10, 20, 25, 50, + // 100, 200, 250, 500, + // 1000, 2000, 2500, 5000), + // + // roundingMode: "ceil" / "floor" / "expand" / "trunc" / + // "halfCeil" / "halfFloor" / "halfExpand" / "halfTrunc" / "halfEven", + // } + // + // Note that lazy data is only installed as a final step of initialization, + // so every PluralRules lazy data object has *all* these properties, never a + // subset of them. + var lazyPluralRulesData = std_Object_create(null); + + // Step 1. + var requestedLocales = CanonicalizeLocaleList(locales); + lazyPluralRulesData.requestedLocales = requestedLocales; + + // Step 2. (Inlined call to CoerceOptionsToObject.) + if (options === undefined) { + options = std_Object_create(null); + } else { + options = ToObject(options); + } + + // Step 3. + var opt = new_Record(); + lazyPluralRulesData.opt = opt; + + // Steps 4-5. + var matcher = GetOption( + options, + "localeMatcher", + "string", + ["lookup", "best fit"], + "best fit" + ); + opt.localeMatcher = matcher; + + // Steps 6-7. + var type = GetOption( + options, + "type", + "string", + ["cardinal", "ordinal"], + "cardinal" + ); + lazyPluralRulesData.type = type; + + // Step 8. + SetNumberFormatDigitOptions(lazyPluralRulesData, options, 0, 3, "standard"); + + // Step 12. + // + // We've done everything that must be done now: mark the lazy data as fully + // computed and install it. + initializeIntlObject(pluralRules, "PluralRules", lazyPluralRulesData); +} + +/** + * 16.2.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] ) + * + * Returns the subset of the given locale list for which this locale list has a + * matching (possibly fallback) locale. Locales appear in the same order in the + * returned list as in the input list. + * + * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + */ +function Intl_PluralRules_supportedLocalesOf(locales /*, options*/) { + var options = ArgumentsLength() > 1 ? GetArgument(1) : undefined; + + // Step 1. + var availableLocales = "PluralRules"; + + // Step 2. + var requestedLocales = CanonicalizeLocaleList(locales); + + // Step 3. + return SupportedLocales(availableLocales, requestedLocales, options); +} + +/** + * 16.3.3 Intl.PluralRules.prototype.select ( value ) + * + * Returns a String value representing the plural category matching + * the number passed as value according to the + * effective locale and the formatting options of this PluralRules. + * + * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + */ +function Intl_PluralRules_select(value) { + // Step 1. + var pluralRules = this; + + // Step 2. + if ( + !IsObject(pluralRules) || + (pluralRules = intl_GuardToPluralRules(pluralRules)) === null + ) { + return callFunction( + intl_CallPluralRulesMethodIfWrapped, + this, + value, + "Intl_PluralRules_select" + ); + } + + // Step 3. + var n = ToNumber(value); + + // Ensure the PluralRules internals are resolved. + getPluralRulesInternals(pluralRules); + + // Step 4. + return intl_SelectPluralRule(pluralRules, n); +} + +/** + * 16.3.4 Intl.PluralRules.prototype.selectRange ( start, end ) + * + * Returns a String value representing the plural category matching the input + * number range according to the effective locale and the formatting options + * of this PluralRules. + * + * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + */ +function Intl_PluralRules_selectRange(start, end) { + // Step 1. + var pluralRules = this; + + // Step 2. + if ( + !IsObject(pluralRules) || + (pluralRules = intl_GuardToPluralRules(pluralRules)) === null + ) { + return callFunction( + intl_CallPluralRulesMethodIfWrapped, + this, + start, + end, + "Intl_PluralRules_selectRange" + ); + } + + // Step 3. + if (start === undefined || end === undefined) { + ThrowTypeError( + JSMSG_UNDEFINED_NUMBER, + start === undefined ? "start" : "end", + "PluralRules", + "selectRange" + ); + } + + // Step 4. + var x = ToNumber(start); + + // Step 5. + var y = ToNumber(end); + + // Step 6. + return intl_SelectPluralRuleRange(pluralRules, x, y); +} + +/** + * 16.3.5 Intl.PluralRules.prototype.resolvedOptions ( ) + * + * Returns the resolved options for a PluralRules object. + * + * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + */ +function Intl_PluralRules_resolvedOptions() { + // Step 1. + var pluralRules = this; + + // Step 2. + if ( + !IsObject(pluralRules) || + (pluralRules = intl_GuardToPluralRules(pluralRules)) === null + ) { + return callFunction( + intl_CallPluralRulesMethodIfWrapped, + this, + "Intl_PluralRules_resolvedOptions" + ); + } + + var internals = getPluralRulesInternals(pluralRules); + + // Steps 3-4. + var result = { + locale: internals.locale, + type: internals.type, + minimumIntegerDigits: internals.minimumIntegerDigits, + }; + + // Min/Max fraction digits are either both present or not present at all. + assert( + hasOwn("minimumFractionDigits", internals) === + hasOwn("maximumFractionDigits", internals), + "minimumFractionDigits is present iff maximumFractionDigits is present" + ); + + if (hasOwn("minimumFractionDigits", internals)) { + DefineDataProperty( + result, + "minimumFractionDigits", + internals.minimumFractionDigits + ); + DefineDataProperty( + result, + "maximumFractionDigits", + internals.maximumFractionDigits + ); + } + + // Min/Max significant digits are either both present or not present at all. + assert( + hasOwn("minimumSignificantDigits", internals) === + hasOwn("maximumSignificantDigits", internals), + "minimumSignificantDigits is present iff maximumSignificantDigits is present" + ); + + if (hasOwn("minimumSignificantDigits", internals)) { + DefineDataProperty( + result, + "minimumSignificantDigits", + internals.minimumSignificantDigits + ); + DefineDataProperty( + result, + "maximumSignificantDigits", + internals.maximumSignificantDigits + ); + } + + DefineDataProperty(result, "roundingMode", internals.roundingMode); + DefineDataProperty(result, "roundingIncrement", internals.roundingIncrement); + DefineDataProperty( + result, + "trailingZeroDisplay", + internals.trailingZeroDisplay + ); + + // Step 5. + var internalsPluralCategories = internals.pluralCategories; + if (internalsPluralCategories === null) { + internalsPluralCategories = intl_GetPluralCategories(pluralRules); + internals.pluralCategories = internalsPluralCategories; + } + + var pluralCategories = []; + for (var i = 0; i < internalsPluralCategories.length; i++) { + DefineDataProperty(pluralCategories, i, internalsPluralCategories[i]); + } + + // Step 6. + DefineDataProperty(result, "pluralCategories", pluralCategories); + + // Steps 7-9. + // + // Our implementation doesn't use [[RoundingType]], but instead directly + // stores the computed `roundingPriority` value. + DefineDataProperty(result, "roundingPriority", internals.roundingPriority); + + // Step 10. + return result; +} -- cgit v1.2.3