-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathgenerate.mjs
More file actions
137 lines (109 loc) · 4.65 KB
/
generate.mjs
File metadata and controls
137 lines (109 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import {spawnSync} from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
function execute(cmd, args, options) {
console.log(cmd, ...args);
options = { ...options || {}, shell: true, stdio: 'inherit' };
if (options.input) {
options.stdio = ['pipe', 'inherit', 'inherit'];
}
const { error, status } = spawnSync(cmd, args, options);
if (error) {
throw new(Error);
}
if (status !== 0) {
throw new Error(`${cmd} exited with status code: ${status}`);
}
}
function executeWithCapture(cmd, args, options) {
console.log(cmd, ...args);
const { error, status, stdout } = spawnSync(cmd, args, {...options || {}, shell: true, encoding: 'utf-8' });
if (error) {
throw new(Error);
}
if (status !== 0) {
throw new Error(`${cmd} exited with status code: ${status}`);
}
return stdout;
}
function readFileAsUTF8(filename) {
return fs.readFileSync(filename, { encoding: 'utf-8' });
}
function generateDiff(fromFilename, toFilename, commit) {
return executeWithCapture('git', ['diff', `${commit}:${fromFilename}`, `${commit}:${toFilename}`]);
}
function fixupGenerated(srcFilename, dstFilename) {
//execute('git')
let ts = `\
// *********************************************************************************************
// This file is manually-edited by diffing against an autogenerated file. See README.md.
// *********************************************************************************************
// *********************************************************************************************
// Manually-written - auto copied from extra.d.ts
// *********************************************************************************************
${readFileAsUTF8('extra.d.ts')}
// *********************************************************************************************
// Semi-auto-generated (by manual diff with autogenerated types)
// *********************************************************************************************
${readFileAsUTF8(srcFilename)}
`
ts = ts
// Replace broken AllowSharedBufferSource with GPUAllowSharedBufferSource
.replace(/(?<!\/\/.*)\bAllowSharedBufferSource\b/g, 'GPUAllowSharedBufferSource')
// convert [[#anchor]] to {@link spec_url}
// convert [[#anchor|text]] to {@link spec_url|text}
.replace(/([^#])\[\[([^\[].*?)\]\]/g, '$1{@link https://www.w3.org/TR/webgpu/$2}')
// convert {{ref}} to {@link ref}
// convert {{ref|text}} to {@link ref|text}
.replace(/\{\{(.*?)\}\}/g, '{@link $1}')
// convert {@link foo/method(...)} to {@link foo#method}
.replace(/\{@link ([^[}]+)\/(.*?)\(.*?\)}/g, '{@link $1#$2}')
// convert {@link foo#[[bar]]} to {@link foo}.`[[bar]]`
.replace(/\{@link ([^[}]+)#\[\[(.*?)]]}/g, '{@link $1}.`[[$2]]`')
// convert {@link foo#"bar"} to {@link foo} `"bar"`
.replace(/\{@link ([^[}]+)#"(.*?)"}/g, '{@link $1} `"$2"`')
// fix links of the form {@link foo|text} -> {@link foo | text}
.replace(/\{@link ([^}|]+)\|([^}|]+)\}/g, '{@link $1 | $2}')
// remove items that are known not to be linkable
.replace(/{@link Promise}/g, 'Promise')
.replace(/{@link ArrayBuffer}/g, 'ArrayBuffer')
.replace(/{@link Uint32Array}/g, 'Uint32Array')
.replace(/{@link RenderState}/g, 'RenderState')
.replace(/{@link double}/g, '`double`')
.replace(/<pre highlight=['"]?(.*)['"]?>/g, '```$1')
.replace(/<\/pre>/g, '```')
// add new(): never;
.replace(/(\ndeclare\svar\s\w+:\s\{\n\s+prototype:.*?\n)\};/g, '$1 new(): never;\n};')
// replace : GPUExtent3D -> : GPUExtent3DStrict
.replace(/: GPUExtent3D\b/g, ': GPUExtent3DStrict')
// replace Promise<... | undefined> with Promise<...>
.replace(/( Promise<[^>]*?)\s+\|\s+undefined\s*>/g, '$1>')
; // end of replacements
fs.writeFileSync(dstFilename, ts);
console.log(`wrote ${dstFilename}`);
}
const fromFilename = 'generated/index-temp.d.ts';
const toFilename = 'dist/index.d.ts';
// This file should always exist but it won't the first time we run this
const diff = fs.existsSync(fromFilename)
? generateDiff(fromFilename, toFilename, 'HEAD')
: undefined;
execute(
'./node_modules/.bin/bikeshed-to-ts',
[
'--in', './gpuweb/spec/index.bs',
'--out', fromFilename,
'--forceGlobal',
'--nominal',
]
);
fixupGenerated(fromFilename, fromFilename);
execute('./node_modules/.bin/prettier', ['-w', fromFilename]);
const generatedFilename = 'generated/index.d.ts';
fs.copyFileSync(fromFilename, generatedFilename);
if (diff) {
const inPlaceDiff = diff
.replaceAll(fromFilename, generatedFilename)
.replaceAll(toFilename, generatedFilename);
execute('git', ['apply', '-'], { input: inPlaceDiff });
}