Title: [195330] trunk
Revision
195330
Author
[email protected]
Date
2016-01-19 17:07:34 -0800 (Tue, 19 Jan 2016)

Log Message

[INTL] Implement Date.prototype.toLocaleDateString in ECMA-402
https://bugs.webkit.org/show_bug.cgi?id=147612

Patch by Andy VanWagoner <[email protected]> on 2016-01-19
Reviewed by Benjamin Poulain.

Source/_javascript_Core:

Implement toLocaleDateString in builtin _javascript_. Remove comments with
spec steps, and instead link to the new HTML version of the spec.

Avoids creating an extra empty object in the prototype chain of the options
object in ToDateTimeOptions. The version used in toLocaleString was updated
to match as well.

* builtins/DatePrototype.js:
(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):
(toLocaleDateString.toDateTimeOptionsDateDate):
(toLocaleDateString):
* runtime/DatePrototype.cpp:
(JSC::DatePrototype::finishCreation):

LayoutTests:

Added tests for toLocaleDateString.

* js/date-toLocaleString-expected.txt:
* js/script-tests/date-toLocaleString.js:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (195329 => 195330)


--- trunk/LayoutTests/ChangeLog	2016-01-20 01:05:29 UTC (rev 195329)
+++ trunk/LayoutTests/ChangeLog	2016-01-20 01:07:34 UTC (rev 195330)
@@ -1,3 +1,15 @@
+2016-01-19  Andy VanWagoner  <[email protected]>
+
+        [INTL] Implement Date.prototype.toLocaleDateString in ECMA-402
+        https://bugs.webkit.org/show_bug.cgi?id=147612
+
+        Reviewed by Benjamin Poulain.
+
+        Added tests for toLocaleDateString.
+
+        * js/date-toLocaleString-expected.txt:
+        * js/script-tests/date-toLocaleString.js:
+
 2016-01-19  Brady Eidson  <[email protected]>
 
         Modern IDB: Split all storage/indexeddb/modern tests into separate HTML + JS format.

Modified: trunk/LayoutTests/js/date-toLocaleString-expected.txt (195329 => 195330)


--- trunk/LayoutTests/js/date-toLocaleString-expected.txt	2016-01-20 01:05:29 UTC (rev 195329)
+++ trunk/LayoutTests/js/date-toLocaleString-expected.txt	2016-01-20 01:07:34 UTC (rev 195330)
@@ -26,6 +26,29 @@
 PASS new Date(0).toLocaleString('en', null) threw exception TypeError: null is not an object.
 PASS new Date(0).toLocaleString('en', { timeZone: 'UTC', hour:'numeric', minute:'2-digit' }) is "12:00 AM"
 PASS new Date(0).toLocaleString('en', { timeZone: 'UTC', year:'numeric', month:'long' }) is "January 1970"
+PASS Date.prototype.toLocaleDateString.length is 0
+PASS Object.getOwnPropertyDescriptor(Date.prototype, 'toLocaleDateString').enumerable is false
+PASS Object.getOwnPropertyDescriptor(Date.prototype, 'toLocaleDateString').configurable is true
+PASS Object.getOwnPropertyDescriptor(Date.prototype, 'toLocaleDateString').writable is true
+PASS Date.prototype.toLocaleDateString.call(new Date) did not throw exception.
+PASS Date.prototype.toLocaleDateString.call() threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call(undefined) threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call(null) threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call(0) threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call(NaN) threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call(Infinity) threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call('1') threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call({}) threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call([]) threw exception TypeError: Type error.
+PASS Date.prototype.toLocaleDateString.call(Symbol()) threw exception TypeError: Type error.
+PASS typeof new Date().toLocaleDateString() === 'string' is true
+PASS new Date(NaN).toLocaleDateString() is "Invalid Date"
+PASS new Date().toLocaleDateString('i') threw exception RangeError: invalid language tag: i.
+PASS new Date(0).toLocaleDateString('zh-Hans-CN-u-nu-hanidec', { timeZone: 'UTC' }) is "一九七〇/一/一"
+PASS new Date(0).toLocaleDateString('en', { timeZone: 'UTC' }) is "1/1/1970"
+PASS new Date(0).toLocaleDateString('en', null) threw exception TypeError: null is not an object.
+PASS new Date(0).toLocaleDateString('en', { timeZone: 'UTC', hour:'numeric', minute:'2-digit' }) is "1/1/1970, 12:00 AM"
+PASS new Date(0).toLocaleDateString('en', { timeZone: 'UTC', year:'numeric', month:'long' }) is "January 1970"
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/js/script-tests/date-toLocaleString.js (195329 => 195330)


--- trunk/LayoutTests/js/script-tests/date-toLocaleString.js	2016-01-20 01:05:29 UTC (rev 195329)
+++ trunk/LayoutTests/js/script-tests/date-toLocaleString.js	2016-01-20 01:07:34 UTC (rev 195330)
@@ -35,3 +35,40 @@
 shouldBeEqualToString("new Date(0).toLocaleString('en', { timeZone: 'UTC', hour:'numeric', minute:'2-digit' })", "12:00 AM");
 shouldBeEqualToString("new Date(0).toLocaleString('en', { timeZone: 'UTC', year:'numeric', month:'long' })", "January 1970");
 
+// Test toLocaleDateString ()
+shouldBe("Date.prototype.toLocaleDateString.length", "0");
+shouldBeFalse("Object.getOwnPropertyDescriptor(Date.prototype, 'toLocaleDateString').enumerable");
+shouldBeTrue("Object.getOwnPropertyDescriptor(Date.prototype, 'toLocaleDateString').configurable");
+shouldBeTrue("Object.getOwnPropertyDescriptor(Date.prototype, 'toLocaleDateString').writable");
+
+// Test thisTimeValue abrupt completion.
+shouldNotThrow("Date.prototype.toLocaleDateString.call(new Date)");
+shouldThrow("Date.prototype.toLocaleDateString.call()");
+shouldThrow("Date.prototype.toLocaleDateString.call(undefined)");
+shouldThrow("Date.prototype.toLocaleDateString.call(null)");
+shouldThrow("Date.prototype.toLocaleDateString.call(0)");
+shouldThrow("Date.prototype.toLocaleDateString.call(NaN)");
+shouldThrow("Date.prototype.toLocaleDateString.call(Infinity)");
+shouldThrow("Date.prototype.toLocaleDateString.call('1')");
+shouldThrow("Date.prototype.toLocaleDateString.call({})");
+shouldThrow("Date.prototype.toLocaleDateString.call([])");
+shouldThrow("Date.prototype.toLocaleDateString.call(Symbol())");
+
+shouldBeTrue("typeof new Date().toLocaleDateString() === 'string'");
+
+shouldBeEqualToString("new Date(NaN).toLocaleDateString()", "Invalid Date");
+
+// Test for DateTimeFormat behavior.
+// Test that locale parameter is passed through properly.
+shouldThrow("new Date().toLocaleDateString('i')");
+shouldBeEqualToString("new Date(0).toLocaleDateString('zh-Hans-CN-u-nu-hanidec', { timeZone: 'UTC' })", "一九七〇/一/一");
+
+// Defaults to mdy
+shouldBeEqualToString("new Date(0).toLocaleDateString('en', { timeZone: 'UTC' })", "1/1/1970");
+
+// Test that options parameter is passed through properly.
+shouldThrow("new Date(0).toLocaleDateString('en', null)", "'TypeError: null is not an object'");
+// Adds mdy if no date formats specified.
+shouldBeEqualToString("new Date(0).toLocaleDateString('en', { timeZone: 'UTC', hour:'numeric', minute:'2-digit' })", "1/1/1970, 12:00 AM");
+// If any date formats specified, just use them.
+shouldBeEqualToString("new Date(0).toLocaleDateString('en', { timeZone: 'UTC', year:'numeric', month:'long' })", "January 1970");

Modified: trunk/Source/_javascript_Core/ChangeLog (195329 => 195330)


--- trunk/Source/_javascript_Core/ChangeLog	2016-01-20 01:05:29 UTC (rev 195329)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-01-20 01:07:34 UTC (rev 195330)
@@ -1,3 +1,25 @@
+2016-01-19  Andy VanWagoner  <[email protected]>
+
+        [INTL] Implement Date.prototype.toLocaleDateString in ECMA-402
+        https://bugs.webkit.org/show_bug.cgi?id=147612
+
+        Reviewed by Benjamin Poulain.
+
+        Implement toLocaleDateString in builtin _javascript_. Remove comments with
+        spec steps, and instead link to the new HTML version of the spec.
+
+        Avoids creating an extra empty object in the prototype chain of the options
+        object in ToDateTimeOptions. The version used in toLocaleString was updated
+        to match as well.
+
+        * builtins/DatePrototype.js:
+        (toLocaleString.toDateTimeOptionsAnyAll):
+        (toLocaleString):
+        (toLocaleDateString.toDateTimeOptionsDateDate):
+        (toLocaleDateString):
+        * runtime/DatePrototype.cpp:
+        (JSC::DatePrototype::finishCreation):
+
 2016-01-19  Benjamin Poulain  <[email protected]>
 
         [JSC] fixSpillSlotZDef() crashes on ARM64

Modified: trunk/Source/_javascript_Core/builtins/DatePrototype.js (195329 => 195330)


--- trunk/Source/_javascript_Core/builtins/DatePrototype.js	2016-01-20 01:05:29 UTC (rev 195329)
+++ trunk/Source/_javascript_Core/builtins/DatePrototype.js	2016-01-20 01:07:34 UTC (rev 195330)
@@ -31,54 +31,31 @@
 
     function toDateTimeOptionsAnyAll(opts)
     {
-        // ToDateTimeOptions abstract operation (ECMA-402 2.0)
-        // http://ecma-international.org/publications/standards/Ecma-402.htm
+        // ToDateTimeOptions(options, "any", "all")
+        // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
 
-        // 1. If options is undefined, then let options be null, else let options be ToObject(options).
-        // 2. ReturnIfAbrupt(options).
-        var optObj;
+        var options;
         if (opts === undefined)
-            optObj = null;
+            options = null;
         else if (opts === null)
             throw new @TypeError("null is not an object");
         else
-            optObj = @Object(opts);
+            options = @Object(opts);
 
-        // 3. Let options be ObjectCreate(options).
-        var options = @Object.create(optObj);
-
-        // 4. Let needDefaults be true.
-        // 5. If required is "date" or "any",
-        // a. For each of the property names "weekday", "year", "month", "day":
-        // i. Let prop be the property name.
-        // ii. Let value be Get(options, prop).
-        // iii. ReturnIfAbrupt(value).
-        // iv. If value is not undefined, then let needDefaults be false.
-        // 6. If required is "time" or "any",
-        // a. For each of the property names "hour", "minute", "second":
-        // i. Let prop be the property name.
-        // ii. Let value be Get(options, prop).
-        // iii. ReturnIfAbrupt(value).
-        // iv. If value is not undefined, then let needDefaults be false.
-        // Check optObj instead of options to reduce lookups up the prototype chain.
-        var needsDefaults = !optObj || (
-            optObj.weekday === undefined &&
-            optObj.year === undefined &&
-            optObj.month === undefined &&
-            optObj.day === undefined &&
-            optObj.hour === undefined &&
-            optObj.minute === undefined &&
-            optObj.second === undefined
+        // Check original instead of descendant to reduce lookups up the prototype chain.
+        var needsDefaults = !options || (
+            options.weekday === undefined &&
+            options.year === undefined &&
+            options.month === undefined &&
+            options.day === undefined &&
+            options.hour === undefined &&
+            options.minute === undefined &&
+            options.second === undefined
         );
 
-        // 7. If needDefaults is true and defaults is either "date" or "all", then a. For each of the property names "year", "month", "day":
-        // i. Let status be CreateDatePropertyOrThrow(options, prop, "numeric").
-        // ii. ReturnIfAbrupt(status).
-        // 8. If needDefaults is true and defaults is either "time" or "all", then
-        // a. For each of the property names "hour", "minute", "second":
-        // i. Let status be CreateDatePropertyOrThrow(options, prop, "numeric").
-        // ii. ReturnIfAbrupt(status).
+        // Only create descendant if it will have own properties.
         if (needsDefaults) {
+            options = @Object.create(options)
             options.year = "numeric";
             options.month = "numeric";
             options.day = "numeric";
@@ -92,25 +69,65 @@
     }
 
     // 13.3.1 Date.prototype.toLocaleString ([locales [, options ]]) (ECMA-402 2.0)
-    // http://ecma-international.org/publications/standards/Ecma-402.htm
+    // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleString
 
-    // 1. Let x be thisTimeValue(this value).
-    // 2. ReturnIfAbrupt(x).
     var value = @thisTimeValue.@call(this);
-
-    // 3. If x is NaN, return "Invalid Date".
     if (@isNaN(value))
         return "Invalid Date";
 
-    // 4. Let options be ToDateTimeOptions(options, "any", "all").
-    // 5. ReturnIfAbrupt(options).
     var options = toDateTimeOptionsAnyAll(arguments[1]);
+    var locales = arguments[0];
 
-    // 6. Let dateFormat be Construct(%DateTimeFormat%, «locales, options»).
-    // 7. ReturnIfAbrupt(dateFormat).
+    var dateFormat = new @DateTimeFormat(locales, options);
+    return dateFormat.format(value);
+}
+
+function toLocaleDateString(/* locales, options */)
+{
+    "use strict";
+
+    function toDateTimeOptionsDateDate(opts)
+    {
+        // ToDateTimeOptions(options, "date", "date")
+        // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
+
+        var options;
+        if (opts === undefined)
+            options = null;
+        else if (opts === null)
+            throw new @TypeError("null is not an object");
+        else
+            options = @Object(opts);
+
+        // Check original instead of descendant to reduce lookups up the prototype chain.
+        var needsDefaults = !options || (
+            options.weekday === undefined &&
+            options.year === undefined &&
+            options.month === undefined &&
+            options.day === undefined
+        );
+
+        // Only create descendant if it will have own properties.
+        if (needsDefaults) {
+            options = @Object.create(options)
+            options.year = "numeric";
+            options.month = "numeric";
+            options.day = "numeric";
+        }
+
+        return options;
+    }
+
+    // 13.3.2 Date.prototype.toLocaleDateString ([locales [, options ]]) (ECMA-402 2.0)
+    // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleDateString
+
+    var value = @thisTimeValue.@call(this);
+    if (@isNaN(value))
+        return "Invalid Date";
+
+    var options = toDateTimeOptionsDateDate(arguments[1]);
     var locales = arguments[0];
+
     var dateFormat = new @DateTimeFormat(locales, options);
-
-    // 8. Return FormatDateTime(dateFormat, x).
     return dateFormat.format(value);
 }

Modified: trunk/Source/_javascript_Core/runtime/DatePrototype.cpp (195329 => 195330)


--- trunk/Source/_javascript_Core/runtime/DatePrototype.cpp	2016-01-20 01:05:29 UTC (rev 195329)
+++ trunk/Source/_javascript_Core/runtime/DatePrototype.cpp	2016-01-20 01:07:34 UTC (rev 195330)
@@ -493,6 +493,7 @@
 
 #if ENABLE(INTL)
     JSC_BUILTIN_FUNCTION("toLocaleString", datePrototypeToLocaleStringCodeGenerator, DontEnum);
+    JSC_BUILTIN_FUNCTION("toLocaleDateString", datePrototypeToLocaleDateStringCodeGenerator, DontEnum);
 #else
     UNUSED_PARAM(globalObject);
 #endif // ENABLE(INTL)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to