com.oracle.truffle.js.runtime.util.IntlUtil Maven / Gradle / Ivy
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.oracle.truffle.js.runtime.util;
import java.time.ZoneId;
import java.time.zone.ZoneRulesProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.IllformedLocaleException;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.TreeMap;
import org.graalvm.shadowed.com.ibm.icu.text.CaseMap;
import org.graalvm.shadowed.com.ibm.icu.text.CaseMap.Lower;
import org.graalvm.shadowed.com.ibm.icu.text.CaseMap.Upper;
import org.graalvm.shadowed.com.ibm.icu.text.Collator;
import org.graalvm.shadowed.com.ibm.icu.text.CurrencyMetaInfo;
import org.graalvm.shadowed.com.ibm.icu.text.DateFormat;
import org.graalvm.shadowed.com.ibm.icu.text.NumberingSystem;
import org.graalvm.shadowed.com.ibm.icu.util.Calendar;
import org.graalvm.shadowed.com.ibm.icu.util.TimeZone;
import org.graalvm.shadowed.com.ibm.icu.util.ULocale;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.js.runtime.Errors;
import com.oracle.truffle.js.runtime.JSContext;
import com.oracle.truffle.js.runtime.JSRealm;
import com.oracle.truffle.js.runtime.Strings;
import com.oracle.truffle.js.runtime.builtins.JSOrdinary;
import com.oracle.truffle.js.runtime.objects.JSObject;
/**
*
* ECMA 402 Utilities.
*/
public final class IntlUtil {
private IntlUtil() {
// should not be constructed
}
public static final String _2_DIGIT = "2-digit";
public static final String ACCENT = "accent";
public static final String ACCOUNTING = "accounting";
public static final String ALWAYS = "always";
public static final String AUTO = "auto";
public static final String BEST_FIT = "best fit";
public static final String BASE = "base";
public static final String BASIC = "basic";
public static final String CALENDAR = "calendar";
public static final String CARDINAL = "cardinal";
public static final String CASE = "case";
public static final String CASE_FIRST = "caseFirst";
public static final String CEIL = "ceil";
public static final String CODE = "code";
public static final String COLLATION = "collation";
public static final String COMPACT = "compact";
public static final String COMPACT_DISPLAY = "compactDisplay";
public static final String CONJUNCTION = "conjunction";
public static final String CURRENCY = "currency";
public static final String CURRENCY_DISPLAY = "currencyDisplay";
public static final String CURRENCY_SIGN = "currencySign";
public static final String DATE_STYLE = "dateStyle";
public static final String DATE_TIME_FIELD = "dateTimeField";
public static final String DAY = "day";
public static final String DAY_PERIOD = "dayPeriod";
public static final String DEFAULT = "default";
public static final String DECIMAL = "decimal";
public static final String DIALECT = "dialect";
public static final String DIRECTION = "direction";
public static final String DISJUNCTION = "disjunction";
public static final String ELEMENT = "element";
public static final String END_RANGE = "endRange";
public static final String ENGINEERING = "engineering";
public static final String ERA = "era";
public static final String EXCEPT_ZERO = "exceptZero";
public static final String EXPAND = "expand";
public static final String FALLBACK = "fallback";
public static final String FALSE = "false";
public static final String FIRST_DAY = "firstDay";
public static final String FIRST_DAY_OF_WEEK = "firstDayOfWeek";
public static final String FLOOR = "floor";
public static final String FORMAT_MATCHER = "formatMatcher";
public static final String FRACTIONAL_SECOND_DIGITS = "fractionalSecondDigits";
public static final String FRACTION_DIGITS = "fractionDigits";
public static final String FULL = "full";
public static final String GRANULARITY = "granularity";
public static final String GRAPHEME = "grapheme";
public static final String H11 = "h11";
public static final String H12 = "h12";
public static final String H23 = "h23";
public static final String H24 = "h24";
public static final String HALF_CEIL = "halfCeil";
public static final String HALF_EVEN = "halfEven";
public static final String HALF_EXPAND = "halfExpand";
public static final String HALF_FLOOR = "halfFloor";
public static final String HALF_TRUNC = "halfTrunc";
public static final String HOUR = "hour";
public static final String HOUR_CYCLE = "hourCycle";
public static final String HOUR12 = "hour12";
public static final String INDEX = "index";
public static final String INFINITY = "infinity";
public static final String INPUT = "input";
public static final String INTEGER = "integer";
public static final String IS_WORD_LIKE = "isWordLike";
public static final String IGNORE_PUNCTUATION = "ignorePunctuation";
public static final String LANGUAGE = "language";
public static final String LANGUAGE_DISPLAY = "languageDisplay";
public static final String LESS_PRECISION = "lessPrecision";
public static final String LITERAL = "literal";
public static final String LOCALE = "locale";
public static final String LOCALE_MATCHER = "localeMatcher";
public static final String LONG = "long";
public static final String LONG_GENERIC = "longGeneric";
public static final String LONG_OFFSET = "longOffset";
public static final String LOOKUP = "lookup";
public static final String LOWER = "lower";
public static final String LTR = "ltr";
public static final String MAXIMUM_FRACTION_DIGITS = "maximumFractionDigits";
public static final String MAXIMUM_SIGNIFICANT_DIGITS = "maximumSignificantDigits";
public static final String MEDIUM = "medium";
public static final String MIN2 = "min2";
public static final String MINIMAL_DAYS = "minimalDays";
public static final String MINIMUM_FRACTION_DIGITS = "minimumFractionDigits";
public static final String MINIMUM_INTEGER_DIGITS = "minimumIntegerDigits";
public static final String MINIMUM_SIGNIFICANT_DIGITS = "minimumSignificantDigits";
public static final String MINUS_SIGN = "minusSign";
public static final String MINUTE = "minute";
public static final String MONTH = "month";
public static final String MORE_PRECISION = "morePrecision";
public static final String NAME = "name";
public static final String NAN = "nan";
public static final String NARROW = "narrow";
public static final String NARROW_SYMBOL = "narrowSymbol";
public static final String NEGATIVE = "negative";
public static final String NEVER = "never";
public static final String NONE = "none";
public static final String NOTATION = "notation";
public static final String NUMERIC = "numeric";
public static final String NUMBERING_SYSTEM = "numberingSystem";
public static final String OR = "or";
public static final String OR_NARROW = "or-narrow";
public static final String OR_SHORT = "or-short";
public static final String ORDINAL = "ordinal";
public static final String PERCENT = "percent";
public static final String PLURAL_CATEGORIES = "pluralCategories";
public static final String PLUS_SIGN = "plusSign";
public static final String QUARTER = "quarter";
public static final String REGION = "region";
public static final String ROUNDING_INCREMENT = "roundingIncrement";
public static final String ROUNDING_MODE = "roundingMode";
public static final String ROUNDING_PRIORITY = "roundingPriority";
public static final String RTL = "rtl";
public static final String SCIENTIFIC = "scientific";
public static final String SCRIPT = "script";
public static final String SEARCH = "search";
public static final String SECOND = "second";
public static final String SEGMENT = "segment";
public static final String SENTENCE = "sentence";
public static final String SENSITIVITY = "sensitivity";
public static final String SHARED = "shared";
public static final String SHORT = "short";
public static final String SHORT_GENERIC = "shortGeneric";
public static final String SHORT_OFFSET = "shortOffset";
public static final String SIGNIFICANT_DIGITS = "significantDigits";
public static final String SIGN_DISPLAY = "signDisplay";
public static final String SORT = "sort";
public static final String SOURCE = "source";
public static final String STANDARD = "standard";
public static final String STANDARD_NARROW = "standard-narrow";
public static final String STANDARD_SHORT = "standard-short";
public static final String START_RANGE = "startRange";
public static final String STRICT = "strict";
public static final String STRIP_IF_INTEGER = "stripIfInteger";
public static final String STYLE = "style";
public static final String SYMBOL = "symbol";
public static final String TIME_STYLE = "timeStyle";
public static final String TIME_ZONE = "timeZone";
public static final String TIME_ZONE_NAME = "timeZoneName";
public static final String TRAILING_ZERO_DISPLAY = "trailingZeroDisplay";
public static final String TRUNC = "trunc";
public static final String TYPE = "type";
public static final String UND = "und";
public static final String UNIT = "unit";
public static final String UNIT_DISPLAY = "unitDisplay";
public static final String UNIT_NARROW = "unit-narrow";
public static final String UNIT_SHORT = "unit-short";
public static final String UPPER = "upper";
public static final String USAGE = "usage";
public static final String USE_GROUPING = "useGrouping";
public static final String VALUE = "value";
public static final String VARIANT = "variant";
public static final String WORD = "word";
public static final String WEEKDAY = "weekday";
public static final String WEEKEND = "weekend";
public static final String WEEK_OF_YEAR = "weekOfYear";
public static final String YEAR = "year";
public static final String YEAR_NAME = "yearName";
public static final TruffleString KEY_CALENDAR = Strings.CALENDAR;
public static final TruffleString KEY_CASE_FIRST = Strings.constant(CASE_FIRST);
public static final TruffleString KEY_COLLATION = Strings.constant(COLLATION);
public static final TruffleString KEY_COMPACT_DISPLAY = Strings.constant(COMPACT_DISPLAY);
public static final TruffleString KEY_CURRENCY = Strings.constant(CURRENCY);
public static final TruffleString KEY_CURRENCY_DISPLAY = Strings.constant(CURRENCY_DISPLAY);
public static final TruffleString KEY_CURRENCY_SIGN = Strings.constant(CURRENCY_SIGN);
public static final TruffleString KEY_DATE_STYLE = Strings.constant(DATE_STYLE);
public static final TruffleString KEY_DAY = Strings.DAY;
public static final TruffleString KEY_DAY_PERIOD = Strings.constant(DAY_PERIOD);
public static final TruffleString KEY_DIRECTION = Strings.constant(DIRECTION);
public static final TruffleString KEY_ERA = Strings.ERA;
public static final TruffleString KEY_FALLBACK = Strings.constant(FALLBACK);
public static final TruffleString KEY_FIRST_DAY = Strings.constant(FIRST_DAY);
public static final TruffleString KEY_FIRST_DAY_OF_WEEK = Strings.constant(FIRST_DAY_OF_WEEK);
public static final TruffleString KEY_FORMAT_MATCHER = Strings.constant(FORMAT_MATCHER);
public static final TruffleString KEY_FRACTIONAL_SECOND_DIGITS = Strings.FRACTIONAL_SECOND_DIGITS;
public static final TruffleString KEY_GRANULARITY = Strings.constant(GRANULARITY);
public static final TruffleString KEY_HOUR = Strings.HOUR;
public static final TruffleString KEY_HOUR_CYCLE = Strings.constant(HOUR_CYCLE);
public static final TruffleString KEY_HOUR12 = Strings.constant(HOUR12);
public static final TruffleString KEY_INDEX = Strings.INDEX;
public static final TruffleString KEY_INPUT = Strings.INPUT;
public static final TruffleString KEY_IS_WORD_LIKE = Strings.constant(IS_WORD_LIKE);
public static final TruffleString KEY_IGNORE_PUNCTUATION = Strings.constant(IGNORE_PUNCTUATION);
public static final TruffleString KEY_LANGUAGE = Strings.LANGUAGE;
public static final TruffleString KEY_LANGUAGE_DISPLAY = Strings.constant(LANGUAGE_DISPLAY);
public static final TruffleString KEY_LOCALE = Strings.constant(LOCALE);
public static final TruffleString KEY_LOCALE_MATCHER = Strings.constant(LOCALE_MATCHER);
public static final TruffleString KEY_LTR = Strings.constant(LTR);
public static final TruffleString KEY_MAXIMUM_FRACTION_DIGITS = Strings.constant(MAXIMUM_FRACTION_DIGITS);
public static final TruffleString KEY_MAXIMUM_SIGNIFICANT_DIGITS = Strings.constant(MAXIMUM_SIGNIFICANT_DIGITS);
public static final TruffleString KEY_MINIMAL_DAYS = Strings.constant(MINIMAL_DAYS);
public static final TruffleString KEY_MINIMUM_FRACTION_DIGITS = Strings.constant(MINIMUM_FRACTION_DIGITS);
public static final TruffleString KEY_MINIMUM_INTEGER_DIGITS = Strings.constant(MINIMUM_INTEGER_DIGITS);
public static final TruffleString KEY_MINIMUM_SIGNIFICANT_DIGITS = Strings.constant(MINIMUM_SIGNIFICANT_DIGITS);
public static final TruffleString KEY_MINUTE = Strings.MINUTE;
public static final TruffleString KEY_MONTH = Strings.MONTH;
public static final TruffleString KEY_NOTATION = Strings.constant(NOTATION);
public static final TruffleString KEY_NUMERIC = Strings.constant(NUMERIC);
public static final TruffleString KEY_NUMBERING_SYSTEM = Strings.constant(NUMBERING_SYSTEM);
public static final TruffleString KEY_PLURAL_CATEGORIES = Strings.constant(PLURAL_CATEGORIES);
public static final TruffleString KEY_REGION = Strings.constant(REGION);
public static final TruffleString KEY_ROUNDING_INCREMENT = Strings.ROUNDING_INCREMENT;
public static final TruffleString KEY_ROUNDING_MODE = Strings.ROUNDING_MODE;
public static final TruffleString KEY_ROUNDING_PRIORITY = Strings.constant(ROUNDING_PRIORITY);
public static final TruffleString KEY_RTL = Strings.constant(RTL);
public static final TruffleString KEY_SCRIPT = Strings.SCRIPT;
public static final TruffleString KEY_SECOND = Strings.SECOND;
public static final TruffleString KEY_SEGMENT = Strings.constant(SEGMENT);
public static final TruffleString KEY_SENSITIVITY = Strings.constant(SENSITIVITY);
public static final TruffleString KEY_SIGN_DISPLAY = Strings.constant(SIGN_DISPLAY);
public static final TruffleString KEY_SOURCE = Strings.SOURCE;
public static final TruffleString KEY_STYLE = Strings.constant(STYLE);
public static final TruffleString KEY_TIME_STYLE = Strings.constant(TIME_STYLE);
public static final TruffleString KEY_TIME_ZONE = Strings.TIME_ZONE;
public static final TruffleString KEY_TIME_ZONE_NAME = Strings.TIME_ZONE_NAME;
public static final TruffleString KEY_TRAILING_ZERO_DISPLAY = Strings.constant(TRAILING_ZERO_DISPLAY);
public static final TruffleString KEY_TYPE = Strings.TYPE;
public static final TruffleString KEY_UNIT = Strings.UNIT;
public static final TruffleString KEY_UNIT_DISPLAY = Strings.constant(UNIT_DISPLAY);
public static final TruffleString KEY_USAGE = Strings.constant(USAGE);
public static final TruffleString KEY_USE_GROUPING = Strings.constant(USE_GROUPING);
public static final TruffleString KEY_VALUE = Strings.VALUE;
public static final TruffleString KEY_WEEKDAY = Strings.constant(WEEKDAY);
public static final TruffleString KEY_WEEKEND = Strings.constant(WEEKEND);
public static final TruffleString KEY_YEAR = Strings.YEAR;
// https://tc39.es/ecma402/#table-sanctioned-simple-unit-identifiers
private static final Set SANCTIONED_SIMPLE_UNIT_IDENTIFIERS = Set.of(new String[]{
"acre",
"bit",
"byte",
"celsius",
"centimeter",
"day",
"degree",
"fahrenheit",
"fluid-ounce",
"foot",
"gallon",
"gigabit",
"gigabyte",
"gram",
"hectare",
"hour",
"inch",
"kilobit",
"kilobyte",
"kilogram",
"kilometer",
"liter",
"megabit",
"megabyte",
"meter",
"microsecond",
"mile",
"mile-scandinavian",
"milliliter",
"millimeter",
"millisecond",
"minute",
"month",
"nanosecond",
"ounce",
"percent",
"petabyte",
"pound",
"second",
"stone",
"terabit",
"terabyte",
"week",
"yard",
"year"
});
public static Locale selectedLocale(JSContext ctx, String[] locales) {
// We don't distinguish BestFitMatcher and LookupMatcher i.e.
// the implementation dependent BestFitMatcher is implemented as LookupMatcher
return lookupMatcher(ctx, locales);
}
public static Locale bestAvailableLocale(JSContext context, Locale locale) {
Locale candidate = locale;
while (true) {
if (isAvailableLocale(context, candidate)) {
return candidate;
}
String candidateLanguageTag = candidate.toLanguageTag();
int pos = candidateLanguageTag.lastIndexOf('-');
if (pos == -1) {
return null;
} else {
if (pos >= 2 && candidateLanguageTag.charAt(pos - 2) == '-') {
pos -= 2;
}
candidateLanguageTag = candidateLanguageTag.substring(0, pos);
candidate = Locale.forLanguageTag(candidateLanguageTag);
}
}
}
@TruffleBoundary
public static Locale lookupMatcher(JSContext ctx, String[] requestedLocales) {
for (String locale : requestedLocales) {
Locale requestedLocale = Locale.forLanguageTag(locale);
Locale noExtensionsLocale = requestedLocale.stripExtensions();
Locale availableLocale = bestAvailableLocale(ctx, noExtensionsLocale);
if (availableLocale != null) {
String unicodeExtension = requestedLocale.getExtension('u');
if (unicodeExtension != null) {
availableLocale = new Locale.Builder().setLocale(availableLocale).setExtension('u', unicodeExtension).build();
}
return availableLocale;
}
}
return ctx.getLocale();
}
@TruffleBoundary
public static List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy