feat(unstable): add Temporal API support (#21738)

This commit adds support for [Stage 3 Temporal API
proposal](https://tc39.es/proposal-temporal/docs/).

The API is available when `--unstable-temporal` flag is passed.

---------

Signed-off-by: Bartek Iwańczuk <biwanczuk@gmail.com>
Co-authored-by: David Sherret <dsherret@gmail.com>
Co-authored-by: Kenta Moriuchi <moriken@kimamass.com>
This commit is contained in:
Bartek Iwańczuk 2024-01-15 01:26:57 +01:00 committed by GitHub
parent f46c03d6b4
commit 5143b9e7d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 2621 additions and 70 deletions

View file

@ -315,22 +315,28 @@ pub(crate) static UNSTABLE_GRANULAR_FLAGS: &[(
"Enable unstable net APIs",
7,
),
(
"temporal",
"Enable unstable Temporal API",
// Not used in JS
8,
),
(
"unsafe-proto",
"Enable unsafe __proto__ support. This is a security risk.",
// This number is used directly in the JS code. Search
// for "unstableFeatures" to see where it's used.
8,
// for "unstableIds" to see where it's used.
9,
),
(
deno_runtime::deno_webgpu::UNSTABLE_FEATURE_NAME,
"Enable unstable `WebGPU` API",
9,
10,
),
(
deno_runtime::ops::worker_host::UNSTABLE_FEATURE_NAME,
"Enable unstable Web Worker APIs",
10,
11,
),
];
@ -394,7 +400,15 @@ pub fn main() {
// Using same default as VSCode:
// https://github.com/microsoft/vscode/blob/48d4ba271686e8072fc6674137415bc80d936bc7/extensions/typescript-language-features/src/configuration/configuration.ts#L213-L214
DenoSubcommand::Lsp => vec!["--max-old-space-size=3072".to_string()],
_ => vec![],
_ => {
if flags.unstable
|| flags.unstable_features.contains(&"temporal".to_string())
{
vec!["--harmony-temporal".to_string()]
} else {
vec![]
}
}
};
init_v8_flags(&default_v8_flags, &flags.v8_flags, get_v8_flags_from_env());
deno_core::JsRuntime::init_platform(None);

View file

@ -9012,68 +9012,458 @@ fn lsp_workspace_symbol() {
);
assert_eq!(
res,
json!([{
"name": "fieldA",
"kind": 8,
"location": {
"uri": "file:///a/file.ts",
"range": {
"start": { "line": 1, "character": 2 },
"end": { "line": 1, "character": 17 }
}
},
"containerName": "A"
}, {
"name": "fieldB",
"kind": 8,
"location": {
"uri": "file:///a/file.ts",
"range": {
"start": { "line": 2, "character": 2 },
"end": { "line": 2, "character": 17 }
}
},
"containerName": "A"
}, {
"name": "fieldC",
"kind": 8,
"location": {
"uri": "file:///a/file_01.ts",
"range": {
"start": { "line": 1, "character": 2 },
"end": { "line": 1, "character": 17 }
}
},
"containerName": "B"
}, {
"name": "fieldD",
"kind": 8,
"location": {
"uri": "file:///a/file_01.ts",
"range": {
"start": { "line": 2, "character": 2 },
"end": { "line": 2, "character": 17 }
}
},
"containerName": "B"
}, {
"name": "ClassFieldDecoratorContext",
"kind": 11,
"location": {
"uri": "deno:/asset/lib.decorators.d.ts",
"range": {
"start": {
"line": 343,
"character": 0,
},
"end": {
"line": 385,
"character": 1,
},
json!([
{
"name": "fieldA",
"kind": 8,
"location": {
"uri": "file:///a/file.ts",
"range": {
"start": {
"line": 1,
"character": 2
},
"end": {
"line": 1,
"character": 17
}
}
},
"containerName": "A"
},
"containerName": "",
}])
{
"name": "fieldB",
"kind": 8,
"location": {
"uri": "file:///a/file.ts",
"range": {
"start": {
"line": 2,
"character": 2
},
"end": {
"line": 2,
"character": 17
}
}
},
"containerName": "A"
},
{
"name": "fieldC",
"kind": 8,
"location": {
"uri": "file:///a/file_01.ts",
"range": {
"start": {
"line": 1,
"character": 2
},
"end": {
"line": 1,
"character": 17
}
}
},
"containerName": "B"
},
{
"name": "fieldD",
"kind": 8,
"location": {
"uri": "file:///a/file_01.ts",
"range": {
"start": {
"line": 2,
"character": 2
},
"end": {
"line": 2,
"character": 17
}
}
},
"containerName": "B"
},
{
"name": "fields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3139,
"character": 4
},
"end": {
"line": 3139,
"character": 55
}
}
},
"containerName": "CalendarProtocol"
},
{
"name": "fields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3309,
"character": 4
},
"end": {
"line": 3309,
"character": 47
}
}
},
"containerName": "Calendar"
},
{
"name": "ClassFieldDecoratorContext",
"kind": 11,
"location": {
"uri": "deno:/asset/lib.decorators.d.ts",
"range": {
"start": {
"line": 343,
"character": 0
},
"end": {
"line": 385,
"character": 1
}
}
},
"containerName": ""
},
{
"name": "dateFromFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3117,
"character": 4
},
"end": {
"line": 3120,
"character": 26
}
}
},
"containerName": "CalendarProtocol"
},
{
"name": "dateFromFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3287,
"character": 4
},
"end": {
"line": 3290,
"character": 26
}
}
},
"containerName": "Calendar"
},
{
"name": "getISOFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3413,
"character": 4
},
"end": {
"line": 3413,
"character": 39
}
}
},
"containerName": "PlainDate"
},
{
"name": "getISOFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3576,
"character": 4
},
"end": {
"line": 3576,
"character": 43
}
}
},
"containerName": "PlainDateTime"
},
{
"name": "getISOFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3625,
"character": 4
},
"end": {
"line": 3625,
"character": 39
}
}
},
"containerName": "PlainMonthDay"
},
{
"name": "getISOFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3744,
"character": 4
},
"end": {
"line": 3744,
"character": 39
}
}
},
"containerName": "PlainTime"
},
{
"name": "getISOFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3897,
"character": 4
},
"end": {
"line": 3897,
"character": 39
}
}
},
"containerName": "PlainYearMonth"
},
{
"name": "getISOFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 4056,
"character": 4
},
"end": {
"line": 4056,
"character": 43
}
}
},
"containerName": "ZonedDateTime"
},
{
"name": "mergeFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3140,
"character": 4
},
"end": {
"line": 3143,
"character": 31
}
}
},
"containerName": "CalendarProtocol"
},
{
"name": "mergeFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3310,
"character": 4
},
"end": {
"line": 3313,
"character": 31
}
}
},
"containerName": "Calendar"
},
{
"name": "monthDayFromFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3125,
"character": 4
},
"end": {
"line": 3128,
"character": 30
}
}
},
"containerName": "CalendarProtocol"
},
{
"name": "monthDayFromFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3295,
"character": 4
},
"end": {
"line": 3298,
"character": 30
}
}
},
"containerName": "Calendar"
},
{
"name": "PlainDateISOFields",
"kind": 5,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3329,
"character": 2
},
"end": {
"line": 3334,
"character": 4
}
}
},
"containerName": "Temporal"
},
{
"name": "PlainDateTimeISOFields",
"kind": 5,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3440,
"character": 2
},
"end": {
"line": 3451,
"character": 4
}
}
},
"containerName": "Temporal"
},
{
"name": "PlainTimeISOFields",
"kind": 5,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3645,
"character": 2
},
"end": {
"line": 3652,
"character": 4
}
}
},
"containerName": "Temporal"
},
{
"name": "yearMonthFromFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3121,
"character": 4
},
"end": {
"line": 3124,
"character": 31
}
}
},
"containerName": "CalendarProtocol"
},
{
"name": "yearMonthFromFields",
"kind": 6,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3291,
"character": 4
},
"end": {
"line": 3294,
"character": 31
}
}
},
"containerName": "Calendar"
},
{
"name": "ZonedDateTimeISOFields",
"kind": 5,
"location": {
"uri": "deno:/asset/lib.deno.unstable.d.ts",
"range": {
"start": {
"line": 3926,
"character": 2
},
"end": {
"line": 3939,
"character": 4
}
}
},
"containerName": "Temporal"
}
])
);
client.shutdown();
}

View file

@ -4925,3 +4925,17 @@ Warning Sloppy module resolution (hint: specify path to index.tsx file in direct
",
);
}
itest!(unstable_temporal_api {
args: "run --unstable-temporal --check run/unstable_temporal_api/main.ts",
output: "run/unstable_temporal_api/main.out",
http_server: false,
exit_code: 0,
});
itest!(unstable_temporal_api_missing_flag {
args: "run run/unstable_temporal_api/missing_flag.js",
output: "run/unstable_temporal_api/missing_flag.out",
http_server: false,
exit_code: 1,
});

View file

@ -0,0 +1,12 @@
Check [WILDCARD]
Temporal.Now [WILDCARD]
Temporal.Instant 1969-07-20T20:17:00Z
Temporal.ZonedDateTime 1995-12-07T03:24:30.0000035-08:00[America/Los_Angeles]
Temporal.PlainDate 2006-08-24
Temporal.PlainTime 19:39:09.068346205
Temporal.PlainDateTime 1995-12-07T15:00:00
Temporal.PlainYearMonth 2020-10
Temporal.PlainMonthDay 07-14
Temporal.Duration PT130H20M
Temporal.TimeZone Africa/Cairo
Temporal.Calendar 1999-12-31

View file

@ -0,0 +1,71 @@
console.log("Temporal.Now", Temporal.Now.instant());
console.log(
"Temporal.Instant",
Temporal.Instant.from("1969-07-20T20:17Z"),
);
console.log(
"Temporal.ZonedDateTime",
Temporal.ZonedDateTime.from({
timeZone: "America/Los_Angeles",
year: 1995,
month: 12,
day: 7,
hour: 3,
minute: 24,
second: 30,
millisecond: 0,
microsecond: 3,
nanosecond: 500,
}),
);
console.log(
"Temporal.PlainDate",
Temporal.PlainDate.from({ year: 2006, month: 8, day: 24 }),
);
console.log(
"Temporal.PlainTime",
Temporal.PlainTime.from({
hour: 19,
minute: 39,
second: 9,
millisecond: 68,
microsecond: 346,
nanosecond: 205,
}),
);
console.log(
"Temporal.PlainDateTime",
Temporal.PlainDateTime.from({
year: 1995,
month: 12,
day: 7,
hour: 15,
}),
);
console.log(
"Temporal.PlainYearMonth",
Temporal.PlainYearMonth.from({ year: 2020, month: 10 }),
);
console.log(
"Temporal.PlainMonthDay",
Temporal.PlainMonthDay.from({ month: 7, day: 14 }),
);
console.log(
"Temporal.Duration",
Temporal.Duration.from({
hours: 130,
minutes: 20,
}),
);
console.log(
"Temporal.TimeZone",
Temporal.TimeZone.from("Africa/Cairo"),
);
console.log(
"Temporal.Calendar",
Temporal.Calendar.from("iso8601").dateFromFields({
year: 1999,
month: 12,
day: 31,
}, {}),
);

View file

@ -0,0 +1 @@
Temporal.Now.instant();

View file

@ -0,0 +1,4 @@
error: Uncaught (in promise) ReferenceError: Temporal is not defined
Temporal.Now.instant();
^
at [WILDCARD]missing_flag.js:1:1

File diff suppressed because it is too large Load diff

View file

@ -267,7 +267,7 @@ declare namespace Intl {
}
interface DateTimeFormatOptions {
calendar?: string | undefined;
calendar?: string | (typeof globalThis extends { Temporal: { CalendarProtocol: infer T; }; } ? T : undefined) | undefined;
dayPeriod?: "narrow" | "short" | "long" | undefined;
numberingSystem?: string | undefined;

View file

@ -4474,7 +4474,7 @@ declare namespace Intl {
timeZoneName?: "short" | "long" | "shortOffset" | "longOffset" | "shortGeneric" | "longGeneric" | undefined;
formatMatcher?: "best fit" | "basic" | undefined;
hour12?: boolean | undefined;
timeZone?: string | undefined;
timeZone?: string | (typeof globalThis extends { Temporal: { TimeZoneProtocol: infer T; }; } ? T : undefined) | undefined
}
interface ResolvedDateTimeFormatOptions {

View file

@ -188,6 +188,7 @@ const styles = {
regexp: "red",
module: "underline",
internalError: "red",
temporal: "magenta",
};
const defaultFG = 39;
@ -776,6 +777,55 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) {
return ctx.stylize(base, "date");
}
}
} else if (
proxyDetails === null &&
typeof globalThis.Temporal !== "undefined" &&
(
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.Instant.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.ZonedDateTime.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.PlainDate.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.PlainTime.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.PlainDateTime.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.PlainYearMonth.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.PlainMonthDay.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.Duration.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.TimeZone.prototype,
value,
) ||
ObjectPrototypeIsPrototypeOf(
globalThis.Temporal.Calendar.prototype,
value,
)
)
) {
// Temporal is not available in primordials yet
// deno-lint-ignore prefer-primordials
return ctx.stylize(value.toString(), "temporal");
} else if (
(proxyDetails === null &&
(isNativeError(value) ||

View file

@ -167,9 +167,10 @@ const unstableIds = {
http: 5,
kv: 6,
net: 7,
unsafeProto: 8,
webgpu: 9,
workerOptions: 10,
temporal: 8,
unsafeProto: 9,
webgpu: 10,
workerOptions: 11,
};
const denoNsUnstableById = {};