/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.runtime.objects.intl; import static com.github.anba.es6draft.runtime.AbstractOperations.ToObject; import static com.github.anba.es6draft.runtime.internal.Properties.createProperties; import static com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.*; import static java.util.Arrays.asList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import com.github.anba.es6draft.runtime.ExecutionContext; import com.github.anba.es6draft.runtime.Realm; import com.github.anba.es6draft.runtime.internal.Initializable; import com.github.anba.es6draft.runtime.internal.Lazy; import com.github.anba.es6draft.runtime.internal.Properties.Attributes; import com.github.anba.es6draft.runtime.internal.Properties.Function; import com.github.anba.es6draft.runtime.internal.Properties.Prototype; import com.github.anba.es6draft.runtime.internal.Properties.Value; import com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.ExtensionKey; import com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.LocaleData; import com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.LocaleDataInfo; import com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.OptionsRecord; import com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.ResolvedLocale; import com.github.anba.es6draft.runtime.types.Constructor; import com.github.anba.es6draft.runtime.types.Intrinsics; import com.github.anba.es6draft.runtime.types.ScriptObject; import com.github.anba.es6draft.runtime.types.Type; import com.github.anba.es6draft.runtime.types.builtins.BuiltinConstructor; import com.ibm.icu.util.ULocale; /** * <h1>PluralRules Objects</h1> * <ul> * <li>The Intl.PluralRules Constructor * <li>Properties of the Intl.PluralRules Constructor * </ul> */ public final class PluralRulesConstructor extends BuiltinConstructor implements Initializable { /** [[availableLocales]] */ private final Lazy<Set<String>> availableLocales = Lazy .of(() -> GetAvailableLocales(LanguageData.getAvailablePluralRulesLocales())); /** * [[availableLocales]] * * @param cx * the execution context * @return the set of available locales supported by {@code Intl.PluralRules} */ public static Set<String> getAvailableLocales(ExecutionContext cx) { return getAvailableLocalesLazy(cx).get(); } private static Lazy<Set<String>> getAvailableLocalesLazy(ExecutionContext cx) { PluralRulesConstructor pluralRules = (PluralRulesConstructor) cx.getIntrinsic(Intrinsics.Intl_PluralRules); return pluralRules.availableLocales; } /** [[relevantExtensionKeys]] */ private static final List<ExtensionKey> relevantExtensionKeys = Collections.emptyList(); private static final class PluralRulesLocaleData implements LocaleData { @Override public LocaleDataInfo info(ULocale locale) { return new PluralRulesLocaleDataInfo(); } } private static final class PluralRulesLocaleDataInfo implements LocaleDataInfo { @Override public String defaultValue(ExtensionKey extensionKey) { throw new IllegalArgumentException(extensionKey.name()); } @Override public List<String> entries(ExtensionKey extensionKey) { throw new IllegalArgumentException(extensionKey.name()); } } /** * Constructs a new PluralRules constructor function. * * @param realm * the realm object */ public PluralRulesConstructor(Realm realm) { super(realm, "PluralRules", 0); } @Override public void initialize(Realm realm) { createProperties(realm, this, Properties.class); } @Override public PluralRulesConstructor clone() { return new PluralRulesConstructor(getRealm()); } @SafeVarargs private static <T> Set<T> set(T... elements) { return new HashSet<>(asList(elements)); } /** * InitializePluralRules (pluralRules, locales, options) * * @param cx * the execution context * @param pluralRules * the pluralRules object * @param locales * the locales array * @param opts * the options object */ public static void InitializePluralRules(ExecutionContext cx, PluralRulesObject pluralRules, Object locales, Object opts) { /* steps 1-2 (not applicable) */ /* step 3 */ Set<String> requestedLocales = CanonicalizeLocaleList(cx, locales); /* steps 4-5 */ ScriptObject options; if (Type.isUndefined(opts)) { options = ObjectCreate(cx, Intrinsics.ObjectPrototype); } else { options = ToObject(cx, opts); } /* step 6 */ OptionsRecord opt = new OptionsRecord(OptionsRecord.MatcherType.forName("lookup")); /* step 7 */ String s = GetStringOption(cx, options, "type", set("cardinal", "ordinal"), "cardinal"); /* step 8 */ pluralRules.setType(s); /* step 9 */ PluralRulesLocaleData localeData = new PluralRulesLocaleData(); /* step 10 */ ResolvedLocale r = ResolveLocale(cx.getRealm(), getAvailableLocalesLazy(cx), requestedLocales, opt, relevantExtensionKeys, localeData); /* step 11 */ pluralRules.setLocale(r.getLocale()); /* steps 12-16 (not applicable) */ /* step 17 */ pluralRules.setBoundResolve(null); /* step 18 (not applicable) */ /* step 19 (return) */ } /** * InitializePluralRules (pluralRules, locales, options) * * @param realm * the realm instance * @param pluralRules * the pluralRules object */ public static void InitializeDefaultPluralRules(Realm realm, PluralRulesObject pluralRules) { /* steps 1-2 (not applicable) */ /* steps 3-6 (not applicable) */ /* steps 7-8 */ pluralRules.setType("cardinal"); /* step 9 */ PluralRulesLocaleData localeData = new PluralRulesLocaleData(); /* step 10 */ ResolvedLocale r = ResolveDefaultLocale(realm, relevantExtensionKeys, localeData); /* step 11 */ pluralRules.setLocale(r.getLocale()); /* steps 12-16 (not applicable) */ /* step 17 */ pluralRules.setBoundResolve(null); /* step 18 (not applicable) */ /* step 19 (return) */ } /** * Intl.PluralRules ([ locales [ , options ]]) */ @Override public PluralRulesObject call(ExecutionContext callerContext, Object thisValue, Object... args) { /* steps 1-3 */ return construct(callerContext, this, args); } /** * Intl.PluralRules ([ locales [ , options ]]) */ @Override public PluralRulesObject construct(ExecutionContext callerContext, Constructor newTarget, Object... args) { ExecutionContext calleeContext = calleeContext(); Object locales = argument(args, 0); Object options = argument(args, 1); /* step 1 (not applicable) */ /* step 2 */ PluralRulesObject pluralRules = OrdinaryCreateFromConstructor(calleeContext, newTarget, Intrinsics.Intl_PluralRulesPrototype, PluralRulesObject::new); /* step 3 */ InitializePluralRules(calleeContext, pluralRules, locales, options); return pluralRules; } /** * Properties of the Intl.PluralRules Constructor */ public enum Properties { ; @Prototype public static final Intrinsics __proto__ = Intrinsics.FunctionPrototype; @Value(name = "length", attributes = @Attributes(writable = false, enumerable = false, configurable = true) ) public static final int length = 0; @Value(name = "name", attributes = @Attributes(writable = false, enumerable = false, configurable = true) ) public static final String name = "PluralRules"; /** * Intl.PluralRules.prototype */ @Value(name = "prototype", attributes = @Attributes(writable = false, enumerable = false, configurable = false) ) public static final Intrinsics prototype = Intrinsics.Intl_PluralRulesPrototype; /** * Intl.PluralRules.supportedLocalesOf (locales [, options ]) * * @param cx * the execution context * @param thisValue * the function this-value * @param locales * the locales array * @param options * the options object * @return the array of supported locales */ @Function(name = "supportedLocalesOf", arity = 1) public static Object supportedLocalesOf(ExecutionContext cx, Object thisValue, Object locales, Object options) { /* steps 1-2 */ Set<String> requestedLocales = CanonicalizeLocaleList(cx, locales); /* step 3 */ return SupportedLocales(cx, getAvailableLocales(cx), requestedLocales, options); } } }