Skip to content

Commit 8ffb44c

Browse files
committed
Refactor
1 parent 790f3ef commit 8ffb44c

File tree

2 files changed

+63
-36
lines changed

2 files changed

+63
-36
lines changed

src/build.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ async function emitDom() {
8989

9090
const overriddenItems = await readInputJSON("overridingTypes.jsonc");
9191
const addedItems = await readInputJSON("addedTypes.jsonc");
92-
const patches = await readPatches();
93-
const removals = await readPatches(true);
92+
const { patches, removalPatches } = await readPatches();
9493
const comments = await readInputJSON("comments.json");
9594
const documentationFromMDN = await generateDescriptions();
9695
const removedItems = await readInputJSON("removedTypes.jsonc");
@@ -205,7 +204,7 @@ async function emitDom() {
205204
webidl = merge(webidl, getRemovalData(webidl));
206205
webidl = merge(webidl, getDocsData(webidl));
207206
webidl = prune(webidl, removedItems);
208-
webidl = prune(webidl, removals);
207+
webidl = prune(webidl, removalPatches);
209208
webidl = merge(webidl, addedItems);
210209
webidl = merge(webidl, overriddenItems);
211210
webidl = merge(webidl, patches);

src/build/patches.ts

Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ type DeepPartial<T> = T extends object
1919
? { [K in keyof T]?: DeepPartial<T[K]> }
2020
: T;
2121

22-
type ParsedType = DeepPartial<WebIdl> & { removals?: DeepPartial<WebIdl> };
23-
2422
interface OverridableMethod extends Omit<Method, "signature"> {
2523
signature: DeepPartial<Signature>[] | Record<number, DeepPartial<Signature>>;
2624
}
@@ -97,30 +95,21 @@ function handleTypeParameters(value: Value) {
9795
}
9896

9997
/**
100-
* Converts patch files in KDL to match the [types](types.d.ts).
98+
* Converts parsed KDL Document nodes to match the [types](types.d.ts).
10199
*/
102-
function parseKDL(kdlText: string | Document): ParsedType {
103-
const { output, errors } =
104-
typeof kdlText === "string"
105-
? parse(kdlText)
106-
: { output: kdlText, errors: [] };
107-
108-
if (errors.length) {
109-
throw new Error("KDL parse errors", { cause: errors });
110-
}
100+
function convertKDLNodes(nodes: Node[] | Document): DeepPartial<WebIdl> {
101+
// Accept either Document or array of nodes
102+
const actualNodes: Node[] = Array.isArray(nodes)
103+
? nodes
104+
: (nodes as Document);
111105

112-
const nodes = output!;
113106
const enums: Record<string, Enum> = {};
114107
const mixin: Record<string, DeepPartial<Interface>> = {};
115108
const interfaces: Record<string, DeepPartial<Interface>> = {};
116109
const dictionary: Record<string, DeepPartial<Dictionary>> = {};
117-
let removals: DeepPartial<WebIdl> = {};
118110

119-
for (const node of nodes) {
120-
if (node.name === "removals") {
121-
removals = parseKDL(node.children);
122-
continue;
123-
}
111+
for (const node of actualNodes) {
112+
// Note: no "removals" handling here; caller is responsible for splitting
124113
const name = string(node.values[0]);
125114
switch (node.name) {
126115
case "enum":
@@ -145,7 +134,6 @@ function parseKDL(kdlText: string | Document): ParsedType {
145134
...optionalMember("mixins.mixin", "object", mixin),
146135
...optionalMember("interfaces.interface", "object", interfaces),
147136
...optionalMember("dictionaries.dictionary", "object", dictionary),
148-
...optionalMember("removals", "object", removals),
149137
};
150138
}
151139

@@ -397,13 +385,18 @@ async function getAllFileURLs(folder: URL): Promise<URL[]> {
397385
}
398386

399387
/**
400-
* Read and parse a single KDL file.
388+
* Read and parse a single KDL file into its KDL Document structure.
401389
*/
402-
export async function readPatch(fileUrl: URL): Promise<any> {
390+
async function readPatchDocument(fileUrl: URL): Promise<Document> {
403391
const text = await readFile(fileUrl, "utf8");
404-
return parseKDL(text);
392+
const { output, errors } = parse(text);
393+
if (errors.length) {
394+
throw new Error(`KDL parse errors in ${fileUrl.toString()}`, {
395+
cause: errors,
396+
});
397+
}
398+
return output!;
405399
}
406-
407400
/**
408401
* Remove all name fields from the object and its children as we don't want
409402
* the names to be part of the removal.
@@ -426,18 +419,53 @@ function removeNamesDeep(obj: unknown): unknown {
426419

427420
/**
428421
* Read, parse, and merge all KDL files under the input folder.
422+
* Splits the main patch content and the removals from each file for combined processing.
423+
*
424+
* Returns:
425+
* {
426+
* patches: merged patch contents (excluding removals),
427+
* removalPatches: merged removals, with names stripped
428+
* }
429429
*/
430-
export default async function readPatches(
431-
isRemovals?: boolean,
432-
): Promise<any> {
430+
export default async function readPatches(): Promise<{
431+
patches: any;
432+
removalPatches: any;
433+
}> {
433434
const patchDirectory = new URL("../../inputfiles/patches/", import.meta.url);
434435
const fileUrls = await getAllFileURLs(patchDirectory);
435436

436-
const parsedContents = await Promise.all(fileUrls.map(readPatch));
437-
const res = parsedContents.reduce((acc, current) => merge(acc, current), {});
438-
const { removals, ...withoutRemovals } = res;
439-
if (isRemovals) {
440-
return removeNamesDeep(removals);
437+
// Stage 1: Parse all file KDLs into Documents
438+
const documents = await Promise.all(fileUrls.map(readPatchDocument));
439+
440+
// Stage 2: For each document, split main nodes and removals nodes
441+
const patchNodeGroups: Node[][] = [];
442+
const removalsNodeGroups: Node[][] = [];
443+
444+
for (const doc of documents) {
445+
const mainNodes: Node[] = [];
446+
let localRemovalsNodes: Node[] = [];
447+
for (const node of doc) {
448+
if (node.name === "removals") {
449+
// Each removals node may itself contain multiple root nodes
450+
localRemovalsNodes = localRemovalsNodes.concat(node.children);
451+
} else {
452+
mainNodes.push(node);
453+
}
454+
}
455+
patchNodeGroups.push(mainNodes);
456+
if (localRemovalsNodes.length > 0) {
457+
removalsNodeGroups.push(localRemovalsNodes);
458+
}
441459
}
442-
return withoutRemovals;
460+
461+
// Stage 3: Merge all main patches and removals separately using convertKDLNodes
462+
const patchObjs = patchNodeGroups.map((nodes) => convertKDLNodes(nodes));
463+
const removalObjs = removalsNodeGroups.map((nodes) => convertKDLNodes(nodes));
464+
465+
const patches = patchObjs.reduce((acc, cur) => merge(acc, cur), {});
466+
const removalPatches = removeNamesDeep(
467+
removalObjs.reduce((acc, cur) => merge(acc, cur), {}),
468+
);
469+
470+
return { patches, removalPatches };
443471
}

0 commit comments

Comments
 (0)