feat(codemode): complete date parity (#37960)

This commit is contained in:
Aiden Cline 2026-07-20 12:13:16 -05:00 committed by GitHub
commit 98c29075b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 401 additions and 12 deletions

View file

@ -1,3 +1,25 @@
import { type AstNode, InterpreterRuntimeError } from "../interpreter/model.js"
import { CodeModeDate } from "../values.js"
import { coerceToNumber, coerceToString } from "./value.js"
const dateSetterArguments = new Map<string, number>([
["setTime", 1],
["setMilliseconds", 1],
["setUTCMilliseconds", 1],
["setSeconds", 2],
["setUTCSeconds", 2],
["setMinutes", 3],
["setUTCMinutes", 3],
["setHours", 4],
["setUTCHours", 4],
["setDate", 1],
["setUTCDate", 1],
["setMonth", 2],
["setUTCMonth", 2],
["setFullYear", 3],
["setUTCFullYear", 3],
])
export const dateMethods = new Set([
"getTime",
"valueOf",
@ -23,6 +45,7 @@ export const dateMethods = new Set([
"getUTCSeconds",
"getUTCMilliseconds",
"getTimezoneOffset",
...dateSetterArguments.keys(),
])
export const dateStatics = new Set(["now", "parse", "UTC"])
@ -40,8 +63,16 @@ export const invokeDateStatic = (name: string, args: Array<unknown>, node: AstNo
}
}
export const invokeDateMethod = (value: CodeModeDate, name: string, node: AstNode): unknown => {
const hosted = new Date(value.time)
export const dateSetterArgumentCount = (name: string): number | undefined => dateSetterArguments.get(name)
export const invokeDateMethod = (
value: CodeModeDate,
name: string,
args: Array<number>,
node: AstNode,
initialTime = value.time,
): unknown => {
const hosted = new Date(initialTime)
switch (name) {
case "getTime":
case "valueOf":
@ -90,10 +121,60 @@ export const invokeDateMethod = (value: CodeModeDate, name: string, node: AstNod
return hosted.getUTCMilliseconds()
case "getTimezoneOffset":
return hosted.getTimezoneOffset()
case "setTime":
return updateDate(value, hosted.setTime(args[0]))
case "setMilliseconds":
return updateDate(value, hosted.setMilliseconds(args[0]))
case "setUTCMilliseconds":
return updateDate(value, hosted.setUTCMilliseconds(args[0]))
case "setSeconds":
if (args.length < 2) return updateDate(value, hosted.setSeconds(args[0]))
return updateDate(value, hosted.setSeconds(args[0], args[1]))
case "setUTCSeconds":
if (args.length < 2) return updateDate(value, hosted.setUTCSeconds(args[0]))
return updateDate(value, hosted.setUTCSeconds(args[0], args[1]))
case "setMinutes":
if (args.length < 2) return updateDate(value, hosted.setMinutes(args[0]))
if (args.length < 3) return updateDate(value, hosted.setMinutes(args[0], args[1]))
return updateDate(value, hosted.setMinutes(args[0], args[1], args[2]))
case "setUTCMinutes":
if (args.length < 2) return updateDate(value, hosted.setUTCMinutes(args[0]))
if (args.length < 3) return updateDate(value, hosted.setUTCMinutes(args[0], args[1]))
return updateDate(value, hosted.setUTCMinutes(args[0], args[1], args[2]))
case "setHours":
if (args.length < 2) return updateDate(value, hosted.setHours(args[0]))
if (args.length < 3) return updateDate(value, hosted.setHours(args[0], args[1]))
if (args.length < 4) return updateDate(value, hosted.setHours(args[0], args[1], args[2]))
return updateDate(value, hosted.setHours(args[0], args[1], args[2], args[3]))
case "setUTCHours":
if (args.length < 2) return updateDate(value, hosted.setUTCHours(args[0]))
if (args.length < 3) return updateDate(value, hosted.setUTCHours(args[0], args[1]))
if (args.length < 4) return updateDate(value, hosted.setUTCHours(args[0], args[1], args[2]))
return updateDate(value, hosted.setUTCHours(args[0], args[1], args[2], args[3]))
case "setDate":
return updateDate(value, hosted.setDate(args[0]))
case "setUTCDate":
return updateDate(value, hosted.setUTCDate(args[0]))
case "setMonth":
if (args.length < 2) return updateDate(value, hosted.setMonth(args[0]))
return updateDate(value, hosted.setMonth(args[0], args[1]))
case "setUTCMonth":
if (args.length < 2) return updateDate(value, hosted.setUTCMonth(args[0]))
return updateDate(value, hosted.setUTCMonth(args[0], args[1]))
case "setFullYear":
if (args.length < 2) return updateDate(value, hosted.setFullYear(args[0]))
if (args.length < 3) return updateDate(value, hosted.setFullYear(args[0], args[1]))
return updateDate(value, hosted.setFullYear(args[0], args[1], args[2]))
case "setUTCFullYear":
if (args.length < 2) return updateDate(value, hosted.setUTCFullYear(args[0]))
if (args.length < 3) return updateDate(value, hosted.setUTCFullYear(args[0], args[1]))
return updateDate(value, hosted.setUTCFullYear(args[0], args[1], args[2]))
default:
throw new InterpreterRuntimeError(`Date method '${name}' is not available in CodeMode.`, node)
}
}
import { type AstNode, InterpreterRuntimeError } from "../interpreter/model.js"
import { CodeModeDate } from "../values.js"
import { coerceToNumber, coerceToString } from "./value.js"
const updateDate = (value: CodeModeDate, time: number): number => {
value.time = time
return time
}