@defold-typescript/types 0.35.0 → 0.36.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/api-signatures.json +9391 -3
- package/examples/translations.json +6 -6
- package/generated/factory.d.ts +11 -10
- package/generated/render.d.ts +5 -5
- package/generated/versions/defold-1.12.4/factory.d.ts +11 -10
- package/generated/versions/defold-1.12.4/render.d.ts +5 -5
- package/generated/versions/defold-1.12.4/zlib.d.ts +2 -1
- package/generated/versions/defold-1.13.0/factory.d.ts +11 -10
- package/generated/versions/defold-1.13.0/render.d.ts +5 -5
- package/generated/versions/defold-1.13.0/zlib.d.ts +2 -1
- package/generated/zlib.d.ts +2 -1
- package/index.d.ts +1 -0
- package/package.json +5 -2
- package/scripts/generate-api-signatures.ts +33 -8
- package/src/emit-dts.ts +173 -63
- package/src/index.ts +1 -0
- package/src/render-overloads.d.ts +17 -0
package/src/emit-dts.ts
CHANGED
|
@@ -222,7 +222,9 @@ export const OVERLOAD_COVERED_SKIPS = new Set([
|
|
|
222
222
|
// is the TSTL non-string-key Lua-table idiom and resolves the same way the
|
|
223
223
|
// already-emitted `LuaMultiReturn` does. The audit consults this map too, so the
|
|
224
224
|
// gate and the emitted surface stay coupled; a slot not curated here still
|
|
225
|
-
// surfaces under `recordTables` until a human adds it.
|
|
225
|
+
// surfaces under `recordTables` until a human adds it. Key and value are both
|
|
226
|
+
// `A | B` union tokens split per token, so a key whose doc names constants
|
|
227
|
+
// brands each of them rather than widening to `number`.
|
|
226
228
|
export const MAPPING_TABLE_SLOTS: ReadonlyMap<string, { key: string; value: string }> = new Map([
|
|
227
229
|
["gui.clone_tree", { key: "hash", value: "node" }],
|
|
228
230
|
["gui.get_tree", { key: "hash", value: "node" }],
|
|
@@ -408,6 +410,18 @@ export function documentedConstantTokens(text: string, universe: ReadonlySet<str
|
|
|
408
410
|
return [...out];
|
|
409
411
|
}
|
|
410
412
|
|
|
413
|
+
// The constants a `table` slot's doc names as the table's *keys*, as opposed to
|
|
414
|
+
// the far commoner shape where a field's *value* is a constant
|
|
415
|
+
// (`physics.get_shape`'s `type`, `resource.create_texture`'s `format`). Upstream
|
|
416
|
+
// marks the difference in prose — render.clear reads "table with keys specifying
|
|
417
|
+
// which buffers to clear ... Available keys are:" — so a key mention alongside a
|
|
418
|
+
// named constant is the discriminator. Empty means the slot has no documented
|
|
419
|
+
// constant keys, which is true of every `table` slot but one today.
|
|
420
|
+
export function documentedConstantKeyTokens(doc: string, universe: ReadonlySet<string>): string[] {
|
|
421
|
+
if (!/\bkeys?\b/i.test(doc.replace(/<[^>]*>/g, ""))) return [];
|
|
422
|
+
return documentedConstantTokens(doc, universe);
|
|
423
|
+
}
|
|
424
|
+
|
|
411
425
|
type SlotDocLookup = (slotKey: string) => string | undefined;
|
|
412
426
|
|
|
413
427
|
function constantSlotTokens(
|
|
@@ -830,11 +844,20 @@ export const TABLE_SLOT_CURATIONS: ReadonlyMap<string, TableSlotCuration> = new
|
|
|
830
844
|
// render.predicate's `tags` is "table of tags ... can be of either hash or
|
|
831
845
|
// string type", a homogeneous array whose element is the string|hash union.
|
|
832
846
|
["render.predicate:param:tags", { kind: "array", element: ["string", "hash"] }],
|
|
833
|
-
// render.clear's `buffers` maps the
|
|
834
|
-
// their clear value: vector4 for the color buffer, number for
|
|
835
|
-
//
|
|
836
|
-
//
|
|
837
|
-
|
|
847
|
+
// render.clear's `buffers` maps the graphics.BUFFER_TYPE_* constants its doc
|
|
848
|
+
// names as keys to their clear value: vector4 for the color buffer, number for
|
|
849
|
+
// depth/stencil. Both sides are union tokens the mapping string branch splits,
|
|
850
|
+
// so the key emits the three branded constants and the value `number | Vector4`.
|
|
851
|
+
// The key is branded rather than `number`, which is the narrowing users migrate
|
|
852
|
+
// to via the authored `render.ClearBufferKey` alias.
|
|
853
|
+
[
|
|
854
|
+
"render.clear:param:buffers",
|
|
855
|
+
{
|
|
856
|
+
kind: "mapping",
|
|
857
|
+
key: "graphics.BUFFER_TYPE_COLOR0_BIT | graphics.BUFFER_TYPE_DEPTH_BIT | graphics.BUFFER_TYPE_STENCIL_BIT",
|
|
858
|
+
value: "number | vector4",
|
|
859
|
+
},
|
|
860
|
+
],
|
|
838
861
|
// go.on_input and gui.on_input share the same well-known InputAction shape
|
|
839
862
|
// (the on_input function description lists the well-known fields: value,
|
|
840
863
|
// pressed, released, repeated, x/y/screen_x/screen_y/dx/dy/screen_dx/screen_dy,
|
|
@@ -1883,10 +1906,25 @@ export function emitDeclarations(module: ApiModule, options?: EmitOptions): stri
|
|
|
1883
1906
|
return `${lines.join("\n")}\n`;
|
|
1884
1907
|
}
|
|
1885
1908
|
|
|
1909
|
+
/**
|
|
1910
|
+
* Every documented slot's rendered TS type, keyed `param|return:<position>:<raw
|
|
1911
|
+
* ref-doc name>`. The position is part of the key because a multi-return can
|
|
1912
|
+
* carry several unnamed slots (`push.schedule` renders two), which a name-only
|
|
1913
|
+
* key would collapse into one. Each value appears verbatim inside the symbol's
|
|
1914
|
+
* own `tsSignature`, so a consumer rendering a slot's type beside that signature
|
|
1915
|
+
* cannot contradict it.
|
|
1916
|
+
*/
|
|
1917
|
+
export type SlotTypes = Readonly<Record<string, string>>;
|
|
1918
|
+
|
|
1919
|
+
function slotKey(kind: "param" | "return", position: number, name: string): string {
|
|
1920
|
+
return `${kind}:${position}:${name}`;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1886
1923
|
/** One emitted symbol's identity paired with its rendered TS signature text. */
|
|
1887
1924
|
export interface SymbolSignature {
|
|
1888
1925
|
readonly identity: ApiSymbolIdentity;
|
|
1889
1926
|
readonly tsSignature: string;
|
|
1927
|
+
readonly slotTypes: SlotTypes;
|
|
1890
1928
|
}
|
|
1891
1929
|
|
|
1892
1930
|
/**
|
|
@@ -1931,9 +1969,14 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
1931
1969
|
});
|
|
1932
1970
|
const emitName = (name: string): string => (TS_RESERVED_NAMES.has(name) ? `_${name}` : name);
|
|
1933
1971
|
|
|
1972
|
+
// A member with no call list (constant, variable, property, typedef) documents
|
|
1973
|
+
// no slot, so it reports an empty map rather than being absent from the ledger.
|
|
1974
|
+
const NO_SLOTS: SlotTypes = {};
|
|
1975
|
+
|
|
1934
1976
|
for (const fn of module.functions) {
|
|
1935
1977
|
const prepared = prepareFunction(fn, prefix);
|
|
1936
1978
|
if (prepared === null) continue;
|
|
1979
|
+
const slotTypes: Record<string, string> = {};
|
|
1937
1980
|
out.push({
|
|
1938
1981
|
identity: fnIdentity(fn),
|
|
1939
1982
|
tsSignature: emitFunction(
|
|
@@ -1943,7 +1986,9 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
1943
1986
|
resolver,
|
|
1944
1987
|
constantTokens,
|
|
1945
1988
|
urlParameters,
|
|
1989
|
+
slotTypes,
|
|
1946
1990
|
),
|
|
1991
|
+
slotTypes,
|
|
1947
1992
|
});
|
|
1948
1993
|
}
|
|
1949
1994
|
|
|
@@ -1957,9 +2002,11 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
1957
2002
|
signature: "",
|
|
1958
2003
|
},
|
|
1959
2004
|
tsSignature: emitVariable(v, emitName(v.name), mapType),
|
|
2005
|
+
slotTypes: NO_SLOTS,
|
|
1960
2006
|
});
|
|
1961
2007
|
}
|
|
1962
2008
|
for (const fn of nested.functions) {
|
|
2009
|
+
const slotTypes: Record<string, string> = {};
|
|
1963
2010
|
out.push({
|
|
1964
2011
|
identity: fnIdentity(fn.original),
|
|
1965
2012
|
tsSignature: emitFunction(
|
|
@@ -1969,16 +2016,27 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
1969
2016
|
resolver,
|
|
1970
2017
|
constantTokens,
|
|
1971
2018
|
urlParameters,
|
|
2019
|
+
slotTypes,
|
|
1972
2020
|
),
|
|
2021
|
+
slotTypes,
|
|
1973
2022
|
});
|
|
1974
2023
|
}
|
|
1975
2024
|
|
|
1976
2025
|
const handleGroups = collectHandleMethodGroups(module);
|
|
1977
2026
|
for (const group of handleGroups.values()) {
|
|
1978
2027
|
for (const prepared of group) {
|
|
2028
|
+
const slotTypes: Record<string, string> = {};
|
|
1979
2029
|
out.push({
|
|
1980
2030
|
identity: fnIdentity(prepared.original),
|
|
1981
|
-
tsSignature: emitMethod(
|
|
2031
|
+
tsSignature: emitMethod(
|
|
2032
|
+
prepared,
|
|
2033
|
+
mapType,
|
|
2034
|
+
resolver,
|
|
2035
|
+
constantTokens,
|
|
2036
|
+
urlParameters,
|
|
2037
|
+
slotTypes,
|
|
2038
|
+
),
|
|
2039
|
+
slotTypes,
|
|
1982
2040
|
});
|
|
1983
2041
|
}
|
|
1984
2042
|
}
|
|
@@ -1989,6 +2047,7 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
1989
2047
|
out.push({
|
|
1990
2048
|
identity: { namespace: module.namespace, kind: "CONSTANT", name: c.name, signature: "" },
|
|
1991
2049
|
tsSignature: `const ${prepared.name}: ${brandType(prepared.fqn)};`,
|
|
2050
|
+
slotTypes: NO_SLOTS,
|
|
1992
2051
|
});
|
|
1993
2052
|
}
|
|
1994
2053
|
|
|
@@ -1998,6 +2057,7 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
1998
2057
|
out.push({
|
|
1999
2058
|
identity: { namespace: module.namespace, kind: "VARIABLE", name: v.name, signature: "" },
|
|
2000
2059
|
tsSignature: emitVariable(prepared, emitName(prepared.name), mapType),
|
|
2060
|
+
slotTypes: NO_SLOTS,
|
|
2001
2061
|
});
|
|
2002
2062
|
}
|
|
2003
2063
|
|
|
@@ -2005,6 +2065,7 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
2005
2065
|
out.push({
|
|
2006
2066
|
identity: { namespace: module.namespace, kind: "PROPERTY", name: p.name, signature: "" },
|
|
2007
2067
|
tsSignature: emitPropertyMember(p, mapType, module.namespace),
|
|
2068
|
+
slotTypes: NO_SLOTS,
|
|
2008
2069
|
});
|
|
2009
2070
|
}
|
|
2010
2071
|
|
|
@@ -2013,6 +2074,7 @@ export function emitSymbolSignatures(module: ApiModule, options?: EmitOptions):
|
|
|
2013
2074
|
out.push({
|
|
2014
2075
|
identity: { namespace: module.namespace, kind: "TYPEDEF", name: t.name, signature: "" },
|
|
2015
2076
|
tsSignature: `type ${t.name} = Opaque<"${t.name}">;`,
|
|
2077
|
+
slotTypes: NO_SLOTS,
|
|
2016
2078
|
});
|
|
2017
2079
|
}
|
|
2018
2080
|
|
|
@@ -2208,6 +2270,7 @@ function memberSignature(
|
|
|
2208
2270
|
resolver: TableDocResolver,
|
|
2209
2271
|
constantTokens: ConstantSlotTokens,
|
|
2210
2272
|
urlParameters: UrlParameterTable,
|
|
2273
|
+
slotSink?: Record<string, string>,
|
|
2211
2274
|
): string {
|
|
2212
2275
|
const original = prepared.original.parameters;
|
|
2213
2276
|
const elementName = prepared.original.name;
|
|
@@ -2216,22 +2279,19 @@ function memberSignature(
|
|
|
2216
2279
|
const positional = (varargIndex === -1 ? original : original.slice(0, varargIndex)).map((p, i) =>
|
|
2217
2280
|
emitParameter(p, i, i >= cutoff, mapType, resolver, constantTokens, elementName, urlParameters),
|
|
2218
2281
|
);
|
|
2219
|
-
const
|
|
2282
|
+
const rest =
|
|
2220
2283
|
varargIndex === -1
|
|
2221
|
-
?
|
|
2222
|
-
:
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
),
|
|
2233
|
-
]
|
|
2234
|
-
).join(", ");
|
|
2284
|
+
? null
|
|
2285
|
+
: emitRestParameter(
|
|
2286
|
+
original,
|
|
2287
|
+
varargIndex,
|
|
2288
|
+
mapType,
|
|
2289
|
+
resolver,
|
|
2290
|
+
constantTokens,
|
|
2291
|
+
elementName,
|
|
2292
|
+
urlParameters,
|
|
2293
|
+
);
|
|
2294
|
+
const params = [...positional.map((p) => p.text), ...(rest ? [rest.text] : [])].join(", ");
|
|
2235
2295
|
const ret = emitReturn(
|
|
2236
2296
|
prepared.original.returnValues,
|
|
2237
2297
|
mapType,
|
|
@@ -2241,12 +2301,28 @@ function memberSignature(
|
|
|
2241
2301
|
);
|
|
2242
2302
|
const predicateToken = TYPE_PREDICATES.get(elementName);
|
|
2243
2303
|
const soleParam = original[0];
|
|
2244
|
-
|
|
2304
|
+
const isPredicate =
|
|
2245
2305
|
predicateToken !== undefined &&
|
|
2246
2306
|
soleParam !== undefined &&
|
|
2247
2307
|
original.length === 1 &&
|
|
2248
|
-
ret.type === "boolean"
|
|
2249
|
-
) {
|
|
2308
|
+
ret.type === "boolean";
|
|
2309
|
+
if (slotSink !== undefined) {
|
|
2310
|
+
for (const [i, p] of positional.entries()) {
|
|
2311
|
+
const raw = original[i];
|
|
2312
|
+
if (raw) slotSink[slotKey("param", i, raw.name)] = p.ts;
|
|
2313
|
+
}
|
|
2314
|
+
for (const slot of rest?.slots ?? []) {
|
|
2315
|
+
slotSink[slotKey("param", slot.position, slot.name)] = slot.ts;
|
|
2316
|
+
}
|
|
2317
|
+
// A predicate renders `arg is T` in place of the mapped `boolean`, so its
|
|
2318
|
+
// return slot has no text in the signature to stand on and is not reported.
|
|
2319
|
+
if (!isPredicate) {
|
|
2320
|
+
for (const slot of ret.slots) {
|
|
2321
|
+
slotSink[slotKey("return", slot.position, slot.name)] = slot.ts;
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
if (isPredicate && soleParam !== undefined && predicateToken !== undefined) {
|
|
2250
2326
|
return `${name}(${params}): ${safeParamName(soleParam.name, 0)} is ${mapType(predicateToken)};`;
|
|
2251
2327
|
}
|
|
2252
2328
|
return `${name}(${params}): ${ret.type};${ret.trailing}`;
|
|
@@ -2259,8 +2335,9 @@ function emitFunction(
|
|
|
2259
2335
|
resolver: TableDocResolver,
|
|
2260
2336
|
constantTokens: ConstantSlotTokens,
|
|
2261
2337
|
urlParameters: UrlParameterTable,
|
|
2338
|
+
slotSink?: Record<string, string>,
|
|
2262
2339
|
): string {
|
|
2263
|
-
return `function ${memberSignature(prepared, name, mapType, resolver, constantTokens, urlParameters)}`;
|
|
2340
|
+
return `function ${memberSignature(prepared, name, mapType, resolver, constantTokens, urlParameters, slotSink)}`;
|
|
2264
2341
|
}
|
|
2265
2342
|
|
|
2266
2343
|
// A colon-method member of a handle interface: identical signature machinery to a
|
|
@@ -2272,8 +2349,17 @@ function emitMethod(
|
|
|
2272
2349
|
resolver: TableDocResolver,
|
|
2273
2350
|
constantTokens: ConstantSlotTokens,
|
|
2274
2351
|
urlParameters: UrlParameterTable,
|
|
2352
|
+
slotSink?: Record<string, string>,
|
|
2275
2353
|
): string {
|
|
2276
|
-
return memberSignature(
|
|
2354
|
+
return memberSignature(
|
|
2355
|
+
prepared,
|
|
2356
|
+
prepared.name,
|
|
2357
|
+
mapType,
|
|
2358
|
+
resolver,
|
|
2359
|
+
constantTokens,
|
|
2360
|
+
urlParameters,
|
|
2361
|
+
slotSink,
|
|
2362
|
+
);
|
|
2277
2363
|
}
|
|
2278
2364
|
|
|
2279
2365
|
// Build the indented JSDoc lines for a function from its ref-doc prose. The
|
|
@@ -2444,21 +2530,29 @@ function emitRestParameter(
|
|
|
2444
2530
|
constantTokens: ConstantSlotTokens,
|
|
2445
2531
|
elementName: string,
|
|
2446
2532
|
urlParameters: UrlParameterTable,
|
|
2447
|
-
): string {
|
|
2533
|
+
): { text: string; slots: EmittedSlot[] } {
|
|
2448
2534
|
const vararg = params[varargIndex];
|
|
2449
|
-
if (vararg === undefined) return "";
|
|
2450
|
-
const
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
),
|
|
2457
|
-
),
|
|
2458
|
-
];
|
|
2535
|
+
if (vararg === undefined) return { text: "", slots: [] };
|
|
2536
|
+
const folded = params.slice(varargIndex).map((p, offset) => ({
|
|
2537
|
+
position: varargIndex + offset,
|
|
2538
|
+
name: p.name,
|
|
2539
|
+
ts: parameterType(p, mapType, resolver, constantTokens, elementName, urlParameters),
|
|
2540
|
+
}));
|
|
2541
|
+
const members = [...new Set(folded.map((slot) => slot.ts))];
|
|
2459
2542
|
const first = members[0] ?? "unknown";
|
|
2460
2543
|
const element = members.length > 1 ? `(${members.join(" | ")})` : first;
|
|
2461
|
-
return
|
|
2544
|
+
return {
|
|
2545
|
+
text: `...${varargParamName(vararg.name, varargIndex)}: ${element}[]`,
|
|
2546
|
+
slots: folded,
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// A slot's rendered type paired with the position and raw ref-doc name that
|
|
2551
|
+
// identify it, so the signature text and the per-slot map come out of one call.
|
|
2552
|
+
interface EmittedSlot {
|
|
2553
|
+
readonly position: number;
|
|
2554
|
+
readonly name: string;
|
|
2555
|
+
readonly ts: string;
|
|
2462
2556
|
}
|
|
2463
2557
|
|
|
2464
2558
|
function emitParameter(
|
|
@@ -2470,7 +2564,7 @@ function emitParameter(
|
|
|
2470
2564
|
constantTokens: ConstantSlotTokens,
|
|
2471
2565
|
elementName: string,
|
|
2472
2566
|
urlParameters: UrlParameterTable,
|
|
2473
|
-
): string {
|
|
2567
|
+
): { text: string; ts: string } {
|
|
2474
2568
|
const name = safeParamName(p.name, index);
|
|
2475
2569
|
const ts = parameterType(p, mapType, resolver, constantTokens, elementName, urlParameters);
|
|
2476
2570
|
// An interior doc-optional param (a required param follows, so the trailing-`?`
|
|
@@ -2478,7 +2572,7 @@ function emitParameter(
|
|
|
2478
2572
|
// lowers `undefined` to `nil`, the faithful call. Trailing optionals keep the
|
|
2479
2573
|
// `?` form; required params are untouched.
|
|
2480
2574
|
const interiorOptional = !optional && isDocOptional(p, elementName) ? " | undefined" : "";
|
|
2481
|
-
return `${name}${optional ? "?" : ""}: ${ts}${interiorOptional}
|
|
2575
|
+
return { text: `${name}${optional ? "?" : ""}: ${ts}${interiorOptional}`, ts };
|
|
2482
2576
|
}
|
|
2483
2577
|
|
|
2484
2578
|
function emitReturn(
|
|
@@ -2487,33 +2581,42 @@ function emitReturn(
|
|
|
2487
2581
|
resolver: TableDocResolver,
|
|
2488
2582
|
constantTokens: ConstantSlotTokens,
|
|
2489
2583
|
elementName: string,
|
|
2490
|
-
): { type: string; trailing: string } {
|
|
2584
|
+
): { type: string; trailing: string; slots: EmittedSlot[] } {
|
|
2585
|
+
// An authored whole-return override is not a per-slot render, so it reports no
|
|
2586
|
+
// slots and leaves the consumer on its token-derived fallback.
|
|
2491
2587
|
const override = RETURN_TYPE_OVERRIDES.get(elementName);
|
|
2492
|
-
if (override !== undefined) return { type: override, trailing: "" };
|
|
2493
|
-
if (returnValues.length === 0) return { type: "void", trailing: "" };
|
|
2588
|
+
if (override !== undefined) return { type: override, trailing: "", slots: [] };
|
|
2589
|
+
if (returnValues.length === 0) return { type: "void", trailing: "", slots: [] };
|
|
2494
2590
|
if (returnValues.length > 1) {
|
|
2495
2591
|
// Defold multi-returns are positional and always present; each slot maps
|
|
2496
2592
|
// straight through (unknown when the doc lists no type) into a tuple that
|
|
2497
2593
|
// typescript-to-lua erases to `local a, b = fn()`.
|
|
2498
|
-
const
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2594
|
+
const emitted = returnValues.map((rv, index) => ({
|
|
2595
|
+
position: index,
|
|
2596
|
+
name: rv.name,
|
|
2597
|
+
ts:
|
|
2598
|
+
rv.types.length > 0
|
|
2599
|
+
? mapSlotUnion(
|
|
2600
|
+
rv.types,
|
|
2601
|
+
rv.doc,
|
|
2602
|
+
mapType,
|
|
2603
|
+
false,
|
|
2604
|
+
resolver,
|
|
2605
|
+
constantTokens,
|
|
2606
|
+
elementName,
|
|
2607
|
+
"return",
|
|
2608
|
+
rv.name,
|
|
2609
|
+
)
|
|
2610
|
+
: "unknown",
|
|
2611
|
+
}));
|
|
2612
|
+
return {
|
|
2613
|
+
type: `LuaMultiReturn<[${emitted.map((slot) => slot.ts).join(", ")}]>`,
|
|
2614
|
+
trailing: "",
|
|
2615
|
+
slots: emitted,
|
|
2616
|
+
};
|
|
2514
2617
|
}
|
|
2515
2618
|
const first = returnValues[0];
|
|
2516
|
-
if (!first) return { type: "void", trailing: "" };
|
|
2619
|
+
if (!first) return { type: "void", trailing: "", slots: [] };
|
|
2517
2620
|
const ts =
|
|
2518
2621
|
first.types.length > 0
|
|
2519
2622
|
? mapSlotUnion(
|
|
@@ -2528,7 +2631,7 @@ function emitReturn(
|
|
|
2528
2631
|
first.name,
|
|
2529
2632
|
)
|
|
2530
2633
|
: "unknown";
|
|
2531
|
-
return { type: ts, trailing: "" };
|
|
2634
|
+
return { type: ts, trailing: "", slots: [{ position: 0, name: first.name, ts }] };
|
|
2532
2635
|
}
|
|
2533
2636
|
|
|
2534
2637
|
function emitPropertyMember(
|
|
@@ -2606,7 +2709,14 @@ function mapSlotUnion(
|
|
|
2606
2709
|
const nested = mapping.value as NestedMapping;
|
|
2607
2710
|
value = `LuaMap<${mapType(nested.key)}, ${mapType(nested.value)}>`;
|
|
2608
2711
|
}
|
|
2609
|
-
|
|
2712
|
+
// A mapping key may be a `A | B` union token too (render.clear's three
|
|
2713
|
+
// documented graphics.BUFFER_TYPE_* constants); split it the same way
|
|
2714
|
+
// the value above is split. A single-token key (no `|`) is unaffected.
|
|
2715
|
+
const key = unionFromTokens(
|
|
2716
|
+
mapping.key.split("|").map((token) => token.trim()),
|
|
2717
|
+
mapType,
|
|
2718
|
+
);
|
|
2719
|
+
ts = `LuaMap<${key}, ${value}>`;
|
|
2610
2720
|
} else if (element !== undefined) {
|
|
2611
2721
|
ts = arrayTypeFromTokens(element, mapType);
|
|
2612
2722
|
} else if (curation?.kind === "object" || curation?.kind === "array-object") {
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,23 @@ import type { Opaque } from "./core-types";
|
|
|
4
4
|
|
|
5
5
|
declare global {
|
|
6
6
|
namespace render {
|
|
7
|
+
/**
|
|
8
|
+
* The buffer keys `render.clear` accepts: the three `graphics.BUFFER_TYPE_*`
|
|
9
|
+
* constants the reference names. Declare the clear table with this alias —
|
|
10
|
+
* `LuaMap`'s iterator makes its key parameter invariant, so a
|
|
11
|
+
* `LuaMap<number, ...>` is not assignable however its entries were set.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const buffers = new LuaMap<render.ClearBufferKey, number | Vector4>();
|
|
16
|
+
* buffers.set(graphics.BUFFER_TYPE_COLOR0_BIT, vmath.vector4(0, 0, 0, 0));
|
|
17
|
+
* render.clear(buffers);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
type ClearBufferKey =
|
|
21
|
+
| typeof graphics.BUFFER_TYPE_COLOR0_BIT
|
|
22
|
+
| typeof graphics.BUFFER_TYPE_DEPTH_BIT
|
|
23
|
+
| typeof graphics.BUFFER_TYPE_STENCIL_BIT;
|
|
7
24
|
/**
|
|
8
25
|
* Creates a new render target according to the supplied specification table.
|
|
9
26
|
* The parameter table is keyed by buffer type, with one parameter table per
|