/** * 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.CreateDataProperty; import static com.github.anba.es6draft.runtime.AbstractOperations.ToNumber; import static com.github.anba.es6draft.runtime.internal.Errors.newTypeError; import static com.github.anba.es6draft.runtime.internal.Properties.createProperties; import static com.github.anba.es6draft.runtime.types.builtins.BoundFunctionObject.BoundFunctionCreate; 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.Messages; import com.github.anba.es6draft.runtime.internal.Properties.Accessor; 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.types.BuiltinSymbol; import com.github.anba.es6draft.runtime.types.Intrinsics; import com.github.anba.es6draft.runtime.types.Property; import com.github.anba.es6draft.runtime.types.builtins.BoundFunctionObject; import com.github.anba.es6draft.runtime.types.builtins.BuiltinFunction; import com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject; /** * <h1>PluralRules Objects</h1> * <ul> * <li>Properties of the Intl.PluralRules Prototype Object * </ul> */ public final class PluralRulesPrototype extends PluralRulesObject implements Initializable { /** * Constructs a new PluralRules prototype object. * * @param realm * the realm object */ public PluralRulesPrototype(Realm realm) { super(realm); } @Override public void initialize(Realm realm) { createProperties(realm, this, Properties.class); // Initialize Intl.PluralRules.prototype's internal state. PluralRulesConstructor.InitializeDefaultPluralRules(realm, this); } /** * Properties of the Intl.PluralRules Prototype Object */ public enum Properties { ; private static PluralRulesObject thisPluralRulesObject(ExecutionContext cx, Object object) { if (object instanceof PluralRulesObject) { return (PluralRulesObject) object; } throw newTypeError(cx, Messages.Key.IncompatibleObject); } @Prototype public static final Intrinsics __proto__ = Intrinsics.ObjectPrototype; /** * Intl.PluralRules.prototype.constructor */ @Value(name = "constructor") public static final Intrinsics constructor = Intrinsics.Intl_PluralRules; /** * Intl.PluralRules.prototype[@@toStringTag] */ @Value(name = "[Symbol.toStringTag]", symbol = BuiltinSymbol.toStringTag, attributes = @Attributes(writable = false, enumerable = false, configurable = true) ) public static final String toStringTag = "Object"; /** * get Intl.PluralRules.prototype.select * * @param cx * the execution context * @param thisValue * the function this-value * @return the bound compare function */ @Accessor(name = "select", type = Accessor.Type.Getter) public static Object select(ExecutionContext cx, Object thisValue) { /* step 1 */ PluralRulesObject pluralRules = thisPluralRulesObject(cx, thisValue); /* step 2 */ if (pluralRules.getBoundResolve() == null) { /* step 2.a */ SelectFunction f = new SelectFunction(cx.getRealm()); /* step 2.b (not applicable) */ /* step 2.c */ BoundFunctionObject bf = BoundFunctionCreate(cx, f, thisValue); // FIXME: spec bug - missing define for .length bf.infallibleDefineOwnProperty("length", new Property(1, false, false, true)); // FIXME: spec issue - set .name property? /* step 2.d */ pluralRules.setBoundResolve(bf); } /* step 3 */ return pluralRules.getBoundResolve(); } /** * Intl.PluralRules.prototype.resolvedOptions () * * @param cx * the execution context * @param thisValue * the function this-value * @return the resolved options object */ @Function(name = "resolvedOptions", arity = 0) public static Object resolvedOptions(ExecutionContext cx, Object thisValue) { PluralRulesObject pluralRules = thisPluralRulesObject(cx, thisValue); OrdinaryObject object = ObjectCreate(cx, Intrinsics.ObjectPrototype); CreateDataProperty(cx, object, "locale", pluralRules.getLocale()); CreateDataProperty(cx, object, "type", pluralRules.getType()); // TODO: spec issue - undefined pluralCategories property? return object; } } /** * ResolvePlural (pluralRules, x) * * @param pluralRules * the pluralRules object * @param x * the number value * @return the locale specific plural form */ public static String ResolvePlural(PluralRulesObject pluralRules, double x) { return pluralRules.getPluralRules().select(x); } /** * Plural Rules Functions */ public static final class SelectFunction extends BuiltinFunction { public SelectFunction(Realm realm) { super(realm, "select", 1); createDefaultFunctionProperties(); } private SelectFunction(Realm realm, Void ignore) { super(realm, "select", 1); } @Override public SelectFunction clone() { return new SelectFunction(getRealm(), null); } @Override public String call(ExecutionContext callerContext, Object thisValue, Object... args) { ExecutionContext calleeContext = calleeContext(); /* steps 1-2 */ assert thisValue instanceof PluralRulesObject; PluralRulesObject pluralRules = (PluralRulesObject) thisValue; /* step 3 */ Object value = argument(args, 0); /* step 4 */ double x = ToNumber(calleeContext, value); /* step 5 */ return ResolvePlural(pluralRules, x); } } }