Commit a52c42da authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Implement Intl.RelativeTimeFormat.prototype.resolvedOptions

Spec: http://tc39.github.io/proposal-intl-relative-time/

Design Doc: go/add-intl.relativetimeformat-to-v8

Test: test262/intl402/RelativeTimeFormat/*, intl/relative-time-format/*

R=gsathya@chromium.org, mstarzinger@chromium.org

Bug: v8:7869
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Ic1ef2e26d164275791dfdbe37d016ba350256d94
Reviewed-on: https://chromium-review.googlesource.com/1125539
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54359}
parent 97cdf44d
......@@ -4586,6 +4586,10 @@ void Genesis::InitializeGlobal_harmony_intl_relative_time_format() {
JSObject::AddProperty(isolate(), prototype, factory()->to_string_tag_symbol(),
factory()->Object_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
SimpleInstallFunction(isolate(), prototype, "resolvedOptions",
Builtins::kRelativeTimeFormatPrototypeResolvedOptions,
0, false);
}
#endif // V8_INTL_SUPPORT
......
......@@ -1311,41 +1311,43 @@ namespace internal {
ASM(MathPowInternal)
#ifdef V8_INTL_SUPPORT
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_FROM_DSL(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
\
TFS(StringToLowerCaseIntl, kString) \
/* ES #sec-string.prototype.tolowercase */ \
TFJ(StringPrototypeToLowerCaseIntl, 0, kReceiver) \
/* ES #sec-string.prototype.touppercase */ \
CPP(StringPrototypeToUpperCaseIntl) \
/* ES #sec-string.prototype.normalize */ \
CPP(StringPrototypeNormalizeIntl) \
/* ecma402 #sec-intl.numberformat.prototype.formattoparts */ \
CPP(NumberFormatPrototypeFormatToParts) \
/* ecma402 #sec-intl.datetimeformat.prototype.formattoparts */ \
CPP(DateTimeFormatPrototypeFormatToParts) \
/* ecma402 #new proposal */ \
/* ecma402 #sec-intl-locale-constructor */ \
CPP(LocaleConstructor) \
CPP(LocalePrototypeLanguage) \
CPP(LocalePrototypeScript) \
CPP(LocalePrototypeRegion) \
CPP(LocalePrototypeBaseName) \
CPP(LocalePrototypeCalendar) \
CPP(LocalePrototypeCaseFirst) \
CPP(LocalePrototypeCollation) \
CPP(LocalePrototypeHourCycle) \
CPP(LocalePrototypeNumeric) \
CPP(LocalePrototypeNumberingSystem) \
CPP(LocalePrototypeToString) \
/* ecma402 #sec-number-format-functions */ \
CPP(NumberFormatInternalFormatNumber) \
/* ecma402 #sec-intl.numberformat.prototype.format */ \
CPP(NumberFormatPrototypeFormatNumber) \
/* ecma402 #sec-intl-relativetimeformat-constructor */ \
CPP(RelativeTimeFormatConstructor)
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_FROM_DSL(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
\
TFS(StringToLowerCaseIntl, kString) \
/* ES #sec-string.prototype.tolowercase */ \
TFJ(StringPrototypeToLowerCaseIntl, 0, kReceiver) \
/* ES #sec-string.prototype.touppercase */ \
CPP(StringPrototypeToUpperCaseIntl) \
/* ES #sec-string.prototype.normalize */ \
CPP(StringPrototypeNormalizeIntl) \
/* ecma402 #sec-intl.numberformat.prototype.formattoparts */ \
CPP(NumberFormatPrototypeFormatToParts) \
/* ecma402 #sec-intl.datetimeformat.prototype.formattoparts */ \
CPP(DateTimeFormatPrototypeFormatToParts) \
/* ecma402 #new proposal */ \
/* ecma402 #sec-intl-locale-constructor */ \
CPP(LocaleConstructor) \
CPP(LocalePrototypeLanguage) \
CPP(LocalePrototypeScript) \
CPP(LocalePrototypeRegion) \
CPP(LocalePrototypeBaseName) \
CPP(LocalePrototypeCalendar) \
CPP(LocalePrototypeCaseFirst) \
CPP(LocalePrototypeCollation) \
CPP(LocalePrototypeHourCycle) \
CPP(LocalePrototypeNumeric) \
CPP(LocalePrototypeNumberingSystem) \
CPP(LocalePrototypeToString) \
/* ecma402 #sec-number-format-functions */ \
CPP(NumberFormatInternalFormatNumber) \
/* ecma402 #sec-intl.numberformat.prototype.format */ \
CPP(NumberFormatPrototypeFormatNumber) \
/* ecma402 #sec-intl-relativetimeformat-constructor */ \
CPP(RelativeTimeFormatConstructor) \
/* ecma402 #sec-intl.relativetimeformat.prototype.resolvedoptions */ \
CPP(RelativeTimeFormatPrototypeResolvedOptions)
#else
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
......
......@@ -675,6 +675,13 @@ BUILTIN(RelativeTimeFormatConstructor) {
options));
}
BUILTIN(RelativeTimeFormatPrototypeResolvedOptions) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
"Intl.RelativeTimeFormat.prototype.resolvedOptions");
return *JSRelativeTimeFormat::ResolvedOptions(isolate, format_holder);
}
// Locale getters.
BUILTIN(LocalePrototypeLanguage) {
HandleScope scope(isolate);
......
......@@ -35,4 +35,10 @@
'*': [SKIP],
}], # variant == no_wasm_traps
['system == windows', {
# noi18n cannot turn on ICU backend for Date
'relative-time-format/default-locale-fr-CA': [SKIP],
'relative-time-format/default-locale-pt-BR': [SKIP],
}], # system == windows'
]
// Copyright 2018 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-intl-relative-time-format --harmony-locale
// Environment Variables: LC_ALL=fr_CA
assertEquals(
'fr-CA',
(new Intl.RelativeTimeFormat()).resolvedOptions().locale);
assertEquals(
'fr-CA',
(new Intl.RelativeTimeFormat([], {style: 'short', numeric: 'auto'}))
.resolvedOptions().locale);
// Copyright 2018 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-intl-relative-time-format --harmony-locale
// Environment Variables: LC_ALL=pt_BR
assertEquals(
'pt-BR',
(new Intl.RelativeTimeFormat()).resolvedOptions().locale);
assertEquals(
'pt-BR',
(new Intl.RelativeTimeFormat([], {style: 'short', numeric: 'auto'}))
.resolvedOptions().locale);
// Copyright 2018 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-intl-relative-time-format
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ()
// The default style is 'long'
assertEquals('long', rtf.resolvedOptions().style);
// The default numeric is 'always'
assertEquals('always', rtf.resolvedOptions().numeric);
// contains style, numeric and locale key
assertEquals(3, Object.getOwnPropertyNames(rtf.resolvedOptions()).length);
// contains style, numeric and locale key
assertEquals(3, Object.getOwnPropertyNames(new Intl.RelativeTimeFormat('en').resolvedOptions()).length);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long'}))
.resolvedOptions().numeric);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['ar'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['ar', 'en'])).resolvedOptions().locale);
assertEquals(
'fr',
(new Intl.RelativeTimeFormat(['fr', 'en'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['xyz', 'ar'])).resolvedOptions().locale);
{
var receiver = 1;
assertThrows(() =>
Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError);
receiver = {};
assertThrows(() =>
Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError);
}
// The following is not working yet because it depend on the getAvailableLocales
// work in another path set.
// TODO(ftang): uncomment the following once that patchset is checked in.
//assertEquals(
// 'ar',
// (new Intl.RelativeTimeFormat(['i-default', 'ar'])).resolvedOptions().locale);
......@@ -26,10 +26,13 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import re
from testrunner.local import testsuite
from testrunner.objects import testcase
ENV_PATTERN = re.compile(r"//\s+Environment Variables:(.*)")
class TestSuite(testsuite.TestSuite):
def ListTests(self):
tests = []
......@@ -58,6 +61,20 @@ class TestCase(testcase.TestCase):
super(TestCase, self).__init__(*args, **kwargs)
self._source_flags = self._parse_source_flags()
source = self.get_source()
self._env = self._parse_source_env(source)
def _parse_source_env(self, source):
env_match = ENV_PATTERN.search(source)
env = {}
if env_match:
for env_pair in env_match.group(1).strip().split():
var, value = env_pair.split('=')
env[var] = value
return env
def _get_cmd_env(self):
return self._env
def _get_files_params(self):
files = map(lambda f: os.path.join(self.suite.root, f), [
......
......@@ -608,9 +608,6 @@
'intl402/RelativeTimeFormat/prototype/formatToParts/length': [FAIL],
'intl402/RelativeTimeFormat/prototype/formatToParts/name': [FAIL],
'intl402/RelativeTimeFormat/prototype/formatToParts/prop-desc': [FAIL],
'intl402/RelativeTimeFormat/prototype/resolvedOptions/length': [FAIL],
'intl402/RelativeTimeFormat/prototype/resolvedOptions/name': [FAIL],
'intl402/RelativeTimeFormat/prototype/resolvedOptions/prop-desc': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=7813
'built-ins/Array/prototype/lastIndexOf/calls-only-has-on-prototype-after-length-zeroed': [FAIL],
......
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