/**
* 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.CreateArrayFromList;
import static com.github.anba.es6draft.runtime.AbstractOperations.CreateDataProperty;
import static com.github.anba.es6draft.runtime.AbstractOperations.ToFlatString;
import static com.github.anba.es6draft.runtime.internal.Errors.newRangeError;
import static com.github.anba.es6draft.runtime.internal.Properties.createProperties;
import static com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.CanonicalizeLanguageTag;
import static com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.CanonicalizeLocaleList;
import static com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.IsStructurallyValidLanguageTag;
import static com.github.anba.es6draft.runtime.objects.intl.IntlAbstractOperations.RemoveUnicodeLocaleExtension;
import static com.github.anba.es6draft.runtime.types.builtins.ArrayObject.ArrayCreate;
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.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.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.LanguageTagParser.LanguageTag;
import com.github.anba.es6draft.runtime.types.Intrinsics;
import com.github.anba.es6draft.runtime.types.builtins.ArrayObject;
import com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject;
/**
* <h1>8 The Intl Object</h1>
*/
public final class IntlObject extends OrdinaryObject implements Initializable {
/**
* Constructs a new Intl object.
*
* @param realm
* the realm object
*/
public IntlObject(Realm realm) {
super(realm);
}
@Override
public void initialize(Realm realm) {
createProperties(realm, this, Properties.class);
createProperties(realm, this, PluralRulesProperty.class);
createProperties(realm, this, LocaleProperties.class);
}
/**
* 8.1 Properties of the Intl Object
*/
public enum Properties {
;
@Prototype
public static final Intrinsics __proto__ = Intrinsics.ObjectPrototype;
@Value(name = "Collator")
public static final Intrinsics Collator = Intrinsics.Intl_Collator;
@Value(name = "NumberFormat")
public static final Intrinsics NumberFormat = Intrinsics.Intl_NumberFormat;
@Value(name = "DateTimeFormat")
public static final Intrinsics DateTimeFormat = Intrinsics.Intl_DateTimeFormat;
}
/**
* Intl.PluralRules property
*/
@CompatibilityExtension(CompatibilityOption.PluralRules)
public enum PluralRulesProperty {
;
@Value(name = "PluralRules")
public static final Intrinsics PluralRules = Intrinsics.Intl_PluralRules;
}
/**
* Locale Operations
*/
@CompatibilityExtension(CompatibilityOption.Locale)
public enum LocaleProperties {
;
/**
* Intl.getCanonicalLocales (locales)
*
* @param cx
* the execution context
* @param thisValue
* the function this-value
* @param locales
* the locales array
* @return the array of canonicalized locales
*/
@Function(name = "getCanonicalLocales", arity = 1)
public static Object getCanonicalLocales(ExecutionContext cx, Object thisValue, Object locales) {
/* step 2 */
Set<String> localesList = CanonicalizeLocaleList(cx, locales);
// FIXME: spec issue - should use CreateArrayFromList abstract op.
/* steps 1, 3-5 */
return CreateArrayFromList(cx, localesList);
}
/**
* Intl.getParentLocales (locale)
*
* @param cx
* the execution context
* @param thisValue
* the function this-value
* @param locale
* the locale
* @return the array of parent locales
*/
@Function(name = "getParentLocales", arity = 1)
public static Object getParentLocales(ExecutionContext cx, Object thisValue, Object locale) {
/* step 1 */
ArrayObject localeChain = ArrayCreate(cx, 0);
/* step 2 */
// FIXME: spec bug - CanonicalizeLanguageTag expects a previously validated language tag.
String tag = ToFlatString(cx, locale);
LanguageTag langTag = IsStructurallyValidLanguageTag(tag);
if (langTag == null) {
throw newRangeError(cx, Messages.Key.IntlStructurallyInvalidLanguageTag, tag);
}
String candidate = CanonicalizeLanguageTag(langTag);
// FIXME: spec bug - unicode locale extension sequences should be removed (?).
// FIXME: spec issue - how to handle privateuse sequences?
// FIXME: spec bug - how to handle certain special languages, like the grandfathered "i-enochian"?
// FIXME: spec bug - handle privateuse only tags, like "x-foo-bar".
candidate = RemoveUnicodeLocaleExtension(candidate);
/* step 3 */
int n = 0;
/* step 4 */
// FIXME: spec bug - `n` not incremented resp. use 0 here and start n with 1.
CreateDataProperty(cx, localeChain, n++, candidate);
/* step 5 */
int pos = candidate.lastIndexOf('-');
/* step 6 */
while (pos > -1) {
/* step 6.a */
if (pos >= 2 && candidate.charAt(pos - 2) == '-') {
pos -= 2;
}
/* step 6.b */
candidate = candidate.substring(0, pos);
/* steps 6.c, 6.e */
CreateDataProperty(cx, localeChain, n++, candidate);
/* step 6.d */
pos = candidate.lastIndexOf('-');
}
/* step 7 */
return localeChain;
}
}
}