@sandstone-mc/mcdoc-ts-generator 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3150 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +3086 -0
- package/dist/typegen/compile.d.ts +2 -0
- package/dist/typegen/export.d.ts +39 -0
- package/dist/typegen/import.d.ts +6 -0
- package/dist/typegen/index.d.ts +38 -0
- package/dist/typegen/mcdoc/assert.d.ts +427 -0
- package/dist/typegen/mcdoc/bind.d.ts +61 -0
- package/dist/typegen/mcdoc/complex/dispatcher.d.ts +34 -0
- package/dist/typegen/mcdoc/complex/index.d.ts +3 -0
- package/dist/typegen/mcdoc/complex/indexed.d.ts +47 -0
- package/dist/typegen/mcdoc/complex/template.d.ts +54 -0
- package/dist/typegen/mcdoc/dispatcher_symbol.d.ts +58 -0
- package/dist/typegen/mcdoc/index.d.ts +425 -0
- package/dist/typegen/mcdoc/list/array/byte.d.ts +20 -0
- package/dist/typegen/mcdoc/list/array/index.d.ts +3 -0
- package/dist/typegen/mcdoc/list/array/int.d.ts +20 -0
- package/dist/typegen/mcdoc/list/array/long.d.ts +20 -0
- package/dist/typegen/mcdoc/list/index.d.ts +2 -0
- package/dist/typegen/mcdoc/list/list.d.ts +66 -0
- package/dist/typegen/mcdoc/multi/enum.d.ts +8 -0
- package/dist/typegen/mcdoc/multi/index.d.ts +4 -0
- package/dist/typegen/mcdoc/multi/struct.d.ts +31 -0
- package/dist/typegen/mcdoc/multi/tuple.d.ts +62 -0
- package/dist/typegen/mcdoc/multi/union.d.ts +62 -0
- package/dist/typegen/mcdoc/primitives/any.d.ts +7 -0
- package/dist/typegen/mcdoc/primitives/boolean.d.ts +7 -0
- package/dist/typegen/mcdoc/primitives/byte.d.ts +19 -0
- package/dist/typegen/mcdoc/primitives/concrete.d.ts +37 -0
- package/dist/typegen/mcdoc/primitives/double.d.ts +27 -0
- package/dist/typegen/mcdoc/primitives/float.d.ts +19 -0
- package/dist/typegen/mcdoc/primitives/index.d.ts +12 -0
- package/dist/typegen/mcdoc/primitives/int.d.ts +35 -0
- package/dist/typegen/mcdoc/primitives/literal.d.ts +14 -0
- package/dist/typegen/mcdoc/primitives/long.d.ts +19 -0
- package/dist/typegen/mcdoc/primitives/reference.d.ts +54 -0
- package/dist/typegen/mcdoc/primitives/short.d.ts +19 -0
- package/dist/typegen/mcdoc/primitives/string.d.ts +28 -0
- package/dist/typegen/mcdoc/utils.d.ts +20 -0
- package/dist/util/config.d.ts +1 -0
- package/dist/util/fetch.d.ts +18 -0
- package/dist/util/index.d.ts +22 -0
- package/package.json +58 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3086 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { dirname, resolve } from "path";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
4
|
+
import {
|
|
5
|
+
ConfigService,
|
|
6
|
+
fileUtil,
|
|
7
|
+
Service,
|
|
8
|
+
VanillaConfig
|
|
9
|
+
} from "@spyglassmc/core";
|
|
10
|
+
import { NodeJsExternals } from "@spyglassmc/core/lib/nodejs.js";
|
|
11
|
+
import * as je from "@spyglassmc/java-edition";
|
|
12
|
+
import { ReleaseVersion } from "@spyglassmc/java-edition/lib/dependency/index.js";
|
|
13
|
+
import * as mcdoc5 from "@spyglassmc/mcdoc";
|
|
14
|
+
|
|
15
|
+
// src/util/index.ts
|
|
16
|
+
function errorMessage(e) {
|
|
17
|
+
if (e instanceof Error)
|
|
18
|
+
return e.message;
|
|
19
|
+
return `${e}`;
|
|
20
|
+
}
|
|
21
|
+
var join = (...paths) => paths.join("/");
|
|
22
|
+
function pascal_case(name) {
|
|
23
|
+
const words = name.split(/\/|_/);
|
|
24
|
+
return words.map((word) => word[0].toUpperCase() + word.slice(1)).join("");
|
|
25
|
+
}
|
|
26
|
+
function pluralize(name) {
|
|
27
|
+
if (name.endsWith("y"))
|
|
28
|
+
return name.slice(0, -1) + "ies";
|
|
29
|
+
if (name.endsWith("s") || name.endsWith("ch") || name.endsWith("sh") || name.endsWith("x") || name.endsWith("z"))
|
|
30
|
+
return name + "es";
|
|
31
|
+
return name + "s";
|
|
32
|
+
}
|
|
33
|
+
function add(obj) {
|
|
34
|
+
const filtered = {};
|
|
35
|
+
for (const key of Object.keys(obj)) {
|
|
36
|
+
const value = obj[key];
|
|
37
|
+
if (value !== undefined) {
|
|
38
|
+
filtered[key] = value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return filtered;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/util/fetch.ts
|
|
45
|
+
import fs from "fs";
|
|
46
|
+
import fsp from "fs/promises";
|
|
47
|
+
import stream from "stream";
|
|
48
|
+
import os from "os";
|
|
49
|
+
import { join as join2 } from "node:path";
|
|
50
|
+
class HttpCache {
|
|
51
|
+
#cacheRoot;
|
|
52
|
+
constructor(cacheRoot) {
|
|
53
|
+
if (cacheRoot) {
|
|
54
|
+
this.#cacheRoot = `${cacheRoot}http/`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async match(request, _options) {
|
|
58
|
+
if (!this.#cacheRoot) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const fileName = this.#getFileName(request);
|
|
62
|
+
try {
|
|
63
|
+
const etag = (await fsp.readFile(join2(this.#cacheRoot, `${fileName}.etag`), "utf8")).trim();
|
|
64
|
+
const bodyStream = fs.createReadStream(join2(this.#cacheRoot, `${fileName}.bin`));
|
|
65
|
+
return new Response(stream.Readable.toWeb(bodyStream), { headers: { etag } });
|
|
66
|
+
} catch (e) {
|
|
67
|
+
if (e?.code === "ENOENT") {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
throw e;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async put(request, response) {
|
|
74
|
+
const clonedResponse = response.clone();
|
|
75
|
+
const etag = clonedResponse.headers.get("etag");
|
|
76
|
+
if (!(this.#cacheRoot && clonedResponse.body && etag)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const fileName = this.#getFileName(request);
|
|
80
|
+
await fsp.mkdir(this.#cacheRoot, { recursive: true });
|
|
81
|
+
await Promise.all([
|
|
82
|
+
fsp.writeFile(join2(this.#cacheRoot, `${fileName}.bin`), stream.Readable.fromWeb(clonedResponse.body)),
|
|
83
|
+
fsp.writeFile(join2(this.#cacheRoot, `${fileName}.etag`), `${etag}${os.EOL}`)
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
#getFileName(request) {
|
|
87
|
+
const uriString = request instanceof Request ? request.url : request.toString();
|
|
88
|
+
return Buffer.from(uriString, "utf8").toString("base64url");
|
|
89
|
+
}
|
|
90
|
+
async add() {
|
|
91
|
+
throw new Error("Method not implemented.");
|
|
92
|
+
}
|
|
93
|
+
async addAll() {
|
|
94
|
+
throw new Error("Method not implemented.");
|
|
95
|
+
}
|
|
96
|
+
async delete() {
|
|
97
|
+
throw new Error("Method not implemented.");
|
|
98
|
+
}
|
|
99
|
+
async keys() {
|
|
100
|
+
throw new Error("Method not implemented.");
|
|
101
|
+
}
|
|
102
|
+
async matchAll() {
|
|
103
|
+
throw new Error("Method not implemented.");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
var cache = new HttpCache("./cache");
|
|
107
|
+
async function fetchWithCache(input, init) {
|
|
108
|
+
const request = new Request(input, init);
|
|
109
|
+
const cachedResponse = await cache.match(request);
|
|
110
|
+
const cachedEtag = cachedResponse?.headers.get("ETag");
|
|
111
|
+
if (cachedEtag) {
|
|
112
|
+
request.headers.set("If-None-Match", cachedEtag);
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const response = await fetch(request);
|
|
116
|
+
if (response.status === 304) {
|
|
117
|
+
console.info(`[fetchWithCache] reusing cache for ${request.url}`);
|
|
118
|
+
return cachedResponse;
|
|
119
|
+
} else {
|
|
120
|
+
try {
|
|
121
|
+
await cache.put(request, response);
|
|
122
|
+
console.info(`[fetchWithCache] updated cache for ${request.url}`);
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.warn("[fetchWithCache] put cache", e);
|
|
125
|
+
}
|
|
126
|
+
return response;
|
|
127
|
+
}
|
|
128
|
+
} catch (e) {
|
|
129
|
+
console.warn("[fetchWithCache] fetch", e);
|
|
130
|
+
if (cachedResponse) {
|
|
131
|
+
console.info(`[fetchWithCache] falling back to cache for ${request.url}`);
|
|
132
|
+
return cachedResponse;
|
|
133
|
+
}
|
|
134
|
+
throw e;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/typegen/index.ts
|
|
139
|
+
import { AllCategories } from "@spyglassmc/core";
|
|
140
|
+
import ts26 from "typescript";
|
|
141
|
+
|
|
142
|
+
// src/typegen/mcdoc/list/list.ts
|
|
143
|
+
import ts3 from "typescript";
|
|
144
|
+
import * as mcdoc2 from "@spyglassmc/mcdoc";
|
|
145
|
+
|
|
146
|
+
// src/typegen/mcdoc/utils.ts
|
|
147
|
+
function is_valid_registry(symbols, registry_id) {
|
|
148
|
+
if (symbols === undefined) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
const registry_name = registry_id.replace(/^minecraft:/, "");
|
|
152
|
+
const registry = symbols.getVisibleSymbols(registry_name);
|
|
153
|
+
return Object.keys(registry).length > 0;
|
|
154
|
+
}
|
|
155
|
+
function add_import(imports, add_import2) {
|
|
156
|
+
if (imports === undefined) {
|
|
157
|
+
return {
|
|
158
|
+
ordered: [add_import2],
|
|
159
|
+
check: new Map([[add_import2, 0]])
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (imports.check.has(add_import2)) {
|
|
163
|
+
return imports;
|
|
164
|
+
}
|
|
165
|
+
if (imports.ordered.length === 1) {
|
|
166
|
+
const existing_import = imports.ordered[0];
|
|
167
|
+
if (add_import2.localeCompare(existing_import) < 0) {
|
|
168
|
+
imports.ordered.unshift(add_import2);
|
|
169
|
+
imports.check.set(add_import2, 0);
|
|
170
|
+
imports.check.set(existing_import, 1);
|
|
171
|
+
} else {
|
|
172
|
+
imports.ordered.push(add_import2);
|
|
173
|
+
imports.check.set(add_import2, 1);
|
|
174
|
+
}
|
|
175
|
+
return imports;
|
|
176
|
+
}
|
|
177
|
+
let left = 0;
|
|
178
|
+
let right = imports.ordered.length;
|
|
179
|
+
while (left < right) {
|
|
180
|
+
const mid = Math.floor((left + right) / 2);
|
|
181
|
+
const mid_path = imports.ordered[mid];
|
|
182
|
+
if (add_import2.localeCompare(mid_path) < 0) {
|
|
183
|
+
right = mid;
|
|
184
|
+
} else {
|
|
185
|
+
left = mid + 1;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
imports.ordered.splice(left, 0, add_import2);
|
|
189
|
+
imports.check.set(add_import2, left);
|
|
190
|
+
for (let i = left + 1;i < imports.ordered.length; i++) {
|
|
191
|
+
imports.check.set(imports.ordered[i], i);
|
|
192
|
+
}
|
|
193
|
+
return imports;
|
|
194
|
+
}
|
|
195
|
+
function merge_imports(imports, new_imports) {
|
|
196
|
+
if (imports === undefined) {
|
|
197
|
+
return new_imports;
|
|
198
|
+
}
|
|
199
|
+
for (const import_path of new_imports.ordered) {
|
|
200
|
+
if (!imports.check.has(import_path)) {
|
|
201
|
+
imports = add_import(imports, import_path);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return imports;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
class Set2 extends global.Set {
|
|
208
|
+
constructor(...args) {
|
|
209
|
+
super(...args);
|
|
210
|
+
}
|
|
211
|
+
has(value) {
|
|
212
|
+
return super.has(value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/typegen/mcdoc/assert.ts
|
|
217
|
+
import { match, P } from "ts-pattern";
|
|
218
|
+
|
|
219
|
+
class AssertKinds {
|
|
220
|
+
static AttributeRootValueKind = new Set2(["dispatcher", "reference", "literal", "tree"]);
|
|
221
|
+
static AttributeTreeChildKind = new Set2(["reference", "literal", "tree"]);
|
|
222
|
+
static ImplementedAttributes = new Set2([
|
|
223
|
+
"id",
|
|
224
|
+
"since",
|
|
225
|
+
"until",
|
|
226
|
+
"permutation",
|
|
227
|
+
"texture_slot",
|
|
228
|
+
"item_slots",
|
|
229
|
+
"tag",
|
|
230
|
+
"team",
|
|
231
|
+
"translation_key",
|
|
232
|
+
"translation_value",
|
|
233
|
+
"crafting_ingredient",
|
|
234
|
+
"block_predicate",
|
|
235
|
+
"game_rule",
|
|
236
|
+
"objective",
|
|
237
|
+
"dispatcher_key",
|
|
238
|
+
"regex_pattern",
|
|
239
|
+
"canonical",
|
|
240
|
+
"color",
|
|
241
|
+
"time_pattern",
|
|
242
|
+
"criterion",
|
|
243
|
+
"nbt",
|
|
244
|
+
"nbt_path",
|
|
245
|
+
"match_regex",
|
|
246
|
+
"deprecated",
|
|
247
|
+
"command",
|
|
248
|
+
"url",
|
|
249
|
+
"uuid",
|
|
250
|
+
"random",
|
|
251
|
+
"divisible_by",
|
|
252
|
+
"entity",
|
|
253
|
+
"integer",
|
|
254
|
+
"score_holder",
|
|
255
|
+
"vector",
|
|
256
|
+
"bitfield",
|
|
257
|
+
"text_component"
|
|
258
|
+
]);
|
|
259
|
+
static RegistryAttributeArgument = new Set2(["registry", "path", "definition", "exclude", "tags", "empty", "prefix"]);
|
|
260
|
+
static RegistryAttributeTagsArgument = new Set2(["allowed", "implicit", "required"]);
|
|
261
|
+
static ColorAttributeKind = new Set2(["composite_rgb", "composite_argb", "hex_rgb", "hex_argb", "dec_rgb", "dec_rgba", "particle", "named"]);
|
|
262
|
+
static CommandAttributeArgument = new Set2(["macro", "slash", "incomplete", "empty", "max_length"]);
|
|
263
|
+
static CommandAttributeSlashKind = new Set2(["allowed", "required", "chat", "none"]);
|
|
264
|
+
static TextureSlotAttributeKind = new Set2(["definition", "value", "reference"]);
|
|
265
|
+
static ArrayKind = new Set2(["byte_array", "int_array", "long_array"]);
|
|
266
|
+
static StructKeyKind = new Set2(["reference", "concrete", "string", "union"]);
|
|
267
|
+
static StructSpreadKind = new Set2(["reference", "dispatcher", "concrete", "template", "struct", "union"]);
|
|
268
|
+
static NumericKind = new Set2(["byte", "double", "float", "int", "long", "short"]);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
class Assert {
|
|
272
|
+
static Attributes(type, implemented) {
|
|
273
|
+
if (type !== undefined) {
|
|
274
|
+
for (const attribute of type) {
|
|
275
|
+
if (attribute.value !== undefined && !AssertKinds.AttributeRootValueKind.has(attribute.value.kind)) {
|
|
276
|
+
throw new Error(`[mcdoc_assert] Attribute Type value is an unsupported kind ${attribute}`);
|
|
277
|
+
}
|
|
278
|
+
if (implemented) {
|
|
279
|
+
if (!AssertKinds.ImplementedAttributes.has(attribute.name)) {
|
|
280
|
+
throw new Error(`[mcdoc_assert] Attribute Type is unsupported ${attribute.name}`);
|
|
281
|
+
}
|
|
282
|
+
const attribute_type = attribute.name;
|
|
283
|
+
match(attribute_type).with("since", "until", "deprecated", () => {
|
|
284
|
+
if (attribute.value === undefined) {
|
|
285
|
+
throw new Error(`[mcdoc_assert] Versioned attribute '${attribute_type}' must have a value`);
|
|
286
|
+
}
|
|
287
|
+
if (attribute.value.kind !== "literal" || attribute.value.value.kind !== "string" || !/^\d+\.\d+(?:\.\d+)?$/.test(attribute.value.value.value)) {
|
|
288
|
+
throw new Error(`[mcdoc_assert] Versioned Attribute Type value is invalid ${attribute.value}`);
|
|
289
|
+
}
|
|
290
|
+
}).with("id", () => {
|
|
291
|
+
if (attribute.value !== undefined) {
|
|
292
|
+
match(attribute.value).with({ kind: "literal", value: { kind: "string", value: P.string } }, () => {}).with({ kind: "tree", values: { registry: { kind: "literal", value: { kind: "string", value: P.string } } } }, (tree) => {
|
|
293
|
+
const invalid_argument = Object.keys(tree.values).find((argument) => !AssertKinds.RegistryAttributeArgument.has(argument));
|
|
294
|
+
if (invalid_argument !== undefined) {
|
|
295
|
+
throw new Error(`[mcdoc_assert] Invalid Registry Attribute Type argument ${invalid_argument}`);
|
|
296
|
+
}
|
|
297
|
+
const args = tree.values;
|
|
298
|
+
if (args.exclude !== undefined) {
|
|
299
|
+
if (args.exclude.kind === "tree") {
|
|
300
|
+
if ("0" in args.exclude.values) {
|
|
301
|
+
Object.values(args.exclude.values).forEach((exclusion) => {
|
|
302
|
+
if (exclusion.kind !== "literal" || exclusion.value.kind !== "string") {
|
|
303
|
+
throw new Error(`[mcdoc_assert] Invalid Registry Attribute Type exclusion ${args.exclude}`);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
} else {
|
|
307
|
+
throw new Error(`[mcdoc_assert] Invalid Registry Attribute Type exclusion ${args.exclude}`);
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
throw new Error(`[mcdoc_assert] Invalid Registry Attribute Type exclusion ${args.exclude}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (args.empty !== undefined) {
|
|
314
|
+
if (args.empty.kind !== "literal" || args.empty.value.value !== "allowed") {
|
|
315
|
+
throw new Error(`[mcdoc_assert] Invalid Registry Attribute Type empty argument ${args.empty}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (args.definition !== undefined) {
|
|
319
|
+
if (args.definition.kind !== "literal" || args.definition?.value.value !== true) {
|
|
320
|
+
throw new Error(`[mcdoc_assert] Invalid Definition Registry Attribute Type ${args.empty}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (args.path !== undefined) {
|
|
324
|
+
if (args.path.kind !== "literal" || !`${args.path.value.value}`.endsWith("/")) {
|
|
325
|
+
throw new Error(`[mcdoc_assert] Invalid Pathed Registry Attribute Type ${args.path}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (args.prefix !== undefined) {
|
|
329
|
+
if (args.prefix.kind !== "literal" || args.prefix.value.value !== "!") {
|
|
330
|
+
throw new Error(`[mcdoc_assert] Invalid Registry Attribute Type prefix ${args.prefix}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (args.tags !== undefined) {
|
|
334
|
+
if (args.tags.kind !== "literal" || !AssertKinds.RegistryAttributeTagsArgument.has(args.tags.value.value)) {
|
|
335
|
+
throw new Error(`[mcdoc_assert] Invalid Tag Registry Attribute Type ${args.tags}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}).otherwise(() => {
|
|
339
|
+
throw new Error(`[mcdoc_assert] Invalid #[id] attribute value format: expected literal string or tree with registry, got kind '${attribute.value?.kind}'`);
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
}).with("bitfield", () => {
|
|
343
|
+
if (attribute.value === undefined || attribute.value.kind !== "reference" || attribute.value.path === undefined) {
|
|
344
|
+
throw new Error(`[mcdoc_assert] #[bitfield] attribute must have a reference value with a defined path, got: ${JSON.stringify(attribute.value)}`);
|
|
345
|
+
}
|
|
346
|
+
}).with("color", () => {
|
|
347
|
+
if (attribute.value === undefined) {
|
|
348
|
+
throw new Error(`[mcdoc_assert] #[color] attribute must have a value`);
|
|
349
|
+
}
|
|
350
|
+
if (attribute.value.kind !== "literal" || attribute.value.value.kind !== "string") {
|
|
351
|
+
throw new Error(`[mcdoc_assert] #[color] attribute value must be a string literal, got kind '${attribute.value.kind}'`);
|
|
352
|
+
}
|
|
353
|
+
if (!AssertKinds.ColorAttributeKind.has(attribute.value.value.value)) {
|
|
354
|
+
throw new Error(`[mcdoc_assert] #[color] attribute has invalid color kind '${attribute.value.value.value}', expected one of: ${[...AssertKinds.ColorAttributeKind].join(", ")}`);
|
|
355
|
+
}
|
|
356
|
+
}).with("command", () => {
|
|
357
|
+
if (attribute.value === undefined) {
|
|
358
|
+
throw new Error(`[mcdoc_assert] #[command] attribute must have a value`);
|
|
359
|
+
}
|
|
360
|
+
if (attribute.value.kind === "tree") {
|
|
361
|
+
const invalid_argument = Object.keys(attribute.value.values).find((argument) => !AssertKinds.CommandAttributeArgument.has(argument));
|
|
362
|
+
if (invalid_argument) {
|
|
363
|
+
throw new Error(`[mcdoc_assert] #[command] attribute has invalid argument '${invalid_argument}', expected one of: ${[...AssertKinds.CommandAttributeArgument].join(", ")}`);
|
|
364
|
+
}
|
|
365
|
+
if ("macro" in attribute.value.values && !("slash" in attribute.value.values)) {
|
|
366
|
+
if (attribute.value.values.macro.kind === "literal") {
|
|
367
|
+
if (attribute.value.values.macro.value.value !== "implicit" && attribute.value.values.macro.value.value !== "allowed") {
|
|
368
|
+
throw new Error(`[mcdoc_assert] #[command(macro)] value must be 'implicit' or 'allowed', got '${attribute.value.values.macro.value.value}'`);
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
throw new Error(`[mcdoc_assert] #[command(macro)] must be a literal, got kind '${attribute.value.values.macro.kind}'`);
|
|
372
|
+
}
|
|
373
|
+
} else if ("slash" in attribute.value.values) {
|
|
374
|
+
if (attribute.value.values.slash.kind === "literal") {
|
|
375
|
+
if (!AssertKinds.CommandAttributeSlashKind.has(attribute.value.values.slash.value.value)) {
|
|
376
|
+
throw new Error(`[mcdoc_assert] #[command(slash)] value must be one of: ${[...AssertKinds.CommandAttributeSlashKind].join(", ")}, got '${attribute.value.values.slash.value.value}'`);
|
|
377
|
+
}
|
|
378
|
+
} else {
|
|
379
|
+
throw new Error(`[mcdoc_assert] #[command(slash)] must be a literal, got kind '${attribute.value.values.slash.kind}'`);
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
throw new Error(`[mcdoc_assert] #[command] attribute must have either 'macro' or 'slash' argument`);
|
|
383
|
+
}
|
|
384
|
+
if ("empty" in attribute.value.values) {
|
|
385
|
+
if (attribute.value.values.empty.kind === "literal") {
|
|
386
|
+
if (attribute.value.values.empty.value.value !== "allowed") {
|
|
387
|
+
throw new Error(`[mcdoc_assert] #[command(empty)] value must be 'allowed', got '${attribute.value.values.empty.value.value}'`);
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
throw new Error(`[mcdoc_assert] #[command(empty)] must be a literal, got kind '${attribute.value.values.empty.kind}'`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if ("max_length" in attribute.value.values) {
|
|
394
|
+
if (attribute.value.values.max_length.kind === "literal") {
|
|
395
|
+
if (attribute.value.values.max_length.value.kind !== "int" || attribute.value.values.max_length.value.value < 4) {
|
|
396
|
+
throw new Error(`[mcdoc_assert] #[command(max_length)] value must be an integer >= 4, got '${attribute.value.values.max_length.value.value}'`);
|
|
397
|
+
}
|
|
398
|
+
} else {
|
|
399
|
+
throw new Error(`[mcdoc_assert] #[command(max_length)] must be a literal, got kind '${attribute.value.values.max_length.kind}'`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if ("incomplete" in attribute.value.values) {
|
|
403
|
+
if (attribute.value.values.incomplete.kind === "literal") {
|
|
404
|
+
if (attribute.value.values.incomplete.value.value !== "allowed") {
|
|
405
|
+
throw new Error(`[mcdoc_assert] #[command(incomplete)] value must be 'allowed', got '${attribute.value.values.incomplete.value.value}'`);
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
throw new Error(`[mcdoc_assert] #[command(incomplete)] must be a literal, got kind '${attribute.value.values.incomplete.kind}'`);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
} else {
|
|
412
|
+
throw new Error(`[mcdoc_assert] #[command] attribute value must be a tree, got kind '${attribute.value.kind}'`);
|
|
413
|
+
}
|
|
414
|
+
}).with("criterion", "crafting_ingredient", () => {
|
|
415
|
+
if (attribute.value !== undefined) {
|
|
416
|
+
if (attribute.value.kind !== "tree" || !("definition" in attribute.value.values) || attribute.value.values.definition.kind !== "literal" || attribute.value.values.definition.value.value !== true) {
|
|
417
|
+
throw new Error(`[mcdoc_assert] #[${attribute_type}] attribute value must be a tree with 'definition: true', got: ${JSON.stringify(attribute.value)}`);
|
|
418
|
+
}
|
|
419
|
+
if (Object.keys(attribute.value.values).length > 1) {
|
|
420
|
+
throw new Error(`[mcdoc_assert] #[${attribute_type}] attribute tree has unexpected extra arguments: ${Object.keys(attribute.value.values).filter((k) => k !== "definition").join(", ")}`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}).with("dispatcher_key", () => {
|
|
424
|
+
if (attribute.value === undefined) {
|
|
425
|
+
throw new Error(`[mcdoc_assert] #[dispatcher_key] attribute must have a value`);
|
|
426
|
+
}
|
|
427
|
+
if (attribute.value.kind !== "literal" || !/^[\w_]+:[\w_]+$/.test(`${attribute.value.value.value}`)) {
|
|
428
|
+
throw new Error(`[mcdoc_assert] #[dispatcher_key] attribute value must be a namespaced ID (e.g., 'namespace:path'), got '${attribute.value?.kind === "literal" ? attribute.value.value.value : attribute.value.kind}'`);
|
|
429
|
+
}
|
|
430
|
+
}).with("divisible_by", () => {
|
|
431
|
+
if (attribute.value === undefined) {
|
|
432
|
+
throw new Error(`[mcdoc_assert] #[divisible_by] attribute must have a value`);
|
|
433
|
+
}
|
|
434
|
+
if (attribute.value.kind !== "literal" || !Number.isInteger(Number(attribute.value.value.value))) {
|
|
435
|
+
throw new Error(`[mcdoc_assert] #[divisible_by] attribute value must be an integer literal, got: ${JSON.stringify(attribute.value)}`);
|
|
436
|
+
}
|
|
437
|
+
}).with("integer", () => {
|
|
438
|
+
if (attribute.value === undefined) {
|
|
439
|
+
throw new Error(`[mcdoc_assert] #[integer] attribute must have a value`);
|
|
440
|
+
}
|
|
441
|
+
if (attribute.value.kind !== "tree" || !("min" in attribute.value.values) || attribute.value.values.min.kind !== "literal" || attribute.value.values.min.value.value !== 1) {
|
|
442
|
+
throw new Error(`[mcdoc_assert] #[integer] attribute value must be a tree with 'min: 1', got: ${JSON.stringify(attribute.value)}`);
|
|
443
|
+
}
|
|
444
|
+
if (Object.keys(attribute.value.values).length > 1) {
|
|
445
|
+
throw new Error(`[mcdoc_assert] #[integer] attribute tree has unexpected extra arguments: ${Object.keys(attribute.value.values).filter((k) => k !== "min").join(", ")}`);
|
|
446
|
+
}
|
|
447
|
+
}).with("nbt", () => {
|
|
448
|
+
if (attribute.value !== undefined && attribute.value.kind !== "dispatcher" && attribute.value.kind !== "reference") {
|
|
449
|
+
throw new Error(`[mcdoc_assert] #[nbt] attribute value must be a dispatcher or reference, got kind '${attribute.value.kind}'`);
|
|
450
|
+
}
|
|
451
|
+
if (attribute.value?.kind === "reference" && attribute.value.path === undefined) {
|
|
452
|
+
throw new Error(`[mcdoc_assert] #[nbt] attribute reference value must have a defined path`);
|
|
453
|
+
}
|
|
454
|
+
}).with("nbt_path", () => {
|
|
455
|
+
if (attribute.value !== undefined && attribute.value.kind !== "dispatcher") {
|
|
456
|
+
throw new Error(`[mcdoc_assert] #[nbt_path] attribute value must be a dispatcher, got kind '${attribute.value.kind}'`);
|
|
457
|
+
}
|
|
458
|
+
}).with("match_regex", () => {
|
|
459
|
+
if (attribute.value === undefined || attribute.value.kind !== "literal" || attribute.value.value.kind !== "string") {
|
|
460
|
+
throw new Error(`[mcdoc_assert] #[match_regex] attribute value must be a string literal, got: ${JSON.stringify(attribute.value)}`);
|
|
461
|
+
} else {
|
|
462
|
+
try {
|
|
463
|
+
new RegExp(attribute.value.value.value);
|
|
464
|
+
} catch (e) {
|
|
465
|
+
throw new Error(`[mcdoc_assert] #[match_regex] attribute contains invalid regex pattern '${attribute.value.value.value}': ${e}`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}).with("permutation", () => {
|
|
469
|
+
if (attribute.value === undefined) {
|
|
470
|
+
throw new Error(`[mcdoc_assert] #[permutation] attribute must have a value`);
|
|
471
|
+
}
|
|
472
|
+
if (!(attribute.value.kind === "tree" && ("definition" in attribute.value.values) && attribute.value.values.definition.kind === "literal" && attribute.value.values.definition.value.value === true)) {
|
|
473
|
+
throw new Error(`[mcdoc_assert] #[permutation] attribute value must be a tree with 'definition: true', got: ${JSON.stringify(attribute.value)}`);
|
|
474
|
+
}
|
|
475
|
+
if (Object.keys(attribute.value.values).length > 1) {
|
|
476
|
+
throw new Error(`[mcdoc_assert] #[permutation] attribute tree has unexpected extra arguments: ${Object.keys(attribute.value.values).filter((k) => k !== "definition").join(", ")}`);
|
|
477
|
+
}
|
|
478
|
+
}).with("entity", (entity) => {
|
|
479
|
+
if (attribute.value !== undefined) {
|
|
480
|
+
if (attribute.value.kind !== "tree") {
|
|
481
|
+
throw new Error(`[mcdoc_assert] #[entity] attribute value must contain arguments, received a ${attribute.value.kind}`);
|
|
482
|
+
}
|
|
483
|
+
const keys = new Set2(Object.keys(attribute.value.values));
|
|
484
|
+
if ("amount" in attribute.value.values) {
|
|
485
|
+
keys.delete("amount");
|
|
486
|
+
if (attribute.value.values.amount.kind !== "literal" || attribute.value.values.amount.value.kind !== "string") {
|
|
487
|
+
throw new Error(`[mcdoc_assert] #[entity(amount)] has unsupported value: ${JSON.stringify(attribute.value.values.amount)}`);
|
|
488
|
+
}
|
|
489
|
+
if (attribute.value.values.amount.value.value !== "multiple" && attribute.value.values.amount.value.value !== "single") {
|
|
490
|
+
throw new Error(`[mcdoc_assert] #[entity(amount="${attribute.value.values.amount.value.value}")] is unsupported`);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
if ("type" in attribute.value.values) {
|
|
494
|
+
keys.delete("type");
|
|
495
|
+
if (attribute.value.values.type.kind !== "literal" || attribute.value.values.type.value.kind !== "string") {
|
|
496
|
+
throw new Error(`[mcdoc_assert] #[entity(type)] has unsupported value: ${JSON.stringify(attribute.value.values.type)}`);
|
|
497
|
+
}
|
|
498
|
+
if (attribute.value.values.type.value.value !== "entities" && attribute.value.values.type.value.value !== "players") {
|
|
499
|
+
throw new Error(`[mcdoc_assert] #[entity(type="${attribute.value.values.type.value.value}")] is unsupported`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if (keys.size > 0) {
|
|
503
|
+
throw new Error(`[mcdoc_assert] Unsupported #[entity] attribute arguments: ${[...keys.values()].join(", ")}`);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}).with("random", "regex_pattern", "time_pattern", "canonical", "text_component", "score_holder", "objective", "translation_key", "translation_value", "item_slots", "uuid", "url", "team", "game_rule", "tag", "block_predicate", (a) => {
|
|
507
|
+
if (a !== "translation_key" && a !== "game_rule" && attribute.value !== undefined) {
|
|
508
|
+
console.log(attribute);
|
|
509
|
+
throw new Error(`[mcdoc_assert] Unexpected value on attribute '${a}'`);
|
|
510
|
+
}
|
|
511
|
+
}).with("texture_slot", () => {
|
|
512
|
+
if (attribute.value === undefined) {
|
|
513
|
+
throw new Error(`[mcdoc_assert] #[texture_slot] attribute must have a value`);
|
|
514
|
+
}
|
|
515
|
+
if (attribute.value.kind !== "tree" || !("kind" in attribute.value.values) || attribute.value.values.kind.kind !== "literal" || !AssertKinds.TextureSlotAttributeKind.has(attribute.value.values.kind.value.value)) {
|
|
516
|
+
throw new Error(`[mcdoc_assert] #[texture_slot] attribute value must be a tree with a valid 'kind' (one of: ${[...AssertKinds.TextureSlotAttributeKind].join(", ")}), got: ${JSON.stringify(attribute.value)}`);
|
|
517
|
+
}
|
|
518
|
+
if (Object.keys(attribute.value.values).length > 1) {
|
|
519
|
+
throw new Error(`[mcdoc_assert] #[texture_slot] attribute tree has unexpected extra arguments: ${Object.keys(attribute.value.values).filter((k) => k !== "kind").join(", ")}`);
|
|
520
|
+
}
|
|
521
|
+
}).with("vector", () => {
|
|
522
|
+
if (attribute.value === undefined) {
|
|
523
|
+
throw new Error(`[mcdoc_assert] #[vector] attribute must have a value`);
|
|
524
|
+
}
|
|
525
|
+
if (attribute.value.kind !== "tree" || !("dimension" in attribute.value.values) || !("integer" in attribute.value.values)) {
|
|
526
|
+
throw new Error(`[mcdoc_assert] #[vector] attribute value must be a tree with 'dimension' and 'integer' arguments, got: ${JSON.stringify(attribute.value)}`);
|
|
527
|
+
}
|
|
528
|
+
if (attribute.value.values.dimension.kind !== "literal" || attribute.value.values.dimension.value.value !== 3) {
|
|
529
|
+
throw new Error(`[mcdoc_assert] #[vector(dimension)] must be 3, got: ${JSON.stringify(attribute.value.values.dimension)}`);
|
|
530
|
+
}
|
|
531
|
+
if (attribute.value.values.integer.kind !== "literal" || attribute.value.values.integer.value.value !== true) {
|
|
532
|
+
throw new Error(`[mcdoc_assert] #[vector(integer)] must be true, got: ${JSON.stringify(attribute.value.values.integer)}`);
|
|
533
|
+
}
|
|
534
|
+
if (Object.keys(attribute.value.values).length > 2) {
|
|
535
|
+
throw new Error(`[mcdoc_assert] #[vector] attribute tree has unexpected extra arguments: ${Object.keys(attribute.value.values).filter((k) => k !== "dimension" && k !== "integer").join(", ")}`);
|
|
536
|
+
}
|
|
537
|
+
}).exhaustive();
|
|
538
|
+
} else if (attribute.value !== undefined) {
|
|
539
|
+
switch (attribute.value.kind) {
|
|
540
|
+
case "literal":
|
|
541
|
+
{
|
|
542
|
+
if (attribute.value.value.kind !== "string") {
|
|
543
|
+
throw new Error(`[mcdoc_assert] Literal Attribute Type value type is an unsupported kind ${attribute}`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
break;
|
|
547
|
+
case "reference":
|
|
548
|
+
{
|
|
549
|
+
if (attribute.value.path === undefined) {
|
|
550
|
+
throw new Error(`[mcdoc_assert] Reference Attribute Type value type must have a defined path ${attribute}`);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
break;
|
|
554
|
+
case "tree":
|
|
555
|
+
{
|
|
556
|
+
for (const [key, value] of Object.entries(attribute.value.values)) {
|
|
557
|
+
if (!Number.isNaN(Number(key.charAt(0)))) {
|
|
558
|
+
throw new Error(`[mcdoc_assert] Root Tree Attribute Type value type is an array, this is unsupported ${attribute}`);
|
|
559
|
+
}
|
|
560
|
+
if (!AssertKinds.AttributeTreeChildKind.has(value.kind)) {
|
|
561
|
+
throw new Error(`[mcdoc_assert] Root Tree Attribute Type value value is an unsupported kind ${attribute}`);
|
|
562
|
+
}
|
|
563
|
+
switch (value.kind) {
|
|
564
|
+
case "literal":
|
|
565
|
+
{
|
|
566
|
+
if (value.value.kind !== "boolean" && value.value.kind !== "string") {
|
|
567
|
+
throw new Error(`[mcdoc_assert] Numerical Literal Root Tree Attribute Type value value type is unsupported ${attribute}`);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
break;
|
|
571
|
+
case "tree": {
|
|
572
|
+
if (!("0" in value.values)) {
|
|
573
|
+
throw new Error(`[mcdoc_assert] Nested Named Tree Attribute value type is unsupported ${attribute}`);
|
|
574
|
+
}
|
|
575
|
+
for (const member of Object.values(value.values)) {
|
|
576
|
+
if (member.kind !== "literal" || member.value.kind !== "string") {
|
|
577
|
+
throw new Error(`[mcdoc_assert] Array Attribute Type value type is not string, this is unsupported ${attribute}`);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
static DispatcherType(type) {
|
|
591
|
+
if (type.kind !== "dispatcher") {}
|
|
592
|
+
}
|
|
593
|
+
static IndexedType(type) {
|
|
594
|
+
if (type.kind !== "indexed") {
|
|
595
|
+
throw new Error(`[mcdoc_assert] Type is not an IndexedType: ${type.kind}`);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
static TemplateType(type) {
|
|
599
|
+
if (type.kind !== "template") {
|
|
600
|
+
throw new Error(`[mcdoc_assert] Type is not a TemplateType: ${type.kind}`);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
static ArrayType(type) {
|
|
604
|
+
if (!AssertKinds.ArrayKind.has(type.kind)) {
|
|
605
|
+
throw new Error(`[mcdoc_assert] Type is not a PrimitiveArrayType: ${type.kind}`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
static ListType(type) {
|
|
609
|
+
if (type.kind !== "list") {
|
|
610
|
+
throw new Error(`[mcdoc_assert] Type is not a ListType: ${type.kind}`);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
static EnumType(type) {
|
|
614
|
+
if (type.kind !== "enum") {
|
|
615
|
+
throw new Error(`[mcdoc_assert] Type is not an EnumType: ${type.kind}`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
static StructType(type) {
|
|
619
|
+
if (type.kind !== "struct") {
|
|
620
|
+
throw new Error(`[mcdoc_assert] Type is not a StructType: ${type.kind}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
static StructKeyType(type) {
|
|
624
|
+
if (!AssertKinds.StructKeyKind.has(type.kind)) {
|
|
625
|
+
throw new Error(`[mcdoc_assert] Struct field key must be a ReferenceType or StringType, got: ${type.kind}`);
|
|
626
|
+
}
|
|
627
|
+
if (type.kind === "concrete" && (type.child.kind !== "reference" || type.child.path === undefined)) {
|
|
628
|
+
throw new Error(`[mcdoc_assert] Struct field key ConcreteType must wrap a ReferenceType with a defined path. ${type}`);
|
|
629
|
+
}
|
|
630
|
+
if (type.kind === "reference" && type.path === undefined) {
|
|
631
|
+
throw new Error(`[mcdoc_assert] Struct field key ReferenceType must have a path defined. ${type}`);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
static StructSpreadType(type) {
|
|
635
|
+
if (!AssertKinds.StructSpreadKind.has(type.kind)) {
|
|
636
|
+
throw new Error(`[mcdoc_assert] Struct spread type must be a reference-alike, got: ${type.kind}`);
|
|
637
|
+
}
|
|
638
|
+
if (type.kind === "reference" && type.path === undefined) {
|
|
639
|
+
throw new Error(`[mcdoc_assert] Struct spread ReferenceType must have a path defined. ${type}`);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
static TupleType(type) {
|
|
643
|
+
if (type.kind !== "tuple") {
|
|
644
|
+
throw new Error(`[mcdoc_assert] Type is not a TupleType: ${type.kind}`);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
static UnionType(type) {
|
|
648
|
+
if (type.kind !== "union") {
|
|
649
|
+
throw new Error(`[mcdoc_assert] Type is not a UnionType: ${type.kind}`);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
static KeywordType(type) {
|
|
653
|
+
if (type.kind !== "any" && type.kind !== "boolean" && type.kind !== "unsafe") {
|
|
654
|
+
throw new Error(`[mcdoc_assert] Type is not a KeywordType: ${type.kind}`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
static NumericType(type) {
|
|
658
|
+
if (!AssertKinds.NumericKind.has(type.kind)) {
|
|
659
|
+
throw new Error(`[mcdoc_assert] Type is not a NumericType: ${type.kind}`);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
static ConcreteType(type) {
|
|
663
|
+
if (type.kind !== "concrete") {
|
|
664
|
+
throw new Error(`[mcdoc_assert] Type is not a ConcreteType: ${type.kind}`);
|
|
665
|
+
}
|
|
666
|
+
if (type.child.kind === "reference") {
|
|
667
|
+
if (type.child.path === undefined) {
|
|
668
|
+
throw new Error(`[mcdoc_assert] ConcreteType child type of ReferenceType is missing a path: ${type}`);
|
|
669
|
+
}
|
|
670
|
+
} else if (type.child.kind !== "dispatcher") {
|
|
671
|
+
throw new Error(`[mcdoc_assert] Concrete child type is invalid: ${type}`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
static LiteralType(type) {
|
|
675
|
+
if (type.kind !== "literal") {
|
|
676
|
+
throw new Error(`[mcdoc_assert] Type is not a LiteralType: ${type.kind}`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
static ReferenceType(type) {
|
|
680
|
+
if (type.kind !== "reference" || type.path === undefined) {
|
|
681
|
+
throw new Error(`[mcdoc_assert] Type is not a valid ReferenceType: ${type}`);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
static StringType(type) {
|
|
685
|
+
if (type.kind !== "string") {
|
|
686
|
+
throw new Error(`[mcdoc_assert] Type is not a StringType: ${type.kind}`);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
static ColorStringType(type) {
|
|
690
|
+
if (type !== "hex_argb" && type !== "hex_rgb") {
|
|
691
|
+
throw new Error(`[mcdoc_assert] String color type is not valid ${type}`);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// src/typegen/mcdoc/bind.ts
|
|
697
|
+
import ts from "typescript";
|
|
698
|
+
var { factory } = ts;
|
|
699
|
+
|
|
700
|
+
class Bind {
|
|
701
|
+
static NumericLiteral(literal) {
|
|
702
|
+
if (Math.sign(literal) === -1) {
|
|
703
|
+
return factory.createLiteralTypeNode(factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(literal))));
|
|
704
|
+
} else {
|
|
705
|
+
return factory.createLiteralTypeNode(factory.createNumericLiteral(literal));
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
static StringLiteral(literal) {
|
|
709
|
+
return factory.createLiteralTypeNode(factory.createStringLiteral(literal, true));
|
|
710
|
+
}
|
|
711
|
+
static NonEmptyString = factory.createTemplateLiteralType(factory.createTemplateHead(""), [
|
|
712
|
+
factory.createTemplateLiteralTypeSpan(factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), factory.createTemplateMiddle("")),
|
|
713
|
+
factory.createTemplateLiteralTypeSpan(factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), factory.createTemplateTail(""))
|
|
714
|
+
]);
|
|
715
|
+
static Namespaced = factory.createTemplateLiteralType(factory.createTemplateHead(""), [
|
|
716
|
+
factory.createTemplateLiteralTypeSpan(factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), factory.createTemplateMiddle(":")),
|
|
717
|
+
factory.createTemplateLiteralTypeSpan(factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), factory.createTemplateTail(""))
|
|
718
|
+
]);
|
|
719
|
+
static MappedType(key_type, value_type, options) {
|
|
720
|
+
const { key_name = "Key", parenthesized = true } = options ?? {};
|
|
721
|
+
const constraint_type = key_type.kind === ts.SyntaxKind.StringKeyword ? Bind.NonEmptyString : factory.createTypeReferenceNode("Extract", [
|
|
722
|
+
key_type,
|
|
723
|
+
factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
724
|
+
]);
|
|
725
|
+
const mapped_type = factory.createMappedTypeNode(undefined, factory.createTypeParameterDeclaration(undefined, key_name, constraint_type), undefined, factory.createToken(ts.SyntaxKind.QuestionToken), value_type, undefined);
|
|
726
|
+
return parenthesized ? factory.createParenthesizedType(mapped_type) : mapped_type;
|
|
727
|
+
}
|
|
728
|
+
static EmptyObject = factory.createTypeReferenceNode("Record", [
|
|
729
|
+
factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
730
|
+
factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)
|
|
731
|
+
]);
|
|
732
|
+
static DocPart(doc) {
|
|
733
|
+
return doc.trim().replaceAll(`
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
`, "@@bad@@").replaceAll(`
|
|
738
|
+
|
|
739
|
+
`, `
|
|
740
|
+
`).replaceAll("@@bad@@", `
|
|
741
|
+
|
|
742
|
+
`).split(`
|
|
743
|
+
`);
|
|
744
|
+
}
|
|
745
|
+
static Doc(node, docs) {
|
|
746
|
+
let doc = "*";
|
|
747
|
+
if (docs === undefined) {
|
|
748
|
+
return node;
|
|
749
|
+
}
|
|
750
|
+
for (const _doc of docs) {
|
|
751
|
+
if (Array.isArray(_doc)) {
|
|
752
|
+
try {
|
|
753
|
+
const sanitized = Bind.DocPart(_doc[0]);
|
|
754
|
+
for (const __doc of sanitized) {
|
|
755
|
+
if (__doc === "") {
|
|
756
|
+
doc += `
|
|
757
|
+
*`;
|
|
758
|
+
} else {
|
|
759
|
+
doc += `
|
|
760
|
+
* ${__doc}`;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
} catch (e) {
|
|
764
|
+
console.log(node, docs);
|
|
765
|
+
}
|
|
766
|
+
} else {
|
|
767
|
+
if (_doc === "") {
|
|
768
|
+
doc += `
|
|
769
|
+
*`;
|
|
770
|
+
} else {
|
|
771
|
+
doc += `
|
|
772
|
+
* ${_doc}`;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `${doc}
|
|
777
|
+
`, true);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// src/typegen/mcdoc/primitives/int.ts
|
|
782
|
+
import * as mcdoc from "@spyglassmc/mcdoc";
|
|
783
|
+
import ts2 from "typescript";
|
|
784
|
+
var { factory: factory2 } = ts2;
|
|
785
|
+
var NBTIntType = "NBTInt";
|
|
786
|
+
function mcdoc_int(type) {
|
|
787
|
+
const int = type;
|
|
788
|
+
Assert.NumericType(int);
|
|
789
|
+
return (args) => {
|
|
790
|
+
if (int.valueRange === undefined) {
|
|
791
|
+
return {
|
|
792
|
+
type: factory2.createTypeReferenceNode(NBTIntType),
|
|
793
|
+
imports: {
|
|
794
|
+
ordered: [`sandstone::${NBTIntType}`],
|
|
795
|
+
check: new Map([[`sandstone::${NBTIntType}`, 0]])
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
} else {
|
|
799
|
+
return whole_number_generic(int.valueRange, NBTIntType);
|
|
800
|
+
}
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
var McdocInt = mcdoc_int;
|
|
804
|
+
function whole_number_generic(range, type) {
|
|
805
|
+
const docs = [
|
|
806
|
+
`Range: ${mcdoc.NumericRange.toString(range)}`
|
|
807
|
+
];
|
|
808
|
+
const generic = [];
|
|
809
|
+
let has_min = false;
|
|
810
|
+
let has_max = false;
|
|
811
|
+
const left_exclusive = mcdoc.RangeKind.isLeftExclusive(range.kind);
|
|
812
|
+
const right_exclusive = mcdoc.RangeKind.isRightExclusive(range.kind);
|
|
813
|
+
if (range.min !== undefined) {
|
|
814
|
+
has_min = true;
|
|
815
|
+
if (left_exclusive) {
|
|
816
|
+
docs.push(`Effective minimum: ${range.min + 1}`);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (range.max !== undefined) {
|
|
820
|
+
has_max = true;
|
|
821
|
+
if (right_exclusive) {
|
|
822
|
+
docs.push(`Effective maximum: ${range.max - 1}`);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
if (has_min && has_max) {
|
|
826
|
+
if (integer_range_size(range.min, range.max) <= 100) {
|
|
827
|
+
generic.push(factory2.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(range.min + (left_exclusive ? 1 : 0))), factory2.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(range.max - (right_exclusive ? 1 : 0))));
|
|
828
|
+
} else if (range.min >= 0) {
|
|
829
|
+
let number = 0;
|
|
830
|
+
if (left_exclusive && range.min === 0 || range.min >= 1) {
|
|
831
|
+
number = 1;
|
|
832
|
+
}
|
|
833
|
+
generic.push(factory2.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(number)));
|
|
834
|
+
}
|
|
835
|
+
} else if (has_min) {
|
|
836
|
+
if (range.min >= 0) {
|
|
837
|
+
let number = 0;
|
|
838
|
+
if (left_exclusive && range.min === 0 || range.min >= 1) {
|
|
839
|
+
number = 1;
|
|
840
|
+
}
|
|
841
|
+
generic.push(factory2.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(number)));
|
|
842
|
+
} else if (left_exclusive) {
|
|
843
|
+
generic.push(factory2.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(range.min)));
|
|
844
|
+
}
|
|
845
|
+
} else {
|
|
846
|
+
if (range.max < 0 || right_exclusive && range.max === 0) {
|
|
847
|
+
generic.push(factory2.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(-1)));
|
|
848
|
+
} else if (right_exclusive) {
|
|
849
|
+
generic.push(factory2.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(range.max)));
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return {
|
|
853
|
+
type: factory2.createTypeReferenceNode(type, [
|
|
854
|
+
factory2.createTypeLiteralNode(generic)
|
|
855
|
+
]),
|
|
856
|
+
docs,
|
|
857
|
+
imports: {
|
|
858
|
+
ordered: [`sandstone::${type}`],
|
|
859
|
+
check: new Map([[`sandstone::${type}`, 0]])
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
function integer_range_size(lower, upper) {
|
|
864
|
+
if (lower > upper) {
|
|
865
|
+
throw new Error(`[mcdoc_int] Invalid integer range: lower bound (${lower}) must be <= upper bound (${upper})`);
|
|
866
|
+
}
|
|
867
|
+
if (upper < 0) {
|
|
868
|
+
return lower * -1 - upper * -1;
|
|
869
|
+
}
|
|
870
|
+
if (lower < 0) {
|
|
871
|
+
return lower * -1 + upper;
|
|
872
|
+
}
|
|
873
|
+
return upper - lower;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// src/typegen/mcdoc/list/list.ts
|
|
877
|
+
var { factory: factory3 } = ts3;
|
|
878
|
+
var NBTListType = "NBTList";
|
|
879
|
+
var NBTListImport = `sandstone::${NBTListType}`;
|
|
880
|
+
function mcdoc_list(type) {
|
|
881
|
+
const list = type;
|
|
882
|
+
Assert.ListType(list);
|
|
883
|
+
return (args) => {
|
|
884
|
+
args.root_type = false;
|
|
885
|
+
const item = TypeHandlers[list.item.kind](list.item)(args);
|
|
886
|
+
let imports = "imports" in item ? item.imports : undefined;
|
|
887
|
+
const child_dispatcher = "child_dispatcher" in item ? item.child_dispatcher.map(([parent_count, property]) => {
|
|
888
|
+
if (parent_count === 0) {
|
|
889
|
+
throw new Error(`[mcdoc_list] List contains a dynamic dispatcher with invalid parenting: ${item}`);
|
|
890
|
+
}
|
|
891
|
+
return [parent_count - 1, property];
|
|
892
|
+
}) : undefined;
|
|
893
|
+
if (list.lengthRange) {
|
|
894
|
+
const { generic, docs } = length_range_generic(list.lengthRange, "List");
|
|
895
|
+
imports = add_import(imports, NBTListImport);
|
|
896
|
+
const list_type = factory3.createTypeReferenceNode(NBTListType, [
|
|
897
|
+
item.type,
|
|
898
|
+
factory3.createTypeLiteralNode(generic)
|
|
899
|
+
]);
|
|
900
|
+
Object.assign(list_type, { "--mcdoc_has_non_indexable": true });
|
|
901
|
+
return {
|
|
902
|
+
type: list_type,
|
|
903
|
+
docs,
|
|
904
|
+
...add({ imports, child_dispatcher })
|
|
905
|
+
};
|
|
906
|
+
} else {
|
|
907
|
+
const array_type = factory3.createTypeReferenceNode("Array", [item.type]);
|
|
908
|
+
Object.assign(array_type, { "--mcdoc_has_non_indexable": true });
|
|
909
|
+
return {
|
|
910
|
+
type: array_type,
|
|
911
|
+
...add({ imports, child_dispatcher })
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
var McdocList = mcdoc_list;
|
|
917
|
+
function length_range_generic(range, label) {
|
|
918
|
+
const docs = [
|
|
919
|
+
`${label} length range: ${mcdoc2.NumericRange.toString(range)}`
|
|
920
|
+
];
|
|
921
|
+
const generic = [];
|
|
922
|
+
let has_min = false;
|
|
923
|
+
let has_max = false;
|
|
924
|
+
const left_exclusive = mcdoc2.RangeKind.isLeftExclusive(range.kind);
|
|
925
|
+
const right_exclusive = mcdoc2.RangeKind.isRightExclusive(range.kind);
|
|
926
|
+
if (range.min !== undefined) {
|
|
927
|
+
has_min = true;
|
|
928
|
+
generic.push(factory3.createPropertySignature(undefined, "leftExclusive", undefined, factory3.createLiteralTypeNode(left_exclusive ? factory3.createTrue() : factory3.createFalse())));
|
|
929
|
+
if (left_exclusive) {
|
|
930
|
+
docs.push(`Effective minimum ${label.toLowerCase()} length: ${range.min + 1}`);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
if (range.max !== undefined) {
|
|
934
|
+
has_max = true;
|
|
935
|
+
generic.push(factory3.createPropertySignature(undefined, "rightExclusive", undefined, factory3.createLiteralTypeNode(right_exclusive ? factory3.createTrue() : factory3.createFalse())));
|
|
936
|
+
if (right_exclusive) {
|
|
937
|
+
docs.push(`Effective maximum ${label.toLowerCase()} length: ${range.max - 1}`);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
if (has_min && has_max) {
|
|
941
|
+
if (integer_range_size(range.min, range.max) <= 100) {
|
|
942
|
+
generic.push(factory3.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(range.min + (left_exclusive ? 1 : 0))), factory3.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(range.max - (right_exclusive ? 1 : 0))));
|
|
943
|
+
}
|
|
944
|
+
} else if (has_min) {
|
|
945
|
+
if (range.min >= 0) {
|
|
946
|
+
let number = 0;
|
|
947
|
+
if (left_exclusive && range.min === 0 || range.min >= 1) {
|
|
948
|
+
number = 1;
|
|
949
|
+
}
|
|
950
|
+
generic.push(factory3.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(number)));
|
|
951
|
+
} else if (left_exclusive) {
|
|
952
|
+
generic.push(factory3.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(range.min)));
|
|
953
|
+
}
|
|
954
|
+
} else {
|
|
955
|
+
if (range.max < 0 || right_exclusive && range.max === 0) {
|
|
956
|
+
generic.push(factory3.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(-1)));
|
|
957
|
+
} else if (right_exclusive) {
|
|
958
|
+
generic.push(factory3.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(range.max)));
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return { generic, docs };
|
|
962
|
+
}
|
|
963
|
+
// src/typegen/mcdoc/list/array/byte.ts
|
|
964
|
+
import ts4 from "typescript";
|
|
965
|
+
var { factory: factory4 } = ts4;
|
|
966
|
+
var NBTByteArrayType = "NBTByteArray";
|
|
967
|
+
var NBTByteArrayImport = `sandstone::${NBTByteArrayType}`;
|
|
968
|
+
function mcdoc_byte_array(type) {
|
|
969
|
+
Assert.ArrayType(type);
|
|
970
|
+
return (args) => {
|
|
971
|
+
const imports = {
|
|
972
|
+
ordered: [NBTByteArrayImport],
|
|
973
|
+
check: new Map([[NBTByteArrayImport, 0]])
|
|
974
|
+
};
|
|
975
|
+
if (type.lengthRange) {
|
|
976
|
+
const { generic, docs } = length_range_generic(type.lengthRange, "Array");
|
|
977
|
+
return {
|
|
978
|
+
type: factory4.createTypeReferenceNode(NBTByteArrayType, [
|
|
979
|
+
factory4.createTypeLiteralNode(generic)
|
|
980
|
+
]),
|
|
981
|
+
imports,
|
|
982
|
+
docs
|
|
983
|
+
};
|
|
984
|
+
} else {
|
|
985
|
+
return {
|
|
986
|
+
type: factory4.createTypeReferenceNode(NBTByteArrayType),
|
|
987
|
+
imports
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
var McdocByteArray = mcdoc_byte_array;
|
|
993
|
+
// src/typegen/mcdoc/list/array/int.ts
|
|
994
|
+
import ts5 from "typescript";
|
|
995
|
+
var { factory: factory5 } = ts5;
|
|
996
|
+
var NBTIntArrayType = "NBTIntArray";
|
|
997
|
+
var NBTIntArrayImport = `sandstone::${NBTIntArrayType}`;
|
|
998
|
+
function mcdoc_int_array(type) {
|
|
999
|
+
Assert.ArrayType(type);
|
|
1000
|
+
return (args) => {
|
|
1001
|
+
const imports = {
|
|
1002
|
+
ordered: [NBTIntArrayImport],
|
|
1003
|
+
check: new Map([[NBTIntArrayImport, 0]])
|
|
1004
|
+
};
|
|
1005
|
+
if (type.lengthRange) {
|
|
1006
|
+
const { generic, docs } = length_range_generic(type.lengthRange, "Array");
|
|
1007
|
+
return {
|
|
1008
|
+
type: factory5.createTypeReferenceNode(NBTIntArrayType, [
|
|
1009
|
+
factory5.createTypeLiteralNode(generic)
|
|
1010
|
+
]),
|
|
1011
|
+
imports,
|
|
1012
|
+
docs
|
|
1013
|
+
};
|
|
1014
|
+
} else {
|
|
1015
|
+
return {
|
|
1016
|
+
type: factory5.createTypeReferenceNode(NBTIntArrayType),
|
|
1017
|
+
imports
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
var McdocIntArray = mcdoc_int_array;
|
|
1023
|
+
// src/typegen/mcdoc/list/array/long.ts
|
|
1024
|
+
import ts6 from "typescript";
|
|
1025
|
+
var { factory: factory6 } = ts6;
|
|
1026
|
+
var NBTLongArrayType = "NBTLongArray";
|
|
1027
|
+
var NBTLongArrayImport = `sandstone::${NBTLongArrayType}`;
|
|
1028
|
+
function mcdoc_long_array(type) {
|
|
1029
|
+
Assert.ArrayType(type);
|
|
1030
|
+
return (args) => {
|
|
1031
|
+
const imports = {
|
|
1032
|
+
ordered: [NBTLongArrayImport],
|
|
1033
|
+
check: new Map([[NBTLongArrayImport, 0]])
|
|
1034
|
+
};
|
|
1035
|
+
if (type.lengthRange) {
|
|
1036
|
+
const { generic, docs } = length_range_generic(type.lengthRange, "Array");
|
|
1037
|
+
return {
|
|
1038
|
+
type: factory6.createTypeReferenceNode(NBTLongArrayType, [
|
|
1039
|
+
factory6.createTypeLiteralNode(generic)
|
|
1040
|
+
]),
|
|
1041
|
+
imports,
|
|
1042
|
+
docs
|
|
1043
|
+
};
|
|
1044
|
+
} else {
|
|
1045
|
+
return {
|
|
1046
|
+
type: factory6.createTypeReferenceNode(NBTLongArrayType),
|
|
1047
|
+
imports
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
var McdocLongArray = mcdoc_long_array;
|
|
1053
|
+
// src/typegen/mcdoc/primitives/any.ts
|
|
1054
|
+
import ts7 from "typescript";
|
|
1055
|
+
var { factory: factory7 } = ts7;
|
|
1056
|
+
var static_value = {
|
|
1057
|
+
type: factory7.createKeywordTypeNode(ts7.SyntaxKind.UnknownKeyword)
|
|
1058
|
+
};
|
|
1059
|
+
function mcdoc_any(type) {
|
|
1060
|
+
const any = type;
|
|
1061
|
+
Assert.KeywordType(any);
|
|
1062
|
+
return (args) => static_value;
|
|
1063
|
+
}
|
|
1064
|
+
var McdocAny = mcdoc_any;
|
|
1065
|
+
// src/typegen/mcdoc/primitives/boolean.ts
|
|
1066
|
+
import ts8 from "typescript";
|
|
1067
|
+
var { factory: factory8 } = ts8;
|
|
1068
|
+
var static_value2 = {
|
|
1069
|
+
type: factory8.createKeywordTypeNode(ts8.SyntaxKind.BooleanKeyword)
|
|
1070
|
+
};
|
|
1071
|
+
function mcdoc_boolean(type) {
|
|
1072
|
+
const boolean = type;
|
|
1073
|
+
Assert.KeywordType(boolean);
|
|
1074
|
+
return (args) => static_value2;
|
|
1075
|
+
}
|
|
1076
|
+
var McdocBoolean = mcdoc_boolean;
|
|
1077
|
+
// src/typegen/mcdoc/primitives/byte.ts
|
|
1078
|
+
import ts9 from "typescript";
|
|
1079
|
+
var { factory: factory9 } = ts9;
|
|
1080
|
+
var NBTByteType = "NBTByte";
|
|
1081
|
+
function mcdoc_byte(type) {
|
|
1082
|
+
const byte = type;
|
|
1083
|
+
Assert.NumericType(byte);
|
|
1084
|
+
return (args) => {
|
|
1085
|
+
if (byte.valueRange === undefined) {
|
|
1086
|
+
return {
|
|
1087
|
+
type: factory9.createTypeReferenceNode(NBTByteType),
|
|
1088
|
+
imports: {
|
|
1089
|
+
ordered: [`sandstone::${NBTByteType}`],
|
|
1090
|
+
check: new Map([[`sandstone::${NBTByteType}`, 0]])
|
|
1091
|
+
}
|
|
1092
|
+
};
|
|
1093
|
+
} else {
|
|
1094
|
+
return whole_number_generic(byte.valueRange, NBTByteType);
|
|
1095
|
+
}
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
var McdocByte = mcdoc_byte;
|
|
1099
|
+
// src/typegen/mcdoc/primitives/concrete.ts
|
|
1100
|
+
import ts10 from "typescript";
|
|
1101
|
+
function mcdoc_concrete(type) {
|
|
1102
|
+
Assert.ConcreteType(type);
|
|
1103
|
+
return (args) => {
|
|
1104
|
+
const generic_types = [];
|
|
1105
|
+
let imports = undefined;
|
|
1106
|
+
let child_dispatcher;
|
|
1107
|
+
for (const generic of type.typeArgs) {
|
|
1108
|
+
const generic_type = TypeHandlers[generic.kind](generic)(args);
|
|
1109
|
+
if ("imports" in generic_type) {
|
|
1110
|
+
imports = merge_imports(imports, generic_type.imports);
|
|
1111
|
+
}
|
|
1112
|
+
if ("child_dispatcher" in generic_type) {
|
|
1113
|
+
if (child_dispatcher === undefined) {
|
|
1114
|
+
child_dispatcher = [];
|
|
1115
|
+
}
|
|
1116
|
+
child_dispatcher.push(...generic_type.child_dispatcher);
|
|
1117
|
+
}
|
|
1118
|
+
generic_types.push(generic_type.type);
|
|
1119
|
+
}
|
|
1120
|
+
const child = TypeHandlers[type.child.kind](type.child)({ ...args, generic_types });
|
|
1121
|
+
if ("imports" in child) {
|
|
1122
|
+
imports = merge_imports(imports, child.imports);
|
|
1123
|
+
}
|
|
1124
|
+
if ("child_dispatcher" in child) {
|
|
1125
|
+
if (child_dispatcher === undefined) {
|
|
1126
|
+
child_dispatcher = [];
|
|
1127
|
+
}
|
|
1128
|
+
child_dispatcher.push(...child.child_dispatcher);
|
|
1129
|
+
}
|
|
1130
|
+
return {
|
|
1131
|
+
type: child.type,
|
|
1132
|
+
...add({ imports, child_dispatcher })
|
|
1133
|
+
};
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
var McdocConcrete = mcdoc_concrete;
|
|
1137
|
+
// src/typegen/mcdoc/primitives/double.ts
|
|
1138
|
+
import * as mcdoc3 from "@spyglassmc/mcdoc";
|
|
1139
|
+
import ts11 from "typescript";
|
|
1140
|
+
var { factory: factory10 } = ts11;
|
|
1141
|
+
var NBTDoubleType = "NBTDouble";
|
|
1142
|
+
function mcdoc_double(type) {
|
|
1143
|
+
const double = type;
|
|
1144
|
+
Assert.NumericType(double);
|
|
1145
|
+
return (args) => {
|
|
1146
|
+
if (double.valueRange === undefined) {
|
|
1147
|
+
return {
|
|
1148
|
+
type: factory10.createParenthesizedType(factory10.createUnionTypeNode([
|
|
1149
|
+
factory10.createTypeReferenceNode(NBTDoubleType),
|
|
1150
|
+
factory10.createKeywordTypeNode(ts11.SyntaxKind.NumberKeyword)
|
|
1151
|
+
])),
|
|
1152
|
+
imports: {
|
|
1153
|
+
ordered: [`sandstone::${NBTDoubleType}`],
|
|
1154
|
+
check: new Map([[`sandstone::${NBTDoubleType}`, 0]])
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
} else {
|
|
1158
|
+
return non_integral_generic(double.valueRange, NBTDoubleType, true);
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
var McdocDouble = mcdoc_double;
|
|
1163
|
+
function non_integral_generic(range, type, allow_js_number) {
|
|
1164
|
+
const docs = [
|
|
1165
|
+
`Range: ${mcdoc3.NumericRange.toString(range)}`
|
|
1166
|
+
];
|
|
1167
|
+
const generic = [];
|
|
1168
|
+
let has_min = false;
|
|
1169
|
+
let has_max = false;
|
|
1170
|
+
const left_exclusive = mcdoc3.RangeKind.isLeftExclusive(range.kind);
|
|
1171
|
+
const right_exclusive = mcdoc3.RangeKind.isRightExclusive(range.kind);
|
|
1172
|
+
if (range.min !== undefined) {
|
|
1173
|
+
has_min = true;
|
|
1174
|
+
generic.push(factory10.createPropertySignature(undefined, "leftExclusive", undefined, factory10.createLiteralTypeNode(left_exclusive ? factory10.createTrue() : factory10.createFalse())));
|
|
1175
|
+
if (left_exclusive) {
|
|
1176
|
+
docs.push(`Minimum is exclusive; must be higher than ${range.min}`);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
if (range.max !== undefined) {
|
|
1180
|
+
has_max = true;
|
|
1181
|
+
generic.push(factory10.createPropertySignature(undefined, "rightExclusive", undefined, factory10.createLiteralTypeNode(right_exclusive ? factory10.createTrue() : factory10.createFalse())));
|
|
1182
|
+
if (right_exclusive) {
|
|
1183
|
+
docs.push(`Maximum is exclusive; must be lower than ${range.max}`);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
if (has_min && has_max) {
|
|
1187
|
+
if (range.min === 0 && range.max === 1) {
|
|
1188
|
+
generic.push(factory10.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(0)));
|
|
1189
|
+
generic.push(factory10.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(1)));
|
|
1190
|
+
} else if (range.min >= 0) {
|
|
1191
|
+
let number = 0;
|
|
1192
|
+
if (left_exclusive && range.min === 0 || range.min >= 1) {
|
|
1193
|
+
number = 1;
|
|
1194
|
+
}
|
|
1195
|
+
generic.push(factory10.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(number)));
|
|
1196
|
+
if (right_exclusive) {
|
|
1197
|
+
generic.push(factory10.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(range.max)));
|
|
1198
|
+
}
|
|
1199
|
+
} else if (left_exclusive) {
|
|
1200
|
+
generic.push(factory10.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(range.min)));
|
|
1201
|
+
if (right_exclusive) {
|
|
1202
|
+
generic.push(factory10.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(range.max)));
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
} else if (has_min) {
|
|
1206
|
+
if (range.min >= 0) {
|
|
1207
|
+
let number = 0;
|
|
1208
|
+
if (left_exclusive && range.min === 0 || range.min >= 1) {
|
|
1209
|
+
number = 1;
|
|
1210
|
+
}
|
|
1211
|
+
generic.push(factory10.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(number)));
|
|
1212
|
+
} else if (left_exclusive) {
|
|
1213
|
+
generic.push(factory10.createPropertySignature(undefined, "min", undefined, Bind.NumericLiteral(range.min)));
|
|
1214
|
+
}
|
|
1215
|
+
} else {
|
|
1216
|
+
if (range.max < 0 || right_exclusive && range.max === 0) {
|
|
1217
|
+
generic.push(factory10.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(-1)));
|
|
1218
|
+
} else if (right_exclusive) {
|
|
1219
|
+
generic.push(factory10.createPropertySignature(undefined, "max", undefined, Bind.NumericLiteral(range.max)));
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
const returned_type = allow_js_number ? factory10.createParenthesizedType(factory10.createUnionTypeNode([
|
|
1223
|
+
factory10.createTypeReferenceNode(type, [
|
|
1224
|
+
factory10.createTypeLiteralNode(generic)
|
|
1225
|
+
]),
|
|
1226
|
+
factory10.createKeywordTypeNode(ts11.SyntaxKind.NumberKeyword)
|
|
1227
|
+
])) : factory10.createTypeReferenceNode(type, [
|
|
1228
|
+
factory10.createTypeLiteralNode(generic)
|
|
1229
|
+
]);
|
|
1230
|
+
return {
|
|
1231
|
+
type: returned_type,
|
|
1232
|
+
docs,
|
|
1233
|
+
imports: {
|
|
1234
|
+
ordered: [`sandstone::${type}`],
|
|
1235
|
+
check: new Map([[`sandstone::${type}`, 0]])
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
// src/typegen/mcdoc/primitives/float.ts
|
|
1240
|
+
import ts12 from "typescript";
|
|
1241
|
+
var { factory: factory11 } = ts12;
|
|
1242
|
+
var NBTFloatType = "NBTFloat";
|
|
1243
|
+
function mcdoc_float(type) {
|
|
1244
|
+
const float = type;
|
|
1245
|
+
Assert.NumericType(float);
|
|
1246
|
+
return (args) => {
|
|
1247
|
+
if (float.valueRange === undefined) {
|
|
1248
|
+
return {
|
|
1249
|
+
type: factory11.createTypeReferenceNode(NBTFloatType),
|
|
1250
|
+
imports: {
|
|
1251
|
+
ordered: [`sandstone::${NBTFloatType}`],
|
|
1252
|
+
check: new Map([[`sandstone::${NBTFloatType}`, 0]])
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
} else {
|
|
1256
|
+
return non_integral_generic(float.valueRange, NBTFloatType);
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
var McdocFloat = mcdoc_float;
|
|
1261
|
+
// src/typegen/mcdoc/primitives/literal.ts
|
|
1262
|
+
import ts13 from "typescript";
|
|
1263
|
+
import { match as match2 } from "ts-pattern";
|
|
1264
|
+
var { factory: factory12 } = ts13;
|
|
1265
|
+
var boolean_static = {
|
|
1266
|
+
true: {
|
|
1267
|
+
type: factory12.createLiteralTypeNode(factory12.createTrue())
|
|
1268
|
+
},
|
|
1269
|
+
false: {
|
|
1270
|
+
type: factory12.createLiteralTypeNode(factory12.createFalse())
|
|
1271
|
+
}
|
|
1272
|
+
};
|
|
1273
|
+
function mcdoc_literal(type) {
|
|
1274
|
+
const literal = type;
|
|
1275
|
+
Assert.LiteralType(literal);
|
|
1276
|
+
return (args) => match2(literal.value).with({ kind: "boolean" }, (boolean) => match2(boolean.value).with(true, () => boolean_static.true).with(false, () => boolean_static.false).exhaustive()).with({ kind: "byte" }, (byte) => {
|
|
1277
|
+
const type2 = "NBTByte";
|
|
1278
|
+
return {
|
|
1279
|
+
type: factory12.createTypeReferenceNode(type2, [
|
|
1280
|
+
Bind.NumericLiteral(byte.value)
|
|
1281
|
+
]),
|
|
1282
|
+
imports: {
|
|
1283
|
+
ordered: [`sandstone::${type2}`],
|
|
1284
|
+
check: new Map([[`sandstone::${type2}`, 0]])
|
|
1285
|
+
}
|
|
1286
|
+
};
|
|
1287
|
+
}).narrow().with({ kind: "double" }, { kind: "int" }, (num) => ({
|
|
1288
|
+
type: Bind.NumericLiteral(num.value)
|
|
1289
|
+
})).with({ kind: "float" }, (float) => {
|
|
1290
|
+
const type2 = "NBTFloat";
|
|
1291
|
+
return {
|
|
1292
|
+
type: factory12.createTypeReferenceNode(type2, [
|
|
1293
|
+
Bind.NumericLiteral(float.value)
|
|
1294
|
+
]),
|
|
1295
|
+
imports: {
|
|
1296
|
+
ordered: [`sandstone::${type2}`],
|
|
1297
|
+
check: new Map([[`sandstone::${type2}`, 0]])
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
}).with({ kind: "long" }, (long) => {
|
|
1301
|
+
const type2 = "NBTLong";
|
|
1302
|
+
return {
|
|
1303
|
+
type: factory12.createTypeReferenceNode(type2, [
|
|
1304
|
+
Bind.StringLiteral(`${long.value}`)
|
|
1305
|
+
]),
|
|
1306
|
+
imports: {
|
|
1307
|
+
ordered: [`sandstone::${type2}`],
|
|
1308
|
+
check: new Map([[`sandstone::${type2}`, 0]])
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
}).with({ kind: "short" }, (short) => {
|
|
1312
|
+
const type2 = "NBTShort";
|
|
1313
|
+
return {
|
|
1314
|
+
type: factory12.createTypeReferenceNode(type2, [
|
|
1315
|
+
Bind.NumericLiteral(short.value)
|
|
1316
|
+
]),
|
|
1317
|
+
imports: {
|
|
1318
|
+
ordered: [`sandstone::${type2}`],
|
|
1319
|
+
check: new Map([[`sandstone::${type2}`, 0]])
|
|
1320
|
+
}
|
|
1321
|
+
};
|
|
1322
|
+
}).with({ kind: "string" }, (string) => ({
|
|
1323
|
+
type: Bind.StringLiteral(string.value)
|
|
1324
|
+
})).exhaustive();
|
|
1325
|
+
}
|
|
1326
|
+
var McdocLiteral = mcdoc_literal;
|
|
1327
|
+
// src/typegen/mcdoc/primitives/long.ts
|
|
1328
|
+
import ts14 from "typescript";
|
|
1329
|
+
var { factory: factory13 } = ts14;
|
|
1330
|
+
var NBTLongType = "NBTLong";
|
|
1331
|
+
function mcdoc_long(type) {
|
|
1332
|
+
const long = type;
|
|
1333
|
+
Assert.NumericType(long);
|
|
1334
|
+
return (args) => {
|
|
1335
|
+
if (long.valueRange === undefined) {
|
|
1336
|
+
return {
|
|
1337
|
+
type: factory13.createTypeReferenceNode(NBTLongType),
|
|
1338
|
+
imports: {
|
|
1339
|
+
ordered: [`sandstone::${NBTLongType}`],
|
|
1340
|
+
check: new Map([[`sandstone::${NBTLongType}`, 0]])
|
|
1341
|
+
}
|
|
1342
|
+
};
|
|
1343
|
+
} else {
|
|
1344
|
+
return whole_number_generic(long.valueRange, NBTLongType);
|
|
1345
|
+
}
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
var McdocLong = mcdoc_long;
|
|
1349
|
+
// src/typegen/mcdoc/primitives/reference.ts
|
|
1350
|
+
import ts16 from "typescript";
|
|
1351
|
+
|
|
1352
|
+
// src/typegen/mcdoc/multi/enum.ts
|
|
1353
|
+
import ts15 from "typescript";
|
|
1354
|
+
var { factory: factory14 } = ts15;
|
|
1355
|
+
function enum_docs(enum_type) {
|
|
1356
|
+
const docs = [""];
|
|
1357
|
+
for (const member of enum_type.values) {
|
|
1358
|
+
const id_value = `${member.identifier}(\`${member.value}\`)`;
|
|
1359
|
+
if (member.desc) {
|
|
1360
|
+
const member_doc = Bind.DocPart(member.desc);
|
|
1361
|
+
if (member_doc.length > 1) {
|
|
1362
|
+
docs.push(` - ${id_value}:`);
|
|
1363
|
+
docs.push(...member_doc.map((doc) => ` ${doc}`));
|
|
1364
|
+
} else {
|
|
1365
|
+
docs.push(` - ${id_value}: ${member_doc[0]}`);
|
|
1366
|
+
}
|
|
1367
|
+
} else {
|
|
1368
|
+
docs.push(` - ${id_value}`);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return docs;
|
|
1372
|
+
}
|
|
1373
|
+
function mcdoc_enum(type) {
|
|
1374
|
+
const enum_type = type;
|
|
1375
|
+
Assert.EnumType(enum_type);
|
|
1376
|
+
return (args) => {
|
|
1377
|
+
const bind_value = (() => enum_type.enumKind === "string" ? (value) => Bind.StringLiteral(value) : (value) => Bind.NumericLiteral(value))();
|
|
1378
|
+
const members = enum_type.values.map(({ value }) => bind_value(value));
|
|
1379
|
+
return {
|
|
1380
|
+
type: factory14.createParenthesizedType(factory14.createUnionTypeNode(members))
|
|
1381
|
+
};
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
var McdocEnum = mcdoc_enum;
|
|
1385
|
+
|
|
1386
|
+
// src/typegen/mcdoc/primitives/reference.ts
|
|
1387
|
+
var { factory: factory15 } = ts16;
|
|
1388
|
+
function ReferenceArgs(args) {}
|
|
1389
|
+
function mcdoc_reference(type) {
|
|
1390
|
+
const reference = type;
|
|
1391
|
+
Assert.ReferenceType(reference);
|
|
1392
|
+
return (args) => {
|
|
1393
|
+
ReferenceArgs(args);
|
|
1394
|
+
let import_path = reference.path;
|
|
1395
|
+
const initial_peek = args.module_map[reference.path]?.data;
|
|
1396
|
+
if (initial_peek !== undefined && initial_peek !== null && typeof initial_peek === "object" && "typeDef" in initial_peek) {
|
|
1397
|
+
const initial_type = initial_peek.typeDef;
|
|
1398
|
+
if (initial_type.kind === "reference" && !(("attributes" in initial_type) && Array.isArray(initial_type.attributes) && initial_type.attributes.length > 0)) {
|
|
1399
|
+
import_path = initial_type.path;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
const type_name_point = import_path.lastIndexOf(":");
|
|
1403
|
+
const type_name = import_path.slice(type_name_point + 1);
|
|
1404
|
+
const base_path = import_path.slice(0, type_name_point - 1);
|
|
1405
|
+
if ("dispatcher_symbol" in args) {
|
|
1406
|
+
const dispatcher = args.dispatcher_symbol();
|
|
1407
|
+
const location_counts_index = dispatcher.locations.get(base_path);
|
|
1408
|
+
if (location_counts_index === undefined) {
|
|
1409
|
+
dispatcher.locations.set(base_path, dispatcher.location_counts.length);
|
|
1410
|
+
dispatcher.location_counts.push([base_path, 1]);
|
|
1411
|
+
} else {
|
|
1412
|
+
dispatcher.location_counts[location_counts_index][1]++;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
const imports = args.module_path === base_path ? undefined : {
|
|
1416
|
+
ordered: [import_path],
|
|
1417
|
+
check: new Map([[import_path, 0]])
|
|
1418
|
+
};
|
|
1419
|
+
let docs;
|
|
1420
|
+
let child_dispatcher;
|
|
1421
|
+
let id_wrap = (ref) => ref;
|
|
1422
|
+
const peek = args.module_map[import_path]?.data;
|
|
1423
|
+
if (peek !== undefined && peek !== null && typeof peek === "object" && "typeDef" in peek) {
|
|
1424
|
+
const referenced_type = peek.typeDef;
|
|
1425
|
+
if (referenced_type.kind === "enum") {
|
|
1426
|
+
docs = enum_docs(referenced_type);
|
|
1427
|
+
if ("desc" in referenced_type && typeof referenced_type.desc === "string") {
|
|
1428
|
+
docs.push("", [referenced_type.desc]);
|
|
1429
|
+
}
|
|
1430
|
+
if ("attributes" in type) {
|
|
1431
|
+
Assert.Attributes(type.attributes, true);
|
|
1432
|
+
if (type.attributes[0].name === "id" && type.attributes[0].value === undefined) {
|
|
1433
|
+
id_wrap = (ref) => {
|
|
1434
|
+
const id_ref = factory15.createParenthesizedType(factory15.createUnionTypeNode([
|
|
1435
|
+
ref,
|
|
1436
|
+
factory15.createTemplateLiteralType(factory15.createTemplateHead("minecraft:", "minecraft:"), [factory15.createTemplateLiteralTypeSpan(ref, factory15.createTemplateTail(""))])
|
|
1437
|
+
]));
|
|
1438
|
+
Object.assign(id_ref, {
|
|
1439
|
+
"--mcdoc_id_ref": {
|
|
1440
|
+
ref,
|
|
1441
|
+
alt: factory15.createParenthesizedType(factory15.createUnionTypeNode([
|
|
1442
|
+
factory15.createTypeReferenceNode("S"),
|
|
1443
|
+
factory15.createTemplateLiteralType(factory15.createTemplateHead("minecraft:", "minecraft:"), [factory15.createTemplateLiteralTypeSpan(factory15.createTypeReferenceNode("S"), factory15.createTemplateTail(""))])
|
|
1444
|
+
]))
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
return id_ref;
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
} else if (referenced_type.kind === "struct" && args.spread) {
|
|
1452
|
+
const generic_field = referenced_type.fields.find((f) => f.type.kind === "dispatcher" && f.type.parallelIndices[0].kind === "dynamic" && typeof f.type.parallelIndices[0].accessor[0] === "string" && ((key) => referenced_type.fields.findIndex((_f) => _f.kind === "pair" && _f.key === key))(f.type.parallelIndices[0].accessor[0]) === -1)?.type.parallelIndices[0].accessor[0];
|
|
1453
|
+
if (generic_field !== undefined) {
|
|
1454
|
+
child_dispatcher = [[0, generic_field]];
|
|
1455
|
+
args.generic_types = [factory15.createTypeReferenceNode("S")];
|
|
1456
|
+
}
|
|
1457
|
+
} else if ("desc" in referenced_type && typeof referenced_type.desc === "string") {
|
|
1458
|
+
docs = [[referenced_type.desc]];
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
if ("generic_types" in args) {
|
|
1462
|
+
return {
|
|
1463
|
+
type: factory15.createTypeReferenceNode(type_name, args.generic_types),
|
|
1464
|
+
...add({ imports, child_dispatcher, docs })
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
if ("generics" in args && args.generics.has(reference.path)) {
|
|
1468
|
+
return {
|
|
1469
|
+
type: factory15.createTypeReferenceNode(type_name),
|
|
1470
|
+
...add({ docs })
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
return {
|
|
1474
|
+
type: id_wrap(factory15.createTypeReferenceNode(type_name)),
|
|
1475
|
+
...add({ imports, child_dispatcher, docs })
|
|
1476
|
+
};
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
var McdocReference = mcdoc_reference;
|
|
1480
|
+
// src/typegen/mcdoc/primitives/short.ts
|
|
1481
|
+
import ts17 from "typescript";
|
|
1482
|
+
var { factory: factory16 } = ts17;
|
|
1483
|
+
var NBTShortType = "NBTShort";
|
|
1484
|
+
function mcdoc_short(type) {
|
|
1485
|
+
const short = type;
|
|
1486
|
+
Assert.NumericType(short);
|
|
1487
|
+
return (args) => {
|
|
1488
|
+
if (short.valueRange === undefined) {
|
|
1489
|
+
return {
|
|
1490
|
+
type: factory16.createTypeReferenceNode(NBTShortType),
|
|
1491
|
+
imports: {
|
|
1492
|
+
ordered: [`sandstone::${NBTShortType}`],
|
|
1493
|
+
check: new Map([[`sandstone::${NBTShortType}`, 0]])
|
|
1494
|
+
}
|
|
1495
|
+
};
|
|
1496
|
+
} else {
|
|
1497
|
+
return whole_number_generic(short.valueRange, NBTShortType);
|
|
1498
|
+
}
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
var McdocShort = mcdoc_short;
|
|
1502
|
+
// src/typegen/mcdoc/primitives/string.ts
|
|
1503
|
+
import ts18 from "typescript";
|
|
1504
|
+
import { match as match3, P as P3 } from "ts-pattern";
|
|
1505
|
+
import * as mcdoc4 from "@spyglassmc/mcdoc";
|
|
1506
|
+
var { factory: factory17 } = ts18;
|
|
1507
|
+
var StringKeyword = factory17.createKeywordTypeNode(ts18.SyntaxKind.StringKeyword);
|
|
1508
|
+
var static_value3 = {
|
|
1509
|
+
normal: {
|
|
1510
|
+
type: StringKeyword
|
|
1511
|
+
},
|
|
1512
|
+
not_empty: factory17.createTemplateLiteralType(factory17.createTemplateHead(""), [
|
|
1513
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.AnyKeyword), factory17.createTemplateMiddle("")),
|
|
1514
|
+
factory17.createTemplateLiteralTypeSpan(StringKeyword, factory17.createTemplateTail(""))
|
|
1515
|
+
]),
|
|
1516
|
+
namespaced_tag: {
|
|
1517
|
+
type: factory17.createTemplateLiteralType(factory17.createTemplateHead("#"), [
|
|
1518
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.StringKeyword), factory17.createTemplateMiddle(":")),
|
|
1519
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.StringKeyword), factory17.createTemplateTail(""))
|
|
1520
|
+
])
|
|
1521
|
+
},
|
|
1522
|
+
namespaced: {
|
|
1523
|
+
type: Bind.Namespaced
|
|
1524
|
+
},
|
|
1525
|
+
hash: {
|
|
1526
|
+
type: factory17.createTemplateLiteralType(factory17.createTemplateHead("#"), [factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.StringKeyword), factory17.createTemplateTail(""))])
|
|
1527
|
+
},
|
|
1528
|
+
number: {
|
|
1529
|
+
type: factory17.createTemplateLiteralType(factory17.createTemplateHead(""), [factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.NumberKeyword), factory17.createTemplateTail(""))])
|
|
1530
|
+
},
|
|
1531
|
+
time: {
|
|
1532
|
+
type: factory17.createParenthesizedType(factory17.createUnionTypeNode([
|
|
1533
|
+
factory17.createTemplateLiteralType(factory17.createTemplateHead(""), [
|
|
1534
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.NumberKeyword), factory17.createTemplateMiddle("-")),
|
|
1535
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.NumberKeyword), factory17.createTemplateMiddle("-")),
|
|
1536
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.NumberKeyword), factory17.createTemplateTail(""))
|
|
1537
|
+
]),
|
|
1538
|
+
factory17.createTemplateLiteralType(factory17.createTemplateHead(""), [
|
|
1539
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.NumberKeyword), factory17.createTemplateMiddle(":")),
|
|
1540
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.NumberKeyword), factory17.createTemplateMiddle(":")),
|
|
1541
|
+
factory17.createTemplateLiteralTypeSpan(factory17.createKeywordTypeNode(ts18.SyntaxKind.NumberKeyword), factory17.createTemplateTail(""))
|
|
1542
|
+
])
|
|
1543
|
+
]))
|
|
1544
|
+
}
|
|
1545
|
+
};
|
|
1546
|
+
var ResourceClasses = {
|
|
1547
|
+
"minecraft:advancement": "AdvancementClass",
|
|
1548
|
+
"minecraft:function": "_RawFunctionClass"
|
|
1549
|
+
};
|
|
1550
|
+
function mcdoc_string(type) {
|
|
1551
|
+
const string = type;
|
|
1552
|
+
Assert.StringType(string);
|
|
1553
|
+
if (string.attributes === undefined && string.lengthRange === undefined) {
|
|
1554
|
+
return (args) => static_value3.normal;
|
|
1555
|
+
} else if (string.attributes === undefined) {
|
|
1556
|
+
return (args) => ({
|
|
1557
|
+
type: static_value3.not_empty,
|
|
1558
|
+
docs: [`String length range: ${mcdoc4.NumericRange.toString(string.lengthRange)}`]
|
|
1559
|
+
});
|
|
1560
|
+
} else {
|
|
1561
|
+
Assert.Attributes(string.attributes, true);
|
|
1562
|
+
const attribute = string.attributes.find((attr) => attr.name !== "since" && attr.name !== "until");
|
|
1563
|
+
return match3(attribute).with(P3.nullish, () => {
|
|
1564
|
+
return (args) => static_value3.normal;
|
|
1565
|
+
}).with({ name: "id", value: P3.optional(P3.nullish) }, () => {
|
|
1566
|
+
return (args) => static_value3.namespaced;
|
|
1567
|
+
}).with({ name: "id", value: P3.nonNullable }, ({ value }) => {
|
|
1568
|
+
const id_attr = value;
|
|
1569
|
+
return (args) => {
|
|
1570
|
+
const symbols = args.symbols;
|
|
1571
|
+
let registry_id;
|
|
1572
|
+
let exclude = (reg) => reg;
|
|
1573
|
+
let Resource = () => (registry_id in ResourceClasses) ? ResourceClasses[registry_id] : undefined;
|
|
1574
|
+
const registry_import = `::java::registry::Registry`;
|
|
1575
|
+
const types = [];
|
|
1576
|
+
let has_non_indexable = false;
|
|
1577
|
+
const imports = {
|
|
1578
|
+
ordered: [registry_import],
|
|
1579
|
+
check: new Map([[registry_import, 0]])
|
|
1580
|
+
};
|
|
1581
|
+
if (id_attr.kind === "literal") {
|
|
1582
|
+
registry_id = `minecraft:${id_attr.value.value}`;
|
|
1583
|
+
if (is_valid_registry(symbols, registry_id)) {
|
|
1584
|
+
types.push(exclude(factory17.createIndexedAccessTypeNode(factory17.createTypeReferenceNode("Registry"), Bind.StringLiteral(registry_id))));
|
|
1585
|
+
} else {
|
|
1586
|
+
types.push(static_value3.namespaced.type);
|
|
1587
|
+
}
|
|
1588
|
+
} else {
|
|
1589
|
+
registry_id = `minecraft:${id_attr.values.registry.value.value}`;
|
|
1590
|
+
let empty_registry = !is_valid_registry(symbols, registry_id);
|
|
1591
|
+
if (!empty_registry) {
|
|
1592
|
+
types.push(exclude(factory17.createIndexedAccessTypeNode(factory17.createTypeReferenceNode("Registry"), Bind.StringLiteral(registry_id))));
|
|
1593
|
+
} else {
|
|
1594
|
+
types.push(static_value3.namespaced.type);
|
|
1595
|
+
}
|
|
1596
|
+
if ("path" in id_attr.values) {
|
|
1597
|
+
return {
|
|
1598
|
+
type: static_value3.namespaced.type,
|
|
1599
|
+
docs: ["", `Value: A ${registry_id} ID within a path root of \`(namespace)/textures/${id_attr.values.path.value.value}\``]
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
if ("definition" in id_attr.values) {
|
|
1603
|
+
return {
|
|
1604
|
+
type: static_value3.namespaced.type,
|
|
1605
|
+
docs: ["", `Value: Defines a \`${registry_id}\` id.`]
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
if ("exclude" in id_attr.values) {
|
|
1609
|
+
exclude = (reg) => factory17.createTypeReferenceNode("Exclude", [
|
|
1610
|
+
reg,
|
|
1611
|
+
factory17.createParenthesizedType(factory17.createUnionTypeNode(Object.values(id_attr.values.exclude.values).map((literal) => Bind.StringLiteral(literal.value.value))))
|
|
1612
|
+
]);
|
|
1613
|
+
}
|
|
1614
|
+
if ("tags" in id_attr.values) {
|
|
1615
|
+
const Tag = "TagClass";
|
|
1616
|
+
const tag_registry_id = registry_id.replace(":", ":tag/");
|
|
1617
|
+
const empty_tag_registry = !is_valid_registry(symbols, tag_registry_id);
|
|
1618
|
+
switch (id_attr.values.tags.value.value) {
|
|
1619
|
+
case "allowed":
|
|
1620
|
+
{
|
|
1621
|
+
types.push(empty_tag_registry ? static_value3.namespaced_tag.type : factory17.createTemplateLiteralType(factory17.createTemplateHead("#"), [factory17.createTemplateLiteralTypeSpan(factory17.createIndexedAccessTypeNode(factory17.createTypeReferenceNode("Registry"), Bind.StringLiteral(tag_registry_id)), factory17.createTemplateTail(""))]), factory17.createTypeReferenceNode(Tag, [Bind.StringLiteral(registry_id.split(":")[1])]));
|
|
1622
|
+
add_import(imports, `sandstone::${Tag}`);
|
|
1623
|
+
has_non_indexable = true;
|
|
1624
|
+
}
|
|
1625
|
+
break;
|
|
1626
|
+
case "implicit": {
|
|
1627
|
+
return {
|
|
1628
|
+
type: empty_tag_registry ? static_value3.namespaced.type : factory17.createParenthesizedType(factory17.createUnionTypeNode([
|
|
1629
|
+
factory17.createIndexedAccessTypeNode(factory17.createTypeReferenceNode("Registry"), Bind.StringLiteral(tag_registry_id))
|
|
1630
|
+
])),
|
|
1631
|
+
imports
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
case "required": {
|
|
1635
|
+
add_import(imports, "sandstone::TagClass");
|
|
1636
|
+
return {
|
|
1637
|
+
type: factory17.createParenthesizedType(factory17.createUnionTypeNode([
|
|
1638
|
+
empty_tag_registry ? static_value3.namespaced_tag.type : factory17.createTemplateLiteralType(factory17.createTemplateHead("#"), [factory17.createTemplateLiteralTypeSpan(factory17.createIndexedAccessTypeNode(factory17.createTypeReferenceNode("Registry"), Bind.StringLiteral(tag_registry_id)), factory17.createTemplateTail(""))]),
|
|
1639
|
+
factory17.createTypeReferenceNode(Tag, [Bind.StringLiteral(registry_id.split(":")[1])])
|
|
1640
|
+
])),
|
|
1641
|
+
imports
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
if ("empty" in id_attr.values) {
|
|
1647
|
+
types.push(Bind.StringLiteral(""));
|
|
1648
|
+
}
|
|
1649
|
+
if ("prefix" in id_attr.values) {
|
|
1650
|
+
throw new Error("[mcdoc_string] ID prefix is not currently supported as a value");
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
Resource = Resource();
|
|
1654
|
+
if (Resource !== undefined) {
|
|
1655
|
+
types.push(factory17.createTypeReferenceNode(Resource));
|
|
1656
|
+
add_import(imports, `sandstone::${Resource}`);
|
|
1657
|
+
has_non_indexable = true;
|
|
1658
|
+
}
|
|
1659
|
+
const result_type = types.length === 1 ? types[0] : factory17.createParenthesizedType(factory17.createUnionTypeNode(types));
|
|
1660
|
+
if (has_non_indexable) {
|
|
1661
|
+
Object.assign(result_type, { "--mcdoc_has_non_indexable": true });
|
|
1662
|
+
}
|
|
1663
|
+
return {
|
|
1664
|
+
type: result_type,
|
|
1665
|
+
imports
|
|
1666
|
+
};
|
|
1667
|
+
};
|
|
1668
|
+
}).narrow().with({ name: "color" }, ({ value: { value: { value } } }) => {
|
|
1669
|
+
Assert.ColorStringType(value);
|
|
1670
|
+
return (args) => static_value3.hash;
|
|
1671
|
+
}).with({ name: "command" }, ({ value: { values } }) => {
|
|
1672
|
+
return (args) => ({ type: static_value3.not_empty });
|
|
1673
|
+
}).with({ name: "crafting_ingredient" }, () => {
|
|
1674
|
+
return (args) => ({ type: static_value3.not_empty });
|
|
1675
|
+
}).with({ name: "criterion", value: P3.optional(P3.nullish) }, () => {
|
|
1676
|
+
return (args) => ({ type: static_value3.not_empty });
|
|
1677
|
+
}).with({ name: "entity" }, ({ value }) => {
|
|
1678
|
+
let Target = "SingleEntityArgument";
|
|
1679
|
+
if (value === undefined || value.values.amount?.value.value !== "single" && value.values.type?.value.value !== "players") {
|
|
1680
|
+
Target = "MultipleEntitiesArgument";
|
|
1681
|
+
} else if (value.values.amount?.value.value !== "single" && value.values.type?.value.value === "players") {
|
|
1682
|
+
Target = "MultiplePlayersArgument";
|
|
1683
|
+
} else if (value.values.amount?.value.value === "single" && value.values.type?.value.value === "players") {
|
|
1684
|
+
Target = "SinglePlayerArgument";
|
|
1685
|
+
}
|
|
1686
|
+
return (args) => ({
|
|
1687
|
+
type: factory17.createTypeReferenceNode(Target),
|
|
1688
|
+
imports: {
|
|
1689
|
+
ordered: [`sandstone::arguments::${Target}`],
|
|
1690
|
+
check: new Map([[`sandstone::arguments::${Target}`, 0]])
|
|
1691
|
+
}
|
|
1692
|
+
});
|
|
1693
|
+
}).with({ name: "integer" }, () => {
|
|
1694
|
+
return (args) => static_value3.number;
|
|
1695
|
+
}).with({ name: "item_slots" }, () => {
|
|
1696
|
+
const ITEM_SLOTS = "ITEM_SLOTS";
|
|
1697
|
+
const LiteralUnion = "LiteralUnion";
|
|
1698
|
+
return (args) => ({
|
|
1699
|
+
type: factory17.createTypeReferenceNode(LiteralUnion, [
|
|
1700
|
+
factory17.createTypeReferenceNode(ITEM_SLOTS)
|
|
1701
|
+
]),
|
|
1702
|
+
imports: {
|
|
1703
|
+
ordered: [`sandstone::arguments::${ITEM_SLOTS}`, `sandstone::${LiteralUnion}`],
|
|
1704
|
+
check: new Map([[`sandstone::arguments::${ITEM_SLOTS}`, 0], [`sandstone::${LiteralUnion}`, 1]])
|
|
1705
|
+
}
|
|
1706
|
+
});
|
|
1707
|
+
}).with({ name: "nbt" }, ({ value }) => {
|
|
1708
|
+
const NBT = "NBTClass";
|
|
1709
|
+
return (args) => ({
|
|
1710
|
+
type: factory17.createUnionTypeNode([
|
|
1711
|
+
static_value3.not_empty,
|
|
1712
|
+
factory17.createTypeReferenceNode(NBT)
|
|
1713
|
+
]),
|
|
1714
|
+
imports: {
|
|
1715
|
+
ordered: [`sandstone::${NBT}`],
|
|
1716
|
+
check: new Map([[`sandstone::${NBT}`, 0]])
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
}).with({ name: "nbt_path" }, ({ value }) => {
|
|
1720
|
+
const DataPoint = "DataPointClass";
|
|
1721
|
+
return (args) => ({
|
|
1722
|
+
type: factory17.createUnionTypeNode([
|
|
1723
|
+
static_value3.not_empty,
|
|
1724
|
+
factory17.createTypeReferenceNode(DataPoint)
|
|
1725
|
+
]),
|
|
1726
|
+
imports: {
|
|
1727
|
+
ordered: [`sandstone::${DataPoint}`],
|
|
1728
|
+
check: new Map([[`sandstone::${DataPoint}`, 0]])
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1731
|
+
}).with({ name: "match_regex" }, ({ value: { value: { value } } }) => {
|
|
1732
|
+
return (args) => ({
|
|
1733
|
+
type: static_value3.not_empty,
|
|
1734
|
+
docs: [`Must match regex of ${value}`]
|
|
1735
|
+
});
|
|
1736
|
+
}).with({ name: "objective" }, () => {
|
|
1737
|
+
const Objective = "ObjectiveClass";
|
|
1738
|
+
return (args) => ({
|
|
1739
|
+
type: factory17.createUnionTypeNode([
|
|
1740
|
+
static_value3.not_empty,
|
|
1741
|
+
factory17.createTypeReferenceNode(Objective)
|
|
1742
|
+
]),
|
|
1743
|
+
imports: {
|
|
1744
|
+
ordered: [`sandstone::${Objective}`],
|
|
1745
|
+
check: new Map([[`sandstone::${Objective}`, 0]])
|
|
1746
|
+
}
|
|
1747
|
+
});
|
|
1748
|
+
}).with({ name: "regex_pattern" }, () => {
|
|
1749
|
+
return (args) => ({
|
|
1750
|
+
type: factory17.createUnionTypeNode([
|
|
1751
|
+
static_value3.not_empty,
|
|
1752
|
+
factory17.createTypeReferenceNode("RegExp")
|
|
1753
|
+
])
|
|
1754
|
+
});
|
|
1755
|
+
}).with({ name: "score_holder" }, () => {
|
|
1756
|
+
const Score = "ScoreClass";
|
|
1757
|
+
return (args) => ({
|
|
1758
|
+
type: factory17.createUnionTypeNode([
|
|
1759
|
+
static_value3.not_empty,
|
|
1760
|
+
factory17.createTypeReferenceNode(Score)
|
|
1761
|
+
]),
|
|
1762
|
+
imports: {
|
|
1763
|
+
ordered: [`sandstone::${Score}`],
|
|
1764
|
+
check: new Map([[`sandstone::${Score}`, 0]])
|
|
1765
|
+
}
|
|
1766
|
+
});
|
|
1767
|
+
}).with({ name: "tag" }, () => {
|
|
1768
|
+
const Label = "LabelClass";
|
|
1769
|
+
return (args) => ({
|
|
1770
|
+
type: factory17.createUnionTypeNode([
|
|
1771
|
+
static_value3.not_empty,
|
|
1772
|
+
factory17.createTypeReferenceNode(Label)
|
|
1773
|
+
]),
|
|
1774
|
+
imports: {
|
|
1775
|
+
ordered: [`sandstone::${Label}`],
|
|
1776
|
+
check: new Map([[`sandstone::${Label}`, 0]])
|
|
1777
|
+
}
|
|
1778
|
+
});
|
|
1779
|
+
}).with({ name: "team" }, () => {
|
|
1780
|
+
return (args) => ({ type: static_value3.not_empty });
|
|
1781
|
+
}).with({ name: "text_component" }, () => {
|
|
1782
|
+
return (args) => ({ type: static_value3.not_empty });
|
|
1783
|
+
}).with({ name: "texture_slot" }, ({ value: { values: { kind: { value: { value } } } } }) => {
|
|
1784
|
+
const Texture = "TextureClass";
|
|
1785
|
+
if (value === "reference") {
|
|
1786
|
+
return (args) => static_value3.hash;
|
|
1787
|
+
}
|
|
1788
|
+
return (args) => ({
|
|
1789
|
+
type: factory17.createUnionTypeNode([
|
|
1790
|
+
static_value3.not_empty,
|
|
1791
|
+
static_value3.hash.type,
|
|
1792
|
+
factory17.createTypeReferenceNode(Texture)
|
|
1793
|
+
]),
|
|
1794
|
+
imports: {
|
|
1795
|
+
ordered: [`sandstone::${Texture}`],
|
|
1796
|
+
check: new Map([[`sandstone::${Texture}`, 0]])
|
|
1797
|
+
}
|
|
1798
|
+
});
|
|
1799
|
+
}).with({ name: "time_pattern" }, () => {
|
|
1800
|
+
return (args) => static_value3.time;
|
|
1801
|
+
}).with({ name: "translation_key" }, () => {
|
|
1802
|
+
const TRANSLATION_KEYS = "TRANSLATION_KEYS";
|
|
1803
|
+
const LiteralUnion = "LiteralUnion";
|
|
1804
|
+
return (args) => ({
|
|
1805
|
+
type: factory17.createTypeReferenceNode(LiteralUnion, [
|
|
1806
|
+
factory17.createTypeReferenceNode(TRANSLATION_KEYS)
|
|
1807
|
+
]),
|
|
1808
|
+
imports: {
|
|
1809
|
+
ordered: [`sandstone::arguments::${TRANSLATION_KEYS}`, `sandstone::${LiteralUnion}`],
|
|
1810
|
+
check: new Map([[`sandstone::arguments::${TRANSLATION_KEYS}`, 0], [`sandstone::${LiteralUnion}`, 1]])
|
|
1811
|
+
}
|
|
1812
|
+
});
|
|
1813
|
+
}).with({ name: "translation_value" }, () => {
|
|
1814
|
+
return (args) => static_value3.normal;
|
|
1815
|
+
}).with({ name: "url" }, () => {
|
|
1816
|
+
return (args) => ({
|
|
1817
|
+
type: factory17.createUnionTypeNode([
|
|
1818
|
+
static_value3.not_empty,
|
|
1819
|
+
factory17.createTypeReferenceNode("URL")
|
|
1820
|
+
])
|
|
1821
|
+
});
|
|
1822
|
+
}).with({ name: "vector" }, ({ value: { values } }) => {
|
|
1823
|
+
const Coordinates = "Coordinates";
|
|
1824
|
+
return (args) => ({
|
|
1825
|
+
type: factory17.createTypeReferenceNode(Coordinates),
|
|
1826
|
+
imports: {
|
|
1827
|
+
ordered: [`sandstone::arguments::${Coordinates}`],
|
|
1828
|
+
check: new Map([[`sandstone::arguments::${Coordinates}`, 0]])
|
|
1829
|
+
}
|
|
1830
|
+
});
|
|
1831
|
+
}).with({ name: P3.union("game_rule", "uuid", "block_predicate") }, () => {
|
|
1832
|
+
return (args) => ({ type: static_value3.not_empty });
|
|
1833
|
+
}).otherwise(() => {
|
|
1834
|
+
console.log(attribute?.name);
|
|
1835
|
+
throw new Error(`[mcdoc_string] Unsupported string attribute: ${attribute}`);
|
|
1836
|
+
});
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
var McdocString = mcdoc_string;
|
|
1840
|
+
// src/typegen/mcdoc/multi/struct.ts
|
|
1841
|
+
import ts19 from "typescript";
|
|
1842
|
+
import { match as match4, P as P4 } from "ts-pattern";
|
|
1843
|
+
var { factory: factory18 } = ts19;
|
|
1844
|
+
function StructArgs(args) {}
|
|
1845
|
+
var FieldProperties = {
|
|
1846
|
+
optional: P4.optional(P4.boolean),
|
|
1847
|
+
deprecated: P4.optional(P4.boolean),
|
|
1848
|
+
desc: P4.optional(P4.string),
|
|
1849
|
+
attributes: P4.optional(P4.when((attributes) => Array.isArray(attributes)))
|
|
1850
|
+
};
|
|
1851
|
+
function mcdoc_struct(type) {
|
|
1852
|
+
const struct = type;
|
|
1853
|
+
Assert.StructType(struct);
|
|
1854
|
+
return (args) => {
|
|
1855
|
+
StructArgs(args);
|
|
1856
|
+
const { name } = args;
|
|
1857
|
+
const spread = args.spread ? true : false;
|
|
1858
|
+
const root_type = args.root_type ? true : false;
|
|
1859
|
+
delete args.spread;
|
|
1860
|
+
args.root_type = false;
|
|
1861
|
+
let imports = undefined;
|
|
1862
|
+
const pair_indices = {};
|
|
1863
|
+
const pairs = [];
|
|
1864
|
+
const inherit = [];
|
|
1865
|
+
let pair_inserted = false;
|
|
1866
|
+
const merge = [];
|
|
1867
|
+
let child_dispatcher;
|
|
1868
|
+
for (const field of struct.fields) {
|
|
1869
|
+
let unsupported = false;
|
|
1870
|
+
if (field.attributes !== undefined) {
|
|
1871
|
+
Assert.Attributes(field.attributes, true);
|
|
1872
|
+
const attributes = field.attributes;
|
|
1873
|
+
for (const attribute of attributes) {
|
|
1874
|
+
if (attribute.name === "until" || attribute.name === "deprecated") {
|
|
1875
|
+
unsupported = true;
|
|
1876
|
+
break;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
if (unsupported) {
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
match4(field).with({ kind: "pair", key: P4.string, ...FieldProperties }, (pair) => {
|
|
1884
|
+
const value = TypeHandlers[pair.type.kind](pair.type)({ ...args, name: `${name}${pascal_case(pair.key)}` });
|
|
1885
|
+
if ("imports" in value) {
|
|
1886
|
+
imports = merge_imports(imports, value.imports);
|
|
1887
|
+
}
|
|
1888
|
+
if ("child_dispatcher" in value) {
|
|
1889
|
+
if (child_dispatcher === undefined) {
|
|
1890
|
+
child_dispatcher = [];
|
|
1891
|
+
}
|
|
1892
|
+
child_dispatcher.push(...value.child_dispatcher);
|
|
1893
|
+
}
|
|
1894
|
+
let field_docs = undefined;
|
|
1895
|
+
if ("desc" in pair && typeof pair.desc === "string") {
|
|
1896
|
+
if (field_docs === undefined) {
|
|
1897
|
+
field_docs = [[pair.desc]];
|
|
1898
|
+
} else {
|
|
1899
|
+
field_docs.push([pair.desc]);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
if ("docs" in value) {
|
|
1903
|
+
if (field_docs === undefined) {
|
|
1904
|
+
field_docs = ["Value:", ...value.docs];
|
|
1905
|
+
} else {
|
|
1906
|
+
field_docs.push("", "Value:", ...value.docs);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
pair_indices[pair.key] = pairs.length;
|
|
1910
|
+
pairs.push(Bind.Doc(factory18.createPropertySignature(undefined, pair.key, pair.optional ? factory18.createToken(ts19.SyntaxKind.QuestionToken) : undefined, value.type), field_docs));
|
|
1911
|
+
pair_inserted = true;
|
|
1912
|
+
}).narrow().with({ kind: "pair" }, (pair) => {
|
|
1913
|
+
Assert.StructKeyType(pair.key);
|
|
1914
|
+
const value = TypeHandlers[pair.type.kind](pair.type)({ ...args, name: `${name}IndexSignature` });
|
|
1915
|
+
if ("imports" in value) {
|
|
1916
|
+
imports = merge_imports(imports, value.imports);
|
|
1917
|
+
}
|
|
1918
|
+
if ("child_dispatcher" in value) {
|
|
1919
|
+
if (child_dispatcher === undefined) {
|
|
1920
|
+
child_dispatcher = [];
|
|
1921
|
+
}
|
|
1922
|
+
child_dispatcher.push(...value.child_dispatcher);
|
|
1923
|
+
}
|
|
1924
|
+
match4(pair.key.kind).with("reference", "concrete", (kind) => {
|
|
1925
|
+
const key = TypeHandlers[kind](pair.key)(args);
|
|
1926
|
+
if ("imports" in key) {
|
|
1927
|
+
imports = merge_imports(imports, key.imports);
|
|
1928
|
+
}
|
|
1929
|
+
inherit.push(Bind.MappedType(key.type, value.type));
|
|
1930
|
+
}).with("string", () => {
|
|
1931
|
+
if (pair.key.attributes === undefined) {
|
|
1932
|
+
Assert.StringType(pair.key);
|
|
1933
|
+
inherit.push(Bind.MappedType(("lengthRange" in pair.key && "min" in pair.key.lengthRange ? pair.key.lengthRange.min : 0) >= 1 ? Bind.NonEmptyString : factory18.createKeywordTypeNode(ts19.SyntaxKind.StringKeyword), value.type));
|
|
1934
|
+
} else {
|
|
1935
|
+
Assert.Attributes(pair.key.attributes, true);
|
|
1936
|
+
const attribute = pair.key.attributes[0];
|
|
1937
|
+
match4(attribute).with({ name: "id" }, (attr) => {
|
|
1938
|
+
const id_attr = attr.value;
|
|
1939
|
+
let registry_id;
|
|
1940
|
+
if (id_attr === undefined) {
|
|
1941
|
+
throw new Error(`[mcdoc_struct] #[id] on a struct key is currently not handled`);
|
|
1942
|
+
}
|
|
1943
|
+
if (id_attr.kind === "literal") {
|
|
1944
|
+
registry_id = `minecraft:${id_attr.value.value}`;
|
|
1945
|
+
} else {
|
|
1946
|
+
registry_id = `minecraft:${id_attr.values.registry.value.value}`;
|
|
1947
|
+
}
|
|
1948
|
+
const symbols = "symbols" in args ? args.symbols : undefined;
|
|
1949
|
+
if (!is_valid_registry(symbols, registry_id)) {
|
|
1950
|
+
inherit.push(Bind.MappedType(Bind.Namespaced, value.type));
|
|
1951
|
+
return;
|
|
1952
|
+
}
|
|
1953
|
+
const registry_import = `::java::registry::Registry`;
|
|
1954
|
+
imports = add_import(imports, registry_import);
|
|
1955
|
+
inherit.push(Bind.MappedType(factory18.createIndexedAccessTypeNode(factory18.createTypeReferenceNode("Registry"), Bind.StringLiteral(registry_id)), value.type));
|
|
1956
|
+
}).with({ name: "item_slots" }, () => {
|
|
1957
|
+
const ITEM_SLOTS = "ITEM_SLOTS";
|
|
1958
|
+
const LiteralUnion = "LiteralUnion";
|
|
1959
|
+
imports = add_import(imports, `sandstone::arguments::${ITEM_SLOTS}`);
|
|
1960
|
+
imports = add_import(imports, `sandstone::${LiteralUnion}`);
|
|
1961
|
+
inherit.push(Bind.MappedType(factory18.createTypeReferenceNode(LiteralUnion, [
|
|
1962
|
+
factory18.createTypeReferenceNode(ITEM_SLOTS)
|
|
1963
|
+
]), value.type));
|
|
1964
|
+
}).with({ name: "objective" }, () => {
|
|
1965
|
+
const Objective = "ObjectiveClass";
|
|
1966
|
+
imports = add_import(imports, `sandstone::${Objective}`);
|
|
1967
|
+
inherit.push(Bind.MappedType(factory18.createUnionTypeNode([
|
|
1968
|
+
factory18.createKeywordTypeNode(ts19.SyntaxKind.StringKeyword),
|
|
1969
|
+
factory18.createTypeReferenceNode(Objective)
|
|
1970
|
+
]), value.type));
|
|
1971
|
+
}).with({ name: "texture_slot" }, () => {
|
|
1972
|
+
inherit.push(Bind.MappedType(factory18.createKeywordTypeNode(ts19.SyntaxKind.StringKeyword), value.type));
|
|
1973
|
+
}).with({ name: "criterion" }, () => {
|
|
1974
|
+
inherit.push(Bind.MappedType(factory18.createKeywordTypeNode(ts19.SyntaxKind.StringKeyword), value.type));
|
|
1975
|
+
}).with({ name: "crafting_ingredient" }, () => {
|
|
1976
|
+
const CRAFTING_INGREDIENT = "CRAFTING_INGREDIENT";
|
|
1977
|
+
imports = add_import(imports, `sandstone::arguments::${CRAFTING_INGREDIENT}`);
|
|
1978
|
+
inherit.push(Bind.MappedType(factory18.createTypeReferenceNode(CRAFTING_INGREDIENT), value.type));
|
|
1979
|
+
}).with({ name: P4.union("dispatcher_key", "translation_key", "permutation") }, () => {
|
|
1980
|
+
inherit.push(Bind.MappedType(factory18.createKeywordTypeNode(ts19.SyntaxKind.StringKeyword), value.type));
|
|
1981
|
+
}).otherwise(() => {
|
|
1982
|
+
throw new Error(`[mcdoc_struct] Unsupported dynamic key attribute: ${attribute}`);
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
});
|
|
1986
|
+
}).with({ kind: "spread" }, (_spread) => {
|
|
1987
|
+
Assert.StructSpreadType(_spread.type);
|
|
1988
|
+
const spread2 = TypeHandlers[_spread.type.kind](_spread.type)({ spread: true, ...args });
|
|
1989
|
+
if ("imports" in spread2) {
|
|
1990
|
+
imports = merge_imports(imports, spread2.imports);
|
|
1991
|
+
}
|
|
1992
|
+
if ("child_dispatcher" in spread2) {
|
|
1993
|
+
if (child_dispatcher === undefined) {
|
|
1994
|
+
child_dispatcher = [];
|
|
1995
|
+
}
|
|
1996
|
+
child_dispatcher.push(...spread2.child_dispatcher);
|
|
1997
|
+
}
|
|
1998
|
+
if (pair_inserted) {
|
|
1999
|
+
merge.push(spread2.type);
|
|
2000
|
+
} else {
|
|
2001
|
+
inherit.push(spread2.type);
|
|
2002
|
+
}
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
2005
|
+
let inner_type;
|
|
2006
|
+
let indexed_access;
|
|
2007
|
+
let indexed_access_type;
|
|
2008
|
+
let template = (type_node) => type_node;
|
|
2009
|
+
if (child_dispatcher !== undefined && spread === false) {
|
|
2010
|
+
const new_list = child_dispatcher.flatMap(([parent_count, property]) => {
|
|
2011
|
+
if (parent_count === 0) {
|
|
2012
|
+
if (indexed_access === property) {
|
|
2013
|
+
return [];
|
|
2014
|
+
}
|
|
2015
|
+
const generic_prop = pair_indices[property];
|
|
2016
|
+
if (generic_prop === undefined) {
|
|
2017
|
+
if (root_type) {
|
|
2018
|
+
template = (type_node) => factory18.createTypeAliasDeclaration([factory18.createToken(ts19.SyntaxKind.ExportKeyword)], args.name, [factory18.createTypeParameterDeclaration(undefined, "S", undefined, factory18.createKeywordTypeNode(ts19.SyntaxKind.UndefinedKeyword))], type_node);
|
|
2019
|
+
return [];
|
|
2020
|
+
}
|
|
2021
|
+
throw new Error(`[mcdoc_struct] Received an invalid dynamic dispatcher trying to access '${property}'`);
|
|
2022
|
+
}
|
|
2023
|
+
indexed_access = property;
|
|
2024
|
+
indexed_access_type = pairs[generic_prop].type;
|
|
2025
|
+
if ("--mcdoc_has_non_indexable" in indexed_access_type) {
|
|
2026
|
+
if (root_type) {
|
|
2027
|
+
template = (type_node) => factory18.createTypeAliasDeclaration([factory18.createToken(ts19.SyntaxKind.ExportKeyword)], args.name, [factory18.createTypeParameterDeclaration(undefined, "S", undefined, factory18.createKeywordTypeNode(ts19.SyntaxKind.UndefinedKeyword))], type_node);
|
|
2028
|
+
}
|
|
2029
|
+
} else if ("--mcdoc_id_ref" in indexed_access_type) {
|
|
2030
|
+
const id_ref = indexed_access_type["--mcdoc_id_ref"];
|
|
2031
|
+
pairs[generic_prop].type = id_ref.alt;
|
|
2032
|
+
indexed_access_type = id_ref.ref;
|
|
2033
|
+
} else {
|
|
2034
|
+
pairs[generic_prop].type = factory18.createTypeReferenceNode("S");
|
|
2035
|
+
}
|
|
2036
|
+
return [];
|
|
2037
|
+
}
|
|
2038
|
+
if (root_type) {
|
|
2039
|
+
template = (type_node) => factory18.createTypeAliasDeclaration([factory18.createToken(ts19.SyntaxKind.ExportKeyword)], args.name, [factory18.createTypeParameterDeclaration(undefined, "S", undefined, factory18.createKeywordTypeNode(ts19.SyntaxKind.UndefinedKeyword))], type_node);
|
|
2040
|
+
}
|
|
2041
|
+
return [[parent_count - 1, property]];
|
|
2042
|
+
});
|
|
2043
|
+
child_dispatcher = new_list.length === 0 ? undefined : new_list;
|
|
2044
|
+
}
|
|
2045
|
+
const types = [...inherit];
|
|
2046
|
+
if (pair_inserted) {
|
|
2047
|
+
types.push(factory18.createTypeLiteralNode(pairs));
|
|
2048
|
+
}
|
|
2049
|
+
types.push(...merge);
|
|
2050
|
+
if (types.length === 1) {
|
|
2051
|
+
inner_type = types[0];
|
|
2052
|
+
} else if (types.length > 1) {
|
|
2053
|
+
inner_type = factory18.createParenthesizedType(factory18.createIntersectionTypeNode(types));
|
|
2054
|
+
} else {
|
|
2055
|
+
inner_type = Bind.EmptyObject;
|
|
2056
|
+
}
|
|
2057
|
+
if (indexed_access === undefined) {
|
|
2058
|
+
return {
|
|
2059
|
+
type: template(inner_type),
|
|
2060
|
+
...add({ imports, child_dispatcher })
|
|
2061
|
+
};
|
|
2062
|
+
} else if ("--mcdoc_has_non_indexable" in indexed_access_type) {
|
|
2063
|
+
return {
|
|
2064
|
+
type: template(inner_type),
|
|
2065
|
+
...add({ imports, child_dispatcher })
|
|
2066
|
+
};
|
|
2067
|
+
} else {
|
|
2068
|
+
return {
|
|
2069
|
+
type: template(factory18.createParenthesizedType(factory18.createIndexedAccessTypeNode(Bind.MappedType(indexed_access_type, inner_type, { key_name: "S", parenthesized: false }), indexed_access_type))),
|
|
2070
|
+
...add({ imports, child_dispatcher })
|
|
2071
|
+
};
|
|
2072
|
+
}
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
2075
|
+
var McdocStruct = mcdoc_struct;
|
|
2076
|
+
// src/typegen/mcdoc/multi/tuple.ts
|
|
2077
|
+
import ts20 from "typescript";
|
|
2078
|
+
var { factory: factory19 } = ts20;
|
|
2079
|
+
function mcdoc_tuple(type) {
|
|
2080
|
+
const tuple = type;
|
|
2081
|
+
Assert.TupleType(tuple);
|
|
2082
|
+
return (args) => {
|
|
2083
|
+
args.root_type = false;
|
|
2084
|
+
let imports = undefined;
|
|
2085
|
+
const members = [];
|
|
2086
|
+
let has_docs = false;
|
|
2087
|
+
const member_docs = [];
|
|
2088
|
+
let child_dispatcher;
|
|
2089
|
+
for (const item of tuple.items) {
|
|
2090
|
+
let unsupported = false;
|
|
2091
|
+
if (item.attributes !== undefined) {
|
|
2092
|
+
Assert.Attributes(item.attributes, true);
|
|
2093
|
+
const attributes = item.attributes;
|
|
2094
|
+
for (const attribute of attributes) {
|
|
2095
|
+
if (attribute.name === "until" || attribute.name === "deprecated") {
|
|
2096
|
+
unsupported = true;
|
|
2097
|
+
break;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
if (unsupported) {
|
|
2102
|
+
continue;
|
|
2103
|
+
}
|
|
2104
|
+
const value = TypeHandlers[item.kind](item)(args);
|
|
2105
|
+
if ("imports" in value) {
|
|
2106
|
+
imports = merge_imports(imports, value.imports);
|
|
2107
|
+
}
|
|
2108
|
+
if ("child_dispatcher" in value) {
|
|
2109
|
+
if (child_dispatcher === undefined) {
|
|
2110
|
+
child_dispatcher = [];
|
|
2111
|
+
}
|
|
2112
|
+
child_dispatcher.push(...value.child_dispatcher.map(([parent_count, property]) => {
|
|
2113
|
+
if (parent_count === 0) {
|
|
2114
|
+
throw new Error(`[mcdoc_tuple] Tuple contains a dynamic dispatcher with invalid parenting: ${item}`);
|
|
2115
|
+
}
|
|
2116
|
+
return [parent_count - 1, property];
|
|
2117
|
+
}));
|
|
2118
|
+
}
|
|
2119
|
+
if ("docs" in value) {
|
|
2120
|
+
has_docs = true;
|
|
2121
|
+
const docs2 = value.docs;
|
|
2122
|
+
member_docs.push(value.docs);
|
|
2123
|
+
} else {
|
|
2124
|
+
member_docs.push(false);
|
|
2125
|
+
}
|
|
2126
|
+
members.push(value.type);
|
|
2127
|
+
}
|
|
2128
|
+
const docs = has_docs ? member_docs.flatMap((doc, i) => {
|
|
2129
|
+
if (members.length === 1 && doc !== false) {
|
|
2130
|
+
return [doc];
|
|
2131
|
+
} else {
|
|
2132
|
+
return [
|
|
2133
|
+
...doc === false ? [`*item ${i}*`] : [doc],
|
|
2134
|
+
...i !== member_docs.length - 1 ? ["", "*or*", ""] : []
|
|
2135
|
+
];
|
|
2136
|
+
}
|
|
2137
|
+
}) : undefined;
|
|
2138
|
+
return {
|
|
2139
|
+
type: factory19.createTupleTypeNode(members),
|
|
2140
|
+
...add({ imports, child_dispatcher, docs })
|
|
2141
|
+
};
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2144
|
+
var McdocTuple = mcdoc_tuple;
|
|
2145
|
+
// src/typegen/mcdoc/multi/union.ts
|
|
2146
|
+
import ts21 from "typescript";
|
|
2147
|
+
var { factory: factory20 } = ts21;
|
|
2148
|
+
var Never = factory20.createKeywordTypeNode(ts21.SyntaxKind.NeverKeyword);
|
|
2149
|
+
function mcdoc_union(type) {
|
|
2150
|
+
const union = type;
|
|
2151
|
+
Assert.UnionType(union);
|
|
2152
|
+
return (args) => {
|
|
2153
|
+
args.root_type = false;
|
|
2154
|
+
let imports = undefined;
|
|
2155
|
+
const members = [];
|
|
2156
|
+
let has_docs = false;
|
|
2157
|
+
const member_docs = [];
|
|
2158
|
+
let child_dispatcher;
|
|
2159
|
+
for (const member of union.members) {
|
|
2160
|
+
let unsupported = false;
|
|
2161
|
+
if (member.attributes !== undefined) {
|
|
2162
|
+
Assert.Attributes(member.attributes, true);
|
|
2163
|
+
const attributes = member.attributes;
|
|
2164
|
+
for (const attribute of attributes) {
|
|
2165
|
+
if (attribute.name === "until" || attribute.name === "deprecated") {
|
|
2166
|
+
unsupported = true;
|
|
2167
|
+
break;
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
if (unsupported) {
|
|
2172
|
+
continue;
|
|
2173
|
+
}
|
|
2174
|
+
const value = TypeHandlers[member.kind](member)(args);
|
|
2175
|
+
if ("imports" in value) {
|
|
2176
|
+
imports = merge_imports(imports, value.imports);
|
|
2177
|
+
}
|
|
2178
|
+
if ("child_dispatcher" in value) {
|
|
2179
|
+
if (child_dispatcher === undefined) {
|
|
2180
|
+
child_dispatcher = [];
|
|
2181
|
+
}
|
|
2182
|
+
child_dispatcher.push(...value.child_dispatcher);
|
|
2183
|
+
}
|
|
2184
|
+
if ("docs" in value) {
|
|
2185
|
+
has_docs = true;
|
|
2186
|
+
member_docs.push(value.docs);
|
|
2187
|
+
} else {
|
|
2188
|
+
member_docs.push(false);
|
|
2189
|
+
}
|
|
2190
|
+
members.push(value.type);
|
|
2191
|
+
}
|
|
2192
|
+
if (members.length === 0) {
|
|
2193
|
+
if (union.members.length !== 0) {
|
|
2194
|
+
console.log(union.members);
|
|
2195
|
+
}
|
|
2196
|
+
members.push(Never);
|
|
2197
|
+
}
|
|
2198
|
+
const docs = has_docs ? member_docs.flatMap((doc, i) => {
|
|
2199
|
+
if (members.length === 1 && doc !== false) {
|
|
2200
|
+
return doc;
|
|
2201
|
+
} else {
|
|
2202
|
+
return [
|
|
2203
|
+
...i === 0 ? ["*either*", ""] : [],
|
|
2204
|
+
doc === false ? [`*item ${i}*`] : doc,
|
|
2205
|
+
...i !== member_docs.length - 1 ? ["", "*or*", ""] : []
|
|
2206
|
+
];
|
|
2207
|
+
}
|
|
2208
|
+
}) : undefined;
|
|
2209
|
+
const result_type = members.length === 1 ? members[0] : factory20.createParenthesizedType(factory20.createUnionTypeNode(members));
|
|
2210
|
+
if (members.some((m) => ("--mcdoc_has_non_indexable" in m))) {
|
|
2211
|
+
Object.assign(result_type, { "--mcdoc_has_non_indexable": true });
|
|
2212
|
+
}
|
|
2213
|
+
return {
|
|
2214
|
+
type: result_type,
|
|
2215
|
+
...add({ imports, child_dispatcher, docs })
|
|
2216
|
+
};
|
|
2217
|
+
};
|
|
2218
|
+
}
|
|
2219
|
+
var McdocUnion = mcdoc_union;
|
|
2220
|
+
// src/typegen/mcdoc/complex/dispatcher.ts
|
|
2221
|
+
import ts22 from "typescript";
|
|
2222
|
+
var { factory: factory21 } = ts22;
|
|
2223
|
+
function DispatcherArgs(args) {}
|
|
2224
|
+
var SimpleKeyIndex = JSON.stringify([{
|
|
2225
|
+
kind: "dynamic",
|
|
2226
|
+
accessor: [{
|
|
2227
|
+
keyword: "key"
|
|
2228
|
+
}]
|
|
2229
|
+
}]);
|
|
2230
|
+
var Fallback = Bind.StringLiteral("%fallback");
|
|
2231
|
+
var None = Bind.StringLiteral("%none");
|
|
2232
|
+
function DispatcherGeneric(registry, args) {
|
|
2233
|
+
return factory21.createTypeReferenceNode("Dispatcher", [
|
|
2234
|
+
Bind.StringLiteral(registry),
|
|
2235
|
+
factory21.createTupleTypeNode(args)
|
|
2236
|
+
]);
|
|
2237
|
+
}
|
|
2238
|
+
function DispatcherMapIndex(registry, key, generics) {
|
|
2239
|
+
const dispatcher = factory21.createTypeReferenceNode("Dispatcher", [Bind.StringLiteral(registry), ...generics.length === 0 ? [] : [factory21.createTupleTypeNode(generics)]]);
|
|
2240
|
+
if (key.kind === ts22.SyntaxKind.LiteralType) {
|
|
2241
|
+
return factory21.createIndexedAccessTypeNode(dispatcher, key);
|
|
2242
|
+
}
|
|
2243
|
+
return factory21.createParenthesizedType(factory21.createConditionalTypeNode(key, factory21.createTypeOperatorNode(ts22.SyntaxKind.KeyOfKeyword, dispatcher), factory21.createIndexedAccessTypeNode(dispatcher, key), factory21.createTypeReferenceNode("Record", [
|
|
2244
|
+
factory21.createKeywordTypeNode(ts22.SyntaxKind.StringKeyword),
|
|
2245
|
+
factory21.createKeywordTypeNode(ts22.SyntaxKind.UnknownKeyword)
|
|
2246
|
+
])));
|
|
2247
|
+
}
|
|
2248
|
+
function DispatcherMapSubIndex(registry, member_key, generics, sub_index) {
|
|
2249
|
+
const dispatcher = factory21.createTypeReferenceNode("Dispatcher", [Bind.StringLiteral(registry), ...generics.length === 0 ? [] : [factory21.createTupleTypeNode(generics)]]);
|
|
2250
|
+
const dispatcher_member = factory21.createIndexedAccessTypeNode(dispatcher, member_key);
|
|
2251
|
+
let indexed_dispatcher = undefined;
|
|
2252
|
+
for (let i = sub_index.length;i > 0; i--) {
|
|
2253
|
+
const key = Bind.StringLiteral(sub_index[i - 1]);
|
|
2254
|
+
let index_stack = dispatcher_member;
|
|
2255
|
+
for (let j = 0;j < i - 1; j++) {
|
|
2256
|
+
index_stack = factory21.createIndexedAccessTypeNode(index_stack, Bind.StringLiteral(sub_index[j]));
|
|
2257
|
+
}
|
|
2258
|
+
if (indexed_dispatcher === undefined) {
|
|
2259
|
+
indexed_dispatcher = factory21.createIndexedAccessTypeNode(index_stack, key);
|
|
2260
|
+
}
|
|
2261
|
+
indexed_dispatcher = factory21.createParenthesizedType(factory21.createConditionalTypeNode(key, factory21.createTypeOperatorNode(ts22.SyntaxKind.KeyOfKeyword, index_stack), indexed_dispatcher, factory21.createTypeReferenceNode("Record", [
|
|
2262
|
+
factory21.createKeywordTypeNode(ts22.SyntaxKind.StringKeyword),
|
|
2263
|
+
factory21.createKeywordTypeNode(ts22.SyntaxKind.UnknownKeyword)
|
|
2264
|
+
])));
|
|
2265
|
+
}
|
|
2266
|
+
return factory21.createParenthesizedType(factory21.createConditionalTypeNode(member_key, factory21.createTypeOperatorNode(ts22.SyntaxKind.KeyOfKeyword, dispatcher), indexed_dispatcher, factory21.createTypeReferenceNode("Record", [
|
|
2267
|
+
factory21.createKeywordTypeNode(ts22.SyntaxKind.StringKeyword),
|
|
2268
|
+
factory21.createKeywordTypeNode(ts22.SyntaxKind.UnknownKeyword)
|
|
2269
|
+
])));
|
|
2270
|
+
}
|
|
2271
|
+
function mcdoc_dispatcher(type) {
|
|
2272
|
+
Assert.DispatcherType(type);
|
|
2273
|
+
const dispatcher = type;
|
|
2274
|
+
const registry = dispatcher.registry;
|
|
2275
|
+
const indices = dispatcher.parallelIndices;
|
|
2276
|
+
return (args) => {
|
|
2277
|
+
DispatcherArgs(args);
|
|
2278
|
+
const dispatcher_import = `::java::dispatcher::Dispatcher`;
|
|
2279
|
+
let result_type;
|
|
2280
|
+
let child_dispatcher;
|
|
2281
|
+
const generics = args.generic_types ?? [];
|
|
2282
|
+
if (indices.length === 1 && indices[0].kind === "dynamic" && typeof indices[0].accessor.at(-1) === "string") {
|
|
2283
|
+
if (args.root_type) {
|
|
2284
|
+
result_type = DispatcherGeneric(registry, [...generics, Fallback]);
|
|
2285
|
+
} else {
|
|
2286
|
+
child_dispatcher = [[indices[0].accessor.length - 1, indices[0].accessor.at(-1)]];
|
|
2287
|
+
const indexed_type = DispatcherMapIndex(registry, factory21.createTypeReferenceNode("S"), generics);
|
|
2288
|
+
const properties = args.dispatcher_properties?.get(registry);
|
|
2289
|
+
if (properties?.supports_none) {
|
|
2290
|
+
result_type = factory21.createParenthesizedType(factory21.createConditionalTypeNode(factory21.createTypeReferenceNode("S"), factory21.createKeywordTypeNode(ts22.SyntaxKind.UndefinedKeyword), DispatcherGeneric(registry, [...generics, None]), indexed_type));
|
|
2291
|
+
} else {
|
|
2292
|
+
result_type = indexed_type;
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
} else if (indices.length === 1 && indices[0].kind === "static") {
|
|
2296
|
+
if (indices[0].value === "%fallback") {
|
|
2297
|
+
result_type = DispatcherGeneric(registry, [...generics, Fallback]);
|
|
2298
|
+
} else {
|
|
2299
|
+
result_type = DispatcherMapIndex(registry, Bind.StringLiteral(indices[0].value), generics);
|
|
2300
|
+
}
|
|
2301
|
+
} else if (JSON.stringify(indices) === SimpleKeyIndex) {
|
|
2302
|
+
if (args.index_keys !== undefined) {
|
|
2303
|
+
result_type = DispatcherMapSubIndex(registry, factory21.createTypeReferenceNode("Key"), generics, args.index_keys);
|
|
2304
|
+
} else {
|
|
2305
|
+
result_type = DispatcherMapIndex(registry, factory21.createTypeReferenceNode("Key"), generics);
|
|
2306
|
+
}
|
|
2307
|
+
} else {
|
|
2308
|
+
throw new Error(`[mcdoc_dispatcher] Unsupported dispatcher: ${dispatcher}`);
|
|
2309
|
+
}
|
|
2310
|
+
return {
|
|
2311
|
+
type: result_type,
|
|
2312
|
+
imports: {
|
|
2313
|
+
ordered: [dispatcher_import],
|
|
2314
|
+
check: new Map([[dispatcher_import, 0]])
|
|
2315
|
+
},
|
|
2316
|
+
...add({ child_dispatcher })
|
|
2317
|
+
};
|
|
2318
|
+
};
|
|
2319
|
+
}
|
|
2320
|
+
var McdocDispatcher = mcdoc_dispatcher;
|
|
2321
|
+
// src/typegen/mcdoc/complex/indexed.ts
|
|
2322
|
+
function mcdoc_indexed(type) {
|
|
2323
|
+
Assert.IndexedType(type);
|
|
2324
|
+
Assert.DispatcherType(type.child);
|
|
2325
|
+
const indices = type.parallelIndices;
|
|
2326
|
+
return (args) => {
|
|
2327
|
+
const index_keys = indices.map((index) => index.value);
|
|
2328
|
+
return McdocDispatcher(type.child)({ index_keys, ...args });
|
|
2329
|
+
};
|
|
2330
|
+
}
|
|
2331
|
+
var McdocIndexed = mcdoc_indexed;
|
|
2332
|
+
// src/typegen/mcdoc/complex/template.ts
|
|
2333
|
+
import ts23 from "typescript";
|
|
2334
|
+
var { factory: factory22 } = ts23;
|
|
2335
|
+
function parse_template_args(args) {
|
|
2336
|
+
if (!("name" in args)) {
|
|
2337
|
+
throw new Error(`[mcdoc_template] template name must be included in TypeHandler args, got ${args}`);
|
|
2338
|
+
}
|
|
2339
|
+
return {
|
|
2340
|
+
name: args.name
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
function mcdoc_template(type) {
|
|
2344
|
+
Assert.TemplateType(type);
|
|
2345
|
+
const original_generics = type.typeParams;
|
|
2346
|
+
const child = type.child;
|
|
2347
|
+
return (args) => {
|
|
2348
|
+
const { name } = parse_template_args(args);
|
|
2349
|
+
let imports = undefined;
|
|
2350
|
+
let child_dispatcher;
|
|
2351
|
+
const generic_paths = new Set;
|
|
2352
|
+
const generics = [];
|
|
2353
|
+
for (const generic of original_generics) {
|
|
2354
|
+
generic_paths.add(generic.path);
|
|
2355
|
+
generics.push(factory22.createTypeParameterDeclaration(undefined, generic.path.slice(generic.path.lastIndexOf(":") + 1)));
|
|
2356
|
+
}
|
|
2357
|
+
const child_result = TypeHandlers[child.kind](child)({
|
|
2358
|
+
...args,
|
|
2359
|
+
root_type: false,
|
|
2360
|
+
generics: generic_paths
|
|
2361
|
+
});
|
|
2362
|
+
if ("imports" in child_result) {
|
|
2363
|
+
imports = merge_imports(imports, child_result.imports);
|
|
2364
|
+
}
|
|
2365
|
+
if ("child_dispatcher" in child_result) {
|
|
2366
|
+
child_dispatcher = child_result.child_dispatcher;
|
|
2367
|
+
}
|
|
2368
|
+
const type_alias = factory22.createTypeAliasDeclaration([factory22.createModifier(ts23.SyntaxKind.ExportKeyword)], name, generics, child_result.type);
|
|
2369
|
+
return {
|
|
2370
|
+
type: type_alias,
|
|
2371
|
+
...add({ imports, child_dispatcher })
|
|
2372
|
+
};
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
var McdocTemplate = mcdoc_template;
|
|
2376
|
+
// src/typegen/mcdoc/index.ts
|
|
2377
|
+
class TypeHandlersClass {
|
|
2378
|
+
static any = McdocAny;
|
|
2379
|
+
static boolean = McdocBoolean;
|
|
2380
|
+
static byte = McdocByte;
|
|
2381
|
+
static byte_array = McdocByteArray;
|
|
2382
|
+
static concrete = McdocConcrete;
|
|
2383
|
+
static dispatcher = McdocDispatcher;
|
|
2384
|
+
static double = McdocDouble;
|
|
2385
|
+
static enum = McdocEnum;
|
|
2386
|
+
static float = McdocFloat;
|
|
2387
|
+
static indexed = McdocIndexed;
|
|
2388
|
+
static int = McdocInt;
|
|
2389
|
+
static int_array = McdocIntArray;
|
|
2390
|
+
static list = McdocList;
|
|
2391
|
+
static literal = McdocLiteral;
|
|
2392
|
+
static long = McdocLong;
|
|
2393
|
+
static long_array = McdocLongArray;
|
|
2394
|
+
static mapped = McdocAny;
|
|
2395
|
+
static reference = McdocReference;
|
|
2396
|
+
static short = McdocShort;
|
|
2397
|
+
static string = McdocString;
|
|
2398
|
+
static struct = McdocStruct;
|
|
2399
|
+
static template = McdocTemplate;
|
|
2400
|
+
static tuple = McdocTuple;
|
|
2401
|
+
static union = McdocUnion;
|
|
2402
|
+
static unsafe = McdocAny;
|
|
2403
|
+
}
|
|
2404
|
+
var TypeHandlers = TypeHandlersClass;
|
|
2405
|
+
function get_type_handler(type) {
|
|
2406
|
+
return TypeHandlers[type.kind];
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
// src/typegen/mcdoc/dispatcher_symbol.ts
|
|
2410
|
+
import ts24 from "typescript";
|
|
2411
|
+
var { factory: factory23 } = ts24;
|
|
2412
|
+
var dispatcher_references = new Map;
|
|
2413
|
+
function dispatcher_symbol(id, name, members, dispatcher_properties, module_map, symbols) {
|
|
2414
|
+
let imports = undefined;
|
|
2415
|
+
let has_references = false;
|
|
2416
|
+
const member_types = [];
|
|
2417
|
+
const map_properties = [];
|
|
2418
|
+
const member_type_refs = [];
|
|
2419
|
+
const first_member = members[Object.keys(members)[0]];
|
|
2420
|
+
const first_type = first_member.data.typeDef;
|
|
2421
|
+
const has_generics = first_type.kind === "template";
|
|
2422
|
+
const generic_params = [];
|
|
2423
|
+
const generic_names = [];
|
|
2424
|
+
if (has_generics && first_type.kind === "template") {
|
|
2425
|
+
const template = first_type;
|
|
2426
|
+
for (const type_param of template.typeParams) {
|
|
2427
|
+
const param_name = type_param.path.split("::").pop();
|
|
2428
|
+
generic_params.push(factory23.createTypeParameterDeclaration(undefined, param_name));
|
|
2429
|
+
generic_names.push(factory23.createTypeReferenceNode(param_name));
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
const add_reference = () => {
|
|
2433
|
+
has_references = true;
|
|
2434
|
+
if (!dispatcher_references.has(id)) {
|
|
2435
|
+
dispatcher_references.set(id, {
|
|
2436
|
+
locations: new Map,
|
|
2437
|
+
location_counts: []
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
return dispatcher_references.get(id);
|
|
2441
|
+
};
|
|
2442
|
+
let fallback_type_name;
|
|
2443
|
+
if ("%unknown" in members) {
|
|
2444
|
+
const unknown_member = members["%unknown"].data.typeDef;
|
|
2445
|
+
const unknown_type_name = `${name}FallbackType`;
|
|
2446
|
+
const result = get_type_handler(unknown_member)(unknown_member)({
|
|
2447
|
+
root_type: true,
|
|
2448
|
+
name: unknown_type_name,
|
|
2449
|
+
dispatcher_symbol: add_reference,
|
|
2450
|
+
dispatcher_properties,
|
|
2451
|
+
module_map,
|
|
2452
|
+
symbols
|
|
2453
|
+
});
|
|
2454
|
+
if ("imports" in result) {
|
|
2455
|
+
imports = merge_imports(imports, result.imports);
|
|
2456
|
+
}
|
|
2457
|
+
fallback_type_name = factory23.createTypeReferenceNode(unknown_type_name, has_generics ? generic_names : undefined);
|
|
2458
|
+
if (ts24.isTypeAliasDeclaration(result.type)) {
|
|
2459
|
+
member_types.push(result.type);
|
|
2460
|
+
} else {
|
|
2461
|
+
member_types.push(factory23.createTypeAliasDeclaration(undefined, unknown_type_name, undefined, result.type));
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
const has_none = "%none" in members;
|
|
2465
|
+
if (has_none) {
|
|
2466
|
+
const none_member = members["%none"].data.typeDef;
|
|
2467
|
+
const none_type_name = `${name}NoneType`;
|
|
2468
|
+
const result = get_type_handler(none_member)(none_member)({
|
|
2469
|
+
root_type: true,
|
|
2470
|
+
name: none_type_name,
|
|
2471
|
+
dispatcher_symbol: add_reference,
|
|
2472
|
+
dispatcher_properties,
|
|
2473
|
+
module_map,
|
|
2474
|
+
symbols
|
|
2475
|
+
});
|
|
2476
|
+
if ("imports" in result) {
|
|
2477
|
+
imports = merge_imports(imports, result.imports);
|
|
2478
|
+
}
|
|
2479
|
+
dispatcher_properties.set(id, {
|
|
2480
|
+
supports_none: true
|
|
2481
|
+
});
|
|
2482
|
+
if (ts24.isTypeAliasDeclaration(result.type)) {
|
|
2483
|
+
member_types.push(result.type);
|
|
2484
|
+
} else {
|
|
2485
|
+
member_types.push(factory23.createTypeAliasDeclaration(undefined, none_type_name, undefined, result.type));
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
for (const member_key of Object.keys(members)) {
|
|
2489
|
+
const member = members[member_key];
|
|
2490
|
+
if (member_key.startsWith("%")) {
|
|
2491
|
+
continue;
|
|
2492
|
+
}
|
|
2493
|
+
const member_type = member.data.typeDef;
|
|
2494
|
+
const member_type_name = `${name}${pascal_case(member_key.replace(/[/:]/g, "_"))}`;
|
|
2495
|
+
const result = get_type_handler(member_type)(member_type)({
|
|
2496
|
+
root_type: true,
|
|
2497
|
+
name: member_type_name,
|
|
2498
|
+
dispatcher_symbol: add_reference,
|
|
2499
|
+
dispatcher_properties,
|
|
2500
|
+
module_map,
|
|
2501
|
+
symbols
|
|
2502
|
+
});
|
|
2503
|
+
if ("imports" in result) {
|
|
2504
|
+
imports = merge_imports(imports, result.imports);
|
|
2505
|
+
}
|
|
2506
|
+
if (ts24.isTypeAliasDeclaration(result.type)) {
|
|
2507
|
+
member_types.push(result.type);
|
|
2508
|
+
} else {
|
|
2509
|
+
member_types.push(factory23.createTypeAliasDeclaration(undefined, member_type_name, undefined, result.type));
|
|
2510
|
+
}
|
|
2511
|
+
const member_ref = factory23.createTypeReferenceNode(member_type_name, has_generics ? generic_names : undefined);
|
|
2512
|
+
member_type_refs.push(member_ref);
|
|
2513
|
+
map_properties.push(factory23.createPropertySignature(undefined, factory23.createStringLiteral(member_key, true), undefined, member_ref), factory23.createPropertySignature(undefined, factory23.createStringLiteral(`minecraft:${member_key}`, true), undefined, member_ref));
|
|
2514
|
+
}
|
|
2515
|
+
const map_type = factory23.createTypeAliasDeclaration(undefined, `${name}DispatcherMap`, has_generics ? generic_params : undefined, factory23.createTypeLiteralNode(map_properties));
|
|
2516
|
+
const keys_type = factory23.createTypeAliasDeclaration(undefined, `${name}Keys`, undefined, factory23.createTypeOperatorNode(ts24.SyntaxKind.KeyOfKeyword, factory23.createTypeReferenceNode(`${name}DispatcherMap`, has_generics ? generic_names.map(() => factory23.createKeywordTypeNode(ts24.SyntaxKind.UnknownKeyword)) : undefined)));
|
|
2517
|
+
const fallback_union_members = fallback_type_name ? [...member_type_refs, fallback_type_name] : member_type_refs;
|
|
2518
|
+
const fallback_type = factory23.createTypeAliasDeclaration(undefined, `${name}Fallback`, has_generics ? generic_params : undefined, factory23.createParenthesizedType(factory23.createUnionTypeNode(fallback_union_members)));
|
|
2519
|
+
generic_params.push(factory23.createTypeParameterDeclaration(undefined, "CASE", factory23.createUnionTypeNode([
|
|
2520
|
+
Bind.StringLiteral("map"),
|
|
2521
|
+
Bind.StringLiteral("keys"),
|
|
2522
|
+
Bind.StringLiteral("%fallback"),
|
|
2523
|
+
Bind.StringLiteral("%none")
|
|
2524
|
+
]), Bind.StringLiteral("map")));
|
|
2525
|
+
const symbol_type = factory23.createTypeAliasDeclaration([factory23.createModifier(ts24.SyntaxKind.ExportKeyword)], `Symbol${name}`, generic_params, factory23.createConditionalTypeNode(factory23.createTypeReferenceNode("CASE"), Bind.StringLiteral("map"), factory23.createTypeReferenceNode(`${name}DispatcherMap`, has_generics ? generic_names : undefined), factory23.createConditionalTypeNode(factory23.createTypeReferenceNode("CASE"), Bind.StringLiteral("keys"), factory23.createTypeReferenceNode(`${name}Keys`), factory23.createConditionalTypeNode(factory23.createTypeReferenceNode("CASE"), Bind.StringLiteral("%fallback"), factory23.createTypeReferenceNode(`${name}Fallback`, has_generics ? generic_names : undefined), has_none ? factory23.createConditionalTypeNode(factory23.createTypeReferenceNode("CASE"), Bind.StringLiteral("%none"), factory23.createTypeReferenceNode(`${name}NoneType`, has_generics ? generic_names : undefined), factory23.createKeywordTypeNode(ts24.SyntaxKind.NeverKeyword)) : factory23.createKeywordTypeNode(ts24.SyntaxKind.NeverKeyword)))));
|
|
2526
|
+
return {
|
|
2527
|
+
types: [
|
|
2528
|
+
map_type,
|
|
2529
|
+
keys_type,
|
|
2530
|
+
fallback_type,
|
|
2531
|
+
...member_types,
|
|
2532
|
+
symbol_type
|
|
2533
|
+
],
|
|
2534
|
+
...add({ imports }),
|
|
2535
|
+
...has_references ? { references: dispatcher_references.get(id) } : {},
|
|
2536
|
+
generic_count: has_generics && first_type.kind === "template" ? first_type.typeParams.length : 0
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2539
|
+
var DispatcherSymbol = dispatcher_symbol;
|
|
2540
|
+
|
|
2541
|
+
// src/typegen/export.ts
|
|
2542
|
+
import ts25 from "typescript";
|
|
2543
|
+
var { factory: factory24 } = ts25;
|
|
2544
|
+
function export_registry(resolved_registries) {
|
|
2545
|
+
let imports;
|
|
2546
|
+
const properties = [];
|
|
2547
|
+
for (const [registry_name, { import_path, registry }] of resolved_registries) {
|
|
2548
|
+
imports = add_import(imports, import_path);
|
|
2549
|
+
const registry_id = registry_name.includes(":") ? registry_name : `minecraft:${registry_name}`;
|
|
2550
|
+
properties.push(factory24.createPropertySignature(undefined, factory24.createStringLiteral(registry_id), undefined, factory24.createTypeReferenceNode(registry)));
|
|
2551
|
+
}
|
|
2552
|
+
const registry_type = factory24.createTypeAliasDeclaration([factory24.createToken(ts25.SyntaxKind.ExportKeyword)], "Registry", undefined, factory24.createTypeLiteralNode(properties));
|
|
2553
|
+
return {
|
|
2554
|
+
exports: [registry_type],
|
|
2555
|
+
paths: new Set,
|
|
2556
|
+
...add({ imports })
|
|
2557
|
+
};
|
|
2558
|
+
}
|
|
2559
|
+
function export_dispatcher(resolved_dispatchers) {
|
|
2560
|
+
let imports;
|
|
2561
|
+
const required_args_properties = [];
|
|
2562
|
+
for (const [dispatcher_id, { import_path, generic_count }] of resolved_dispatchers) {
|
|
2563
|
+
imports = add_import(imports, import_path);
|
|
2564
|
+
const tuple_elements = [];
|
|
2565
|
+
for (let i = 0;i < generic_count; i++) {
|
|
2566
|
+
tuple_elements.push(factory24.createKeywordTypeNode(ts25.SyntaxKind.UnknownKeyword));
|
|
2567
|
+
}
|
|
2568
|
+
required_args_properties.push(factory24.createPropertySignature(undefined, factory24.createStringLiteral(dispatcher_id, true), undefined, factory24.createTupleTypeNode(tuple_elements)));
|
|
2569
|
+
}
|
|
2570
|
+
const required_args_type = factory24.createTypeAliasDeclaration(undefined, "DispatcherRequiredArgs", undefined, factory24.createTypeLiteralNode(required_args_properties));
|
|
2571
|
+
const default_args_type = factory24.createTypeAliasDeclaration(undefined, "DefaultArgs", [factory24.createTypeParameterDeclaration(undefined, "R", factory24.createTypeOperatorNode(ts25.SyntaxKind.KeyOfKeyword, factory24.createTypeReferenceNode("DispatcherRequiredArgs")))], factory24.createConditionalTypeNode(factory24.createIndexedAccessTypeNode(factory24.createIndexedAccessTypeNode(factory24.createTypeReferenceNode("DispatcherRequiredArgs"), factory24.createTypeReferenceNode("R")), Bind.StringLiteral("length")), Bind.NumericLiteral(0), factory24.createTupleTypeNode([]), factory24.createKeywordTypeNode(ts25.SyntaxKind.NeverKeyword)));
|
|
2572
|
+
const dispatchers_by_count = new Map;
|
|
2573
|
+
for (const [id, dispatcher] of resolved_dispatchers) {
|
|
2574
|
+
const count = dispatcher.generic_count;
|
|
2575
|
+
if (!dispatchers_by_count.has(count)) {
|
|
2576
|
+
dispatchers_by_count.set(count, []);
|
|
2577
|
+
}
|
|
2578
|
+
dispatchers_by_count.get(count).push([id, dispatcher]);
|
|
2579
|
+
}
|
|
2580
|
+
let apply_dispatcher_body = factory24.createKeywordTypeNode(ts25.SyntaxKind.NeverKeyword);
|
|
2581
|
+
const sorted_counts = [...dispatchers_by_count.keys()].sort((a, b) => b - a);
|
|
2582
|
+
for (const count of sorted_counts) {
|
|
2583
|
+
const dispatchers = dispatchers_by_count.get(count);
|
|
2584
|
+
for (const [dispatcher_id, { symbol_name }] of dispatchers) {
|
|
2585
|
+
const param_names = ["A", "B", "C", "D"].slice(0, count);
|
|
2586
|
+
const infer_params = param_names.map((name) => factory24.createInferTypeNode(factory24.createTypeParameterDeclaration(undefined, name)));
|
|
2587
|
+
const type_refs = param_names.map((name) => factory24.createTypeReferenceNode(name));
|
|
2588
|
+
const map_case = factory24.createConditionalTypeNode(factory24.createTypeReferenceNode("Args"), factory24.createTupleTypeNode(infer_params), factory24.createTypeReferenceNode(symbol_name, [...type_refs, Bind.StringLiteral("map")]), factory24.createKeywordTypeNode(ts25.SyntaxKind.NeverKeyword));
|
|
2589
|
+
const none_case = factory24.createConditionalTypeNode(factory24.createTypeReferenceNode("Args"), factory24.createTupleTypeNode([...infer_params, Bind.StringLiteral("%none")]), factory24.createTypeReferenceNode(symbol_name, [...type_refs, Bind.StringLiteral("%none")]), map_case);
|
|
2590
|
+
const fallback_case = factory24.createConditionalTypeNode(factory24.createTypeReferenceNode("Args"), factory24.createTupleTypeNode([...infer_params, Bind.StringLiteral("%fallback")]), factory24.createTypeReferenceNode(symbol_name, [...type_refs, Bind.StringLiteral("%fallback")]), none_case);
|
|
2591
|
+
apply_dispatcher_body = factory24.createConditionalTypeNode(factory24.createTypeReferenceNode("R"), Bind.StringLiteral(dispatcher_id), fallback_case, apply_dispatcher_body);
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
const apply_dispatcher_type = factory24.createTypeAliasDeclaration(undefined, "ApplyDispatcher", [
|
|
2595
|
+
factory24.createTypeParameterDeclaration(undefined, "R", factory24.createTypeOperatorNode(ts25.SyntaxKind.KeyOfKeyword, factory24.createTypeReferenceNode("DispatcherRequiredArgs"))),
|
|
2596
|
+
factory24.createTypeParameterDeclaration(undefined, "Args", factory24.createTypeReferenceNode("Array", [
|
|
2597
|
+
factory24.createKeywordTypeNode(ts25.SyntaxKind.UnknownKeyword)
|
|
2598
|
+
]))
|
|
2599
|
+
], apply_dispatcher_body);
|
|
2600
|
+
const args_constraint = factory24.createTypeReferenceNode("Array", [
|
|
2601
|
+
factory24.createKeywordTypeNode(ts25.SyntaxKind.UnknownKeyword)
|
|
2602
|
+
]);
|
|
2603
|
+
const dispatcher_type = factory24.createTypeAliasDeclaration([factory24.createToken(ts25.SyntaxKind.ExportKeyword)], "Dispatcher", [
|
|
2604
|
+
factory24.createTypeParameterDeclaration(undefined, "R", factory24.createTypeOperatorNode(ts25.SyntaxKind.KeyOfKeyword, factory24.createTypeReferenceNode("DispatcherRequiredArgs"))),
|
|
2605
|
+
factory24.createTypeParameterDeclaration(undefined, "Args", args_constraint, factory24.createTypeReferenceNode("DefaultArgs", [factory24.createTypeReferenceNode("R")]))
|
|
2606
|
+
], factory24.createTypeReferenceNode("ApplyDispatcher", [
|
|
2607
|
+
factory24.createTypeReferenceNode("R"),
|
|
2608
|
+
factory24.createTypeReferenceNode("Args")
|
|
2609
|
+
]));
|
|
2610
|
+
return {
|
|
2611
|
+
exports: [
|
|
2612
|
+
required_args_type,
|
|
2613
|
+
default_args_type,
|
|
2614
|
+
apply_dispatcher_type,
|
|
2615
|
+
dispatcher_type
|
|
2616
|
+
],
|
|
2617
|
+
paths: new Set,
|
|
2618
|
+
...add({ imports })
|
|
2619
|
+
};
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
// src/typegen/index.ts
|
|
2623
|
+
var { factory: factory25 } = ts26;
|
|
2624
|
+
|
|
2625
|
+
class TypesGenerator {
|
|
2626
|
+
resolved_registries = new Map;
|
|
2627
|
+
dispatcher_properties = new Map;
|
|
2628
|
+
resolved_symbols = new Map;
|
|
2629
|
+
resolved_dispatchers = new Map;
|
|
2630
|
+
constructor() {}
|
|
2631
|
+
resolve_types(symbols) {
|
|
2632
|
+
console.log("registries");
|
|
2633
|
+
this.resolve_registry_symbols(symbols);
|
|
2634
|
+
const registry_exports = export_registry(this.resolved_registries);
|
|
2635
|
+
this.resolved_symbols.set("::java::registry", registry_exports);
|
|
2636
|
+
const dispatchers = symbols.getVisibleSymbols("mcdoc/dispatcher");
|
|
2637
|
+
for (const id of Object.keys(dispatchers)) {
|
|
2638
|
+
if ("%none" in dispatchers[id].members) {
|
|
2639
|
+
this.dispatcher_properties.set(id, { supports_none: true });
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
console.log("modules");
|
|
2643
|
+
const module_map = symbols.getVisibleSymbols("mcdoc");
|
|
2644
|
+
this.resolve_module_symbols(module_map, symbols);
|
|
2645
|
+
console.log("dispatchers");
|
|
2646
|
+
this.resolve_dispatcher_symbols(dispatchers, module_map, symbols);
|
|
2647
|
+
const dispatcher_exports = export_dispatcher(this.resolved_dispatchers);
|
|
2648
|
+
this.resolved_symbols.set("mcdoc::dispatcher", dispatcher_exports);
|
|
2649
|
+
}
|
|
2650
|
+
resolve_registry_symbols(registries) {
|
|
2651
|
+
for (const registry_name of AllCategories) {
|
|
2652
|
+
if (registry_name === "mcdoc" || registry_name === "mcdoc/dispatcher") {
|
|
2653
|
+
continue;
|
|
2654
|
+
}
|
|
2655
|
+
const registry = Object.keys(registries.getVisibleSymbols(registry_name));
|
|
2656
|
+
if (registry.length === 0)
|
|
2657
|
+
continue;
|
|
2658
|
+
const type_name = pluralize(registry_name.split("/").join("_")).toUpperCase();
|
|
2659
|
+
const symbol_path = `::java::_registry::${type_name.toLowerCase()}`;
|
|
2660
|
+
this.resolved_symbols.set(symbol_path, {
|
|
2661
|
+
imports: {
|
|
2662
|
+
check: new Map,
|
|
2663
|
+
ordered: ["sandstone::NamespacedLiteralUnion", "sandstone::Set", "sandstone::SetType"]
|
|
2664
|
+
},
|
|
2665
|
+
exports: [
|
|
2666
|
+
factory25.createTypeAliasDeclaration([factory25.createToken(ts26.SyntaxKind.ExportKeyword)], type_name, undefined, factory25.createParenthesizedType(factory25.createUnionTypeNode([
|
|
2667
|
+
factory25.createTypeReferenceNode("NamespacedLiteralUnion", [factory25.createTypeReferenceNode(factory25.createIdentifier("SetType"), [factory25.createTypeQueryNode(factory25.createIdentifier(`${type_name}_SET`))])]),
|
|
2668
|
+
factory25.createTemplateLiteralType(factory25.createTemplateHead("minecraft:"), [factory25.createTemplateLiteralTypeSpan(factory25.createTypeReferenceNode(factory25.createIdentifier("SetType"), [factory25.createTypeQueryNode(factory25.createIdentifier(`${type_name}_SET`))]), factory25.createTemplateTail(""))])
|
|
2669
|
+
]))),
|
|
2670
|
+
factory25.createVariableStatement([factory25.createToken(ts26.SyntaxKind.ExportKeyword)], factory25.createVariableDeclarationList([factory25.createVariableDeclaration(`${type_name}_SET`, undefined, undefined, factory25.createNewExpression(factory25.createIdentifier("Set"), undefined, [factory25.createAsExpression(factory25.createArrayLiteralExpression(registry.map((s) => factory25.createStringLiteral(s.split(":")[1], true)), true), factory25.createTypeReferenceNode("const"))]))], ts26.NodeFlags.Const))
|
|
2671
|
+
],
|
|
2672
|
+
paths: new Set2
|
|
2673
|
+
});
|
|
2674
|
+
this.resolved_registries.set(registry_name, {
|
|
2675
|
+
registry: factory25.createIdentifier(type_name),
|
|
2676
|
+
import_path: `${symbol_path}::${type_name}`
|
|
2677
|
+
});
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
resolve_module_symbols(module_map, symbols) {
|
|
2681
|
+
for (const _path of Object.keys(module_map)) {
|
|
2682
|
+
const { data } = module_map[_path];
|
|
2683
|
+
if (_path.endsWith(">")) {
|
|
2684
|
+
continue;
|
|
2685
|
+
}
|
|
2686
|
+
const matches = mcdoc_raw.matchAll(new RegExp(_path, "g"));
|
|
2687
|
+
const first_match = matches.next();
|
|
2688
|
+
const second_match = matches.next();
|
|
2689
|
+
if (!first_match.done && second_match.done) {
|
|
2690
|
+
continue;
|
|
2691
|
+
}
|
|
2692
|
+
if (data !== null && typeof data === "object" && "typeDef" in data) {
|
|
2693
|
+
const type = data.typeDef;
|
|
2694
|
+
const path = _path.split("::");
|
|
2695
|
+
const name = path.at(-1);
|
|
2696
|
+
const module_path = path.slice(0, -1).join("::");
|
|
2697
|
+
if (type.kind === "reference") {
|
|
2698
|
+
const has_attrs = "attributes" in type && Array.isArray(type.attributes) && type.attributes.length > 0;
|
|
2699
|
+
if (!has_attrs) {
|
|
2700
|
+
continue;
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
const resolved_member = get_type_handler(type)(type)({
|
|
2704
|
+
dispatcher_properties: this.dispatcher_properties,
|
|
2705
|
+
root_type: true,
|
|
2706
|
+
name,
|
|
2707
|
+
module_path,
|
|
2708
|
+
module_map,
|
|
2709
|
+
symbols
|
|
2710
|
+
});
|
|
2711
|
+
const module = (() => {
|
|
2712
|
+
if (!this.resolved_symbols.has(module_path)) {
|
|
2713
|
+
return this.resolved_symbols.set(module_path, {
|
|
2714
|
+
paths: new Set2([_path]),
|
|
2715
|
+
exports: [],
|
|
2716
|
+
..."imports" in resolved_member ? { imports: resolved_member.imports } : {}
|
|
2717
|
+
}).get(module_path);
|
|
2718
|
+
}
|
|
2719
|
+
const mod = this.resolved_symbols.get(module_path);
|
|
2720
|
+
mod.paths.add(_path);
|
|
2721
|
+
if ("imports" in resolved_member) {
|
|
2722
|
+
mod.imports = merge_imports(mod.imports, resolved_member.imports);
|
|
2723
|
+
}
|
|
2724
|
+
return mod;
|
|
2725
|
+
})();
|
|
2726
|
+
if (ts26.isTypeAliasDeclaration(resolved_member.type)) {
|
|
2727
|
+
module.exports.push(resolved_member.type);
|
|
2728
|
+
} else {
|
|
2729
|
+
module.exports.push(Bind.Doc(factory25.createTypeAliasDeclaration([factory25.createModifier(ts26.SyntaxKind.ExportKeyword)], name, undefined, resolved_member.type), resolved_member.docs));
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
resolve_dispatcher_symbols(dispatchers, module_map, symbols) {
|
|
2735
|
+
for (const id of Object.keys(dispatchers)) {
|
|
2736
|
+
const { members } = dispatchers[id];
|
|
2737
|
+
if (members === undefined) {
|
|
2738
|
+
continue;
|
|
2739
|
+
}
|
|
2740
|
+
const [namespace, _name] = id.split(":");
|
|
2741
|
+
const name = pascal_case(`${namespace === "mcdoc" ? "mcdoc_" : ""}${_name}`);
|
|
2742
|
+
const { types, imports, references, generic_count } = DispatcherSymbol(id, name, members, this.dispatcher_properties, module_map, symbols);
|
|
2743
|
+
let in_module = false;
|
|
2744
|
+
const symbol_path = (() => {
|
|
2745
|
+
if (namespace === "mcdoc") {
|
|
2746
|
+
return `::java::_builtin::${_name}`;
|
|
2747
|
+
}
|
|
2748
|
+
if (references !== undefined) {
|
|
2749
|
+
const sorted = references.location_counts.sort((a, b) => b[1] - a[1]);
|
|
2750
|
+
if (sorted.length === 1 || sorted[0][1] > sorted[1][1] + 5) {
|
|
2751
|
+
in_module = true;
|
|
2752
|
+
return sorted[0][0];
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
return `::java::_dispatcher::${_name}`;
|
|
2756
|
+
})();
|
|
2757
|
+
const dispatcher_type_name = `Symbol${name}`;
|
|
2758
|
+
this.resolved_dispatchers.set(id, {
|
|
2759
|
+
import_path: `${symbol_path}::${dispatcher_type_name}`,
|
|
2760
|
+
type: factory25.createTypeReferenceNode(dispatcher_type_name),
|
|
2761
|
+
generic_count,
|
|
2762
|
+
symbol_name: dispatcher_type_name
|
|
2763
|
+
});
|
|
2764
|
+
if (in_module && this.resolved_symbols.has(symbol_path)) {
|
|
2765
|
+
const mod = this.resolved_symbols.get(symbol_path);
|
|
2766
|
+
mod.exports.push(...types);
|
|
2767
|
+
if (imports !== undefined) {
|
|
2768
|
+
for (const path of imports.ordered) {
|
|
2769
|
+
if (!mod.paths.has(path)) {
|
|
2770
|
+
mod.imports = add_import(mod.imports, path);
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
} else {
|
|
2775
|
+
this.resolved_symbols.set(symbol_path, {
|
|
2776
|
+
exports: types,
|
|
2777
|
+
paths: new Set2,
|
|
2778
|
+
...add({ imports })
|
|
2779
|
+
});
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
// src/typegen/compile.ts
|
|
2786
|
+
import ts27 from "typescript";
|
|
2787
|
+
import { ESLint } from "eslint";
|
|
2788
|
+
import stylistic from "@stylistic/eslint-plugin";
|
|
2789
|
+
import wrap from "@seahax/eslint-plugin-wrap";
|
|
2790
|
+
import tsparser from "@typescript-eslint/parser";
|
|
2791
|
+
var eslint = new ESLint({
|
|
2792
|
+
fix: true,
|
|
2793
|
+
overrideConfigFile: true,
|
|
2794
|
+
overrideConfig: [
|
|
2795
|
+
wrap.config({
|
|
2796
|
+
maxLen: 120,
|
|
2797
|
+
tabWidth: 4,
|
|
2798
|
+
autoFix: true,
|
|
2799
|
+
severity: "warn"
|
|
2800
|
+
}),
|
|
2801
|
+
{
|
|
2802
|
+
files: ["**/*.ts"],
|
|
2803
|
+
languageOptions: {
|
|
2804
|
+
parser: tsparser,
|
|
2805
|
+
parserOptions: {
|
|
2806
|
+
ecmaVersion: "latest",
|
|
2807
|
+
sourceType: "module"
|
|
2808
|
+
}
|
|
2809
|
+
},
|
|
2810
|
+
plugins: {
|
|
2811
|
+
"@stylistic": stylistic
|
|
2812
|
+
},
|
|
2813
|
+
rules: {
|
|
2814
|
+
"@stylistic/indent": ["error", 4],
|
|
2815
|
+
"@stylistic/quotes": ["error", "single"],
|
|
2816
|
+
"@stylistic/semi": ["error", "never"],
|
|
2817
|
+
"@stylistic/member-delimiter-style": ["error", {
|
|
2818
|
+
multiline: { delimiter: "none" },
|
|
2819
|
+
singleline: { delimiter: "comma", requireLast: false }
|
|
2820
|
+
}],
|
|
2821
|
+
"@stylistic/comma-dangle": ["error", "always-multiline"],
|
|
2822
|
+
"@stylistic/object-curly-spacing": ["error", "always"],
|
|
2823
|
+
"@stylistic/array-bracket-spacing": ["error", "never"],
|
|
2824
|
+
"@stylistic/block-spacing": ["error", "always"],
|
|
2825
|
+
"@stylistic/brace-style": ["error", "1tbs", { allowSingleLine: true }],
|
|
2826
|
+
"@stylistic/key-spacing": ["error", { beforeColon: false, afterColon: true }],
|
|
2827
|
+
"@stylistic/keyword-spacing": ["error", { before: true, after: true }],
|
|
2828
|
+
"@stylistic/space-before-blocks": ["error", "always"],
|
|
2829
|
+
"@stylistic/space-infix-ops": "error",
|
|
2830
|
+
"@stylistic/eol-last": ["error", "always"],
|
|
2831
|
+
"@stylistic/no-trailing-spaces": "error",
|
|
2832
|
+
"@stylistic/no-multiple-empty-lines": ["error", { max: 1 }],
|
|
2833
|
+
"@stylistic/padding-line-between-statements": [
|
|
2834
|
+
"error",
|
|
2835
|
+
{ blankLine: "always", prev: "export", next: "export" },
|
|
2836
|
+
{ blankLine: "always", prev: "import", next: "*" },
|
|
2837
|
+
{ blankLine: "never", prev: "import", next: "import" }
|
|
2838
|
+
]
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
]
|
|
2842
|
+
});
|
|
2843
|
+
async function compile_types(nodes, file = "code.ts") {
|
|
2844
|
+
const printer = ts27.createPrinter({ newLine: ts27.NewLineKind.LineFeed, omitTrailingSemicolon: true });
|
|
2845
|
+
const printed = printer.printList(ts27.ListFormat.MultiLine, ts27.factory.createNodeArray(nodes), ts27.createSourceFile(file, "", ts27.ScriptTarget.Latest, false, ts27.ScriptKind.TS));
|
|
2846
|
+
const results = await eslint.lintText(printed, { filePath: file });
|
|
2847
|
+
if (results.length > 0) {
|
|
2848
|
+
const result = results[0];
|
|
2849
|
+
if (result.errorCount > 0 && !result.output) {
|
|
2850
|
+
console.log(`[ESLint] ${file}: ${result.errorCount} errors`);
|
|
2851
|
+
console.log("[ESLint] Sample messages:", result.messages.slice(0, 3));
|
|
2852
|
+
}
|
|
2853
|
+
if (result.output) {
|
|
2854
|
+
return result.output;
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
return printed;
|
|
2858
|
+
}
|
|
2859
|
+
|
|
2860
|
+
// src/typegen/import.ts
|
|
2861
|
+
import ts28 from "typescript";
|
|
2862
|
+
var { factory: factory26 } = ts28;
|
|
2863
|
+
function BindImports(module_path, modules, is_type_only = true) {
|
|
2864
|
+
return factory26.createImportDeclaration(undefined, factory26.createImportClause(is_type_only, undefined, factory26.createNamedImports(modules.map((name) => factory26.createImportSpecifier(false, undefined, factory26.createIdentifier(name))))), factory26.createStringLiteral(module_path, true));
|
|
2865
|
+
}
|
|
2866
|
+
function handle_imports(imports) {
|
|
2867
|
+
if (!imports)
|
|
2868
|
+
return [];
|
|
2869
|
+
const grouped = new Map;
|
|
2870
|
+
for (const import_path of imports.ordered) {
|
|
2871
|
+
const parts = import_path.split("::");
|
|
2872
|
+
const type_name = parts.at(-1);
|
|
2873
|
+
const path = parts.slice(0, -1);
|
|
2874
|
+
let file;
|
|
2875
|
+
if (path.length === 0) {
|
|
2876
|
+
throw new Error(`[mcdoc_import] Import path has no module prefix: "${import_path}"`);
|
|
2877
|
+
} else if (path[1] === "java") {
|
|
2878
|
+
file = `sandstone/generated/${path.slice(2).join("/")}`;
|
|
2879
|
+
} else if (path[0] === "sandstone") {
|
|
2880
|
+
file = path.join("/");
|
|
2881
|
+
} else {
|
|
2882
|
+
throw new Error(`[mcdoc_import] Unsupported import location "${path[0]}" in "${import_path}"`);
|
|
2883
|
+
}
|
|
2884
|
+
const existing = grouped.get(file);
|
|
2885
|
+
if (existing) {
|
|
2886
|
+
existing.push(type_name);
|
|
2887
|
+
} else {
|
|
2888
|
+
grouped.set(file, [type_name]);
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
const declarations = [];
|
|
2892
|
+
for (const [file, names] of grouped) {
|
|
2893
|
+
if (file === "sandstone") {
|
|
2894
|
+
const set_index = names.indexOf("Set");
|
|
2895
|
+
if (set_index !== -1) {
|
|
2896
|
+
names.splice(set_index, 1);
|
|
2897
|
+
declarations.push(BindImports(file, ["Set"], false));
|
|
2898
|
+
}
|
|
2899
|
+
if (names.length === 0) {
|
|
2900
|
+
continue;
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
declarations.push(BindImports(file, names));
|
|
2904
|
+
}
|
|
2905
|
+
return declarations;
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2908
|
+
// src/index.ts
|
|
2909
|
+
var cache_root = join(dirname(fileURLToPath(import.meta.url)), "cache");
|
|
2910
|
+
function registerAttributes(meta, release) {
|
|
2911
|
+
mcdoc5.runtime.registerAttribute(meta, "since", mcdoc5.runtime.attribute.validator.string, {
|
|
2912
|
+
filterElement: () => false
|
|
2913
|
+
});
|
|
2914
|
+
mcdoc5.runtime.registerAttribute(meta, "until", mcdoc5.runtime.attribute.validator.string, {
|
|
2915
|
+
filterElement: () => true
|
|
2916
|
+
});
|
|
2917
|
+
mcdoc5.runtime.registerAttribute(meta, "deprecated", mcdoc5.runtime.attribute.validator.optional(mcdoc5.runtime.attribute.validator.string), {
|
|
2918
|
+
mapField: (config, field, ctx) => {
|
|
2919
|
+
if (config === undefined) {
|
|
2920
|
+
return { ...field, deprecated: true };
|
|
2921
|
+
}
|
|
2922
|
+
if (!config.startsWith("1.")) {
|
|
2923
|
+
ctx.logger.warn(`Invalid mcdoc attribute for "deprecated": ${config}`);
|
|
2924
|
+
return field;
|
|
2925
|
+
}
|
|
2926
|
+
if (ReleaseVersion.cmp(release, config) >= 0) {
|
|
2927
|
+
return { ...field, deprecated: true };
|
|
2928
|
+
}
|
|
2929
|
+
return field;
|
|
2930
|
+
}
|
|
2931
|
+
});
|
|
2932
|
+
}
|
|
2933
|
+
var mcdoc_raw = "";
|
|
2934
|
+
var vanillaMcdocUrl = "https://api.spyglassmc.com/vanilla-mcdoc/symbols";
|
|
2935
|
+
async function fetchVanillaMcdoc() {
|
|
2936
|
+
try {
|
|
2937
|
+
const buffer = await fetchWithCache(vanillaMcdocUrl);
|
|
2938
|
+
mcdoc_raw = await buffer.text();
|
|
2939
|
+
return JSON.parse(mcdoc_raw);
|
|
2940
|
+
} catch (e) {
|
|
2941
|
+
throw new Error(`Error occurred while fetching vanilla-mcdoc: ${errorMessage(e)}`);
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
async function fetchRegistries(versionId) {
|
|
2945
|
+
console.debug(`[fetchRegistries] ${versionId}`);
|
|
2946
|
+
let etag = "";
|
|
2947
|
+
try {
|
|
2948
|
+
const req = await fetchWithCache(`https://api.spyglassmc.com/mcje/versions/${versionId}/registries`);
|
|
2949
|
+
etag = req.headers.get("ETag");
|
|
2950
|
+
const data = await req.json();
|
|
2951
|
+
const result = new Map;
|
|
2952
|
+
for (const id in data) {
|
|
2953
|
+
result.set(id, data[id].map((e) => "minecraft:" + e));
|
|
2954
|
+
}
|
|
2955
|
+
return [result, etag];
|
|
2956
|
+
} catch (e) {
|
|
2957
|
+
throw new Error(`Error occurred while fetching registries: ${errorMessage(e)}`);
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
async function fetchBlockStates(versionId) {
|
|
2961
|
+
console.debug(`[fetchBlockStates] ${versionId}`);
|
|
2962
|
+
const result = new Map;
|
|
2963
|
+
let etag = "";
|
|
2964
|
+
try {
|
|
2965
|
+
const req = await fetchWithCache(`https://api.spyglassmc.com/mcje/versions/${versionId}/block_states`);
|
|
2966
|
+
etag = req.headers.get("ETag");
|
|
2967
|
+
const data = await req.json();
|
|
2968
|
+
for (const id in data) {
|
|
2969
|
+
result.set(id, data[id]);
|
|
2970
|
+
}
|
|
2971
|
+
} catch (e) {
|
|
2972
|
+
console.warn("Error occurred while fetching block states:", errorMessage(e));
|
|
2973
|
+
}
|
|
2974
|
+
return [result, etag];
|
|
2975
|
+
}
|
|
2976
|
+
var VanillaMcdocUri = "mcdoc://vanilla-mcdoc/symbols.json";
|
|
2977
|
+
function vanillaMcdocRegistrar(vanillaMcdoc) {
|
|
2978
|
+
return (symbols) => {
|
|
2979
|
+
const start = performance.now();
|
|
2980
|
+
for (const [id, typeDef] of Object.entries(vanillaMcdoc.mcdoc)) {
|
|
2981
|
+
symbols.query(VanillaMcdocUri, "mcdoc", id).enter({
|
|
2982
|
+
data: { data: { typeDef } },
|
|
2983
|
+
usage: { type: "declaration" }
|
|
2984
|
+
});
|
|
2985
|
+
}
|
|
2986
|
+
for (const [dispatcher, ids] of Object.entries(vanillaMcdoc["mcdoc/dispatcher"])) {
|
|
2987
|
+
symbols.query(VanillaMcdocUri, "mcdoc/dispatcher", dispatcher).enter({ usage: { type: "declaration" } }).onEach(Object.entries(ids), ([id, typeDef], query) => {
|
|
2988
|
+
query.member(id, (memberQuery) => {
|
|
2989
|
+
memberQuery.enter({
|
|
2990
|
+
data: { data: { typeDef } },
|
|
2991
|
+
usage: { type: "declaration" }
|
|
2992
|
+
});
|
|
2993
|
+
});
|
|
2994
|
+
});
|
|
2995
|
+
}
|
|
2996
|
+
const duration = performance.now() - start;
|
|
2997
|
+
console.log(`[vanillaMcdocRegistrar] Done in ${duration}ms`);
|
|
2998
|
+
};
|
|
2999
|
+
}
|
|
3000
|
+
var initialize2 = async (ctx) => {
|
|
3001
|
+
const { config, logger, meta, externals, cacheRoot } = ctx;
|
|
3002
|
+
const vanillaMcdoc = await fetchVanillaMcdoc();
|
|
3003
|
+
meta.registerSymbolRegistrar("vanilla-mcdoc", {
|
|
3004
|
+
checksum: vanillaMcdoc.ref,
|
|
3005
|
+
registrar: vanillaMcdocRegistrar(vanillaMcdoc)
|
|
3006
|
+
});
|
|
3007
|
+
meta.registerUriBinder(je.binder.uriBinder);
|
|
3008
|
+
const version = (await (await fetch("https://api.spyglassmc.com/mcje/versions")).json())[0];
|
|
3009
|
+
const release = version.id;
|
|
3010
|
+
const [registries, registriesETag] = await fetchRegistries(version.id);
|
|
3011
|
+
const [blockStates, blockStatesETag] = await fetchBlockStates(version.id);
|
|
3012
|
+
const summary = {
|
|
3013
|
+
registries: Object.fromEntries(registries.entries()),
|
|
3014
|
+
blocks: Object.fromEntries([...blockStates.entries()].map(([id, data]) => [id, data])),
|
|
3015
|
+
fluids: je.dependency.Fluids,
|
|
3016
|
+
commands: { type: "root", children: {} }
|
|
3017
|
+
};
|
|
3018
|
+
const versionETag = registriesETag + blockStatesETag;
|
|
3019
|
+
meta.registerSymbolRegistrar("mcmeta-summary", {
|
|
3020
|
+
checksum: versionETag,
|
|
3021
|
+
registrar: je.dependency.symbolRegistrar(summary, release)
|
|
3022
|
+
});
|
|
3023
|
+
registerAttributes(meta, release);
|
|
3024
|
+
return { loadedVersion: release };
|
|
3025
|
+
};
|
|
3026
|
+
async function generate(options = {}) {
|
|
3027
|
+
const { out_dir = "types", tsconfig = true } = options;
|
|
3028
|
+
const project_path = resolve(process.cwd(), "dummy");
|
|
3029
|
+
await fileUtil.ensureDir(NodeJsExternals, project_path);
|
|
3030
|
+
const service = new Service({
|
|
3031
|
+
logger: {
|
|
3032
|
+
log: (...log_args) => console.log(...log_args),
|
|
3033
|
+
warn: (...log_args) => console.warn(...log_args),
|
|
3034
|
+
error: (...log_args) => console.error(...log_args),
|
|
3035
|
+
info: (...log_args) => console.info(...log_args)
|
|
3036
|
+
},
|
|
3037
|
+
project: {
|
|
3038
|
+
cacheRoot: fileUtil.ensureEndingSlash(pathToFileURL(cache_root).toString()),
|
|
3039
|
+
defaultConfig: ConfigService.merge(VanillaConfig, {
|
|
3040
|
+
env: { dependencies: [] }
|
|
3041
|
+
}),
|
|
3042
|
+
externals: NodeJsExternals,
|
|
3043
|
+
initializers: [mcdoc5.initialize, initialize2],
|
|
3044
|
+
projectRoots: [fileUtil.ensureEndingSlash(pathToFileURL(project_path).toString())]
|
|
3045
|
+
}
|
|
3046
|
+
});
|
|
3047
|
+
await service.project.ready();
|
|
3048
|
+
await service.project.cacheService.save();
|
|
3049
|
+
const type_gen = new TypesGenerator;
|
|
3050
|
+
type_gen.resolve_types(service.project.symbols);
|
|
3051
|
+
for await (const [symbol_path, { exports, imports }] of type_gen.resolved_symbols.entries()) {
|
|
3052
|
+
const parts = symbol_path.split("::");
|
|
3053
|
+
if (parts[0] === "") {
|
|
3054
|
+
parts.shift();
|
|
3055
|
+
}
|
|
3056
|
+
const file = parts.slice(1);
|
|
3057
|
+
file.unshift(out_dir);
|
|
3058
|
+
const out_path = `${join(...file)}.ts`;
|
|
3059
|
+
const code = await compile_types([
|
|
3060
|
+
...handle_imports(imports),
|
|
3061
|
+
...exports
|
|
3062
|
+
], out_path);
|
|
3063
|
+
await Bun.write(out_path, code);
|
|
3064
|
+
}
|
|
3065
|
+
if (tsconfig) {
|
|
3066
|
+
await Bun.write(join(out_dir, "tsconfig.json"), JSON.stringify({
|
|
3067
|
+
compilerOptions: {
|
|
3068
|
+
allowImportingTsExtensions: true,
|
|
3069
|
+
noEmit: true,
|
|
3070
|
+
baseUrl: "./",
|
|
3071
|
+
paths: {
|
|
3072
|
+
sandstone: ["../sandstone-types/index.ts"],
|
|
3073
|
+
"sandstone/generated/*": [`./*`]
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
}, null, 2));
|
|
3077
|
+
}
|
|
3078
|
+
service.project.close();
|
|
3079
|
+
}
|
|
3080
|
+
export {
|
|
3081
|
+
mcdoc_raw,
|
|
3082
|
+
generate,
|
|
3083
|
+
fetchVanillaMcdoc,
|
|
3084
|
+
fetchRegistries,
|
|
3085
|
+
fetchBlockStates
|
|
3086
|
+
};
|