This is an editorial change in the Temporal spec.
See: https://github.com/tc39/proposal-temporal/commit/983902e
We already had these defined as structs, but now they're properly
defined in the spec (opposed to the previous anonymous records), and we
don't have to make up our own names anymore :^)
Note that while we're usually not including 'record' in the name, in
this case the 'Duration Record' has a name clash with the Duration
object. Additionally, later editorial changes introduce CreateFooRecord
AOs, so let's just go with FooRecord structs here.
Two issues:
- The intended range was 9 characters starting from index 1. Since the
second argument to String::substring() is the length, 10 is
potentially reading further than the string's length (when only
providing one fraction digit), causing an assertion failure crash.
- The spec's intention to skip the decimal separator by starting at
index 1 is incorrect, no decimal separator is present in the result of
parsing TimeZoneUTCOffsetFractionalPart. I filed a spec fix for this,
see: https://github.com/tc39/proposal-temporal/pull/1999
As all variables and numeric literals in the expression have an integral
data type, it would evaluate to an int and could easily overflow as
we're multiplying seconds with 10^9.
Introduce a floating point literal into the expression to make it result
in a double.
A sign that's either the value 1 or -1 should obviously not have an
unsigned data type :^)
This would cause it to become 255 for the negative offset case, which
would then completely screw up the offset_nanoseconds calculation as it
serves as a multiplier.
Instead of using plain objects as Iterator records, causes confusion
about the object itself actually being its [[Iterator]] slot, and
requires non-standard type conversion shenanigans fpr the [[NextValue]]
and [[Done]] internal slots, implement a proper Iterator record struct
and use it throughout.
Also annotate the remaining Iterator AOs with spec comments while we're
here.
Not much of a difference as TimeFraction just parses Fraction, but let's
do it correctly. Small mistake I did in 4b7f716.
Thanks to YouTube user gla3dr for noticing this :^)
This is required for Temporal.Duration.prototype.round(). Subsequently,
this now returns ThrowCompletionOr<Optional<String>>, which brings the
signature in line with that of to_smallest_temporal_unit().
Much nicer! :^)
It's not the `to_uint<u8>()` call that would fail, if we have a value
for these productions they will always be valid numbers. We do need to
provide a fallback for when that's not the case and any of them is
undefined, i.e. an empty Optional.
This is the start of a parser for the ISO 8601 grammar used in the
Temporal spec:
https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar
We will, on purpose, not use a generic ISO 8601 parser from AK or
similar for two reasons:
- Many AOs make specific assumptions about which productions exist and
access them directly, even when they're part of a larger production.
- The spec says "The grammar deviates from the standard given in ISO
8601 in the following ways:" and then lists 17 of such deviations.
Making that work with a general purpose parser is not worth it.
The public API is not being used anywhere yet, but will be in the next
couple of commits. Likewise, the Production enum will be populated with
all the productions accessed directly (e.g. TemporalDateString).
Many thanks to Ali for showing me how to improve my initial approach
full of macros with a nice RAII helper - it's much nicer :^)
Co-Authored-By: Ali Mohammad Pur <mpfard@serenityos.org>