Skip to content

Commit

Permalink
Store strings or objects in Temporal objects' [[Calendar]] slot
Browse files Browse the repository at this point in the history
In several tests involving custom calendars, we need to change the
implementation of dateFromFields/monthDayFromFields/yearMonthFromFields so
that the returned object gets the receiver as its calendar after chaining
up to the builtin implementation.

Normative PR: tc39/proposal-temporal#2482
  • Loading branch information
ptomato committed Feb 17, 2023
1 parent 4dda712 commit 3204783
Show file tree
Hide file tree
Showing 141 changed files with 3,116 additions and 166 deletions.
20 changes: 19 additions & 1 deletion harness/temporalHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,20 @@ var TemporalHelpers = {
super("iso8601");
}

dateFromFields(...args) {
return super.dateFromFields(...args).withCalendar(this);
}

monthDayFromFields(...args) {
const { isoYear, isoMonth, isoDay } = super.monthDayFromFields(...args).getISOFields();
return new Temporal.PlainMonthDay(isoMonth, isoDay, this, isoYear);
}

yearMonthFromFields(...args) {
const { isoYear, isoMonth, isoDay } = super.yearMonthFromFields(...args).getISOFields();
return new Temporal.PlainYearMonth(isoYear, isoMonth, this, isoDay);
}

toString() {
return "fast-path-check";
}
Expand Down Expand Up @@ -1059,13 +1073,17 @@ var TemporalHelpers = {
return "dateadd-plain-date-instance";
}

dateFromFields(...args) {
return super.dateFromFields(...args).withCalendar(this);
}

dateAdd(date, duration, options) {
this.dateAddCallCount++;
assert(date instanceof Temporal.PlainDate, "dateAdd() should be called with a PlainDate instance");
if (this.dateAddCallCount === 1 && this.specificPlainDate) {
assert.sameValue(date, this.specificPlainDate, `dateAdd() should be called first with the specific PlainDate instance ${this.specificPlainDate}`);
}
return super.dateAdd(date, duration, options);
return super.dateAdd(date, duration, options).withCalendar(this);
}
}
return new CalendarDateAddPlainDateInstance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");
Object.defineProperty(instance, "dateFromFields", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateFromFields should not be looked up on receiver");
},
});

const calendar = "iso8601";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.duration.compare
description: >
Builtin dateFromFields method is not observably called when the property bag
has a string-valued calendar property
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields");
Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateFromFields should not be looked up");
},
});

const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
Temporal.Duration.compare(new Temporal.Duration(), new Temporal.Duration(), { relativeTo });

Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.duration.prototype.add
description: >
Builtin dateFromFields method is not observably called when the property bag
has a string-valued calendar property
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields");
Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateFromFields should not be looked up");
},
});

const instance = new Temporal.Duration(1, 0, 0, 1);
const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo });

Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.duration.prototype.round
description: >
Builtin dateFromFields method is not observably called when the property bag
has a string-valued calendar property
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields");
Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateFromFields should not be looked up");
},
});

const instance = new Temporal.Duration(1, 0, 0, 0, 24);
const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.round({ largestUnit: "years", relativeTo });

Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.duration.prototype.subtract
description: >
Builtin dateFromFields method is not observably called when the property bag
has a string-valued calendar property
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields");
Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateFromFields should not be looked up");
},
});

const instance = new Temporal.Duration(1, 0, 0, 1);
const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.subtract(new Temporal.Duration(0, 0, 0, 0, 24), { relativeTo });

Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.duration.prototype.total
description: >
Builtin dateFromFields method is not observably called when the property bag
has a string-valued calendar property
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields");
Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateFromFields should not be looked up");
},
});

const instance = new Temporal.Duration(1, 0, 0, 0, 24);
const relativeTo = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.total({ unit: "days", relativeTo });

Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.instant.prototype.tozoneddatetimeiso
description: >
toZonedDateTimeISO() results in a ZonedDateTime with builtin ISO calendar
features: [Temporal]
---*/

const instance = new Temporal.Instant(0n);
const result = instance.toZonedDateTimeISO("UTC");
assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string");
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@
/*---
esid: sec-temporal.plaindate.compare
description: A calendar ID is valid input for Calendar
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dateFromFieldsOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateFromFields");
Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateFromFields should not be looked up");
},
});

const calendar = "iso8601";

const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
Expand All @@ -16,3 +26,5 @@ assert.sameValue(result1, 0, `Calendar created from string "${arg}" (first argum

const result2 = Temporal.PlainDate.compare(new Temporal.PlainDate(1976, 11, 18), arg);
assert.sameValue(result2, 0, `Calendar created from string "${arg}" (second argument)`);

Object.defineProperty(Temporal.Calendar.prototype, "dateFromFields", dateFromFieldsOriginal);
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ const calendar = "iso8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = Temporal.PlainDate.from(arg);
TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, `Calendar created from string "${calendar}"`);
assert.sameValue(result.getISOFields().calendar, "iso8601", "calendar slot stores a string");
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.plaindate.prototype.add
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dateAddOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dateAdd");
Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dateAdd should not be looked up");
},
});

const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601");
instance.add(new Temporal.Duration(1));

Object.defineProperty(Temporal.Calendar.prototype, "dateAdd", dateAddOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.plaindate.prototype.calendarid
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id");
Object.defineProperty(Temporal.Calendar.prototype, "id", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("id should not be looked up");
},
});

const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601");
instance.calendarId;

Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.plaindate.prototype.day
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dayOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "day");
Object.defineProperty(Temporal.Calendar.prototype, "day", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("day should not be looked up");
},
});

const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601");
instance.day;

Object.defineProperty(Temporal.Calendar.prototype, "day", dayOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.plaindate.prototype.dayofweek
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dayOfWeekOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfWeek");
Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dayOfWeek should not be looked up");
},
});

const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601");
instance.dayOfWeek;

Object.defineProperty(Temporal.Calendar.prototype, "dayOfWeek", dayOfWeekOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.plaindate.prototype.dayofyear
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const dayOfYearOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "dayOfYear");
Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("dayOfYear should not be looked up");
},
});

const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601");
instance.dayOfYear;

Object.defineProperty(Temporal.Calendar.prototype, "dayOfYear", dayOfYearOriginal);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.plaindate.prototype.daysinmonth
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const daysInMonthOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "daysInMonth");
Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("daysInMonth should not be looked up");
},
});

const instance = new Temporal.PlainDate(2000, 5, 2, "iso8601");
instance.daysInMonth;

Object.defineProperty(Temporal.Calendar.prototype, "daysInMonth", daysInMonthOriginal);
Loading

0 comments on commit 3204783

Please sign in to comment.