Bug 1403319 - Expose Intl.NumberFormat.prototype.formatToParts. r?andrebargull draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Wed, 27 Sep 2017 19:43:50 +0200
changeset 671835 9e4dfd09f7fbf71dfc69cd77bf9df9d29e297519
parent 669596 7e962631ba4298bcefa571008661983d77c3e652
child 733637 783ed9dcb6a278d77050c3406e4cb84ee3f995c0
push id82067
push userbmo:gandalf@aviary.pl
push dateThu, 28 Sep 2017 12:52:38 +0000
reviewersandrebargull
bugs1403319
milestone58.0a1
Bug 1403319 - Expose Intl.NumberFormat.prototype.formatToParts. r?andrebargull MozReview-Commit-ID: JBZ6SCLYkDt
js/src/builtin/Intl.cpp
js/src/jsapi.h
js/src/shell/js.cpp
js/src/tests/Intl/NumberFormat/formatToParts.js
js/src/tests/jstests.list
js/src/vm/CommonPropertyNames.h
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -1521,16 +1521,17 @@ numberFormat_toSource(JSContext* cx, uns
 
 static const JSFunctionSpec numberFormat_static_methods[] = {
     JS_SELF_HOSTED_FN("supportedLocalesOf", "Intl_NumberFormat_supportedLocalesOf", 1, 0),
     JS_FS_END
 };
 
 static const JSFunctionSpec numberFormat_methods[] = {
     JS_SELF_HOSTED_FN("resolvedOptions", "Intl_NumberFormat_resolvedOptions", 0, 0),
+    JS_SELF_HOSTED_FN("formatToParts", "Intl_NumberFormat_formatToParts", 1, 0),
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str, numberFormat_toSource, 0, 0),
 #endif
     JS_FS_END
 };
 
 static const JSPropertySpec numberFormat_properties[] = {
     JS_SELF_HOSTED_GET("format", "Intl_NumberFormat_format_get", 0),
@@ -1629,32 +1630,16 @@ CreateNumberFormatPrototype(JSContext* c
     // 11.4.4
     if (!JS_DefineFunctions(cx, proto, numberFormat_methods))
         return nullptr;
 
     // 11.4.2 and 11.4.3
     if (!JS_DefineProperties(cx, proto, numberFormat_properties))
         return nullptr;
 
-    // If the still-experimental NumberFormat.prototype.formatToParts method is
-    // enabled, also add it.
-    if (cx->compartment()->creationOptions().experimentalNumberFormatFormatToPartsEnabled()) {
-        RootedValue ftp(cx);
-        HandlePropertyName name = cx->names().formatToParts;
-        if (!GlobalObject::getSelfHostedFunction(cx, cx->global(),
-                                                 cx->names().NumberFormatFormatToParts,
-                                                 name, 1, &ftp))
-        {
-            return nullptr;
-        }
-
-        if (!DefineDataProperty(cx, proto, cx->names().formatToParts, ftp, 0))
-            return nullptr;
-    }
-
     // 8.1
     RootedValue ctorValue(cx, ObjectValue(*ctor));
     if (!DefineDataProperty(cx, Intl, cx->names().NumberFormat, ctorValue, 0))
         return nullptr;
 
     constructor.set(ctor);
     return proto;
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2437,17 +2437,16 @@ class JS_PUBLIC_API(CompartmentCreationO
       : addonId_(nullptr),
         traceGlobal_(nullptr),
         zoneSpec_(NewZoneInSystemZoneGroup),
         zonePointer_(nullptr),
         invisibleToDebugger_(false),
         mergeable_(false),
         preserveJitCode_(false),
         cloneSingletons_(false),
-        experimentalNumberFormatFormatToPartsEnabled_(false),
         sharedMemoryAndAtomics_(false),
         secureContext_(false)
     {}
 
     // A null add-on ID means that the compartment is not associated with an
     // add-on.
     JSAddonId* addonIdOrNull() const { return addonId_; }
     CompartmentCreationOptions& setAddonId(JSAddonId* id) {
@@ -2502,33 +2501,16 @@ class JS_PUBLIC_API(CompartmentCreationO
     }
 
     bool cloneSingletons() const { return cloneSingletons_; }
     CompartmentCreationOptions& setCloneSingletons(bool flag) {
         cloneSingletons_ = flag;
         return *this;
     }
 
-    // ECMA-402 is considering adding a "formatToParts" NumberFormat method,
-    // that exposes not just a formatted string but its subcomponents.  The
-    // method, its semantics, and its name aren't finalized, so for now it's
-    // exposed *only* if requested.
-    //
-    // Until "formatToParts" is included in a final specification edition, it's
-    // subject to change or removal at any time.  Do *not* rely on it in
-    // mission-critical code that can't be changed if ECMA-402 decides not to
-    // accept the method in its current form.
-    bool experimentalNumberFormatFormatToPartsEnabled() const {
-        return experimentalNumberFormatFormatToPartsEnabled_;
-    }
-    CompartmentCreationOptions& setExperimentalNumberFormatFormatToPartsEnabled(bool flag) {
-        experimentalNumberFormatFormatToPartsEnabled_ = flag;
-        return *this;
-    }
-
     bool getSharedMemoryAndAtomicsEnabled() const;
     CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
 
     // This flag doesn't affect JS engine behavior.  It is used by Gecko to
     // mark whether content windows and workers are "Secure Context"s. See
     // https://w3c.github.io/webappsec-secure-contexts/
     // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
     bool secureContext() const { return secureContext_; }
@@ -2541,17 +2523,16 @@ class JS_PUBLIC_API(CompartmentCreationO
     JSAddonId* addonId_;
     JSTraceOp traceGlobal_;
     ZoneSpecifier zoneSpec_;
     void* zonePointer_; // Per zoneSpec_, either a Zone, ZoneGroup, or null.
     bool invisibleToDebugger_;
     bool mergeable_;
     bool preserveJitCode_;
     bool cloneSingletons_;
-    bool experimentalNumberFormatFormatToPartsEnabled_;
     bool sharedMemoryAndAtomics_;
     bool secureContext_;
 };
 
 /**
  * CompartmentBehaviors specifies behaviors of a compartment that can be
  * changed after the compartment's been created.
  */
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4985,21 +4985,16 @@ NewGlobal(JSContext* cx, unsigned argc, 
         if (v.isBoolean())
             creationOptions.setInvisibleToDebugger(v.toBoolean());
 
         if (!JS_GetProperty(cx, opts, "cloneSingletons", &v))
             return false;
         if (v.isBoolean())
             creationOptions.setCloneSingletons(v.toBoolean());
 
-        if (!JS_GetProperty(cx, opts, "experimentalNumberFormatFormatToPartsEnabled", &v))
-            return false;
-        if (v.isBoolean())
-            creationOptions.setExperimentalNumberFormatFormatToPartsEnabled(v.toBoolean());
-
         if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
             return false;
         if (v.isObject())
             creationOptions.setExistingZone(UncheckedUnwrap(&v.toObject()));
 
         if (!JS_GetProperty(cx, opts, "disableLazyParsing", &v))
             return false;
         if (v.isBoolean())
--- a/js/src/tests/Intl/NumberFormat/formatToParts.js
+++ b/js/src/tests/Intl/NumberFormat/formatToParts.js
@@ -1,25 +1,20 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||typeof(newGlobal)!=="function"||!newGlobal({experimentalNumberFormatFormatToPartsEnabled:true}).Intl.NumberFormat().formatToParts)
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
 // Any copyright is dedicated to the Public Domain.
 // http://creativecommons.org/licenses/publicdomain/
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 1289882;
 var summary = "Implement Intl.NumberFormat.prototype.formatToParts";
 
 print(BUGNUMBER + ": " + summary);
 
 //-----------------------------------------------------------------------------
 
-// Once Intl.NumberFormat.prototype.formatToParts isn't feature-guarded, remove
-// this bit.
-assertEq(typeof newGlobal, "function");
-assertEq("formatToParts" in Intl.NumberFormat(), false);
-Intl = newGlobal({ experimentalNumberFormatFormatToPartsEnabled: true }).Intl;
 assertEq("formatToParts" in Intl.NumberFormat(), true);
 
 // NOTE: Some of these tests exercise standard behavior (e.g. that format and
 //       formatToParts expose the same formatted string).  But much of this,
 //       like the exact-formatted-string expectations, is technically
 //       implementation-dependent.  This is necessary as a practical matter to
 //       properly test the conversion from ICU's nested-field exposure to
 //       ECMA-402's sequential-parts exposure.
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -356,21 +356,17 @@ skip script test262/language/statements/
 skip script test262/language/statements/try/cptn-try.js
 skip script test262/language/statements/while/cptn-abrupt-empty.js
 skip script test262/language/statements/while/cptn-iter.js
 skip script test262/language/statements/while/cptn-no-iter.js
 skip script test262/language/statements/with/cptn-abrupt-empty.js
 skip script test262/language/statements/with/cptn-nrml.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1289882
-skip script test262/intl402/NumberFormat/prototype/formatToParts/formatToParts.js
 skip script test262/intl402/NumberFormat/prototype/formatToParts/length.js
-skip script test262/intl402/NumberFormat/prototype/formatToParts/main.js
-skip script test262/intl402/NumberFormat/prototype/formatToParts/name.js
-skip script test262/intl402/NumberFormat/prototype/formatToParts/return-abrupt-tonumber.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1296234
 skip script test262/intl402/Collator/prototype/compare/compare-function-name.js
 skip script test262/intl402/DateTimeFormat/prototype/format/format-function-name.js
 skip script test262/intl402/NumberFormat/prototype/format/format-function-name.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1317373
 skip script test262/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-existing-global-init.js
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -140,17 +140,16 @@
     macro(float32, float32, "float32") \
     macro(Float32x4, Float32x4, "Float32x4") \
     macro(float64, float64, "float64") \
     macro(Float64x2, Float64x2, "Float64x2") \
     macro(for, for_, "for") \
     macro(forceInterpreter, forceInterpreter, "forceInterpreter") \
     macro(forEach, forEach, "forEach") \
     macro(format, format, "format") \
-    macro(formatToParts, formatToParts, "formatToParts") \
     macro(fraction, fraction, "fraction") \
     macro(frame, frame, "frame") \
     macro(from, from, "from") \
     macro(fulfilled, fulfilled, "fulfilled") \
     macro(futexNotEqual, futexNotEqual, "not-equal") \
     macro(futexOK, futexOK, "ok") \
     macro(futexTimedOut, futexTimedOut, "timed-out") \
     macro(gcCycleNumber, gcCycleNumber, "gcCycleNumber") \
@@ -251,17 +250,16 @@
     macro(NFD, NFD, "NFD") \
     macro(NFKC, NFKC, "NFKC") \
     macro(NFKD, NFKD, "NFKD") \
     macro(noFilename, noFilename, "noFilename") \
     macro(nonincrementalReason, nonincrementalReason, "nonincrementalReason") \
     macro(noStack, noStack, "noStack") \
     macro(notes, notes, "notes") \
     macro(NumberFormat, NumberFormat, "NumberFormat") \
-    macro(NumberFormatFormatToParts, NumberFormatFormatToParts, "Intl_NumberFormat_formatToParts") \
     macro(numeric, numeric, "numeric") \
     macro(objectArguments, objectArguments, "[object Arguments]") \
     macro(objectArray, objectArray, "[object Array]") \
     macro(objectBoolean, objectBoolean, "[object Boolean]") \
     macro(objectDate, objectDate, "[object Date]") \
     macro(objectError, objectError, "[object Error]") \
     macro(objectFunction, objectFunction, "[object Function]") \
     macro(objectNull, objectNull, "[object Null]") \