@defold-typescript/transpiler 0.43.0 → 0.44.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/dist/hsm/async.ts +73 -0
- package/dist/hsm/debug.ts +119 -0
- package/dist/hsm/defold.ts +14 -8
- package/dist/hsm/index.ts +895 -173
- package/dist/hsm-builtin.d.ts +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +46 -7
- package/dist/transpile.d.ts +2 -1
- package/package.json +3 -2
- package/src/hsm-builtin.ts +55 -4
- package/src/index.ts +1 -0
- package/src/transpile.ts +14 -4
package/dist/hsm-builtin.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Plugin } from "typescript-to-lua";
|
|
2
2
|
export declare const HSM_MODULE_SPECIFIER = "@defold-typescript/types/hsm";
|
|
3
3
|
export declare const HSM_REQUIRE_ROOT = "defold_typescript_hsm";
|
|
4
|
+
export declare const HSM_LUALIB_MODULES: ReadonlySet<string>;
|
|
4
5
|
export interface HsmModule {
|
|
5
6
|
/** The source file's basename without `.ts`. */
|
|
6
7
|
readonly name: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { buildGuiFlipbookIndex } from "./gui-flipbook-index";
|
|
|
9
9
|
export type { GuiNodeIndex } from "./gui-node-index";
|
|
10
10
|
export { buildGuiNodeIndex, guiScriptResourceOf, guiScriptResourcesOf, } from "./gui-node-index";
|
|
11
11
|
export type { HsmModule } from "./hsm-builtin";
|
|
12
|
-
export { HSM_MODULE_SPECIFIER, HSM_REQUIRE_ROOT, hsmModules, hsmRequireName, hsmSourceFiles, resolveHsmSourceDir, } from "./hsm-builtin";
|
|
12
|
+
export { HSM_MODULE_SPECIFIER, HSM_REQUIRE_ROOT, hsmModules, hsmRequireName, hsmSourceFiles, requireHsmSourceDir, resolveHsmSourceDir, } from "./hsm-builtin";
|
|
13
13
|
export { buildInputActionIndex } from "./input-action-index";
|
|
14
14
|
export type { ExtensionDependency, LibraryIncludedEntries, LibrarySceneDocument, LibrarySceneDocuments, LibrarySharedEntry, } from "./library-dependencies";
|
|
15
15
|
export { archiveWrapperOf, isContainedResourcePath, LIBRARY_DEPENDENCY_ROOT, libraryIncludedEntries, readGameProjectDependencies, readLibrarySceneDocuments, } from "./library-dependencies";
|
package/dist/index.js
CHANGED
|
@@ -1388,6 +1388,7 @@ import { existsSync, readdirSync } from "node:fs";
|
|
|
1388
1388
|
import * as path from "node:path";
|
|
1389
1389
|
import { fileURLToPath } from "node:url";
|
|
1390
1390
|
import * as ts4 from "typescript";
|
|
1391
|
+
import { LuaLibFeature } from "typescript-to-lua";
|
|
1391
1392
|
|
|
1392
1393
|
// src/lua-require-scan.ts
|
|
1393
1394
|
var PLACEHOLDER = "\x00";
|
|
@@ -1485,6 +1486,7 @@ function scanEmittedRequires(lua) {
|
|
|
1485
1486
|
// src/hsm-builtin.ts
|
|
1486
1487
|
var HSM_MODULE_SPECIFIER = "@defold-typescript/types/hsm";
|
|
1487
1488
|
var HSM_REQUIRE_ROOT = "defold_typescript_hsm";
|
|
1489
|
+
var HSM_LUALIB_MODULES = new Set(["async"]);
|
|
1488
1490
|
function hsmRequireName(name) {
|
|
1489
1491
|
return `${HSM_REQUIRE_ROOT}.${name}`;
|
|
1490
1492
|
}
|
|
@@ -1575,6 +1577,33 @@ function hsmClosure(chunks, compile) {
|
|
|
1575
1577
|
function lowerSpecifier(module) {
|
|
1576
1578
|
return ts4.factory.createStringLiteral(`@NoResolution:${module.requireName}`);
|
|
1577
1579
|
}
|
|
1580
|
+
function loweredAnything(lowered) {
|
|
1581
|
+
return Array.isArray(lowered) ? lowered.length > 0 : lowered !== undefined;
|
|
1582
|
+
}
|
|
1583
|
+
function importSurvivesElision(node, context) {
|
|
1584
|
+
const clause = node.importClause;
|
|
1585
|
+
if (clause === undefined) {
|
|
1586
|
+
return true;
|
|
1587
|
+
}
|
|
1588
|
+
const { resolver } = context;
|
|
1589
|
+
if (clause.name !== undefined && resolver.isReferencedAliasDeclaration(clause)) {
|
|
1590
|
+
return true;
|
|
1591
|
+
}
|
|
1592
|
+
const bindings = clause.namedBindings;
|
|
1593
|
+
if (bindings === undefined) {
|
|
1594
|
+
return false;
|
|
1595
|
+
}
|
|
1596
|
+
if (ts4.isNamespaceImport(bindings)) {
|
|
1597
|
+
return resolver.isReferencedAliasDeclaration(bindings);
|
|
1598
|
+
}
|
|
1599
|
+
return bindings.elements.some((element) => resolver.isReferencedAliasDeclaration(element));
|
|
1600
|
+
}
|
|
1601
|
+
function registerLualib(module, emitted, context) {
|
|
1602
|
+
if (emitted && HSM_LUALIB_MODULES.has(module.name)) {
|
|
1603
|
+
context.usedLuaLibFeatures.add(LuaLibFeature.Promise);
|
|
1604
|
+
context.usedLuaLibFeatures.add(LuaLibFeature.New);
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1578
1607
|
var hsmLoweringPlugin = {
|
|
1579
1608
|
visitors: {
|
|
1580
1609
|
[ts4.SyntaxKind.ImportDeclaration]: (node, context) => {
|
|
@@ -1582,6 +1611,7 @@ var hsmLoweringPlugin = {
|
|
|
1582
1611
|
if (module === undefined) {
|
|
1583
1612
|
return context.superTransformStatements(node);
|
|
1584
1613
|
}
|
|
1614
|
+
registerLualib(module, importSurvivesElision(node, context), context);
|
|
1585
1615
|
return context.superTransformStatements(ts4.factory.updateImportDeclaration(node, node.modifiers, node.importClause, lowerSpecifier(module), node.attributes));
|
|
1586
1616
|
},
|
|
1587
1617
|
[ts4.SyntaxKind.ExportDeclaration]: (node, context) => {
|
|
@@ -1589,7 +1619,9 @@ var hsmLoweringPlugin = {
|
|
|
1589
1619
|
if (module === undefined) {
|
|
1590
1620
|
return context.superTransformStatements(node);
|
|
1591
1621
|
}
|
|
1592
|
-
|
|
1622
|
+
const lowered = context.superTransformStatements(ts4.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, lowerSpecifier(module), node.attributes));
|
|
1623
|
+
registerLualib(module, loweredAnything(lowered), context);
|
|
1624
|
+
return lowered;
|
|
1593
1625
|
}
|
|
1594
1626
|
}
|
|
1595
1627
|
};
|
|
@@ -2239,7 +2271,7 @@ var messageGuardLoweringPlugin = {
|
|
|
2239
2271
|
|
|
2240
2272
|
// src/timers-lowering.ts
|
|
2241
2273
|
import * as ts7 from "typescript";
|
|
2242
|
-
import { LuaLibFeature } from "typescript-to-lua";
|
|
2274
|
+
import { LuaLibFeature as LuaLibFeature2 } from "typescript-to-lua";
|
|
2243
2275
|
function isTimersSpecifier(node) {
|
|
2244
2276
|
return ts7.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
|
|
2245
2277
|
}
|
|
@@ -2253,8 +2285,8 @@ var timersLoweringPlugin = {
|
|
|
2253
2285
|
if (!isTimersSpecifier(node.moduleSpecifier)) {
|
|
2254
2286
|
return context.superTransformStatements(node);
|
|
2255
2287
|
}
|
|
2256
|
-
context.usedLuaLibFeatures.add(
|
|
2257
|
-
context.usedLuaLibFeatures.add(
|
|
2288
|
+
context.usedLuaLibFeatures.add(LuaLibFeature2.Promise);
|
|
2289
|
+
context.usedLuaLibFeatures.add(LuaLibFeature2.New);
|
|
2258
2290
|
const rewritten = ts7.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts7.factory.createStringLiteral(TIMERS_REQUIRE_PATH), node.attributes);
|
|
2259
2291
|
return context.superTransformStatements(rewritten);
|
|
2260
2292
|
}
|
|
@@ -3650,6 +3682,9 @@ function transpileProject(input) {
|
|
|
3650
3682
|
return collectOutputs(result.transpiledFiles, result.diagnostics, userKeys, companionEmit.companions);
|
|
3651
3683
|
}
|
|
3652
3684
|
var compiledHsm;
|
|
3685
|
+
function requiresLualib(lua) {
|
|
3686
|
+
return scanEmittedRequires(lua).some(({ path: requirePath }) => requirePath === "lualib_bundle");
|
|
3687
|
+
}
|
|
3653
3688
|
function compileHsmModules() {
|
|
3654
3689
|
if (compiledHsm !== undefined) {
|
|
3655
3690
|
return compiledHsm;
|
|
@@ -3667,14 +3702,17 @@ function compileHsmModules() {
|
|
|
3667
3702
|
const lua = {};
|
|
3668
3703
|
for (const file of result.transpiledFiles) {
|
|
3669
3704
|
if (isLualibBundle(file)) {
|
|
3670
|
-
problems.push("the compiled Lua requires lualib_bundle");
|
|
3671
3705
|
continue;
|
|
3672
3706
|
}
|
|
3673
3707
|
const source = file.sourceFiles.find((s) => nameByKey.has(s.fileName));
|
|
3674
3708
|
const name = source === undefined ? undefined : nameByKey.get(source.fileName);
|
|
3675
|
-
if (name
|
|
3676
|
-
|
|
3709
|
+
if (name === undefined || typeof file.lua !== "string") {
|
|
3710
|
+
continue;
|
|
3711
|
+
}
|
|
3712
|
+
if (!HSM_LUALIB_MODULES.has(name) && requiresLualib(file.lua)) {
|
|
3713
|
+
problems.push(`the compiled ${name} module requires lualib_bundle`);
|
|
3677
3714
|
}
|
|
3715
|
+
lua[name] = file.lua;
|
|
3678
3716
|
}
|
|
3679
3717
|
if (problems.length > 0) {
|
|
3680
3718
|
throw new Error(`@defold-typescript/transpiler: the hsm library does not compile:
|
|
@@ -4282,6 +4320,7 @@ export {
|
|
|
4282
4320
|
readLibrarySceneDocuments,
|
|
4283
4321
|
readSceneDocuments,
|
|
4284
4322
|
relativeAddressesFrom,
|
|
4323
|
+
requireHsmSourceDir,
|
|
4285
4324
|
requirePathForRel,
|
|
4286
4325
|
resolveClassifiedSlotAtPosition,
|
|
4287
4326
|
resolveHsmSourceDir,
|
package/dist/transpile.d.ts
CHANGED
|
@@ -38,7 +38,8 @@ export declare function transpileProject(input: TranspileProjectInput): Transpil
|
|
|
38
38
|
* project gets always comes from the compiler that builds it. Each file sits at
|
|
39
39
|
* `defold_typescript_hsm/<module>.ts`, so a require between modules is already
|
|
40
40
|
* spelled the way the user's lowered imports are. Throws when the compile
|
|
41
|
-
* reports anything or
|
|
41
|
+
* reports anything, or when a module outside `HSM_LUALIB_MODULES` needs the
|
|
42
|
+
* lualib bundle.
|
|
42
43
|
*/
|
|
43
44
|
export declare function compileHsmModules(): Readonly<Record<string, string>>;
|
|
44
45
|
export declare function transpile(source: string): TranspileResult;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defold-typescript/transpiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "TypeScript-to-Lua build pipeline tuned for Defold's runtime.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -35,8 +35,9 @@
|
|
|
35
35
|
"test": "bun test"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@defold-typescript/types": "0.
|
|
38
|
+
"@defold-typescript/types": "0.44.0",
|
|
39
39
|
"@typescript-to-lua/language-extensions": "1.19.0",
|
|
40
|
+
"typescript": "6.0.2",
|
|
40
41
|
"typescript-to-lua": "^1.36.0"
|
|
41
42
|
}
|
|
42
43
|
}
|
package/src/hsm-builtin.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, readdirSync } from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import * as ts from "typescript";
|
|
5
|
-
import type
|
|
5
|
+
import { LuaLibFeature, type Plugin, type TransformationContext } from "typescript-to-lua";
|
|
6
6
|
import { scanEmittedRequires } from "./lua-require-scan";
|
|
7
7
|
|
|
8
8
|
// `@defold-typescript/types/hsm` is the `index` module; every other module is a
|
|
@@ -12,6 +12,10 @@ import { scanEmittedRequires } from "./lua-require-scan";
|
|
|
12
12
|
export const HSM_MODULE_SPECIFIER = "@defold-typescript/types/hsm";
|
|
13
13
|
export const HSM_REQUIRE_ROOT = "defold_typescript_hsm";
|
|
14
14
|
|
|
15
|
+
// The hsm modules whose Lua requires the lualib bundle. Every other module stays
|
|
16
|
+
// plain Lua, so a program that imports none of these ships no bundle.
|
|
17
|
+
export const HSM_LUALIB_MODULES: ReadonlySet<string> = new Set(["async"]);
|
|
18
|
+
|
|
15
19
|
export interface HsmModule {
|
|
16
20
|
/** The source file's basename without `.ts`. */
|
|
17
21
|
readonly name: string;
|
|
@@ -152,12 +156,56 @@ export function hsmClosure(
|
|
|
152
156
|
|
|
153
157
|
// Rewrite an hsm specifier to its flat require, the way the timers lowering
|
|
154
158
|
// does: `@NoResolution:` keeps TSTL from looking for a Lua source behind the
|
|
155
|
-
// `.d.ts` the import type-checks against.
|
|
156
|
-
// because hsm compiles to plain Lua.
|
|
159
|
+
// `.d.ts` the import type-checks against.
|
|
157
160
|
function lowerSpecifier(module: HsmModule): ts.StringLiteral {
|
|
158
161
|
return ts.factory.createStringLiteral(`@NoResolution:${module.requireName}`);
|
|
159
162
|
}
|
|
160
163
|
|
|
164
|
+
type Lowered = ReturnType<TransformationContext["superTransformStatements"]>;
|
|
165
|
+
|
|
166
|
+
function loweredAnything(lowered: Lowered): boolean {
|
|
167
|
+
return Array.isArray(lowered) ? lowered.length > 0 : lowered !== undefined;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// The same resolver verdict TSTL's own import transform uses to decide which
|
|
171
|
+
// bindings it requires, so the bundle and the emitted require cannot disagree.
|
|
172
|
+
// Takes the original node: the resolver has no binding for a synthesized copy.
|
|
173
|
+
function importSurvivesElision(
|
|
174
|
+
node: ts.ImportDeclaration,
|
|
175
|
+
context: TransformationContext,
|
|
176
|
+
): boolean {
|
|
177
|
+
const clause = node.importClause;
|
|
178
|
+
if (clause === undefined) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
const { resolver } = context;
|
|
182
|
+
if (clause.name !== undefined && resolver.isReferencedAliasDeclaration(clause)) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
const bindings = clause.namedBindings;
|
|
186
|
+
if (bindings === undefined) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
if (ts.isNamespaceImport(bindings)) {
|
|
190
|
+
return resolver.isReferencedAliasDeclaration(bindings);
|
|
191
|
+
}
|
|
192
|
+
return bindings.elements.some((element) => resolver.isReferencedAliasDeclaration(element));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// TSTL writes `lualib_bundle.lua` only for features a user chunk registers; it
|
|
196
|
+
// never sees the hsm module's own source, which the CLI writes beside the build.
|
|
197
|
+
// An elided import (type-only, unused) registers nothing. The import visitor
|
|
198
|
+
// passes the resolver's elision verdict, because TSTL's import transform always
|
|
199
|
+
// returns nothing and queues its require on the scope instead; the export
|
|
200
|
+
// visitor passes whether its lowered statements are non-empty, because TSTL's
|
|
201
|
+
// export transform returns them.
|
|
202
|
+
function registerLualib(module: HsmModule, emitted: boolean, context: TransformationContext): void {
|
|
203
|
+
if (emitted && HSM_LUALIB_MODULES.has(module.name)) {
|
|
204
|
+
context.usedLuaLibFeatures.add(LuaLibFeature.Promise);
|
|
205
|
+
context.usedLuaLibFeatures.add(LuaLibFeature.New);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
161
209
|
export const hsmLoweringPlugin: Plugin = {
|
|
162
210
|
visitors: {
|
|
163
211
|
[ts.SyntaxKind.ImportDeclaration]: (node, context) => {
|
|
@@ -165,6 +213,7 @@ export const hsmLoweringPlugin: Plugin = {
|
|
|
165
213
|
if (module === undefined) {
|
|
166
214
|
return context.superTransformStatements(node);
|
|
167
215
|
}
|
|
216
|
+
registerLualib(module, importSurvivesElision(node, context), context);
|
|
168
217
|
return context.superTransformStatements(
|
|
169
218
|
ts.factory.updateImportDeclaration(
|
|
170
219
|
node,
|
|
@@ -180,7 +229,7 @@ export const hsmLoweringPlugin: Plugin = {
|
|
|
180
229
|
if (module === undefined) {
|
|
181
230
|
return context.superTransformStatements(node);
|
|
182
231
|
}
|
|
183
|
-
|
|
232
|
+
const lowered = context.superTransformStatements(
|
|
184
233
|
ts.factory.updateExportDeclaration(
|
|
185
234
|
node,
|
|
186
235
|
node.modifiers,
|
|
@@ -190,6 +239,8 @@ export const hsmLoweringPlugin: Plugin = {
|
|
|
190
239
|
node.attributes,
|
|
191
240
|
),
|
|
192
241
|
);
|
|
242
|
+
registerLualib(module, loweredAnything(lowered), context);
|
|
243
|
+
return lowered;
|
|
193
244
|
},
|
|
194
245
|
},
|
|
195
246
|
};
|
package/src/index.ts
CHANGED
package/src/transpile.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
GO_PROPERTY_DIRECT_CALL_MESSAGE,
|
|
11
11
|
} from "./go-property-direct-call";
|
|
12
12
|
import {
|
|
13
|
+
HSM_LUALIB_MODULES,
|
|
13
14
|
HSM_REQUIRE_ROOT,
|
|
14
15
|
hsmClosure,
|
|
15
16
|
hsmLoweringPlugin,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
requireHsmSourceDir,
|
|
18
19
|
} from "./hsm-builtin";
|
|
19
20
|
import { lifecycleErasurePlugin } from "./lifecycle-erasure";
|
|
21
|
+
import { scanEmittedRequires } from "./lua-require-scan";
|
|
20
22
|
import { messageDispatchLoweringPlugin } from "./message-dispatch-lowering";
|
|
21
23
|
import { messageGuardLoweringPlugin } from "./message-guard-lowering";
|
|
22
24
|
import { importsTimersModule, timersLoweringPlugin } from "./timers-lowering";
|
|
@@ -371,13 +373,18 @@ export function transpileProject(input: TranspileProjectInput): TranspileProject
|
|
|
371
373
|
|
|
372
374
|
let compiledHsm: Readonly<Record<string, string>> | undefined;
|
|
373
375
|
|
|
376
|
+
function requiresLualib(lua: string): boolean {
|
|
377
|
+
return scanEmittedRequires(lua).some(({ path: requirePath }) => requirePath === "lualib_bundle");
|
|
378
|
+
}
|
|
379
|
+
|
|
374
380
|
/**
|
|
375
381
|
* Every `hsm` module compiled to Lua, keyed by module name, once per process.
|
|
376
382
|
* The source is the shipped TypeScript, never a prebuilt Lua copy, so the Lua a
|
|
377
383
|
* project gets always comes from the compiler that builds it. Each file sits at
|
|
378
384
|
* `defold_typescript_hsm/<module>.ts`, so a require between modules is already
|
|
379
385
|
* spelled the way the user's lowered imports are. Throws when the compile
|
|
380
|
-
* reports anything or
|
|
386
|
+
* reports anything, or when a module outside `HSM_LUALIB_MODULES` needs the
|
|
387
|
+
* lualib bundle.
|
|
381
388
|
*/
|
|
382
389
|
export function compileHsmModules(): Readonly<Record<string, string>> {
|
|
383
390
|
if (compiledHsm !== undefined) {
|
|
@@ -399,14 +406,17 @@ export function compileHsmModules(): Readonly<Record<string, string>> {
|
|
|
399
406
|
const lua: Record<string, string> = {};
|
|
400
407
|
for (const file of result.transpiledFiles) {
|
|
401
408
|
if (isLualibBundle(file)) {
|
|
402
|
-
problems.push("the compiled Lua requires lualib_bundle");
|
|
403
409
|
continue;
|
|
404
410
|
}
|
|
405
411
|
const source = file.sourceFiles.find((s) => nameByKey.has(s.fileName));
|
|
406
412
|
const name = source === undefined ? undefined : nameByKey.get(source.fileName);
|
|
407
|
-
if (name
|
|
408
|
-
|
|
413
|
+
if (name === undefined || typeof file.lua !== "string") {
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
if (!HSM_LUALIB_MODULES.has(name) && requiresLualib(file.lua)) {
|
|
417
|
+
problems.push(`the compiled ${name} module requires lualib_bundle`);
|
|
409
418
|
}
|
|
419
|
+
lua[name] = file.lua;
|
|
410
420
|
}
|
|
411
421
|
if (problems.length > 0) {
|
|
412
422
|
throw new Error(
|