-
Notifications
You must be signed in to change notification settings - Fork 458
KDL support for removals #2250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KDL support for removals #2250
Changes from 6 commits
743c7a3
8b611f7
5184d40
94ee9a9
d656a14
117e76b
790f3ef
8ffb44c
b61ee71
184eb7e
6b779dd
6e76de9
8350852
d2ce62e
a92bc94
26e7af8
162b92c
e227deb
2a4aa6a
54ec2f5
fdd8294
729d58a
894101d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| removals { | ||
| enum AuthenticatorTransport { | ||
| smart-card // WebKit only as of 2023-05 | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| import { parse, type Value, type Node } from "kdljs"; | ||
| import { parse, type Value, type Node, type Document } from "kdljs"; | ||
| import type { | ||
| Enum, | ||
| Event, | ||
|
|
@@ -19,26 +19,46 @@ | |
| ? { [K in keyof T]?: DeepPartial<T[K]> } | ||
| : T; | ||
|
|
||
| type ParsedType = DeepPartial<WebIdl> & { removals?: DeepPartial<WebIdl> }; | ||
|
|
||
| interface OverridableMethod extends Omit<Method, "signature"> { | ||
| signature: DeepPartial<Signature>[] | Record<number, DeepPartial<Signature>>; | ||
| } | ||
|
|
||
| function optionalMember<const T>(prop: string, type: T, value?: Value) { | ||
| function optionalMember<const T>( | ||
| prop: string, | ||
| type: T, | ||
| value?: Value | DeepPartial<WebIdl>, | ||
| ) { | ||
| if (value === undefined) { | ||
| return {}; | ||
| } | ||
| // Support deep property assignment, e.g. prop = "a.b.c" | ||
| const propPath = prop.split("."); | ||
| if (typeof value !== type) { | ||
| throw new Error(`Expected type ${value} for ${prop}`); | ||
| throw new Error( | ||
| `Expected type ${type} for ${prop} but got ${typeof value}`, | ||
| ); | ||
| } | ||
| return { | ||
| [prop]: value as T extends "string" | ||
| ? string | ||
| : T extends "number" | ||
| ? number | ||
| : T extends "boolean" | ||
| ? boolean | ||
| : never, | ||
| }; | ||
| // If value is an object, ensure it is not empty (has at least one key) | ||
| if (type === "object" && typeof value === "object" && value !== null) { | ||
| if (Object.keys(value as object).length === 0) { | ||
| return {}; | ||
| } | ||
| } | ||
|
|
||
| // Build the nested object dynamically | ||
| let nested: any = value as T extends "string" | ||
| ? string | ||
| : T extends "number" | ||
| ? number | ||
| : T extends "boolean" | ||
| ? boolean | ||
| : never; | ||
| for (let i = propPath.length - 1; i >= 0; i--) { | ||
| nested = { [propPath[i]]: nested }; | ||
| } | ||
| return nested; | ||
| } | ||
|
|
||
| function string(arg: unknown): string { | ||
|
|
@@ -79,8 +99,11 @@ | |
| /** | ||
| * Converts patch files in KDL to match the [types](types.d.ts). | ||
| */ | ||
| function parseKDL(kdlText: string): DeepPartial<WebIdl> { | ||
| const { output, errors } = parse(kdlText); | ||
| function parseKDL(kdlText: string | Document): ParsedType { | ||
| const { output, errors } = | ||
| typeof kdlText === "string" | ||
| ? parse(kdlText) | ||
| : { output: kdlText, errors: [] }; | ||
|
|
||
| if (errors.length) { | ||
| throw new Error("KDL parse errors", { cause: errors }); | ||
|
|
@@ -91,8 +114,13 @@ | |
| const mixin: Record<string, DeepPartial<Interface>> = {}; | ||
| const interfaces: Record<string, DeepPartial<Interface>> = {}; | ||
| const dictionary: Record<string, DeepPartial<Dictionary>> = {}; | ||
| let removals: DeepPartial<WebIdl> = {}; | ||
|
|
||
| for (const node of nodes) { | ||
| if (node.name === "removals") { | ||
| removals = parseKDL(node.children); | ||
| continue; | ||
|
||
| } | ||
| const name = string(node.values[0]); | ||
| switch (node.name) { | ||
| case "enum": | ||
|
|
@@ -113,10 +141,11 @@ | |
| } | ||
|
|
||
| return { | ||
| enums: { enum: enums }, | ||
| mixins: { mixin }, | ||
| interfaces: { interface: interfaces }, | ||
| dictionaries: { dictionary }, | ||
| ...optionalMember("enums.enum", "object", enums), | ||
|
||
| ...optionalMember("mixins.mixin", "object", mixin), | ||
|
||
| ...optionalMember("interfaces.interface", "object", interfaces), | ||
| ...optionalMember("dictionaries.dictionary", "object", dictionary), | ||
| ...optionalMember("removals", "object", removals), | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -375,10 +404,15 @@ | |
| return parseKDL(text); | ||
| } | ||
|
|
||
| /** | ||
| * Remove all name fields from the object and its children as we don't want | ||
| * the names to be part of the removal. | ||
| */ | ||
| function removeNamesDeep(obj: unknown): unknown { | ||
Bashamega marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (Array.isArray(obj)) { | ||
| return obj.map(removeNamesDeep); | ||
| } else if (obj && typeof obj === "object") { | ||
| } | ||
| if (obj && typeof obj === "object") { | ||
| const newObj: { [key: string]: unknown } = {}; | ||
|
||
| for (const [key, value] of Object.entries(obj as Record<string, unknown>)) { | ||
Bashamega marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (key !== "name") { | ||
|
|
@@ -393,19 +427,17 @@ | |
| /** | ||
| * Read, parse, and merge all KDL files under the input folder. | ||
| */ | ||
| export default async function readPatches( | ||
|
||
| folder: "patches" | "removals", | ||
| isRemovals?: boolean, | ||
| ): Promise<any> { | ||
| const patchDirectory = new URL( | ||
| `../../inputfiles/${folder}/`, | ||
| import.meta.url, | ||
| ); | ||
| const patchDirectory = new URL("../../inputfiles/patches/", import.meta.url); | ||
| const fileUrls = await getAllFileURLs(patchDirectory); | ||
|
|
||
| const parsedContents = await Promise.all(fileUrls.map(readPatch)); | ||
| const res = parsedContents.reduce((acc, current) => merge(acc, current), {}); | ||
| if (folder == "removals") { | ||
| return removeNamesDeep(res); | ||
| const { removals, ...withoutRemovals } = res; | ||
| if (isRemovals) { | ||
| return removeNamesDeep(removals); | ||
| } | ||
| return res; | ||
| return withoutRemovals; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(this should be restored)