Commit 5b64c8a6 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Implement changes in CanonicalizeLocaleList

Change the code to reflect
https://tc39.github.io/proposal-intl-locale/#sec-canonicalizelocalelist

Bug: v8:8655
Change-Id: I114488dee854b7322a5719de13e4fb8b6f18283c
Reviewed-on: https://chromium-review.googlesource.com/c/1400851
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58808}
parent 7701af03
......@@ -20,6 +20,7 @@
#include "src/objects-inl.h"
#include "src/objects/js-collator-inl.h"
#include "src/objects/js-date-time-format-inl.h"
#include "src/objects/js-locale-inl.h"
#include "src/objects/js-number-format-inl.h"
#include "src/objects/string.h"
#include "src/property-descriptor.h"
......@@ -789,7 +790,15 @@ Maybe<std::vector<std::string>> Intl::CanonicalizeLocaleList(
}
// 2. Let seen be a new empty List.
std::vector<std::string> seen;
// 3. If Type(locales) is String, then
// 3. If Type(locales) is String or locales has an [[InitializedLocale]]
// internal slot, then
if (locales->IsJSLocale()) {
// Since this value came from JSLocale, which is already went though the
// CanonializeLanguageTag process once, therefore there are no need to
// call CanonializeLanguageTag again.
seen.push_back(JSLocale::ToString(Handle<JSLocale>::cast(locales)));
return Just(seen);
}
if (locales->IsString()) {
// 3a. Let O be CreateArrayFromList(« locales »).
// Instead of creating a one-element array and then iterating over it,
......@@ -840,8 +849,12 @@ Maybe<std::vector<std::string>> Intl::CanonicalizeLocaleList(
// RangeError exception.
// 7c v. Let canonicalizedTag be CanonicalizeLanguageTag(tag).
std::string canonicalized_tag;
if (!CanonicalizeLanguageTag(isolate, k_value).To(&canonicalized_tag)) {
return Nothing<std::vector<std::string>>();
if (k_value->IsJSLocale()) {
canonicalized_tag = JSLocale::ToString(Handle<JSLocale>::cast(k_value));
} else {
if (!CanonicalizeLanguageTag(isolate, k_value).To(&canonicalized_tag)) {
return Nothing<std::vector<std::string>>();
}
}
// 7c vi. If canonicalizedTag is not an element of seen, append
// canonicalizedTag as the last element of seen.
......
......@@ -447,9 +447,13 @@ Handle<Object> JSLocale::NumberingSystem(Isolate* isolate,
return UnicodeKeywordValue(isolate, locale, "nu");
}
Handle<String> JSLocale::ToString(Isolate* isolate, Handle<JSLocale> locale) {
std::string JSLocale::ToString(Handle<JSLocale> locale) {
icu::Locale* icu_locale = locale->icu_locale()->raw();
std::string locale_str = Intl::ToLanguageTag(*icu_locale).FromJust();
return Intl::ToLanguageTag(*icu_locale).FromJust();
}
Handle<String> JSLocale::ToString(Isolate* isolate, Handle<JSLocale> locale) {
std::string locale_str = JSLocale::ToString(locale);
return isolate->factory()->NewStringFromAsciiChecked(locale_str.c_str());
}
......
......@@ -48,6 +48,7 @@ class JSLocale : public JSObject {
static Handle<Object> NumberingSystem(Isolate* isolate,
Handle<JSLocale> locale);
static Handle<String> ToString(Isolate* isolate, Handle<JSLocale> locale);
static std::string ToString(Handle<JSLocale> locale);
DECL_CAST(JSLocale)
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-locale
//
// Test NumberFormat will accept Intl.Locale as first parameter, or
// as in the array.
let tag = "zh-Hant-TW-u-nu-thai"
let l = new Intl.Locale(tag);
var nf;
// Test with String
assertDoesNotThrow(() => nf = new Intl.NumberFormat(tag));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with Array with one String
assertDoesNotThrow(() => nf = new Intl.NumberFormat([tag]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with Array with two String
assertDoesNotThrow(() => nf = new Intl.NumberFormat([tag, "en"]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with a Locale
assertDoesNotThrow(() => nf = new Intl.NumberFormat(l));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with a Array of one Locale
assertDoesNotThrow(() => nf = new Intl.NumberFormat([l]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with a Array of one Locale and a Sring
assertDoesNotThrow(() => nf = new Intl.NumberFormat([l, "en"]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test DateTimeFormat
var df;
assertDoesNotThrow(() => df = new Intl.DateTimeFormat(tag));
assertEquals(tag, df.resolvedOptions().locale);
assertDoesNotThrow(() => df = new Intl.DateTimeFormat([tag]));
assertEquals(tag, df.resolvedOptions().locale);
// Test RelativeTimeFormat
var rtf;
assertDoesNotThrow(() => rtf = new Intl.RelativeTimeFormat(tag));
assertEquals(tag, rtf.resolvedOptions().locale);
assertDoesNotThrow(() => rtf = new Intl.RelativeTimeFormat([tag]));
assertEquals(tag, rtf.resolvedOptions().locale);
// Test ListFormat
tag = "zh-Hant-TW"
var lf;
assertDoesNotThrow(() => lf = new Intl.ListFormat(tag));
assertEquals(tag, lf.resolvedOptions().locale);
assertDoesNotThrow(() => lf = new Intl.ListFormat([tag]));
assertEquals(tag, lf.resolvedOptions().locale);
// Test Collator
var col;
assertDoesNotThrow(() => col = new Intl.Collator(tag));
assertEquals(tag, lf.resolvedOptions().locale);
assertDoesNotThrow(() => col = new Intl.Collator([tag]));
assertEquals(tag, lf.resolvedOptions().locale);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment