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

[Intl] Implement Intl.RelativeTimeFormat.prototype.{format, formatToParts}

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=cira@chromium.org, gsathya@chromium.org

Bug: v8:7869
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Ied95d601cf707db5d555f9d963b9b1f206e37331
Reviewed-on: https://chromium-review.googlesource.com/1124728Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54520}
parent 26c7aa8c
......@@ -4601,6 +4601,11 @@ void Genesis::InitializeGlobal_harmony_intl_relative_time_format() {
SimpleInstallFunction(isolate(), prototype, "resolvedOptions",
Builtins::kRelativeTimeFormatPrototypeResolvedOptions,
0, false);
SimpleInstallFunction(isolate(), prototype, "format",
Builtins::kRelativeTimeFormatPrototypeFormat, 2, false);
SimpleInstallFunction(isolate(), prototype, "formatToParts",
Builtins::kRelativeTimeFormatPrototypeFormatToParts, 2,
false);
}
#endif // V8_INTL_SUPPORT
......
......@@ -1349,10 +1349,14 @@ namespace internal {
CPP(NumberFormatInternalFormatNumber) \
/* ecma402 #sec-intl.numberformat.prototype.format */ \
CPP(NumberFormatPrototypeFormatNumber) \
/* ecma402 #sec-intl-relativetimeformat-constructor */ \
/* ecma402 #sec-intl.RelativeTimeFormat.constructor */ \
CPP(RelativeTimeFormatConstructor) \
/* ecma402 #sec-intl.relativetimeformat.prototype.resolvedoptions */ \
CPP(RelativeTimeFormatPrototypeResolvedOptions)
/* ecma402 #sec-intl.RelativeTimeFormat.prototype.resolvedOptions */ \
CPP(RelativeTimeFormatPrototypeResolvedOptions) \
/* ecma402 #sec-intl.RelativeTimeFormat.prototype.format */ \
CPP(RelativeTimeFormatPrototypeFormat) \
/* ecma402 #sec-intl.RelativeTimeFormat.prototype.formatToParts */ \
CPP(RelativeTimeFormatPrototypeFormatToParts)
#else
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
......
This diff is collapsed.
......@@ -372,6 +372,7 @@ class ErrorUtils : public AllStatic {
"% is not a function or its return value is not iterable") \
T(NotCallableOrAsyncIterable, \
"% is not a function or its return value is not async iterable") \
T(NotFiniteNumber, "Value need to be finite number for %()") \
T(NotIterable, "% is not iterable") \
T(NotAsyncIterable, "% is not async iterable") \
T(NotPropertyName, "% is not a valid property name") \
......
......@@ -362,7 +362,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(18),
B(LdaConstant), U8(14),
B(Star), R(19),
......
......@@ -123,7 +123,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(19),
B(LdaConstant), U8(11),
B(Star), R(20),
......@@ -377,7 +377,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(19),
B(LdaConstant), U8(11),
B(Star), R(20),
......@@ -653,7 +653,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(19),
B(LdaConstant), U8(11),
B(Star), R(20),
......@@ -885,7 +885,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(17),
B(LdaConstant), U8(9),
B(Star), R(18),
......
......@@ -85,7 +85,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(12),
B(LdaConstant), U8(7),
B(Star), R(13),
......@@ -217,7 +217,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(13),
B(LdaConstant), U8(7),
B(Star), R(14),
......@@ -361,7 +361,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(12),
B(LdaConstant), U8(7),
B(Star), R(13),
......@@ -495,7 +495,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(11),
B(LdaConstant), U8(9),
B(Star), R(12),
......
......@@ -89,7 +89,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(14),
B(LdaConstant), U8(6),
B(Star), R(15),
......@@ -256,7 +256,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(14),
B(LdaConstant), U8(11),
B(Star), R(15),
......@@ -401,7 +401,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(12),
B(LdaConstant), U8(8),
B(Star), R(13),
......@@ -550,7 +550,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(17),
B(LdaConstant), U8(8),
B(Star), R(18),
......@@ -697,7 +697,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(15),
B(LdaConstant), U8(9),
B(Star), R(16),
......@@ -859,7 +859,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(14),
B(LdaConstant), U8(12),
B(Star), R(15),
......@@ -1007,7 +1007,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(20),
B(LdaConstant), U8(6),
B(Star), R(21),
......@@ -1218,7 +1218,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(19),
B(LdaConstant), U8(7),
B(Star), R(20),
......
......@@ -203,7 +203,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(149),
B(Wide), B(LdaSmi), I16(150),
B(Star), R(14),
B(LdaConstant), U8(13),
B(Star), R(15),
......
This diff is collapsed.
// 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
// The following test are not part of the comformance. Just some output in
// English to verify the format does return something reasonable for English.
// It may be changed when we update the CLDR data.
// NOTE: These are UNSPECIFIED behavior in
// http://tc39.github.io/proposal-intl-relative-time/
// From Sample code in https://github.com/tc39/proposal-intl-relative-time#intlrelativetimeformatprototypeformattopartsvalue-unit
// // Format relative time using the day unit.
// rtf.formatToParts(-1, "day");
// // > [{ type: "literal", value: "yesterday"}]
let longAuto = new Intl.RelativeTimeFormat(
"en", {style: "long", localeMatcher: 'lookup', numeric: 'auto'});
var parts = longAuto.formatToParts(-1, "day");
assertEquals(1, parts.length);
assertEquals(2, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('literal', parts[0].type);
assertEquals('yesterday', parts[0].value);
// From Sample code in https://github.com/tc39/proposal-intl-relative-time#intlrelativetimeformatprototypeformattopartsvalue-unit
// rtf.formatToParts(100, "day");
// // > [{ type: "literal", value: "in " }, { type: "integer", value: "100", unit: "day" }, { type: "literal", value: " days" }]
let longAlways = new Intl.RelativeTimeFormat(
"en", {style: "long", localeMatcher: 'lookup', numeric: 'always'});
parts = longAlways.formatToParts(100, "day");
assertEquals(3, parts.length);
assertEquals(2, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('literal', parts[0].type);
assertEquals('in ', parts[0].value);
assertEquals(3, Object.getOwnPropertyNames(parts[1]).length);
assertEquals('integer', parts[1].type);
assertEquals('100', parts[1].value);
assertEquals('day', parts[1].unit);
assertEquals(2, Object.getOwnPropertyNames(parts[2]).length);
assertEquals('literal', parts[2].type);
assertEquals(' days', parts[2].value);
assertThrows(() => longAlways.format(NaN, 'second'), RangeError);
assertThrows(() => longAuto.format(NaN, 'second'), RangeError);
parts = longAlways.formatToParts(-10, "day");
assertEquals(2, parts.length);
assertEquals(3, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('integer', parts[0].type);
assertEquals('10', parts[0].value);
assertEquals('day', parts[0].unit);
assertEquals(2, Object.getOwnPropertyNames(parts[1]).length);
assertEquals('literal', parts[1].type);
assertEquals(' days ago', parts[1].value);
parts = longAlways.formatToParts(-0, "day");
assertEquals(2, parts.length);
assertEquals(3, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('integer', parts[0].type);
assertEquals('00', parts[0].value);
assertEquals('day', parts[0].unit);
assertEquals(2, Object.getOwnPropertyNames(parts[1]).length);
assertEquals('literal', parts[1].type);
assertEquals(' days ago', parts[1].value);
// 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
// Make sure that RelativeTimeFormat exposes all required properties. Those not specified
// should have undefined value.
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.4 Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'seconds')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'second')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'minutes')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'minute')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'hours')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'hour')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'days')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'day')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'weeks')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'week')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'months')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'month')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'quarters')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'quarter')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'years')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'year')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'seconds')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'second')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'minutes')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'minute')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'hours')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'hour')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'days')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'day')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'weeks')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'week')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'months')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'month')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'quarters')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'quarter')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'years')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'year')));
assertThrows(() => rtf.formatToParts(-1, 'decades'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'decade'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'centuries'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'century'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'milliseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'millisecond'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'microseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'microsecond'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'nanoseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'nanosecond'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'seconds'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'second'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'minutes'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'minute'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'hours'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'hour'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'days'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'day'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'weeks'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'week'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'months'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'month'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'years'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'year'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'quarters'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'quarter'), RangeError);
assertEquals(true, Array.isArray(rtf.formatToParts(100, 'day')));
rtf.formatToParts(100, 'day').forEach(function(part) {
assertEquals(true, part.type == 'literal' || part.type == 'integer');
assertEquals('string', typeof part.value);
if (part.type == 'integer') {
assertEquals('string', typeof part.unit);
}
});
// 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
// Make sure that RelativeTimeFormat exposes all required properties. Those not specified
// should have undefined value.
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.3 Intl.RelativeTimeFormat.prototype.format( value, unit )
assertEquals('string', typeof rtf.format(-1, 'seconds'));
assertEquals('string', typeof rtf.format(-1, 'second'));
assertEquals('string', typeof rtf.format(-1, 'minutes'));
assertEquals('string', typeof rtf.format(-1, 'minute'));
assertEquals('string', typeof rtf.format(-1, 'hours'));
assertEquals('string', typeof rtf.format(-1, 'hour'));
assertEquals('string', typeof rtf.format(-1, 'days'));
assertEquals('string', typeof rtf.format(-1, 'day'));
assertEquals('string', typeof rtf.format(-1, 'weeks'));
assertEquals('string', typeof rtf.format(-1, 'week'));
assertEquals('string', typeof rtf.format(-1, 'months'));
assertEquals('string', typeof rtf.format(-1, 'month'));
assertEquals('string', typeof rtf.format(-1, 'years'));
assertEquals('string', typeof rtf.format(-1, 'year'));
assertEquals('string', typeof rtf.format(-1, 'quarter'));
assertEquals('string', typeof rtf.format(-1, 'quarters'));
assertEquals('string', typeof rtf.format(-0, 'seconds'));
assertEquals('string', typeof rtf.format(-0, 'second'));
assertEquals('string', typeof rtf.format(-0, 'minutes'));
assertEquals('string', typeof rtf.format(-0, 'minute'));
assertEquals('string', typeof rtf.format(-0, 'hours'));
assertEquals('string', typeof rtf.format(-0, 'hour'));
assertEquals('string', typeof rtf.format(-0, 'days'));
assertEquals('string', typeof rtf.format(-0, 'day'));
assertEquals('string', typeof rtf.format(-0, 'weeks'));
assertEquals('string', typeof rtf.format(-0, 'week'));
assertEquals('string', typeof rtf.format(-0, 'months'));
assertEquals('string', typeof rtf.format(-0, 'month'));
assertEquals('string', typeof rtf.format(-0, 'years'));
assertEquals('string', typeof rtf.format(-0, 'year'));
assertEquals('string', typeof rtf.format(-0, 'quarter'));
assertEquals('string', typeof rtf.format(-0, 'quarters'));
assertThrows(() => rtf.format(NaN, 'seconds'), RangeError);
assertThrows(() => rtf.format(NaN, 'second'), RangeError);
assertThrows(() => rtf.format(NaN, 'minutes'), RangeError);
assertThrows(() => rtf.format(NaN, 'minute'), RangeError);
assertThrows(() => rtf.format(NaN, 'hours'), RangeError);
assertThrows(() => rtf.format(NaN, 'hour'), RangeError);
assertThrows(() => rtf.format(NaN, 'days'), RangeError);
assertThrows(() => rtf.format(NaN, 'day'), RangeError);
assertThrows(() => rtf.format(NaN, 'weeks'), RangeError);
assertThrows(() => rtf.format(NaN, 'week'), RangeError);
assertThrows(() => rtf.format(NaN, 'months'), RangeError);
assertThrows(() => rtf.format(NaN, 'month'), RangeError);
assertThrows(() => rtf.format(NaN, 'years'), RangeError);
assertThrows(() => rtf.format(NaN, 'year'), RangeError);
assertThrows(() => rtf.format(NaN, 'quarters'), RangeError);
assertThrows(() => rtf.format(NaN, 'quarter'), RangeError);
assertThrows(() => rtf.format(-1, 'decades'), RangeError);
assertThrows(() => rtf.format(-1, 'decade'), RangeError);
assertThrows(() => rtf.format(-1, 'centuries'), RangeError);
assertThrows(() => rtf.format(-1, 'century'), RangeError);
assertThrows(() => rtf.format(-1, 'milliseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'millisecond'), RangeError);
assertThrows(() => rtf.format(-1, 'microseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'microsecond'), RangeError);
assertThrows(() => rtf.format(-1, 'nanoseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'nanosecond'), RangeError);
assertEquals('string', typeof rtf.format(5, 'day'));
assertEquals('string', typeof rtf.format('5', 'day'));
assertEquals('string', typeof rtf.format('-5', 'day'));
assertEquals('string', typeof rtf.format('534', 'day'));
assertEquals('string', typeof rtf.format('-534', 'day'));
//assertThrows(() => rtf.format('xyz', 'day'), RangeError);
......@@ -475,12 +475,6 @@
'intl402/RelativeTimeFormat/constructor/supportedLocalesOf/length': [FAIL],
'intl402/RelativeTimeFormat/constructor/supportedLocalesOf/name': [FAIL],
'intl402/RelativeTimeFormat/constructor/supportedLocalesOf/prop-desc': [FAIL],
'intl402/RelativeTimeFormat/prototype/format/length': [FAIL],
'intl402/RelativeTimeFormat/prototype/format/name': [FAIL],
'intl402/RelativeTimeFormat/prototype/format/prop-desc': [FAIL],
'intl402/RelativeTimeFormat/prototype/formatToParts/length': [FAIL],
'intl402/RelativeTimeFormat/prototype/formatToParts/name': [FAIL],
'intl402/RelativeTimeFormat/prototype/formatToParts/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