Skip to content

Commit 298abe0

Browse files
ptomatoMs2ger
authored andcommitted
Reorganize from() to clone the object
Each type's from() method now calls a new abstract operation, ToFooRecord, which takes a property bag (which can be the actual type) and returns a Record with the appropriate slots. If the argument isn't an object, then from() calls ParseFooString directly. We delete the FooFromString operations, and in most cases the ToFoo operations unless there is a method somewhere in the API that actually needs the casting behaviour (including returning the original object if it's of the correct type.) Reorganizes the abstract operations in the polyfill to match the abstract operations in the spec a bit more. Effectively, this makes Temporal.Foo.from(aFoo) clone the object instead of returning the same object. Closes: #232.
1 parent 6ce0154 commit 298abe0

25 files changed

+489
-320
lines changed

polyfill/lib/absolute.mjs

+7-3
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,13 @@ export class Absolute {
171171
return result;
172172
}
173173
static from(item) {
174-
const absolute = ES.ToTemporalAbsolute(item);
175-
if (this === Absolute) return absolute;
176-
const result = new this(GetSlot(absolute, EPOCHNANOSECONDS).value);
174+
let absolute;
175+
if (ES.IsAbsolute(item)) {
176+
absolute = GetSlot(item, EPOCHNANOSECONDS).value;
177+
} else {
178+
absolute = ES.TemporalAbsoluteFromString(ES.ToString(item));
179+
}
180+
const result = new this(absolute);
177181
if (!ES.IsTemporalAbsolute(result)) throw new TypeError('invalid result');
178182
return result;
179183
}

polyfill/lib/date.mjs

+12-4
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class Date {
7171
with(temporalDateLike = {}, options) {
7272
if (!ES.IsTemporalDate(this)) throw new TypeError('invalid receiver');
7373
const disambiguation = ES.ToTemporalDisambiguation(options);
74-
const props = ES.ValidPropertyBag(temporalDateLike, ['year', 'month', 'day']);
74+
const props = ES.ToPartialRecord(temporalDateLike, ['year', 'month', 'day']);
7575
if (!props) {
7676
throw new RangeError('invalid date-like');
7777
}
@@ -170,9 +170,17 @@ export class Date {
170170
}
171171
static from(item, options = undefined) {
172172
const disambiguation = ES.ToTemporalDisambiguation(options);
173-
let result = ES.ToTemporalDate(item, disambiguation);
174-
if (this === Date) return result;
175-
return new this(GetSlot(result, YEAR), GetSlot(result, MONTH), GetSlot(result, DAY));
173+
let year, month, day;
174+
if (typeof item === 'object' && item) {
175+
// Intentionally alphabetical
176+
({ year, month, day } = ES.ToRecord(item, ['day', 'month', 'year']));
177+
} else {
178+
({ year, month, day } = ES.ParseDateString(ES.ToString(item)));
179+
}
180+
({ year, month, day } = ES.RegulateDate(year, month, day, disambiguation));
181+
const result = new this(year, month, day);
182+
if (!ES.IsDate(result)) throw new TypeError('invalid result');
183+
return result;
176184
}
177185
static compare(one, two) {
178186
if (!ES.IsTemporalDate(one) || !ES.IsTemporalDate(two)) throw new TypeError('invalid Date object');

polyfill/lib/datetime.mjs

+34-14
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export class DateTime {
102102
with(temporalDateTimeLike, options) {
103103
if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver');
104104
const disambiguation = ES.ToTemporalDisambiguation(options);
105-
const props = ES.ValidPropertyBag(temporalDateTimeLike, [
105+
const props = ES.ToPartialRecord(temporalDateTimeLike, [
106106
'year',
107107
'month',
108108
'day',
@@ -316,19 +316,39 @@ export class DateTime {
316316

317317
static from(item, options = undefined) {
318318
const disambiguation = ES.ToTemporalDisambiguation(options);
319-
let result = ES.ToTemporalDateTime(item, disambiguation);
320-
if (this === DateTime) return result;
321-
return new this(
322-
GetSlot(result, YEAR),
323-
GetSlot(result, MONTH),
324-
GetSlot(result, DAY),
325-
GetSlot(result, HOUR),
326-
GetSlot(result, MINUTE),
327-
GetSlot(result, SECOND),
328-
GetSlot(result, MILLISECOND),
329-
GetSlot(result, MICROSECOND),
330-
GetSlot(result, NANOSECOND)
331-
);
319+
let year, month, day, hour, minute, second, millisecond, microsecond, nanosecond;
320+
if (typeof item === 'object' && item) {
321+
({
322+
year,
323+
month,
324+
day,
325+
hour = 0,
326+
minute = 0,
327+
second = 0,
328+
millisecond = 0,
329+
microsecond = 0,
330+
nanosecond = 0
331+
} = ES.ToDateTimeRecord(item));
332+
} else {
333+
({ year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = ES.ParseDateTimeString(
334+
ES.ToString(item)
335+
));
336+
}
337+
({ year, month, day, hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateDateTime(
338+
year,
339+
month,
340+
day,
341+
hour,
342+
minute,
343+
second,
344+
millisecond,
345+
microsecond,
346+
nanosecond,
347+
disambiguation
348+
));
349+
const result = new this(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond);
350+
if (!ES.IsDateTime(result)) throw new TypeError('invalid result');
351+
return result;
332352
}
333353
static compare(one, two) {
334354
if (!ES.IsTemporalDateTime(one) || !ES.IsTemporalDateTime(two)) throw new TypeError('invalid DateTime object');

polyfill/lib/duration.mjs

+46-13
Original file line numberDiff line numberDiff line change
@@ -133,19 +133,52 @@ export class Duration {
133133
}
134134
static from(item, options = undefined) {
135135
const disambiguation = ES.ToTemporalDisambiguation(options);
136-
let result = ES.ToTemporalDuration(item, disambiguation);
137-
if (this === Duration) return result;
138-
return new this(
139-
GetSlot(result, YEARS),
140-
GetSlot(result, MONTHS),
141-
GetSlot(result, DAYS),
142-
GetSlot(result, HOURS),
143-
GetSlot(result, MINUTES),
144-
GetSlot(result, SECONDS),
145-
GetSlot(result, MILLISECONDS),
146-
GetSlot(result, MICROSECONDS),
147-
GetSlot(result, NANOSECONDS)
148-
);
136+
let years, months, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds;
137+
if (typeof arg === 'object' && arg) {
138+
({
139+
years = 0,
140+
months = 0,
141+
days = 0,
142+
hours = 0,
143+
minutes = 0,
144+
seconds = 0,
145+
milliseconds = 0,
146+
microseconds = 0,
147+
nanoseconds = 0
148+
} = ES.ToRecord(
149+
arg,
150+
[],
151+
// Intentionally alphabetical
152+
['days', 'hours', 'microseconds', 'milliseconds', 'minutes', 'months', 'nanoseconds', 'seconds', 'years']
153+
));
154+
} else {
155+
({
156+
years,
157+
months,
158+
days,
159+
hours,
160+
minutes,
161+
seconds,
162+
milliseconds,
163+
microseconds,
164+
nanoseconds
165+
} = ES.ParseDurationString(ES.ToString(arg)));
166+
}
167+
({ years, months, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.RegulateDuration(
168+
years,
169+
months,
170+
days,
171+
hours,
172+
minutes,
173+
seconds,
174+
milliseconds,
175+
microseconds,
176+
nanoseconds,
177+
disambiguation
178+
));
179+
const result = new this(years, months, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds);
180+
if (!ES.IsDuration(result)) throw new TypeError('invalid result');
181+
return result;
149182
}
150183
}
151184
Duration.prototype.toJSON = Duration.prototype.toString;

0 commit comments

Comments
 (0)