/**
* 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.internal.Errors.newTypeError;
import static com.github.anba.es6draft.runtime.internal.Properties.createProperties;
import static com.github.anba.es6draft.runtime.objects.intl.DateTimeFormatConstructor.InitializeDefaultDateTimeFormat;
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.CompatibilityOption;
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.CompatibilityExtension;
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.DateFieldSymbolTable.DateField;
import com.github.anba.es6draft.runtime.objects.intl.DateFieldSymbolTable.FieldWeight;
import com.github.anba.es6draft.runtime.objects.intl.DateFieldSymbolTable.Skeleton;
import com.github.anba.es6draft.runtime.objects.intl.DateTimeFormatConstructor.FormatFunction;
import com.github.anba.es6draft.runtime.objects.intl.DateTimeFormatConstructor.FormatToPartsFunction;
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.OrdinaryObject;
import com.ibm.icu.text.DateTimePatternGenerator;
/**
* <h1>12 DateTimeFormat Objects</h1>
* <ul>
* <li>12.4 Properties of the Intl.DateTimeFormat Prototype Object
* </ul>
*/
public final class DateTimeFormatPrototype extends DateTimeFormatObject implements Initializable {
/**
* Constructs a new DateTimeFormat prototype object.
*
* @param realm
* the realm object
*/
public DateTimeFormatPrototype(Realm realm) {
super(realm);
}
@Override
public void initialize(Realm realm) {
createProperties(realm, this, Properties.class);
createProperties(realm, this, FormatToPartsProperty.class);
// Initialize Intl.DateTimeFormat.prototype's internal state.
InitializeDefaultDateTimeFormat(realm, this);
}
/**
* 12.3 Properties of the Intl.DateTimeFormat Prototype Object
*/
public enum Properties {
;
private static DateTimeFormatObject thisDateTimeFormatObject(ExecutionContext cx, Object object) {
if (object instanceof DateTimeFormatObject) {
return (DateTimeFormatObject) object;
}
throw newTypeError(cx, Messages.Key.IncompatibleObject);
}
@Prototype
public static final Intrinsics __proto__ = Intrinsics.ObjectPrototype;
/**
* 12.3.1 Intl.DateTimeFormat.prototype.constructor
*/
@Value(name = "constructor")
public static final Intrinsics constructor = Intrinsics.Intl_DateTimeFormat;
/**
* 12.3.2 Intl.DateTimeFormat.prototype[@@toStringTag]]
*/
@Value(name = "[Symbol.toStringTag]", symbol = BuiltinSymbol.toStringTag,
attributes = @Attributes(writable = false, enumerable = false, configurable = true))
public static final String toStringTag = "Object";
/**
* 12.3.3 Intl.DateTimeFormat.prototype.format
*
* @param cx
* the execution context
* @param thisValue
* the function this-value
* @return the bound format function
*/
@Accessor(name = "format", type = Accessor.Type.Getter)
public static Object format(ExecutionContext cx, Object thisValue) {
/* step 1 */
DateTimeFormatObject dateTimeFormat = thisDateTimeFormatObject(cx, thisValue);
/* step 2 */
if (dateTimeFormat.getBoundFormat() == null) {
/* step 2.a */
FormatFunction f = new FormatFunction(cx.getRealm());
/* step 2.b */
BoundFunctionObject bf = BoundFunctionCreate(cx, f, thisValue);
/* step 2.c */
bf.infallibleDefineOwnProperty("length", new Property(1, false, false, true));
/* step 2.d */
dateTimeFormat.setBoundFormat(bf);
}
/* step 3 */
return dateTimeFormat.getBoundFormat();
}
/**
* 12.3.5 Intl.DateTimeFormat.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) {
DateTimeFormatObject dateTimeFormat = thisDateTimeFormatObject(cx, thisValue);
OrdinaryObject object = OrdinaryObject.ObjectCreate(cx, Intrinsics.ObjectPrototype);
CreateDataProperty(cx, object, "locale", dateTimeFormat.getLocale());
CreateDataProperty(cx, object, "calendar", dateTimeFormat.getCalendar());
CreateDataProperty(cx, object, "numberingSystem", dateTimeFormat.getNumberingSystem());
assert dateTimeFormat.getTimeZone() != null;
CreateDataProperty(cx, object, "timeZone", dateTimeFormat.getTimeZone());
// hour12, weekday, era, year, month, day, hour, minute, second, and timeZoneName
// properties are restored from pattern field or rather its corresponding skeleton.
DateTimePatternGenerator generator = DateTimePatternGenerator.getEmptyInstance();
Skeleton skeleton = new Skeleton(generator.getSkeleton(dateTimeFormat.getPattern()));
for (DateField field : DateField.values()) {
if (field == DateField.Quarter || field == DateField.Week || field == DateField.Period) {
continue;
}
FieldWeight weight = skeleton.getWeight(field);
if (weight != null) {
CreateDataProperty(cx, object, field.toString(), weight.toString());
if (field == DateField.Hour) {
CreateDataProperty(cx, object, "hour12", skeleton.isHour12());
}
}
}
return object;
}
}
/**
* 12.3 Properties of the Intl.DateTimeFormat Prototype Object
*/
@CompatibilityExtension(CompatibilityOption.FormatToParts)
public enum FormatToPartsProperty {
;
private static DateTimeFormatObject thisDateTimeFormatObject(ExecutionContext cx, Object object) {
if (object instanceof DateTimeFormatObject) {
return (DateTimeFormatObject) object;
}
throw newTypeError(cx, Messages.Key.IncompatibleObject);
}
/**
* get Intl.DateTimeFormat.prototype.formatToParts
*
* @param cx
* the execution context
* @param thisValue
* the function this-value
* @return the bound format function
*/
@Accessor(name = "formatToParts", type = Accessor.Type.Getter)
public static Object formatToParts(ExecutionContext cx, Object thisValue) {
/* steps 1-3 */
DateTimeFormatObject dateTimeFormat = thisDateTimeFormatObject(cx, thisValue);
/* step 4 */
if (dateTimeFormat.getBoundFormatToParts() == null) {
/* step 4.a */
FormatToPartsFunction f = new FormatToPartsFunction(cx.getRealm());
/* step 4.b (not applicable) */
/* step 4.c */
BoundFunctionObject bf = BoundFunctionCreate(cx, f, thisValue);
// FIXME: spec bug - missing define for .length
bf.infallibleDefineOwnProperty("length", new Property(1, false, false, true));
/* step 4.d */
dateTimeFormat.setBoundFormatToParts(bf);
}
/* step 5 */
return dateTimeFormat.getBoundFormatToParts();
}
}
}