From 3666d2132b49dfb090243356cbfc2fdf722dd87c Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Wed, 17 Nov 2021 09:37:53 +0000 Subject: [PATCH] LibJS: Remove fallback value for get_offset_nanoseconds_for This is a normative change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/664f02d Note that the tests are not comprehensive. --- .../Libraries/LibJS/Runtime/GlobalObject.cpp | 2 -- .../Libraries/LibJS/Runtime/GlobalObject.h | 2 -- .../LibJS/Runtime/Temporal/TimeZone.cpp | 18 +++++++----------- .../Temporal/Duration/Duration.compare.js | 8 ++++++++ .../Instant/Instant.prototype.toString.js | 7 +++++++ .../builtins/Temporal/Now/Now.plainDate.js | 8 ++++++++ .../builtins/Temporal/Now/Now.plainDateISO.js | 8 ++++++++ .../builtins/Temporal/Now/Now.plainDateTime.js | 8 ++++++++ .../Temporal/Now/Now.plainDateTimeISO.js | 8 ++++++++ .../builtins/Temporal/Now/Now.plainTimeISO.js | 8 ++++++++ .../Temporal/PlainDate/PlainDate.from.js | 9 +++++++++ .../PlainDateTime/PlainDateTime.from.js | 9 +++++++++ .../Temporal/PlainTime/PlainTime.from.js | 9 +++++++++ .../TimeZone.prototype.getPlainDateTimeFor.js | 9 +++++++++ .../ZonedDateTime.prototype.getISOFields.js | 7 +++++++ .../ZonedDateTime.prototype.offset.js | 7 +++++++ ...onedDateTime.prototype.offsetNanoseconds.js | 7 +++++++ .../ZonedDateTime.prototype.toJSON.js | 7 +++++++ .../ZonedDateTime.prototype.toLocaleString.js | 7 +++++++ .../ZonedDateTime.prototype.toString.js | 7 +++++++ 20 files changed, 140 insertions(+), 15 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index 8a4647c7f02..72fcf06ef59 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -275,7 +275,6 @@ void GlobalObject::initialize_global_object() m_array_prototype_values_function = &m_array_prototype->get_without_side_effects(vm.names.values).as_function(); m_eval_function = &get_without_side_effects(vm.names.eval).as_function(); - m_temporal_time_zone_prototype_get_offset_nanoseconds_for_function = &m_temporal_time_zone_prototype->get_without_side_effects(vm.names.getOffsetNanosecondsFor).as_function(); } GlobalObject::~GlobalObject() @@ -293,7 +292,6 @@ void GlobalObject::visit_edges(Visitor& visitor) visitor.visit(m_generator_object_prototype); visitor.visit(m_array_prototype_values_function); visitor.visit(m_eval_function); - visitor.visit(m_temporal_time_zone_prototype_get_offset_nanoseconds_for_function); visitor.visit(m_throw_type_error_function); #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.h b/Userland/Libraries/LibJS/Runtime/GlobalObject.h index ec95be6bc59..712f584c0b0 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.h @@ -39,7 +39,6 @@ public: FunctionObject* array_prototype_values_function() const { return m_array_prototype_values_function; } FunctionObject* eval_function() const { return m_eval_function; } - FunctionObject* temporal_time_zone_prototype_get_offset_nanoseconds_for_function() const { return m_temporal_time_zone_prototype_get_offset_nanoseconds_for_function; } FunctionObject* throw_type_error_function() const { return m_throw_type_error_function; } #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ @@ -105,7 +104,6 @@ private: FunctionObject* m_array_prototype_values_function { nullptr }; FunctionObject* m_eval_function { nullptr }; - FunctionObject* m_temporal_time_zone_prototype_get_offset_nanoseconds_for_function { nullptr }; FunctionObject* m_throw_type_error_function { nullptr }; #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index fb99452481e..2d67431569e 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -420,29 +420,25 @@ ThrowCompletionOr get_offset_nanoseconds_for(GlobalObject& global_object // 1. Let getOffsetNanosecondsFor be ? GetMethod(timeZone, "getOffsetNanosecondsFor"). auto* get_offset_nanoseconds_for = TRY(time_zone.get_method(global_object, vm.names.getOffsetNanosecondsFor)); - // 2. If getOffsetNanosecondsFor is undefined, set getOffsetNanosecondsFor to %Temporal.TimeZone.prototype.getOffsetNanosecondsFor%. - if (!get_offset_nanoseconds_for) - get_offset_nanoseconds_for = global_object.temporal_time_zone_prototype_get_offset_nanoseconds_for_function(); + // 2. Let offsetNanoseconds be ? Call(getOffsetNanosecondsFor, timeZone, « instant »). + auto offset_nanoseconds_value = TRY(call(global_object, get_offset_nanoseconds_for, time_zone, &instant)); - // 3. Let offsetNanoseconds be ? Call(getOffsetNanosecondsFor, timeZone, « instant »). - auto offset_nanoseconds_value = TRY(vm.call(*get_offset_nanoseconds_for, time_zone, &instant)); - - // 4. If Type(offsetNanoseconds) is not Number, throw a TypeError exception. + // 3. If Type(offsetNanoseconds) is not Number, throw a TypeError exception. if (!offset_nanoseconds_value.is_number()) return vm.throw_completion(global_object, ErrorType::IsNotA, "Offset nanoseconds value", "number"); - // 5. If ! IsIntegralNumber(offsetNanoseconds) is false, throw a RangeError exception. + // 4. If ! IsIntegralNumber(offsetNanoseconds) is false, throw a RangeError exception. if (!offset_nanoseconds_value.is_integral_number()) return vm.throw_completion(global_object, ErrorType::IsNotAn, "Offset nanoseconds value", "integral number"); - // 6. Set offsetNanoseconds to ℝ(offsetNanoseconds). + // 5. Set offsetNanoseconds to ℝ(offsetNanoseconds). auto offset_nanoseconds = offset_nanoseconds_value.as_double(); - // 7. If abs(offsetNanoseconds) > 86400 × 10^9, throw a RangeError exception. + // 6. If abs(offsetNanoseconds) > 86400 × 10^9, throw a RangeError exception. if (fabs(offset_nanoseconds) > 86400000000000.0) return vm.throw_completion(global_object, ErrorType::TemporalInvalidOffsetNanosecondsValue); - // 8. Return offsetNanoseconds. + // 7. Return offsetNanoseconds. return offset_nanoseconds; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.compare.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.compare.js index cf4fba699e9..aeaa3c2b0d8 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.compare.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.compare.js @@ -93,4 +93,12 @@ describe("errors", () => { "A starting point is required for balancing calendar units" ); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + const duration = new Temporal.Duration(); + expect(() => { + Temporal.Duration.compare(duration, duration, { relativeTo: zonedDateTime }); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.toString.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.toString.js index a9661c7c785..6f482e7a858 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.toString.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.prototype.toString.js @@ -62,4 +62,11 @@ describe("errors", () => { Temporal.Instant.prototype.toString.call("foo"); }).toThrowWithMessage(TypeError, "Not an object of type Temporal.Instant"); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const instant = new Temporal.Instant(0n); + expect(() => { + instant.toString({ timeZone: {} }); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDate.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDate.js index a9e2f4501e0..51092297ff3 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDate.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDate.js @@ -35,3 +35,11 @@ describe("correct behavior", () => { } }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + expect(() => { + Temporal.Now.plainDate({}, {}); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateISO.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateISO.js index ad70aedf4d9..c03eb4eccba 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateISO.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateISO.js @@ -33,3 +33,11 @@ describe("correct behavior", () => { } }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + expect(() => { + Temporal.Now.plainDateISO({}); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTime.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTime.js index 76392832951..cd51ccb4caf 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTime.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTime.js @@ -37,3 +37,11 @@ describe("correct behavior", () => { expect(Math.floor(differenceSeconds)).toBe(86400); }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + expect(() => { + Temporal.Now.plainDateTime({}, {}); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTimeISO.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTimeISO.js index 63eab856285..5bdef4f00c9 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTimeISO.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainDateTimeISO.js @@ -35,3 +35,11 @@ describe("correct behavior", () => { expect(Math.floor(differenceSeconds)).toBe(86400); }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + expect(() => { + Temporal.Now.plainDateTimeISO({}); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainTimeISO.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainTimeISO.js index bfdab226c5f..f4635b48e7e 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainTimeISO.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.plainTimeISO.js @@ -20,3 +20,11 @@ describe("correct behavior", () => { // FIXME: Compare these in a sensible way }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + expect(() => { + Temporal.Now.plainTimeISO({}); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js index 65198809616..8873f3e388c 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.from.js @@ -36,3 +36,12 @@ describe("correct behavior", () => { expect(createdPlainDate.day).toBe(26); }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + Temporal.PlainDate.from(zonedDateTime); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js index dcc0c733a8c..433aa60fb09 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.from.js @@ -170,3 +170,12 @@ describe("errors", () => { } }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + Temporal.PlainDateTime.from(zonedDateTime); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js index c0c1a2967ce..5aa7e2edad2 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.from.js @@ -48,3 +48,12 @@ describe("correct behavior", () => { expect(createdPlainTime.nanosecond).toBe(0); }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + Temporal.PlainTime.from(zonedDateTime); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getPlainDateTimeFor.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getPlainDateTimeFor.js index afe021d6a7c..470d61cd5d2 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getPlainDateTimeFor.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getPlainDateTimeFor.js @@ -49,3 +49,12 @@ describe("correct behavior", () => { expect(plainDateTime.nanosecond).toBe(123); }); }); + +describe("errors", () => { + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const instant = new Temporal.Instant(1n); + expect(() => { + Temporal.TimeZone.prototype.getPlainDateTimeFor.call({}, instant); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.getISOFields.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.getISOFields.js index 89394f694e4..d1dd1fca4dc 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.getISOFields.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.getISOFields.js @@ -46,4 +46,11 @@ describe("errors", () => { Temporal.ZonedDateTime.prototype.getISOFields.call("foo"); }).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime"); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + zonedDateTime.getISOFields(); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offset.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offset.js index bf3945bb792..0e29735ec30 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offset.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offset.js @@ -18,4 +18,11 @@ describe("errors", () => { Reflect.get(Temporal.ZonedDateTime.prototype, "offset", "foo"); }).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime"); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + zonedDateTime.offset; + }).toThrowWithMessage(TypeError, "null is not a function"); + }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offsetNanoseconds.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offsetNanoseconds.js index 1fe611c7299..3d72efe734f 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offsetNanoseconds.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.offsetNanoseconds.js @@ -18,4 +18,11 @@ describe("errors", () => { Reflect.get(Temporal.ZonedDateTime.prototype, "offsetNanoseconds", "foo"); }).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime"); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + zonedDateTime.offsetNanoseconds; + }).toThrowWithMessage(TypeError, "null is not a function"); + }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toJSON.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toJSON.js index 844038b815f..4d74eda9e60 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toJSON.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toJSON.js @@ -17,4 +17,11 @@ describe("errors", () => { Temporal.ZonedDateTime.prototype.toJSON.call("foo"); }).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime"); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + zonedDateTime.toJSON(); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toLocaleString.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toLocaleString.js index 78900608069..ba6c42fb2c0 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toLocaleString.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toLocaleString.js @@ -17,4 +17,11 @@ describe("errors", () => { Temporal.ZonedDateTime.prototype.toLocaleString.call("foo"); }).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime"); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + zonedDateTime.toLocaleString(); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); }); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toString.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toString.js index eb2f8938b86..dcf99a06562 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toString.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.toString.js @@ -96,4 +96,11 @@ describe("errors", () => { Temporal.ZonedDateTime.prototype.toString.call("foo"); }).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime"); }); + + test("custom time zone doesn't have a getOffsetNanosecondsFor function", () => { + const zonedDateTime = new Temporal.ZonedDateTime(0n, {}); + expect(() => { + zonedDateTime.toString(); + }).toThrowWithMessage(TypeError, "null is not a function"); + }); });