Reland "[intl] Impl ECMA402 PR 471 rounding behavior"
This is a reland of 40af6aeebf
Change from the rollbacked version
- removes the passed test fixed by this PR in test/test262/test262.status
TBR=jkummerow@chromium.org
Original change's description:
> [intl] Impl ECMA402 PR 471 rounding behavior
>
> Fix awkward rounding behavior
> Change Intl::SetNumberFormatDigitOptions to fix the awkward rounding
> behavior in NumberFormat when formatting a currency with
> "maximumFractionDigits" set to a value less than 2.
>
> Bug: v8:10844
> Change-Id: I2ff4afa9f747cd79cb9964fe4c77a0dd2b8977b5
> Refs: https://github.com/tc39/ecma402/pull/471
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2442191
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Commit-Queue: Frank Tang <ftang@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70270}
Bug: v8:10844
Change-Id: Icfe7363f63d402abccc038e2b8bd78b38d0d9c49
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2444210
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70273}
This commit is contained in:
parent
894bf6df72
commit
940d11ecee
@ -24,6 +24,7 @@
|
||||
#include "src/objects/js-number-format-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/objects/property-descriptor.h"
|
||||
#include "src/objects/smi.h"
|
||||
#include "src/objects/string.h"
|
||||
#include "src/strings/string-case.h"
|
||||
#include "unicode/basictz.h"
|
||||
@ -1275,28 +1276,72 @@ Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions(
|
||||
|
||||
// 15. Else If mnfd is not undefined or mxfd is not undefined, then
|
||||
if (!mnfd_obj->IsUndefined(isolate) || !mxfd_obj->IsUndefined(isolate)) {
|
||||
// 15. b. Let mnfd be ? DefaultNumberOption(mnfd, 0, 20, mnfdDefault).
|
||||
Handle<String> mxfd_str = factory->maximumFractionDigits_string();
|
||||
Handle<String> mnfd_str = factory->minimumFractionDigits_string();
|
||||
if (!DefaultNumberOption(isolate, mnfd_obj, 0, 20, mnfd_default, mnfd_str)
|
||||
|
||||
int specified_mnfd;
|
||||
int specified_mxfd;
|
||||
|
||||
// a. Let _specifiedMnfd_ be ? DefaultNumberOption(_mnfd_, 0, 20,
|
||||
// *undefined*).
|
||||
if (!DefaultNumberOption(isolate, mnfd_obj, 0, 20, -1, mnfd_str)
|
||||
.To(&specified_mnfd)) {
|
||||
return Nothing<NumberFormatDigitOptions>();
|
||||
}
|
||||
Handle<Object> specifiedMnfd_obj;
|
||||
if (specified_mnfd < 0) {
|
||||
specifiedMnfd_obj = factory->undefined_value();
|
||||
} else {
|
||||
specifiedMnfd_obj = handle(Smi::FromInt(specified_mnfd), isolate);
|
||||
}
|
||||
|
||||
// b. Let _specifiedMxfd_ be ? DefaultNumberOption(_mxfd_, 0, 20,
|
||||
// *undefined*).
|
||||
if (!DefaultNumberOption(isolate, mxfd_obj, 0, 20, -1, mxfd_str)
|
||||
.To(&specified_mxfd)) {
|
||||
return Nothing<NumberFormatDigitOptions>();
|
||||
}
|
||||
Handle<Object> specifiedMxfd_obj;
|
||||
if (specified_mxfd < 0) {
|
||||
specifiedMxfd_obj = factory->undefined_value();
|
||||
} else {
|
||||
specifiedMxfd_obj = handle(Smi::FromInt(specified_mxfd), isolate);
|
||||
}
|
||||
|
||||
// c. If _specifiedMxfd_ is not *undefined*, set _mnfdDefault_ to
|
||||
// min(_mnfdDefault_, _specifiedMxfd_).
|
||||
if (specified_mxfd >= 0) {
|
||||
mnfd_default = std::min(mnfd_default, specified_mxfd);
|
||||
}
|
||||
|
||||
// d. Set _mnfd_ to ! DefaultNumberOption(_specifiedMnfd_, 0, 20,
|
||||
// _mnfdDefault_).
|
||||
if (!DefaultNumberOption(isolate, specifiedMnfd_obj, 0, 20, mnfd_default,
|
||||
mnfd_str)
|
||||
.To(&mnfd)) {
|
||||
return Nothing<NumberFormatDigitOptions>();
|
||||
}
|
||||
|
||||
// 15. c. Let mxfdActualDefault be max( mnfd, mxfdDefault ).
|
||||
int mxfd_actual_default = std::max(mnfd, mxfd_default);
|
||||
|
||||
// 15. d. Let mxfd be ? DefaultNumberOption(mxfd, mnfd, 20,
|
||||
// mxfdActualDefault).
|
||||
Handle<String> mxfd_str = factory->maximumFractionDigits_string();
|
||||
if (!DefaultNumberOption(isolate, mxfd_obj, mnfd, 20, mxfd_actual_default,
|
||||
mxfd_str)
|
||||
// e. Set _mxfd_ to ! DefaultNumberOption(_specifiedMxfd_, 0, 20,
|
||||
// max(_mxfdDefault_, _mnfd_)).
|
||||
if (!DefaultNumberOption(isolate, specifiedMxfd_obj, 0, 20,
|
||||
std::max(mxfd_default, mnfd), mxfd_str)
|
||||
.To(&mxfd)) {
|
||||
return Nothing<NumberFormatDigitOptions>();
|
||||
}
|
||||
// 15. e. Set intlObj.[[MinimumFractionDigits]] to mnfd.
|
||||
|
||||
// f. If _mnfd_ is greater than _mxfd_, throw a *RangeError* exception.
|
||||
if (mnfd > mxfd) {
|
||||
THROW_NEW_ERROR_RETURN_VALUE(
|
||||
isolate,
|
||||
NewRangeError(MessageTemplate::kPropertyValueOutOfRange, mxfd_str),
|
||||
Nothing<NumberFormatDigitOptions>());
|
||||
}
|
||||
|
||||
// g. Set intlObj.[[MinimumFractionDigits]] to mnfd.
|
||||
digit_options.minimum_fraction_digits = mnfd;
|
||||
|
||||
// 15. f. Set intlObj.[[MaximumFractionDigits]] to mxfd.
|
||||
// h. Set intlObj.[[MaximumFractionDigits]] to mxfd.
|
||||
digit_options.maximum_fraction_digits = mxfd;
|
||||
// Else If intlObj.[[Notation]] is "compact", then
|
||||
} else if (notation_is_compact) {
|
||||
|
@ -55,3 +55,12 @@ nf = new Intl.NumberFormat('en', {maximumFractionDigits: 3, style: 'currency', c
|
||||
assertEquals("$54,306.405", nf.format(54306.4047970));
|
||||
assertEquals("$54,306.40", nf.format(54306.4));
|
||||
assertEquals("$54,306.00", nf.format(54306));
|
||||
|
||||
nf = new Intl.NumberFormat('en', {maximumFractionDigits: 0, style: 'currency', currency: 'USD'});
|
||||
|
||||
assertEquals("$54,306", nf.format(54306.4047970));
|
||||
assertEquals("$54,306", nf.format(54306.4));
|
||||
assertEquals("$54,306", nf.format(54306));
|
||||
|
||||
assertThrows(() => new Intl.NumberFormat('en',
|
||||
{minimumFractionDigits: 1, maximumFractionDigits: 0, style: 'currency', currency: 'USD'}));
|
||||
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: ECMA-402 #sec-setnfdigitoptions
|
||||
description: >
|
||||
When a currency is used in Intl.NumberFormat and minimumFractionDigits is
|
||||
not provided, maximumFractionDigits should be range-checked against it.
|
||||
include: [assert.js]
|
||||
---*/
|
||||
|
||||
assert.throws(RangeError,
|
||||
() => new Intl.NumberFormat('en', {
|
||||
style: 'currency',
|
||||
currency: 'USD',
|
||||
maximumFractionDigits: 1
|
||||
}));
|
@ -533,9 +533,6 @@
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=7472
|
||||
'intl402/NumberFormat/currency-digits': [FAIL],
|
||||
|
||||
# http://crbug/v8/10844
|
||||
'intl402/NumberFormat/dft-currency-mnfd-range-check-mxfd': [FAIL],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=7831
|
||||
'language/statements/generators/generator-created-after-decl-inst': [FAIL],
|
||||
'language/expressions/generators/generator-created-after-decl-inst': [FAIL],
|
||||
|
Loading…
Reference in New Issue
Block a user