@defold-typescript/transpiler 0.52.0 → 0.54.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/index.js CHANGED
@@ -1,8 +1,53 @@
1
1
  // src/companion-closure.ts
2
- import * as ts3 from "typescript";
2
+ import * as ts4 from "typescript";
3
+
4
+ // src/debug-bootstrap.ts
5
+ import * as ts from "typescript";
6
+ var DEBUG_BLOCK_BEGIN = "// defold-typescript:setup-debug BEGIN — managed block, do not edit";
7
+ var DEBUG_BLOCK_END = "// defold-typescript:setup-debug END";
8
+ var DEBUG_MANAGED_BLOCK = `${DEBUG_BLOCK_BEGIN}
9
+ import * as lldebugger from "lldebugger.debug";
10
+
11
+ if (sys.get_engine_info().is_debug) {
12
+ lldebugger.start();
13
+ }
14
+
15
+ ${DEBUG_BLOCK_END}`;
16
+ function occurrences(haystack, needle) {
17
+ return haystack.split(needle).length - 1;
18
+ }
19
+ function bodyTokens(text) {
20
+ const scanner = ts.createScanner(ts.ScriptTarget.Latest, true, ts.LanguageVariant.Standard, text);
21
+ const tokens = [];
22
+ for (let kind = scanner.scan();kind !== ts.SyntaxKind.EndOfFileToken; kind = scanner.scan()) {
23
+ if (kind === ts.SyntaxKind.SemicolonToken) {
24
+ continue;
25
+ }
26
+ const spelling = kind === ts.SyntaxKind.StringLiteral ? scanner.getTokenValue() : scanner.getTokenText();
27
+ tokens.push(`${kind}:${spelling}`);
28
+ }
29
+ return tokens;
30
+ }
31
+ var CANONICAL_BODY_TOKENS = bodyTokens(DEBUG_MANAGED_BLOCK.slice(DEBUG_BLOCK_BEGIN.length, DEBUG_MANAGED_BLOCK.length - DEBUG_BLOCK_END.length));
32
+ function findManagedBootstrap(sourceFile) {
33
+ const text = sourceFile.text;
34
+ if (occurrences(text, DEBUG_BLOCK_BEGIN) !== 1 || occurrences(text, DEBUG_BLOCK_END) !== 1) {
35
+ return;
36
+ }
37
+ const beginAt = text.indexOf(DEBUG_BLOCK_BEGIN);
38
+ const endAt = text.indexOf(DEBUG_BLOCK_END);
39
+ if (endAt < beginAt) {
40
+ return;
41
+ }
42
+ const bodyStart = beginAt + DEBUG_BLOCK_BEGIN.length;
43
+ const statements = sourceFile.statements.filter((statement) => statement.getStart(sourceFile) >= bodyStart && statement.end <= endAt);
44
+ const tokens = bodyTokens(text.slice(bodyStart, endAt));
45
+ const canonical = tokens.length === CANONICAL_BODY_TOKENS.length && tokens.every((token, index) => token === CANONICAL_BODY_TOKENS[index]);
46
+ return { statements, canonical };
47
+ }
3
48
 
4
49
  // src/lifecycle-erasure.ts
5
- import * as ts2 from "typescript";
50
+ import * as ts3 from "typescript";
6
51
  import {
7
52
  createAssignmentStatement,
8
53
  createBinaryExpression as createBinaryExpression2,
@@ -19,11 +64,11 @@ import {
19
64
  createTableIndexExpression,
20
65
  createVariableDeclarationStatement as createVariableDeclarationStatement2,
21
66
  NodeFlags as NodeFlags2,
22
- SyntaxKind as SyntaxKind4
67
+ SyntaxKind as SyntaxKind5
23
68
  } from "typescript-to-lua";
24
69
 
25
70
  // src/message-dispatch-lowering.ts
26
- import * as ts from "typescript";
71
+ import * as ts2 from "typescript";
27
72
  import {
28
73
  createBinaryExpression,
29
74
  createBlock,
@@ -34,7 +79,7 @@ import {
34
79
  createStringLiteral,
35
80
  createVariableDeclarationStatement,
36
81
  NodeFlags,
37
- SyntaxKind as SyntaxKind2
82
+ SyntaxKind as SyntaxKind3
38
83
  } from "typescript-to-lua";
39
84
  var DISPATCH_MODULE = "@defold-typescript/types";
40
85
  var DISPATCH_NAME = "onMessage";
@@ -44,7 +89,7 @@ function resolvesToDispatchExport(callee, checker) {
44
89
  if (symbol === undefined) {
45
90
  return false;
46
91
  }
47
- if (symbol.flags & ts.SymbolFlags.Alias) {
92
+ if (symbol.flags & ts2.SymbolFlags.Alias) {
48
93
  symbol = checker.getAliasedSymbol(symbol);
49
94
  }
50
95
  if (symbol.getName() !== DISPATCH_NAME) {
@@ -61,13 +106,13 @@ function handlerName(property, checker) {
61
106
  if (name === undefined) {
62
107
  return;
63
108
  }
64
- if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
109
+ if (ts2.isIdentifier(name) || ts2.isStringLiteral(name)) {
65
110
  return name.text;
66
111
  }
67
- if (ts.isNumericLiteral(name)) {
112
+ if (ts2.isNumericLiteral(name)) {
68
113
  return String(Number(name.text));
69
114
  }
70
- if (ts.isComputedPropertyName(name)) {
115
+ if (ts2.isComputedPropertyName(name)) {
71
116
  const type = checker.getTypeAtLocation(name.expression);
72
117
  if (type.isStringLiteral() || type.isNumberLiteral()) {
73
118
  return String(type.value);
@@ -82,32 +127,32 @@ function unlowerableHandler(node, text) {
82
127
  file,
83
128
  start,
84
129
  length: node.getEnd() - start,
85
- category: ts.DiagnosticCategory.Error,
130
+ category: ts2.DiagnosticCategory.Error,
86
131
  code: 0,
87
132
  messageText: `${DISPATCH_NAME} cannot lower \`${text}\`: pass an object literal whose keys are an identifier, a quoted or numeric literal, or a computed literal constant, each with its handler written inline.`
88
133
  };
89
134
  }
90
135
  function handlerFunction(property) {
91
- if (ts.isMethodDeclaration(property) && property.body !== undefined) {
136
+ if (ts2.isMethodDeclaration(property) && property.body !== undefined) {
92
137
  return property;
93
138
  }
94
- if (ts.isPropertyAssignment(property)) {
139
+ if (ts2.isPropertyAssignment(property)) {
95
140
  const initializer = property.initializer;
96
- if (ts.isFunctionExpression(initializer) || ts.isArrowFunction(initializer)) {
141
+ if (ts2.isFunctionExpression(initializer) || ts2.isArrowFunction(initializer)) {
97
142
  return initializer;
98
143
  }
99
144
  }
100
145
  return;
101
146
  }
102
147
  function isThisParameter(param) {
103
- return ts.isIdentifier(param.name) && ts.identifierToKeywordKind(param.name) === ts.SyntaxKind.ThisKeyword;
148
+ return ts2.isIdentifier(param.name) && ts2.identifierToKeywordKind(param.name) === ts2.SyntaxKind.ThisKeyword;
104
149
  }
105
150
  function aliasStatements(fn) {
106
151
  const params = fn.parameters.filter((param) => !isThisParameter(param));
107
152
  const aliases = [];
108
153
  params.forEach((param, index) => {
109
154
  const engineName = HANDLER_PARAM_TARGETS[index];
110
- if (engineName === undefined || !ts.isIdentifier(param.name)) {
155
+ if (engineName === undefined || !ts2.isIdentifier(param.name)) {
111
156
  return;
112
157
  }
113
158
  if (param.name.text !== engineName) {
@@ -117,19 +162,19 @@ function aliasStatements(fn) {
117
162
  return aliases;
118
163
  }
119
164
  function handlerBody(fn, context) {
120
- if (ts.isBlock(fn.body)) {
165
+ if (ts2.isBlock(fn.body)) {
121
166
  return context.transformStatements(fn.body.statements);
122
167
  }
123
- return context.transformStatements([ts.factory.createExpressionStatement(fn.body)]);
168
+ return context.transformStatements([ts2.factory.createExpressionStatement(fn.body)]);
124
169
  }
125
170
  var messageDispatchLoweringPlugin = {
126
171
  visitors: {
127
- [ts.SyntaxKind.CallExpression]: (node, context) => {
172
+ [ts2.SyntaxKind.CallExpression]: (node, context) => {
128
173
  if (!resolvesToDispatchExport(node.expression, context.checker)) {
129
174
  return context.superTransformExpression(node);
130
175
  }
131
176
  const [handlersArg] = node.arguments;
132
- if (node.arguments.length === 1 && handlersArg !== undefined && ts.isObjectLiteralExpression(handlersArg)) {
177
+ if (node.arguments.length === 1 && handlersArg !== undefined && ts2.isObjectLiteralExpression(handlersArg)) {
133
178
  let chain;
134
179
  const properties = [...handlersArg.properties];
135
180
  for (let i = properties.length - 1;i >= 0; i--) {
@@ -144,7 +189,7 @@ var messageDispatchLoweringPlugin = {
144
189
  context.diagnostics.push(unlowerableHandler(property, offending.getText()));
145
190
  continue;
146
191
  }
147
- const condition = createBinaryExpression(createIdentifier("message_id"), createCallExpression(createIdentifier("hash"), [createStringLiteral(name)]), SyntaxKind2.EqualityOperator);
192
+ const condition = createBinaryExpression(createIdentifier("message_id"), createCallExpression(createIdentifier("hash"), [createStringLiteral(name)]), SyntaxKind3.EqualityOperator);
148
193
  const body = [...aliasStatements(fn), ...handlerBody(fn, context)];
149
194
  chain = createIfStatement(condition, createBlock(body), chain);
150
195
  }
@@ -177,7 +222,7 @@ function factoryExportName(callee, checker) {
177
222
  if (symbol === undefined) {
178
223
  return;
179
224
  }
180
- if (symbol.flags & ts2.SymbolFlags.Alias) {
225
+ if (symbol.flags & ts3.SymbolFlags.Alias) {
181
226
  symbol = checker.getAliasedSymbol(symbol);
182
227
  }
183
228
  const name = symbol.getName();
@@ -194,51 +239,51 @@ function resolvesToFactoryExport(callee, checker) {
194
239
  return factoryExportName(callee, checker) !== undefined;
195
240
  }
196
241
  function isThisParameter2(param) {
197
- return ts2.isIdentifier(param.name) && ts2.identifierToKeywordKind(param.name) === ts2.SyntaxKind.ThisKeyword;
242
+ return ts3.isIdentifier(param.name) && ts3.identifierToKeywordKind(param.name) === ts3.SyntaxKind.ThisKeyword;
198
243
  }
199
244
  function hookName(property) {
200
245
  const name = property.name;
201
246
  if (name === undefined) {
202
247
  return;
203
248
  }
204
- if (ts2.isIdentifier(name) || ts2.isStringLiteral(name)) {
249
+ if (ts3.isIdentifier(name) || ts3.isStringLiteral(name)) {
205
250
  return name.text;
206
251
  }
207
252
  return;
208
253
  }
209
254
  function hookFunction(property) {
210
- if (ts2.isMethodDeclaration(property) && property.body !== undefined) {
255
+ if (ts3.isMethodDeclaration(property) && property.body !== undefined) {
211
256
  return property;
212
257
  }
213
- if (ts2.isPropertyAssignment(property)) {
258
+ if (ts3.isPropertyAssignment(property)) {
214
259
  const initializer = property.initializer;
215
- if (ts2.isFunctionExpression(initializer) || ts2.isArrowFunction(initializer)) {
260
+ if (ts3.isFunctionExpression(initializer) || ts3.isArrowFunction(initializer)) {
216
261
  return initializer;
217
262
  }
218
263
  }
219
264
  return;
220
265
  }
221
266
  function dispatcherInitializer(property, checker) {
222
- if (!ts2.isPropertyAssignment(property)) {
267
+ if (!ts3.isPropertyAssignment(property)) {
223
268
  return;
224
269
  }
225
270
  const initializer = property.initializer;
226
- if (!ts2.isCallExpression(initializer)) {
271
+ if (!ts3.isCallExpression(initializer)) {
227
272
  return;
228
273
  }
229
274
  return resolvesToDispatchExport(initializer.expression, checker) ? initializer : undefined;
230
275
  }
231
276
  function transformHookBody(fn, context) {
232
- if (ts2.isBlock(fn.body)) {
277
+ if (ts3.isBlock(fn.body)) {
233
278
  return context.transformStatements(fn.body.statements);
234
279
  }
235
280
  return [createExpressionStatement(context.transformExpression(fn.body))];
236
281
  }
237
282
  function crossesFunctionBoundary(node) {
238
- return ts2.isFunctionDeclaration(node) || ts2.isFunctionExpression(node) || ts2.isArrowFunction(node) || ts2.isMethodDeclaration(node) || ts2.isGetAccessorDeclaration(node) || ts2.isSetAccessorDeclaration(node);
283
+ return ts3.isFunctionDeclaration(node) || ts3.isFunctionExpression(node) || ts3.isArrowFunction(node) || ts3.isMethodDeclaration(node) || ts3.isGetAccessorDeclaration(node) || ts3.isSetAccessorDeclaration(node);
239
284
  }
240
285
  function initReturnsValue(fn) {
241
- if (!ts2.isBlock(fn.body)) {
286
+ if (!ts3.isBlock(fn.body)) {
242
287
  return true;
243
288
  }
244
289
  let found = false;
@@ -246,23 +291,23 @@ function initReturnsValue(fn) {
246
291
  if (found || crossesFunctionBoundary(node)) {
247
292
  return;
248
293
  }
249
- if (ts2.isReturnStatement(node) && node.expression !== undefined) {
294
+ if (ts3.isReturnStatement(node) && node.expression !== undefined) {
250
295
  found = true;
251
296
  return;
252
297
  }
253
- ts2.forEachChild(node, visit);
298
+ ts3.forEachChild(node, visit);
254
299
  };
255
- ts2.forEachChild(fn.body, visit);
300
+ ts3.forEachChild(fn.body, visit);
256
301
  return found;
257
302
  }
258
303
  function initBuilderBody(fn, context) {
259
- if (ts2.isBlock(fn.body)) {
304
+ if (ts3.isBlock(fn.body)) {
260
305
  return context.transformStatements(fn.body.statements);
261
306
  }
262
307
  return [createReturnStatement([context.transformExpression(fn.body)])];
263
308
  }
264
309
  function emitInitMerge(fn, context, property) {
265
- const authorParam = fn.parameters.find((param) => !isThisParameter2(param) && ts2.isIdentifier(param.name));
310
+ const authorParam = fn.parameters.find((param) => !isThisParameter2(param) && ts3.isIdentifier(param.name));
266
311
  const builderParams = authorParam === undefined ? [] : [context.transformExpression(authorParam.name)];
267
312
  const builder = createFunctionExpression2(createBlock2(initBuilderBody(fn, context)), builderParams, undefined, NodeFlags2.Declaration, fn);
268
313
  const builderDecl = createVariableDeclarationStatement2(createIdentifier2("____init"), builder);
@@ -270,7 +315,7 @@ function emitInitMerge(fn, context, property) {
270
315
  const stateDecl = createVariableDeclarationStatement2(createIdentifier2("____s"), createCallExpression2(createIdentifier2("____init"), builderArgs));
271
316
  const mergeAssignment = createAssignmentStatement(createTableIndexExpression(createIdentifier2("self"), createIdentifier2("____k")), createIdentifier2("____v"));
272
317
  const forIn = createForInStatement(createBlock2([mergeAssignment]), [createIdentifier2("____k"), createIdentifier2("____v")], [createCallExpression2(createIdentifier2("pairs"), [createIdentifier2("____s")])]);
273
- const guard = createIfStatement2(createBinaryExpression2(createIdentifier2("____s"), createNilLiteral(), SyntaxKind4.InequalityOperator), createBlock2([forIn]));
318
+ const guard = createIfStatement2(createBinaryExpression2(createIdentifier2("____s"), createNilLiteral(), SyntaxKind5.InequalityOperator), createBlock2([forIn]));
274
319
  const initFn = createFunctionExpression2(createBlock2([stateDecl, guard]), [createIdentifier2("self")], undefined, NodeFlags2.Declaration, fn);
275
320
  return [builderDecl, createAssignmentStatement(createIdentifier2("init"), initFn, property)];
276
321
  }
@@ -284,16 +329,16 @@ var RESOURCE_PROPERTY_MARKERS = new Set([
284
329
  "resource.tile_source"
285
330
  ]);
286
331
  function propertyMembers(property) {
287
- if (!ts2.isPropertyAssignment(property) || !ts2.isObjectLiteralExpression(property.initializer)) {
332
+ if (!ts3.isPropertyAssignment(property) || !ts3.isObjectLiteralExpression(property.initializer)) {
288
333
  return [];
289
334
  }
290
335
  const members = [];
291
336
  for (const member of property.initializer.properties) {
292
- if (!ts2.isPropertyAssignment(member)) {
337
+ if (!ts3.isPropertyAssignment(member)) {
293
338
  continue;
294
339
  }
295
340
  const key = member.name;
296
- if (!ts2.isIdentifier(key) && !ts2.isStringLiteral(key)) {
341
+ if (!ts3.isIdentifier(key) && !ts3.isStringLiteral(key)) {
297
342
  continue;
298
343
  }
299
344
  members.push({ name: key.text, initializer: member.initializer });
@@ -301,14 +346,14 @@ function propertyMembers(property) {
301
346
  return members;
302
347
  }
303
348
  function factoryHooks(expression, checker) {
304
- if (!ts2.isCallExpression(expression)) {
349
+ if (!ts3.isCallExpression(expression)) {
305
350
  return;
306
351
  }
307
352
  if (!resolvesToFactoryExport(expression.expression, checker)) {
308
353
  return;
309
354
  }
310
355
  const hooks = expression.arguments[0];
311
- if (hooks === undefined || !ts2.isObjectLiteralExpression(hooks)) {
356
+ if (hooks === undefined || !ts3.isObjectLiteralExpression(hooks)) {
312
357
  return;
313
358
  }
314
359
  return hooks;
@@ -326,21 +371,21 @@ function scriptOnlyProperties(property, factory) {
326
371
  file,
327
372
  start,
328
373
  length: property.getEnd() - start,
329
- category: ts2.DiagnosticCategory.Error,
374
+ category: ts3.DiagnosticCategory.Error,
330
375
  code: 0,
331
376
  messageText: `\`${factory}\` cannot declare \`properties\`: Defold builds \`go.property\` only in \`.script\` files. Declare the property in a \`defineScript\` and send its value with \`msg.post\`.`
332
377
  };
333
378
  }
334
379
  function outermostWrapper(node) {
335
380
  let current = node;
336
- while (ts2.isParenthesizedExpression(current.parent) || ts2.isAsExpression(current.parent) || ts2.isSatisfiesExpression(current.parent) || ts2.isNonNullExpression(current.parent) || ts2.isTypeAssertionExpression(current.parent)) {
381
+ while (ts3.isParenthesizedExpression(current.parent) || ts3.isAsExpression(current.parent) || ts3.isSatisfiesExpression(current.parent) || ts3.isNonNullExpression(current.parent) || ts3.isTypeAssertionExpression(current.parent)) {
337
382
  current = current.parent;
338
383
  }
339
384
  return current;
340
385
  }
341
386
  function innermostExpression(node) {
342
387
  let current = node;
343
- while (ts2.isParenthesizedExpression(current) || ts2.isAsExpression(current) || ts2.isSatisfiesExpression(current) || ts2.isNonNullExpression(current) || ts2.isTypeAssertionExpression(current)) {
388
+ while (ts3.isParenthesizedExpression(current) || ts3.isAsExpression(current) || ts3.isSatisfiesExpression(current) || ts3.isNonNullExpression(current) || ts3.isTypeAssertionExpression(current)) {
344
389
  current = current.expression;
345
390
  }
346
391
  return current;
@@ -354,7 +399,7 @@ function globalName(symbol, checker) {
354
399
  }
355
400
  function calledGlobal(call, checker) {
356
401
  const declaration = checker.getResolvedSignature(call)?.declaration;
357
- if (declaration === undefined || !ts2.isFunctionDeclaration(declaration) || declaration.name === undefined) {
402
+ if (declaration === undefined || !ts3.isFunctionDeclaration(declaration) || declaration.name === undefined) {
358
403
  return;
359
404
  }
360
405
  return globalName(checker.getSymbolAtLocation(declaration.name), checker);
@@ -362,15 +407,15 @@ function calledGlobal(call, checker) {
362
407
  function isPropertyDefault(call, checker) {
363
408
  const value = outermostWrapper(call);
364
409
  const parent = value.parent;
365
- if (ts2.isCallExpression(parent)) {
410
+ if (ts3.isCallExpression(parent)) {
366
411
  return parent.arguments[1] === value && calledGlobal(parent, checker) === "go.property";
367
412
  }
368
413
  const properties = parent?.parent?.parent;
369
- if (properties === undefined || !ts2.isPropertyAssignment(properties) || !isPropertiesHook(properties)) {
414
+ if (properties === undefined || !ts3.isPropertyAssignment(properties) || !isPropertiesHook(properties)) {
370
415
  return false;
371
416
  }
372
417
  const hooks = properties.parent;
373
- return ts2.isObjectLiteralExpression(hooks) && factoryHooks(hooks.parent, checker) === hooks && propertyMembers(properties).some((member) => member.initializer === value);
418
+ return ts3.isObjectLiteralExpression(hooks) && factoryHooks(hooks.parent, checker) === hooks && propertyMembers(properties).some((member) => member.initializer === value);
374
419
  }
375
420
  function misplacedMarker(node, marker) {
376
421
  const file = node.getSourceFile();
@@ -379,25 +424,25 @@ function misplacedMarker(node, marker) {
379
424
  file,
380
425
  start,
381
426
  length: node.getEnd() - start,
382
- category: ts2.DiagnosticCategory.Error,
427
+ category: ts3.DiagnosticCategory.Error,
383
428
  code: 0,
384
429
  messageText: `\`${marker}\` is a build-time marker: Defold's build reads it only in a \`go.property\` default, and the engine binds no such function. Use it as a \`defineScript\` \`properties\` default.`
385
430
  };
386
431
  }
387
432
  function readsAsMarker(call) {
388
433
  const callee = innermostExpression(call.expression);
389
- if (ts2.isOptionalChain(call) || ts2.isOptionalChain(callee)) {
434
+ if (ts3.isOptionalChain(call) || ts3.isOptionalChain(callee)) {
390
435
  return false;
391
436
  }
392
- if (!ts2.isPropertyAccessExpression(callee) && !(ts2.isElementAccessExpression(callee) && ts2.isStringLiteralLike(innermostExpression(callee.argumentExpression)))) {
437
+ if (!ts3.isPropertyAccessExpression(callee) && !(ts3.isElementAccessExpression(callee) && ts3.isStringLiteralLike(innermostExpression(callee.argumentExpression)))) {
393
438
  return false;
394
439
  }
395
440
  const receiver = innermostExpression(callee.expression);
396
- if (!ts2.isIdentifier(receiver) || receiver.text !== "resource") {
441
+ if (!ts3.isIdentifier(receiver) || receiver.text !== "resource") {
397
442
  return false;
398
443
  }
399
444
  const [path] = call.arguments;
400
- return path === undefined || ts2.isStringLiteralLike(innermostExpression(path));
445
+ return path === undefined || ts3.isStringLiteralLike(innermostExpression(path));
401
446
  }
402
447
  function unreadableMarker(node, marker) {
403
448
  const file = node.getSourceFile();
@@ -406,18 +451,18 @@ function unreadableMarker(node, marker) {
406
451
  file,
407
452
  start,
408
453
  length: node.getEnd() - start,
409
- category: ts2.DiagnosticCategory.Error,
454
+ category: ts3.DiagnosticCategory.Error,
410
455
  code: 0,
411
456
  messageText: `\`${marker}\` in a property default must be written \`${marker}("<path>")\`, with a string literal path: Defold's build reads no other form.`
412
457
  };
413
458
  }
414
459
  function isCallee(node) {
415
460
  const callee = outermostWrapper(node);
416
- return ts2.isCallExpression(callee.parent) && callee.parent.expression === callee;
461
+ return ts3.isCallExpression(callee.parent) && callee.parent.expression === callee;
417
462
  }
418
463
  function eraseFactoryCall(expression, context) {
419
464
  const hooks = factoryHooks(expression, context.checker);
420
- if (hooks === undefined || !ts2.isCallExpression(expression)) {
465
+ if (hooks === undefined || !ts3.isCallExpression(expression)) {
421
466
  return;
422
467
  }
423
468
  const factory = factoryExportName(expression.expression, context.checker);
@@ -448,14 +493,14 @@ function eraseFactoryCall(expression, context) {
448
493
  statements.push(...emitInitMerge(fn, context, property));
449
494
  continue;
450
495
  }
451
- const params = fn.parameters.filter((param) => !isThisParameter2(param) && ts2.isIdentifier(param.name)).map((param) => context.transformExpression(param.name));
496
+ const params = fn.parameters.filter((param) => !isThisParameter2(param) && ts3.isIdentifier(param.name)).map((param) => context.transformExpression(param.name));
452
497
  const fnExpression = createFunctionExpression2(createBlock2(transformHookBody(fn, context)), params, undefined, NodeFlags2.Declaration, fn);
453
498
  statements.push(createAssignmentStatement(createIdentifier2(name), fnExpression, property));
454
499
  }
455
500
  return [...registrations, ...statements];
456
501
  }
457
502
  function isFactoryOnlyImport(node) {
458
- if (!ts2.isStringLiteral(node.moduleSpecifier) || !FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
503
+ if (!ts3.isStringLiteral(node.moduleSpecifier) || !FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
459
504
  return false;
460
505
  }
461
506
  const clause = node.importClause;
@@ -466,7 +511,7 @@ function isFactoryOnlyImport(node) {
466
511
  return false;
467
512
  }
468
513
  const bindings = clause.namedBindings;
469
- if (bindings === undefined || !ts2.isNamedImports(bindings)) {
514
+ if (bindings === undefined || !ts3.isNamedImports(bindings)) {
470
515
  return false;
471
516
  }
472
517
  const runtime = bindings.elements.filter((element) => !element.isTypeOnly);
@@ -477,8 +522,8 @@ function isFactoryOnlyImport(node) {
477
522
  }
478
523
  var lifecycleErasurePlugin = {
479
524
  visitors: {
480
- [ts2.SyntaxKind.ExpressionStatement]: (node, context) => eraseFactoryCall(node.expression, context) ?? context.superTransformStatements(node),
481
- [ts2.SyntaxKind.ExportAssignment]: (node, context) => {
525
+ [ts3.SyntaxKind.ExpressionStatement]: (node, context) => eraseFactoryCall(node.expression, context) ?? context.superTransformStatements(node),
526
+ [ts3.SyntaxKind.ExportAssignment]: (node, context) => {
482
527
  if (!node.isExportEquals) {
483
528
  const erased = eraseFactoryCall(node.expression, context);
484
529
  if (erased !== undefined) {
@@ -487,8 +532,8 @@ var lifecycleErasurePlugin = {
487
532
  }
488
533
  return context.superTransformStatements(node);
489
534
  },
490
- [ts2.SyntaxKind.ImportDeclaration]: (node, context) => isFactoryOnlyImport(node) ? [] : context.superTransformStatements(node),
491
- [ts2.SyntaxKind.CallExpression]: (node, context) => {
535
+ [ts3.SyntaxKind.ImportDeclaration]: (node, context) => isFactoryOnlyImport(node) ? [] : context.superTransformStatements(node),
536
+ [ts3.SyntaxKind.CallExpression]: (node, context) => {
492
537
  const marker = node.parent === undefined ? undefined : calledGlobal(node, context.checker);
493
538
  if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
494
539
  if (!isPropertyDefault(node, context.checker)) {
@@ -499,7 +544,7 @@ var lifecycleErasurePlugin = {
499
544
  }
500
545
  return context.superTransformExpression(node);
501
546
  },
502
- [ts2.SyntaxKind.PropertyAccessExpression]: (node, context) => {
547
+ [ts3.SyntaxKind.PropertyAccessExpression]: (node, context) => {
503
548
  if (node.parent !== undefined && !isCallee(node)) {
504
549
  const marker = globalName(context.checker.getSymbolAtLocation(node.name), context.checker);
505
550
  if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
@@ -508,10 +553,10 @@ var lifecycleErasurePlugin = {
508
553
  }
509
554
  return context.superTransformExpression(node);
510
555
  },
511
- [ts2.SyntaxKind.ElementAccessExpression]: (node, context) => {
556
+ [ts3.SyntaxKind.ElementAccessExpression]: (node, context) => {
512
557
  if (node.parent !== undefined && !isCallee(node)) {
513
558
  const key = innermostExpression(node.argumentExpression);
514
- const marker = ts2.isStringLiteralLike(key) ? globalName(context.checker.getPropertyOfType(context.checker.getTypeAtLocation(node.expression), key.text), context.checker) : undefined;
559
+ const marker = ts3.isStringLiteralLike(key) ? globalName(context.checker.getPropertyOfType(context.checker.getTypeAtLocation(node.expression), key.text), context.checker) : undefined;
515
560
  if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
516
561
  context.diagnostics.push(misplacedMarker(node, marker));
517
562
  }
@@ -524,12 +569,12 @@ var lifecycleErasurePlugin = {
524
569
  // src/companion-closure.ts
525
570
  var COMPANION_INTERNAL_FIELD = "____closure";
526
571
  function isAssignmentOperator(kind) {
527
- return kind >= ts3.SyntaxKind.FirstAssignment && kind <= ts3.SyntaxKind.LastAssignment;
572
+ return kind >= ts4.SyntaxKind.FirstAssignment && kind <= ts4.SyntaxKind.LastAssignment;
528
573
  }
529
574
  function isTypePosition(node) {
530
575
  let current = node.parent;
531
- while (current !== undefined && !ts3.isSourceFile(current)) {
532
- if (ts3.isTypeNode(current)) {
576
+ while (current !== undefined && !ts4.isSourceFile(current)) {
577
+ if (ts4.isTypeNode(current)) {
533
578
  return true;
534
579
  }
535
580
  current = current.parent;
@@ -541,57 +586,57 @@ function isDeclarationName(node) {
541
586
  if (parent === undefined) {
542
587
  return false;
543
588
  }
544
- if (ts3.isPropertyAccessExpression(parent)) {
589
+ if (ts4.isPropertyAccessExpression(parent)) {
545
590
  return parent.name === node;
546
591
  }
547
- if (ts3.isQualifiedName(parent)) {
592
+ if (ts4.isQualifiedName(parent)) {
548
593
  return parent.right === node;
549
594
  }
550
- if ((ts3.isBindingElement(parent) || ts3.isImportSpecifier(parent) || ts3.isExportSpecifier(parent)) && parent.propertyName === node) {
595
+ if ((ts4.isBindingElement(parent) || ts4.isImportSpecifier(parent) || ts4.isExportSpecifier(parent)) && parent.propertyName === node) {
551
596
  return true;
552
597
  }
553
598
  const named = parent;
554
599
  if (named.name !== node) {
555
600
  return false;
556
601
  }
557
- return ts3.isVariableDeclaration(parent) || ts3.isFunctionDeclaration(parent) || ts3.isClassDeclaration(parent) || ts3.isEnumDeclaration(parent) || ts3.isEnumMember(parent) || ts3.isParameter(parent) || ts3.isBindingElement(parent) || ts3.isImportClause(parent) || ts3.isImportSpecifier(parent) || ts3.isNamespaceImport(parent) || ts3.isPropertyAssignment(parent) || ts3.isPropertyDeclaration(parent) || ts3.isPropertySignature(parent) || ts3.isMethodDeclaration(parent) || ts3.isMethodSignature(parent) || ts3.isTypeAliasDeclaration(parent) || ts3.isInterfaceDeclaration(parent) || ts3.isGetAccessor(parent) || ts3.isSetAccessor(parent);
602
+ return ts4.isVariableDeclaration(parent) || ts4.isFunctionDeclaration(parent) || ts4.isClassDeclaration(parent) || ts4.isEnumDeclaration(parent) || ts4.isEnumMember(parent) || ts4.isParameter(parent) || ts4.isBindingElement(parent) || ts4.isImportClause(parent) || ts4.isImportSpecifier(parent) || ts4.isNamespaceImport(parent) || ts4.isPropertyAssignment(parent) || ts4.isPropertyDeclaration(parent) || ts4.isPropertySignature(parent) || ts4.isMethodDeclaration(parent) || ts4.isMethodSignature(parent) || ts4.isTypeAliasDeclaration(parent) || ts4.isInterfaceDeclaration(parent) || ts4.isGetAccessor(parent) || ts4.isSetAccessor(parent);
558
603
  }
559
604
  function forEachReference(root, checker, visit) {
560
605
  const walk = (node) => {
561
- if (ts3.isIdentifier(node) && !isDeclarationName(node) && !isTypePosition(node)) {
606
+ if (ts4.isIdentifier(node) && !isDeclarationName(node) && !isTypePosition(node)) {
562
607
  const symbol = resolveReferencedSymbol(node, checker);
563
608
  if (symbol !== undefined) {
564
609
  visit(node, symbol);
565
610
  }
566
611
  }
567
- ts3.forEachChild(node, walk);
612
+ ts4.forEachChild(node, walk);
568
613
  };
569
614
  walk(root);
570
615
  }
571
616
  function resolveReferencedSymbol(node, checker) {
572
617
  const parent = node.parent;
573
- if (parent !== undefined && ts3.isShorthandPropertyAssignment(parent) && parent.name === node) {
618
+ if (parent !== undefined && ts4.isShorthandPropertyAssignment(parent) && parent.name === node) {
574
619
  return checker.getShorthandAssignmentValueSymbol(parent) ?? checker.getSymbolAtLocation(node);
575
620
  }
576
621
  return checker.getSymbolAtLocation(node);
577
622
  }
578
623
  function forEachAssignmentTarget(root, checker, visit) {
579
624
  const classify = (target) => {
580
- if (ts3.isParenthesizedExpression(target)) {
625
+ if (ts4.isParenthesizedExpression(target)) {
581
626
  classify(target.expression);
582
627
  return;
583
628
  }
584
- if (ts3.isPropertyAccessExpression(target) || ts3.isElementAccessExpression(target)) {
629
+ if (ts4.isPropertyAccessExpression(target) || ts4.isElementAccessExpression(target)) {
585
630
  return;
586
631
  }
587
- if (ts3.isArrayLiteralExpression(target)) {
632
+ if (ts4.isArrayLiteralExpression(target)) {
588
633
  for (const element of target.elements) {
589
- if (ts3.isOmittedExpression(element)) {
634
+ if (ts4.isOmittedExpression(element)) {
590
635
  continue;
591
636
  }
592
- if (ts3.isSpreadElement(element)) {
637
+ if (ts4.isSpreadElement(element)) {
593
638
  classify(element.expression);
594
- } else if (ts3.isBinaryExpression(element) && element.operatorToken.kind === ts3.SyntaxKind.EqualsToken) {
639
+ } else if (ts4.isBinaryExpression(element) && element.operatorToken.kind === ts4.SyntaxKind.EqualsToken) {
595
640
  classify(element.left);
596
641
  } else {
597
642
  classify(element);
@@ -599,13 +644,13 @@ function forEachAssignmentTarget(root, checker, visit) {
599
644
  }
600
645
  return;
601
646
  }
602
- if (ts3.isObjectLiteralExpression(target)) {
647
+ if (ts4.isObjectLiteralExpression(target)) {
603
648
  for (const property of target.properties) {
604
- if (ts3.isPropertyAssignment(property)) {
649
+ if (ts4.isPropertyAssignment(property)) {
605
650
  classify(property.initializer);
606
- } else if (ts3.isSpreadAssignment(property)) {
651
+ } else if (ts4.isSpreadAssignment(property)) {
607
652
  classify(property.expression);
608
- } else if (ts3.isShorthandPropertyAssignment(property)) {
653
+ } else if (ts4.isShorthandPropertyAssignment(property)) {
609
654
  const symbol = checker.getShorthandAssignmentValueSymbol(property);
610
655
  if (symbol !== undefined) {
611
656
  visit(property.name, symbol);
@@ -614,7 +659,7 @@ function forEachAssignmentTarget(root, checker, visit) {
614
659
  }
615
660
  return;
616
661
  }
617
- if (ts3.isIdentifier(target)) {
662
+ if (ts4.isIdentifier(target)) {
618
663
  const symbol = checker.getSymbolAtLocation(target);
619
664
  if (symbol !== undefined) {
620
665
  visit(target, symbol);
@@ -622,14 +667,14 @@ function forEachAssignmentTarget(root, checker, visit) {
622
667
  }
623
668
  };
624
669
  const walk = (node) => {
625
- if (ts3.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
670
+ if (ts4.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
626
671
  classify(node.left);
627
- } else if ((ts3.isPrefixUnaryExpression(node) || ts3.isPostfixUnaryExpression(node)) && (node.operator === ts3.SyntaxKind.PlusPlusToken || node.operator === ts3.SyntaxKind.MinusMinusToken)) {
672
+ } else if ((ts4.isPrefixUnaryExpression(node) || ts4.isPostfixUnaryExpression(node)) && (node.operator === ts4.SyntaxKind.PlusPlusToken || node.operator === ts4.SyntaxKind.MinusMinusToken)) {
628
673
  classify(node.operand);
629
- } else if ((ts3.isForInStatement(node) || ts3.isForOfStatement(node)) && !ts3.isVariableDeclarationList(node.initializer)) {
674
+ } else if ((ts4.isForInStatement(node) || ts4.isForOfStatement(node)) && !ts4.isVariableDeclarationList(node.initializer)) {
630
675
  classify(node.initializer);
631
676
  }
632
- ts3.forEachChild(node, walk);
677
+ ts4.forEachChild(node, walk);
633
678
  };
634
679
  walk(root);
635
680
  }
@@ -637,7 +682,7 @@ function collectTopLevel(sourceFile, checker) {
637
682
  const declarations = new Map;
638
683
  let order = 0;
639
684
  const add = (name, statement, node) => {
640
- if (name === undefined || !ts3.isIdentifier(name)) {
685
+ if (name === undefined || !ts4.isIdentifier(name)) {
641
686
  return;
642
687
  }
643
688
  const symbol = checker.getSymbolAtLocation(name);
@@ -647,24 +692,24 @@ function collectTopLevel(sourceFile, checker) {
647
692
  declarations.set(symbol, { name: name.text, statement, node, order: order++ });
648
693
  };
649
694
  const addBinding = (name, statement, node) => {
650
- if (ts3.isIdentifier(name)) {
695
+ if (ts4.isIdentifier(name)) {
651
696
  add(name, statement, node);
652
697
  return;
653
698
  }
654
699
  for (const element of name.elements) {
655
- if (ts3.isBindingElement(element)) {
700
+ if (ts4.isBindingElement(element)) {
656
701
  addBinding(element.name, statement, node);
657
702
  }
658
703
  }
659
704
  };
660
705
  for (const statement of sourceFile.statements) {
661
- if (ts3.isVariableStatement(statement)) {
706
+ if (ts4.isVariableStatement(statement)) {
662
707
  for (const declaration of statement.declarationList.declarations) {
663
708
  addBinding(declaration.name, statement, declaration);
664
709
  }
665
- } else if (ts3.isFunctionDeclaration(statement) || ts3.isClassDeclaration(statement) || ts3.isEnumDeclaration(statement)) {
710
+ } else if (ts4.isFunctionDeclaration(statement) || ts4.isClassDeclaration(statement) || ts4.isEnumDeclaration(statement)) {
666
711
  add(statement.name, statement, statement);
667
- } else if (ts3.isImportDeclaration(statement)) {
712
+ } else if (ts4.isImportDeclaration(statement)) {
668
713
  const clause = statement.importClause;
669
714
  if (clause === undefined) {
670
715
  continue;
@@ -674,7 +719,7 @@ function collectTopLevel(sourceFile, checker) {
674
719
  if (bindings === undefined) {
675
720
  continue;
676
721
  }
677
- if (ts3.isNamespaceImport(bindings)) {
722
+ if (ts4.isNamespaceImport(bindings)) {
678
723
  add(bindings.name, statement, statement);
679
724
  } else {
680
725
  for (const element of bindings.elements) {
@@ -686,14 +731,14 @@ function collectTopLevel(sourceFile, checker) {
686
731
  return declarations;
687
732
  }
688
733
  function hasExportModifier(statement) {
689
- return ts3.canHaveModifiers(statement) && (ts3.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts3.SyntaxKind.ExportKeyword);
734
+ return ts4.canHaveModifiers(statement) && (ts4.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts4.SyntaxKind.ExportKeyword);
690
735
  }
691
736
  function isValueSymbol(symbol, checker) {
692
737
  if (symbol === undefined) {
693
738
  return false;
694
739
  }
695
- const resolved = symbol.flags & ts3.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
696
- return (resolved.flags & ts3.SymbolFlags.Value) !== 0;
740
+ const resolved = symbol.flags & ts4.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
741
+ return (resolved.flags & ts4.SymbolFlags.Value) !== 0;
697
742
  }
698
743
  function collectExports(sourceFile, checker, topLevel) {
699
744
  const exported = [];
@@ -721,12 +766,12 @@ function collectExports(sourceFile, checker, topLevel) {
721
766
  take(symbol, name.text, declaration.node);
722
767
  };
723
768
  for (const statement of sourceFile.statements) {
724
- if (ts3.isExportDeclaration(statement)) {
769
+ if (ts4.isExportDeclaration(statement)) {
725
770
  if (statement.moduleSpecifier !== undefined || statement.isTypeOnly) {
726
771
  continue;
727
772
  }
728
773
  const clause = statement.exportClause;
729
- if (clause === undefined || !ts3.isNamedExports(clause)) {
774
+ if (clause === undefined || !ts4.isNamedExports(clause)) {
730
775
  continue;
731
776
  }
732
777
  for (const element of clause.elements) {
@@ -740,11 +785,11 @@ function collectExports(sourceFile, checker, topLevel) {
740
785
  if (!hasExportModifier(statement)) {
741
786
  continue;
742
787
  }
743
- if (ts3.isVariableStatement(statement)) {
788
+ if (ts4.isVariableStatement(statement)) {
744
789
  for (const declaration of statement.declarationList.declarations) {
745
790
  forEachDeclaredName(declaration.name, (name) => takeLocal(checker.getSymbolAtLocation(name), name));
746
791
  }
747
- } else if (ts3.isFunctionDeclaration(statement) || ts3.isClassDeclaration(statement) || ts3.isEnumDeclaration(statement)) {
792
+ } else if (ts4.isFunctionDeclaration(statement) || ts4.isClassDeclaration(statement) || ts4.isEnumDeclaration(statement)) {
748
793
  if (statement.name !== undefined) {
749
794
  takeLocal(checker.getSymbolAtLocation(statement.name), statement.name);
750
795
  }
@@ -753,74 +798,74 @@ function collectExports(sourceFile, checker, topLevel) {
753
798
  return exported;
754
799
  }
755
800
  function forEachDeclaredName(name, visit) {
756
- if (ts3.isIdentifier(name)) {
801
+ if (ts4.isIdentifier(name)) {
757
802
  visit(name);
758
803
  return;
759
804
  }
760
805
  for (const element of name.elements) {
761
- if (ts3.isBindingElement(element)) {
806
+ if (ts4.isBindingElement(element)) {
762
807
  forEachDeclaredName(element.name, visit);
763
808
  }
764
809
  }
765
810
  }
766
811
  function isLifecycleFactoryCall(expression, checker) {
767
- return ts3.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
812
+ return ts4.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
768
813
  }
769
814
  function isEffectFreeExpression(expression) {
770
815
  if (expression === undefined) {
771
816
  return true;
772
817
  }
773
- if (ts3.isParenthesizedExpression(expression) || ts3.isAsExpression(expression) || ts3.isTypeAssertionExpression(expression) || ts3.isNonNullExpression(expression)) {
818
+ if (ts4.isParenthesizedExpression(expression) || ts4.isAsExpression(expression) || ts4.isTypeAssertionExpression(expression) || ts4.isNonNullExpression(expression)) {
774
819
  return isEffectFreeExpression(expression.expression);
775
820
  }
776
- if (ts3.isIdentifier(expression) || ts3.isLiteralExpression(expression)) {
821
+ if (ts4.isIdentifier(expression) || ts4.isLiteralExpression(expression)) {
777
822
  return true;
778
823
  }
779
824
  switch (expression.kind) {
780
- case ts3.SyntaxKind.TrueKeyword:
781
- case ts3.SyntaxKind.FalseKeyword:
782
- case ts3.SyntaxKind.NullKeyword:
783
- case ts3.SyntaxKind.ThisKeyword:
825
+ case ts4.SyntaxKind.TrueKeyword:
826
+ case ts4.SyntaxKind.FalseKeyword:
827
+ case ts4.SyntaxKind.NullKeyword:
828
+ case ts4.SyntaxKind.ThisKeyword:
784
829
  return true;
785
830
  default:
786
831
  break;
787
832
  }
788
- if (ts3.isFunctionExpression(expression) || ts3.isArrowFunction(expression)) {
833
+ if (ts4.isFunctionExpression(expression) || ts4.isArrowFunction(expression)) {
789
834
  return true;
790
835
  }
791
- if (ts3.isPrefixUnaryExpression(expression)) {
792
- return expression.operator !== ts3.SyntaxKind.PlusPlusToken && expression.operator !== ts3.SyntaxKind.MinusMinusToken && isEffectFreeExpression(expression.operand);
836
+ if (ts4.isPrefixUnaryExpression(expression)) {
837
+ return expression.operator !== ts4.SyntaxKind.PlusPlusToken && expression.operator !== ts4.SyntaxKind.MinusMinusToken && isEffectFreeExpression(expression.operand);
793
838
  }
794
- if (ts3.isBinaryExpression(expression)) {
839
+ if (ts4.isBinaryExpression(expression)) {
795
840
  return !isAssignmentOperator(expression.operatorToken.kind) && isEffectFreeExpression(expression.left) && isEffectFreeExpression(expression.right);
796
841
  }
797
- if (ts3.isConditionalExpression(expression)) {
842
+ if (ts4.isConditionalExpression(expression)) {
798
843
  return isEffectFreeExpression(expression.condition) && isEffectFreeExpression(expression.whenTrue) && isEffectFreeExpression(expression.whenFalse);
799
844
  }
800
- if (ts3.isArrayLiteralExpression(expression)) {
845
+ if (ts4.isArrayLiteralExpression(expression)) {
801
846
  return expression.elements.every(isEffectFreeExpression);
802
847
  }
803
- if (ts3.isObjectLiteralExpression(expression)) {
848
+ if (ts4.isObjectLiteralExpression(expression)) {
804
849
  return expression.properties.every((property) => {
805
- if (ts3.isPropertyAssignment(property)) {
850
+ if (ts4.isPropertyAssignment(property)) {
806
851
  return isEffectFreeExpression(property.initializer);
807
852
  }
808
- return ts3.isShorthandPropertyAssignment(property) || ts3.isMethodDeclaration(property);
853
+ return ts4.isShorthandPropertyAssignment(property) || ts4.isMethodDeclaration(property);
809
854
  });
810
855
  }
811
856
  return false;
812
857
  }
813
858
  function isEffectFreeStatement(statement, checker) {
814
- if (ts3.isImportDeclaration(statement) || ts3.isInterfaceDeclaration(statement) || ts3.isTypeAliasDeclaration(statement) || ts3.isFunctionDeclaration(statement) || ts3.isExportDeclaration(statement)) {
859
+ if (ts4.isImportDeclaration(statement) || ts4.isInterfaceDeclaration(statement) || ts4.isTypeAliasDeclaration(statement) || ts4.isFunctionDeclaration(statement) || ts4.isExportDeclaration(statement)) {
815
860
  return true;
816
861
  }
817
- if (ts3.isVariableStatement(statement)) {
862
+ if (ts4.isVariableStatement(statement)) {
818
863
  return statement.declarationList.declarations.every((declaration) => isEffectFreeExpression(declaration.initializer));
819
864
  }
820
- if (ts3.isExpressionStatement(statement)) {
865
+ if (ts4.isExpressionStatement(statement)) {
821
866
  return isLifecycleFactoryCall(statement.expression, checker) || isEffectFreeExpression(statement.expression);
822
867
  }
823
- if (ts3.isExportAssignment(statement) && !statement.isExportEquals) {
868
+ if (ts4.isExportAssignment(statement) && !statement.isExportEquals) {
824
869
  return isLifecycleFactoryCall(statement.expression, checker) || isEffectFreeExpression(statement.expression);
825
870
  }
826
871
  return false;
@@ -860,7 +905,7 @@ function computeCompanionClosure(sourceFile, checker) {
860
905
  if (declaration === undefined) {
861
906
  continue;
862
907
  }
863
- if (ts3.isImportDeclaration(declaration.statement)) {
908
+ if (ts4.isImportDeclaration(declaration.statement)) {
864
909
  importBindingSymbols.add(symbol);
865
910
  continue;
866
911
  }
@@ -880,7 +925,7 @@ function computeCompanionClosure(sourceFile, checker) {
880
925
  }
881
926
  const splits = closureStatements.size > 0;
882
927
  for (const statement of sourceFile.statements) {
883
- if (!ts3.isExportDeclaration(statement) || statement.isTypeOnly) {
928
+ if (!ts4.isExportDeclaration(statement) || statement.isTypeOnly) {
884
929
  continue;
885
930
  }
886
931
  if (statement.moduleSpecifier !== undefined) {
@@ -890,7 +935,7 @@ function computeCompanionClosure(sourceFile, checker) {
890
935
  continue;
891
936
  }
892
937
  const clause = statement.exportClause;
893
- if (clause === undefined || !ts3.isNamedExports(clause)) {
938
+ if (clause === undefined || !ts4.isNamedExports(clause)) {
894
939
  continue;
895
940
  }
896
941
  const readsMember = clause.elements.some((element) => {
@@ -913,7 +958,7 @@ function computeCompanionClosure(sourceFile, checker) {
913
958
  });
914
959
  const scriptReferences = new Map;
915
960
  for (const statement of sourceFile.statements) {
916
- if (closureStatements.has(statement) || ts3.isExportDeclaration(statement)) {
961
+ if (closureStatements.has(statement) || ts4.isExportDeclaration(statement)) {
917
962
  continue;
918
963
  }
919
964
  forEachReference(statement, checker, (node, symbol) => {
@@ -957,8 +1002,12 @@ function computeCompanionClosure(sourceFile, checker) {
957
1002
  message: `"${COMPANION_INTERNAL_FIELD}" is reserved for the companion's own internals ` + `and cannot be exported (${formatSites(sites)}). Rename the export.`
958
1003
  });
959
1004
  }
1005
+ const managed = findManagedBootstrap(sourceFile);
1006
+ const bootstrap = managed?.canonical === true ? managed.statements : [];
1007
+ const editedBlock = new Set(managed?.canonical === false ? managed.statements : []);
1008
+ const exempt = new Set(bootstrap);
960
1009
  for (const statement of sourceFile.statements) {
961
- if (closureStatements.has(statement) || isEffectFreeStatement(statement, checker)) {
1010
+ if (closureStatements.has(statement) || exempt.has(statement) || isEffectFreeStatement(statement, checker)) {
962
1011
  continue;
963
1012
  }
964
1013
  const start = statement.getStart(sourceFile);
@@ -970,11 +1019,12 @@ function computeCompanionClosure(sourceFile, checker) {
970
1019
  siteOf(statement, "runs in the script"),
971
1020
  siteOf(hoisted.declaration.node, "moves into the companion")
972
1021
  ];
1022
+ const name = hoisted.declaration.name;
973
1023
  violations.push({
974
1024
  kind: "initialization-order",
975
- member: hoisted.declaration.name,
1025
+ member: name,
976
1026
  sites,
977
- message: `top-level work precedes "${hoisted.declaration.name}", which the companion would run first, ` + `reversing their order (${formatSites(sites)}). ` + "Move that work below the companion's declarations, or into a lifecycle hook."
1027
+ message: editedBlock.has(statement) ? `the setup-debug managed block was edited and now runs top-level work before "${name}", ` + `which the companion would run first (${formatSites(sites)}). ` + "Run `defold-typescript setup-debug` to restore the block." : `top-level work precedes "${name}", which the companion would run first, ` + `reversing their order (${formatSites(sites)}). ` + "Move that work below the companion's declarations, or into a lifecycle hook."
978
1028
  });
979
1029
  }
980
1030
  return {
@@ -983,6 +1033,7 @@ function computeCompanionClosure(sourceFile, checker) {
983
1033
  statements: sourceFile.statements.filter((statement) => closureStatements.has(statement)),
984
1034
  importBindings: ordered.filter(({ symbol }) => importBindingSymbols.has(symbol)).map(({ declaration }) => declaration.name),
985
1035
  internals: ordered.filter(({ symbol }) => !exportSet.has(symbol) && scriptReferences.has(symbol)).map(({ declaration }) => declaration.name),
1036
+ bootstrap,
986
1037
  violations
987
1038
  };
988
1039
  }
@@ -1531,7 +1582,7 @@ function readGameProjectSetting(gameProjectText, section, key) {
1531
1582
  import { existsSync, readdirSync } from "node:fs";
1532
1583
  import * as path from "node:path";
1533
1584
  import { fileURLToPath } from "node:url";
1534
- import * as ts4 from "typescript";
1585
+ import * as ts5 from "typescript";
1535
1586
  import { LuaLibFeature } from "typescript-to-lua";
1536
1587
 
1537
1588
  // src/lua-require-scan.ts
@@ -1614,6 +1665,41 @@ function mask(lua) {
1614
1665
  return { text, literals };
1615
1666
  }
1616
1667
  var REQUIRE_RE = new RegExp(String.raw`(?<![A-Za-z0-9_.])require\s*\(\s*${PLACEHOLDER}(\d+)${PLACEHOLDER}\s*\)`, "g");
1668
+ function isLuaSpace(c) {
1669
+ return c === " " || c === "\t" || c === `
1670
+ ` || c === "\r";
1671
+ }
1672
+ var REQUIRE_WORD = "require";
1673
+ function callSpan(lua, literal) {
1674
+ let i = literal.start - 1;
1675
+ while (isLuaSpace(lua[i])) {
1676
+ i--;
1677
+ }
1678
+ if (lua[i] !== "(") {
1679
+ return;
1680
+ }
1681
+ i--;
1682
+ while (isLuaSpace(lua[i])) {
1683
+ i--;
1684
+ }
1685
+ const wordEnd = i + 1;
1686
+ const wordStart = wordEnd - REQUIRE_WORD.length;
1687
+ if (wordStart < 0 || lua.slice(wordStart, wordEnd) !== REQUIRE_WORD) {
1688
+ return;
1689
+ }
1690
+ const before = lua[wordStart - 1];
1691
+ if (before !== undefined && /[A-Za-z0-9_.]/.test(before)) {
1692
+ return;
1693
+ }
1694
+ let j = literal.end;
1695
+ while (isLuaSpace(lua[j])) {
1696
+ j++;
1697
+ }
1698
+ if (lua[j] !== ")") {
1699
+ return;
1700
+ }
1701
+ return { callStart: wordStart, callEnd: j + 1 };
1702
+ }
1617
1703
  function scanEmittedRequires(lua) {
1618
1704
  const { text, literals } = mask(lua);
1619
1705
  const sites = [];
@@ -1622,7 +1708,12 @@ function scanEmittedRequires(lua) {
1622
1708
  if (literal === undefined) {
1623
1709
  continue;
1624
1710
  }
1625
- sites.push({ path: literal.value, start: literal.start, end: literal.end });
1711
+ sites.push({
1712
+ path: literal.value,
1713
+ start: literal.start,
1714
+ end: literal.end,
1715
+ ...callSpan(lua, literal)
1716
+ });
1626
1717
  }
1627
1718
  return sites;
1628
1719
  }
@@ -1679,7 +1770,7 @@ function isHsmRequireName(requirePath) {
1679
1770
  return hsmModuleOfRequire(requirePath) !== undefined;
1680
1771
  }
1681
1772
  function hsmModuleOfSpecifier(node) {
1682
- if (node === undefined || !ts4.isStringLiteral(node)) {
1773
+ if (node === undefined || !ts5.isStringLiteral(node)) {
1683
1774
  return;
1684
1775
  }
1685
1776
  const { text } = node;
@@ -1719,7 +1810,7 @@ function hsmClosure(chunks, compile) {
1719
1810
  return Object.fromEntries(Object.entries(selected).sort(([a], [b]) => a.localeCompare(b)));
1720
1811
  }
1721
1812
  function lowerSpecifier(module) {
1722
- return ts4.factory.createStringLiteral(`@NoResolution:${module.requireName}`);
1813
+ return ts5.factory.createStringLiteral(`@NoResolution:${module.requireName}`);
1723
1814
  }
1724
1815
  function loweredAnything(lowered) {
1725
1816
  return Array.isArray(lowered) ? lowered.length > 0 : lowered !== undefined;
@@ -1737,7 +1828,7 @@ function importSurvivesElision(node, context) {
1737
1828
  if (bindings === undefined) {
1738
1829
  return false;
1739
1830
  }
1740
- if (ts4.isNamespaceImport(bindings)) {
1831
+ if (ts5.isNamespaceImport(bindings)) {
1741
1832
  return resolver.isReferencedAliasDeclaration(bindings);
1742
1833
  }
1743
1834
  return bindings.elements.some((element) => resolver.isReferencedAliasDeclaration(element));
@@ -1750,20 +1841,20 @@ function registerLualib(module, emitted, context) {
1750
1841
  }
1751
1842
  var hsmLoweringPlugin = {
1752
1843
  visitors: {
1753
- [ts4.SyntaxKind.ImportDeclaration]: (node, context) => {
1844
+ [ts5.SyntaxKind.ImportDeclaration]: (node, context) => {
1754
1845
  const module = hsmModuleOfSpecifier(node.moduleSpecifier);
1755
1846
  if (module === undefined) {
1756
1847
  return context.superTransformStatements(node);
1757
1848
  }
1758
1849
  registerLualib(module, importSurvivesElision(node, context), context);
1759
- return context.superTransformStatements(ts4.factory.updateImportDeclaration(node, node.modifiers, node.importClause, lowerSpecifier(module), node.attributes));
1850
+ return context.superTransformStatements(ts5.factory.updateImportDeclaration(node, node.modifiers, node.importClause, lowerSpecifier(module), node.attributes));
1760
1851
  },
1761
- [ts4.SyntaxKind.ExportDeclaration]: (node, context) => {
1852
+ [ts5.SyntaxKind.ExportDeclaration]: (node, context) => {
1762
1853
  const module = hsmModuleOfSpecifier(node.moduleSpecifier);
1763
1854
  if (module === undefined) {
1764
1855
  return context.superTransformStatements(node);
1765
1856
  }
1766
- const lowered = context.superTransformStatements(ts4.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, lowerSpecifier(module), node.attributes));
1857
+ const lowered = context.superTransformStatements(ts5.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, lowerSpecifier(module), node.attributes));
1767
1858
  registerLualib(module, loweredAnything(lowered), context);
1768
1859
  return lowered;
1769
1860
  }
@@ -2283,20 +2374,20 @@ function readLibrarySceneDocuments(host, projectRoot, extensions = LIBRARY_SCENE
2283
2374
  return { documents, unreadable };
2284
2375
  }
2285
2376
  // src/main-entry-factory-imports.ts
2286
- import * as ts5 from "typescript";
2377
+ import * as ts6 from "typescript";
2287
2378
  function findMainEntryFactoryImports(fileName, source) {
2288
- const sourceFile = ts5.createSourceFile(fileName, source, ts5.ScriptTarget.Latest, true);
2379
+ const sourceFile = ts6.createSourceFile(fileName, source, ts6.ScriptTarget.Latest, true);
2289
2380
  const factories = [];
2290
2381
  for (const statement of sourceFile.statements) {
2291
- if (!ts5.isImportDeclaration(statement)) {
2382
+ if (!ts6.isImportDeclaration(statement)) {
2292
2383
  continue;
2293
2384
  }
2294
2385
  const specifier = statement.moduleSpecifier;
2295
- if (!ts5.isStringLiteral(specifier) || specifier.text !== FACTORY_MODULE) {
2386
+ if (!ts6.isStringLiteral(specifier) || specifier.text !== FACTORY_MODULE) {
2296
2387
  continue;
2297
2388
  }
2298
2389
  const bindings = statement.importClause?.namedBindings;
2299
- if (bindings === undefined || !ts5.isNamedImports(bindings)) {
2390
+ if (bindings === undefined || !ts6.isNamedImports(bindings)) {
2300
2391
  continue;
2301
2392
  }
2302
2393
  for (const element of bindings.elements) {
@@ -2369,16 +2460,16 @@ function computeOutputRel(rel, config, kind) {
2369
2460
  return baseRel.replace(/\.ts$/, SCRIPT_SUFFIX_BY_KIND[kind]);
2370
2461
  }
2371
2462
  // src/program-diagnostics.ts
2372
- import * as ts11 from "typescript";
2463
+ import * as ts12 from "typescript";
2373
2464
  import * as tstl from "typescript-to-lua";
2374
2465
 
2375
2466
  // src/message-guard-lowering.ts
2376
- import * as ts6 from "typescript";
2467
+ import * as ts7 from "typescript";
2377
2468
  import {
2378
2469
  createBinaryExpression as createBinaryExpression3,
2379
2470
  createCallExpression as createCallExpression3,
2380
2471
  createIdentifier as createIdentifier3,
2381
- SyntaxKind as SyntaxKind8
2472
+ SyntaxKind as SyntaxKind9
2382
2473
  } from "typescript-to-lua";
2383
2474
  var GUARD_MODULE = "@defold-typescript/types";
2384
2475
  var GUARD_NAME = "isMessage";
@@ -2387,7 +2478,7 @@ function resolvesToGuardExport(callee, checker) {
2387
2478
  if (symbol === undefined) {
2388
2479
  return false;
2389
2480
  }
2390
- if (symbol.flags & ts6.SymbolFlags.Alias) {
2481
+ if (symbol.flags & ts7.SymbolFlags.Alias) {
2391
2482
  symbol = checker.getAliasedSymbol(symbol);
2392
2483
  }
2393
2484
  if (symbol.getName() !== GUARD_NAME) {
@@ -2401,12 +2492,12 @@ function resolvesToGuardExport(callee, checker) {
2401
2492
  }
2402
2493
  var messageGuardLoweringPlugin = {
2403
2494
  visitors: {
2404
- [ts6.SyntaxKind.CallExpression]: (node, context) => {
2495
+ [ts7.SyntaxKind.CallExpression]: (node, context) => {
2405
2496
  const [messageIdArg, , expectedArg] = node.arguments;
2406
2497
  if (node.arguments.length === 3 && messageIdArg !== undefined && expectedArg !== undefined && resolvesToGuardExport(node.expression, context.checker)) {
2407
2498
  const messageId = context.transformExpression(messageIdArg);
2408
2499
  const expected = context.transformExpression(expectedArg);
2409
- return createBinaryExpression3(messageId, createCallExpression3(createIdentifier3("hash"), [expected]), SyntaxKind8.EqualityOperator, node);
2500
+ return createBinaryExpression3(messageId, createCallExpression3(createIdentifier3("hash"), [expected]), SyntaxKind9.EqualityOperator, node);
2410
2501
  }
2411
2502
  return context.superTransformExpression(node);
2412
2503
  }
@@ -2414,14 +2505,14 @@ var messageGuardLoweringPlugin = {
2414
2505
  };
2415
2506
 
2416
2507
  // src/physics-event-guard-lowering.ts
2417
- import * as ts7 from "typescript";
2508
+ import * as ts8 from "typescript";
2418
2509
  import {
2419
2510
  createBinaryExpression as createBinaryExpression4,
2420
2511
  createCallExpression as createCallExpression4,
2421
2512
  createIdentifier as createIdentifier4,
2422
2513
  createStringLiteral as createStringLiteral3,
2423
2514
  createTableIndexExpression as createTableIndexExpression2,
2424
- SyntaxKind as SyntaxKind10
2515
+ SyntaxKind as SyntaxKind11
2425
2516
  } from "typescript-to-lua";
2426
2517
  var GUARD_MODULE2 = "@defold-typescript/types";
2427
2518
  var GUARD_NAME2 = "isPhysicsEvent";
@@ -2430,7 +2521,7 @@ function resolvesToGuardExport2(callee, checker) {
2430
2521
  if (symbol === undefined) {
2431
2522
  return false;
2432
2523
  }
2433
- if (symbol.flags & ts7.SymbolFlags.Alias) {
2524
+ if (symbol.flags & ts8.SymbolFlags.Alias) {
2434
2525
  symbol = checker.getAliasedSymbol(symbol);
2435
2526
  }
2436
2527
  if (symbol.getName() !== GUARD_NAME2) {
@@ -2444,12 +2535,12 @@ function resolvesToGuardExport2(callee, checker) {
2444
2535
  }
2445
2536
  var physicsEventGuardLoweringPlugin = {
2446
2537
  visitors: {
2447
- [ts7.SyntaxKind.CallExpression]: (node, context) => {
2538
+ [ts8.SyntaxKind.CallExpression]: (node, context) => {
2448
2539
  const [eventArg, nameArg] = node.arguments;
2449
2540
  if (node.arguments.length === 2 && eventArg !== undefined && nameArg !== undefined && resolvesToGuardExport2(node.expression, context.checker)) {
2450
2541
  const event = context.transformExpression(eventArg);
2451
2542
  const name = context.transformExpression(nameArg);
2452
- return createBinaryExpression4(createTableIndexExpression2(event, createStringLiteral3("type")), createCallExpression4(createIdentifier4("hash"), [name]), SyntaxKind10.EqualityOperator, node);
2543
+ return createBinaryExpression4(createTableIndexExpression2(event, createStringLiteral3("type")), createCallExpression4(createIdentifier4("hash"), [name]), SyntaxKind11.EqualityOperator, node);
2453
2544
  }
2454
2545
  return context.superTransformExpression(node);
2455
2546
  }
@@ -2457,37 +2548,37 @@ var physicsEventGuardLoweringPlugin = {
2457
2548
  };
2458
2549
 
2459
2550
  // src/timers-lowering.ts
2460
- import * as ts8 from "typescript";
2551
+ import * as ts9 from "typescript";
2461
2552
  import { LuaLibFeature as LuaLibFeature2 } from "typescript-to-lua";
2462
2553
  function isTimersSpecifier(node) {
2463
- return ts8.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
2554
+ return ts9.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
2464
2555
  }
2465
2556
  function importsTimersModule(sourceFile) {
2466
- return sourceFile.statements.some((statement) => ts8.isImportDeclaration(statement) && isTimersSpecifier(statement.moduleSpecifier));
2557
+ return sourceFile.statements.some((statement) => ts9.isImportDeclaration(statement) && isTimersSpecifier(statement.moduleSpecifier));
2467
2558
  }
2468
2559
  var TIMERS_REQUIRE_PATH = `@NoResolution:${TIMERS_REQUIRE_NAME}`;
2469
2560
  var timersLoweringPlugin = {
2470
2561
  visitors: {
2471
- [ts8.SyntaxKind.ImportDeclaration]: (node, context) => {
2562
+ [ts9.SyntaxKind.ImportDeclaration]: (node, context) => {
2472
2563
  if (!isTimersSpecifier(node.moduleSpecifier)) {
2473
2564
  return context.superTransformStatements(node);
2474
2565
  }
2475
2566
  context.usedLuaLibFeatures.add(LuaLibFeature2.Promise);
2476
2567
  context.usedLuaLibFeatures.add(LuaLibFeature2.New);
2477
- const rewritten = ts8.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts8.factory.createStringLiteral(TIMERS_REQUIRE_PATH), node.attributes);
2568
+ const rewritten = ts9.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts9.factory.createStringLiteral(TIMERS_REQUIRE_PATH), node.attributes);
2478
2569
  return context.superTransformStatements(rewritten);
2479
2570
  }
2480
2571
  }
2481
2572
  };
2482
2573
 
2483
2574
  // src/type-application-erasure.ts
2484
- import * as ts9 from "typescript";
2575
+ import * as ts10 from "typescript";
2485
2576
  var TYPE_APPLICATION_APIS = new Set(["go.get", "go.set"]);
2486
2577
  function isTypeApplication(call, checker) {
2487
2578
  if (call.arguments.length !== 0)
2488
2579
  return false;
2489
2580
  const declaration = checker.getResolvedSignature(call)?.declaration;
2490
- if (declaration === undefined || !ts9.isFunctionDeclaration(declaration))
2581
+ if (declaration === undefined || !ts10.isFunctionDeclaration(declaration))
2491
2582
  return false;
2492
2583
  if (declaration.parameters.length !== 0 || declaration.typeParameters === undefined)
2493
2584
  return false;
@@ -2501,7 +2592,7 @@ function isTypeApplication(call, checker) {
2501
2592
  }
2502
2593
  var typeApplicationErasurePlugin = {
2503
2594
  visitors: {
2504
- [ts9.SyntaxKind.CallExpression]: (node, context) => {
2595
+ [ts10.SyntaxKind.CallExpression]: (node, context) => {
2505
2596
  if (isTypeApplication(node, context.checker)) {
2506
2597
  return context.transformExpression(node.expression);
2507
2598
  }
@@ -2511,10 +2602,10 @@ var typeApplicationErasurePlugin = {
2511
2602
  };
2512
2603
 
2513
2604
  // src/window-event-guard-lowering.ts
2514
- import * as ts10 from "typescript";
2605
+ import * as ts11 from "typescript";
2515
2606
  import {
2516
2607
  createBinaryExpression as createBinaryExpression5,
2517
- SyntaxKind as SyntaxKind14
2608
+ SyntaxKind as SyntaxKind15
2518
2609
  } from "typescript-to-lua";
2519
2610
  var GUARD_MODULE3 = "@defold-typescript/types";
2520
2611
  var GUARD_NAME3 = "isWindowEvent";
@@ -2523,7 +2614,7 @@ function resolvesToGuardExport3(callee, checker) {
2523
2614
  if (symbol === undefined) {
2524
2615
  return false;
2525
2616
  }
2526
- if (symbol.flags & ts10.SymbolFlags.Alias) {
2617
+ if (symbol.flags & ts11.SymbolFlags.Alias) {
2527
2618
  symbol = checker.getAliasedSymbol(symbol);
2528
2619
  }
2529
2620
  if (symbol.getName() !== GUARD_NAME3) {
@@ -2537,12 +2628,12 @@ function resolvesToGuardExport3(callee, checker) {
2537
2628
  }
2538
2629
  var windowEventGuardLoweringPlugin = {
2539
2630
  visitors: {
2540
- [ts10.SyntaxKind.CallExpression]: (node, context) => {
2631
+ [ts11.SyntaxKind.CallExpression]: (node, context) => {
2541
2632
  const [eventArg, , expectedArg] = node.arguments;
2542
2633
  if (node.arguments.length === 3 && eventArg !== undefined && expectedArg !== undefined && resolvesToGuardExport3(node.expression, context.checker)) {
2543
2634
  const event = context.transformExpression(eventArg);
2544
2635
  const expected = context.transformExpression(expectedArg);
2545
- return createBinaryExpression5(event, expected, SyntaxKind14.EqualityOperator, node);
2636
+ return createBinaryExpression5(event, expected, SyntaxKind15.EqualityOperator, node);
2546
2637
  }
2547
2638
  return context.superTransformExpression(node);
2548
2639
  }
@@ -2564,7 +2655,7 @@ function isAmbient(fileName) {
2564
2655
  return /[\\/]node_modules[\\/]/.test(fileName) || /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(fileName);
2565
2656
  }
2566
2657
  function getProgramDiagnostics(program, sourceFile) {
2567
- const { diagnostics } = tstl.getProgramTranspileResult(ts11.sys, noopWriteFile, {
2658
+ const { diagnostics } = tstl.getProgramTranspileResult(ts12.sys, noopWriteFile, {
2568
2659
  program,
2569
2660
  plugins: LUA_PLUGINS,
2570
2661
  ...sourceFile ? { sourceFiles: [sourceFile] } : {}
@@ -3135,11 +3226,11 @@ function relativeAddressesFrom(index, context) {
3135
3226
  import { readFileSync as readFileSync2 } from "node:fs";
3136
3227
  import { createRequire as createRequire2 } from "node:module";
3137
3228
  import * as path4 from "node:path";
3138
- import * as ts15 from "typescript";
3229
+ import * as ts17 from "typescript";
3139
3230
  import * as tstl3 from "typescript-to-lua";
3140
3231
 
3141
3232
  // src/companion-emit.ts
3142
- import * as ts12 from "typescript";
3233
+ import * as ts13 from "typescript";
3143
3234
  import {
3144
3235
  createAssignmentStatement as createAssignmentStatement2,
3145
3236
  createCallExpression as createCallExpression5,
@@ -3173,8 +3264,8 @@ function exportsIdentifier() {
3173
3264
  }
3174
3265
  function isRuntimeScriptSource(sourceFile, checker) {
3175
3266
  return sourceFile.statements.some((statement) => {
3176
- const expression = ts12.isExpressionStatement(statement) ? statement.expression : ts12.isExportAssignment(statement) && !statement.isExportEquals ? statement.expression : undefined;
3177
- return expression !== undefined && ts12.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
3267
+ const expression = ts13.isExpressionStatement(statement) ? statement.expression : ts13.isExportAssignment(statement) && !statement.isExportEquals ? statement.expression : undefined;
3268
+ return expression !== undefined && ts13.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
3178
3269
  });
3179
3270
  }
3180
3271
  function planFor(sourceFile, checker) {
@@ -3187,6 +3278,7 @@ function planFor(sourceFile, checker) {
3187
3278
  }
3188
3279
  return {
3189
3280
  closureStarts: new Set(closure.statements.map((statement) => statement.pos)),
3281
+ bootstrapStarts: new Set(closure.bootstrap.map((statement) => statement.pos)),
3190
3282
  internals: closure.internals,
3191
3283
  importBindings: closure.importBindings,
3192
3284
  requirePath: requirePathForRel(sourceFile.fileName)
@@ -3326,11 +3418,11 @@ function freeNames(statements) {
3326
3418
  function resolvedRequirePaths(sourceFile, checker) {
3327
3419
  const paths = new Map;
3328
3420
  for (const statement of sourceFile.statements) {
3329
- const specifier = ts12.isImportDeclaration(statement) || ts12.isExportDeclaration(statement) ? statement.moduleSpecifier : undefined;
3330
- if (specifier === undefined || !ts12.isStringLiteral(specifier)) {
3421
+ const specifier = ts13.isImportDeclaration(statement) || ts13.isExportDeclaration(statement) ? statement.moduleSpecifier : undefined;
3422
+ if (specifier === undefined || !ts13.isStringLiteral(specifier)) {
3331
3423
  continue;
3332
3424
  }
3333
- const target = checker.getSymbolAtLocation(specifier)?.declarations?.find((declaration) => ts12.isSourceFile(declaration));
3425
+ const target = checker.getSymbolAtLocation(specifier)?.declarations?.find((declaration) => ts13.isSourceFile(declaration));
3334
3426
  if (target === undefined || target.isDeclarationFile) {
3335
3427
  continue;
3336
3428
  }
@@ -3473,6 +3565,7 @@ function split(statements, owned) {
3473
3565
  function createCompanionEmitPlugin() {
3474
3566
  const plans = new Map;
3475
3567
  const owned = new Map;
3568
+ const bootstraps = new Map;
3476
3569
  const companions = new Map;
3477
3570
  function planOf(sourceFile, checker) {
3478
3571
  const key = sourceFile.fileName;
@@ -3498,12 +3591,30 @@ function createCompanionEmitPlugin() {
3498
3591
  }
3499
3592
  return statements;
3500
3593
  }
3594
+ function captureBootstrap(node, context) {
3595
+ const statements = context.superTransformStatements(node);
3596
+ const sourceFile = context.sourceFile;
3597
+ const plan = planOf(sourceFile, context.checker);
3598
+ if (plan === undefined || !plan.bootstrapStarts.has(node.pos)) {
3599
+ return statements;
3600
+ }
3601
+ let bucket = bootstraps.get(sourceFile.fileName);
3602
+ if (bucket === undefined) {
3603
+ bucket = new Set;
3604
+ bootstraps.set(sourceFile.fileName, bucket);
3605
+ }
3606
+ for (const statement of statements) {
3607
+ bucket.add(statement);
3608
+ }
3609
+ return statements;
3610
+ }
3501
3611
  const visitors = {
3502
- [ts12.SyntaxKind.VariableStatement]: capture,
3503
- [ts12.SyntaxKind.FunctionDeclaration]: capture,
3504
- [ts12.SyntaxKind.ClassDeclaration]: capture,
3505
- [ts12.SyntaxKind.EnumDeclaration]: capture,
3506
- [ts12.SyntaxKind.ExportDeclaration]: capture
3612
+ [ts13.SyntaxKind.VariableStatement]: capture,
3613
+ [ts13.SyntaxKind.FunctionDeclaration]: capture,
3614
+ [ts13.SyntaxKind.ClassDeclaration]: capture,
3615
+ [ts13.SyntaxKind.EnumDeclaration]: capture,
3616
+ [ts13.SyntaxKind.ExportDeclaration]: capture,
3617
+ [ts13.SyntaxKind.IfStatement]: captureBootstrap
3507
3618
  };
3508
3619
  let configuredNoResolvePaths = [];
3509
3620
  const plugin = {
@@ -3523,7 +3634,8 @@ function createCompanionEmitPlugin() {
3523
3634
  if (plan === undefined || bucket === undefined || bucket.size === 0) {
3524
3635
  continue;
3525
3636
  }
3526
- emitCompanion(program, emitHost, file, sourceFile, plan, bucket, companions);
3637
+ const bootstrap = bootstraps.get(sourceFile.fileName) ?? new Set;
3638
+ emitCompanion(program, emitHost, file, sourceFile, plan, bucket, bootstrap, companions);
3527
3639
  emitted.push(plan.requirePath);
3528
3640
  }
3529
3641
  if (emitted.length > 0) {
@@ -3533,7 +3645,7 @@ function createCompanionEmitPlugin() {
3533
3645
  };
3534
3646
  return { plugin, companions };
3535
3647
  }
3536
- function emitCompanion(program, emitHost, file, sourceFile, plan, owned, companions) {
3648
+ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, bootstrap, companions) {
3537
3649
  const luaAst = file.luaAst;
3538
3650
  if (luaAst === undefined) {
3539
3651
  return;
@@ -3552,12 +3664,14 @@ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, compani
3552
3664
  createReturnStatement2([exportsIdentifier()])
3553
3665
  ];
3554
3666
  const reads = new Set([EXPORTS_NAME, ...plan.internals]);
3555
- const insertAt = requireInsertionPoint(halves.script, reads);
3667
+ const rest = halves.script.filter((statement) => !bootstrap.has(statement));
3668
+ const insertAt = requireInsertionPoint(rest, reads);
3556
3669
  const scriptStatements = [
3557
- ...halves.script.slice(0, insertAt),
3670
+ ...rest.slice(0, insertAt),
3671
+ ...halves.script.filter((statement) => bootstrap.has(statement)),
3558
3672
  createVariableDeclarationStatement3(exportsIdentifier(), createCallExpression5(createIdentifier5("require"), [createStringLiteral4(plan.requirePath)])),
3559
3673
  ...plan.internals.map((name) => createVariableDeclarationStatement3(createIdentifier5(name), internalsField(name))),
3560
- ...halves.script.slice(insertAt),
3674
+ ...rest.slice(insertAt),
3561
3675
  createReturnStatement2([exportsIdentifier()])
3562
3676
  ];
3563
3677
  const features = new Set(luaAst.luaLibFeatures);
@@ -3572,7 +3686,7 @@ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, compani
3572
3686
  }
3573
3687
 
3574
3688
  // src/editor-script-erasure.ts
3575
- import * as ts13 from "typescript";
3689
+ import * as ts14 from "typescript";
3576
3690
  import {
3577
3691
  createReturnStatement as createReturnStatement3
3578
3692
  } from "typescript-to-lua";
@@ -3592,7 +3706,7 @@ function resolveEditorFactoryExport(callee, checker) {
3592
3706
  if (symbol === undefined) {
3593
3707
  return;
3594
3708
  }
3595
- if (symbol.flags & ts13.SymbolFlags.Alias) {
3709
+ if (symbol.flags & ts14.SymbolFlags.Alias) {
3596
3710
  symbol = checker.getAliasedSymbol(symbol);
3597
3711
  }
3598
3712
  const name = symbol.getName();
@@ -3606,7 +3720,7 @@ function resolveEditorFactoryExport(callee, checker) {
3606
3720
  return declaration.getSourceFile().fileName.includes(EDITOR_FACTORY_MODULE) ? name : undefined;
3607
3721
  }
3608
3722
  function lowerEditorFactoryCall(expression, context) {
3609
- if (!ts13.isCallExpression(expression)) {
3723
+ if (!ts14.isCallExpression(expression)) {
3610
3724
  return;
3611
3725
  }
3612
3726
  if (resolveEditorFactoryExport(expression.expression, context.checker) !== EDITOR_SCRIPT_FACTORY_NAME) {
@@ -3619,7 +3733,7 @@ function lowerEditorFactoryCall(expression, context) {
3619
3733
  return [createReturnStatement3([context.transformExpression(module)])];
3620
3734
  }
3621
3735
  function isEditorFactoryOnlyImport(node) {
3622
- if (!ts13.isStringLiteral(node.moduleSpecifier) || !EDITOR_FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
3736
+ if (!ts14.isStringLiteral(node.moduleSpecifier) || !EDITOR_FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
3623
3737
  return false;
3624
3738
  }
3625
3739
  const clause = node.importClause;
@@ -3630,7 +3744,7 @@ function isEditorFactoryOnlyImport(node) {
3630
3744
  return false;
3631
3745
  }
3632
3746
  const bindings = clause.namedBindings;
3633
- if (bindings === undefined || !ts13.isNamedImports(bindings)) {
3747
+ if (bindings === undefined || !ts14.isNamedImports(bindings)) {
3634
3748
  return false;
3635
3749
  }
3636
3750
  const runtime = bindings.elements.filter((element) => !element.isTypeOnly);
@@ -3641,7 +3755,7 @@ function isEditorFactoryOnlyImport(node) {
3641
3755
  }
3642
3756
  var editorScriptErasurePlugin = {
3643
3757
  visitors: {
3644
- [ts13.SyntaxKind.ExportAssignment]: (node, context) => {
3758
+ [ts14.SyntaxKind.ExportAssignment]: (node, context) => {
3645
3759
  if (!node.isExportEquals) {
3646
3760
  const lowered = lowerEditorFactoryCall(node.expression, context);
3647
3761
  if (lowered !== undefined) {
@@ -3650,17 +3764,139 @@ var editorScriptErasurePlugin = {
3650
3764
  }
3651
3765
  return context.superTransformStatements(node);
3652
3766
  },
3653
- [ts13.SyntaxKind.CallExpression]: (node, context) => {
3767
+ [ts14.SyntaxKind.CallExpression]: (node, context) => {
3654
3768
  const command = node.arguments[0];
3655
3769
  if (command !== undefined && resolveEditorFactoryExport(node.expression, context.checker) === EDITOR_COMMAND_FACTORY_NAME) {
3656
3770
  return context.transformExpression(command);
3657
3771
  }
3658
3772
  return context.superTransformExpression(node);
3659
3773
  },
3660
- [ts13.SyntaxKind.ImportDeclaration]: (node, context) => isEditorFactoryOnlyImport(node) ? [] : context.superTransformStatements(node)
3774
+ [ts14.SyntaxKind.ImportDeclaration]: (node, context) => isEditorFactoryOnlyImport(node) ? [] : context.superTransformStatements(node)
3661
3775
  }
3662
3776
  };
3663
3777
 
3778
+ // src/native-global-modules.ts
3779
+ import * as ts15 from "typescript";
3780
+ var GLOBAL_TABLE_TAG = "globalTable";
3781
+ var GLOBAL_TABLE_REQUIRE_MARKER = "@defold-typescript:global-table:";
3782
+ var NO_RESOLUTION_PREFIX = "@NoResolution:";
3783
+ var LUA_GLOBAL_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
3784
+ function resolveGlobalTableTag(specifier, checker) {
3785
+ if (!ts15.isStringLiteral(specifier)) {
3786
+ return { kind: "untagged" };
3787
+ }
3788
+ const symbol = checker.getSymbolAtLocation(specifier);
3789
+ for (const declaration of symbol?.declarations ?? []) {
3790
+ if (!ts15.isModuleDeclaration(declaration) || !ts15.isStringLiteral(declaration.name)) {
3791
+ continue;
3792
+ }
3793
+ const tag = ts15.getJSDocTags(declaration).find((t) => t.tagName.text === GLOBAL_TABLE_TAG);
3794
+ if (tag === undefined) {
3795
+ continue;
3796
+ }
3797
+ const comment = ts15.getTextOfJSDocComment(tag.comment)?.trim();
3798
+ const globalName = comment === undefined || comment === "" ? specifier.text : comment.split(/\s+/)[0] ?? specifier.text;
3799
+ if (!LUA_GLOBAL_NAME_RE.test(globalName)) {
3800
+ return { kind: "invalid", globalName, moduleId: specifier.text };
3801
+ }
3802
+ return { kind: "tagged", globalName };
3803
+ }
3804
+ return { kind: "untagged" };
3805
+ }
3806
+ function markerRequirePath(globalName) {
3807
+ return `${NO_RESOLUTION_PREFIX}${GLOBAL_TABLE_REQUIRE_MARKER}${globalName}`;
3808
+ }
3809
+ function invalidGlobalName(node, resolution) {
3810
+ const file = node.getSourceFile();
3811
+ const start = node.getStart(file);
3812
+ return {
3813
+ file,
3814
+ start,
3815
+ length: node.getEnd() - start,
3816
+ category: ts15.DiagnosticCategory.Error,
3817
+ code: 0,
3818
+ messageText: `@${GLOBAL_TABLE_TAG} on module "${resolution.moduleId}" names \`${resolution.globalName}\`, which is not a valid Lua global name; use dotted identifiers (\`pixels\`, \`b2d.body\`).`
3819
+ };
3820
+ }
3821
+ var nativeGlobalModulesPlugin = {
3822
+ visitors: {
3823
+ [ts15.SyntaxKind.ImportDeclaration]: (node, context) => {
3824
+ const resolution = resolveGlobalTableTag(node.moduleSpecifier, context.checker);
3825
+ if (resolution.kind === "invalid") {
3826
+ context.diagnostics.push(invalidGlobalName(node.moduleSpecifier, resolution));
3827
+ return context.superTransformStatements(node);
3828
+ }
3829
+ if (resolution.kind === "untagged") {
3830
+ return context.superTransformStatements(node);
3831
+ }
3832
+ if (node.importClause === undefined) {
3833
+ return [];
3834
+ }
3835
+ const rewritten = ts15.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts15.factory.createStringLiteral(markerRequirePath(resolution.globalName)), node.attributes);
3836
+ return context.superTransformStatements(rewritten);
3837
+ },
3838
+ [ts15.SyntaxKind.ExportDeclaration]: (node, context) => {
3839
+ const specifier = node.moduleSpecifier;
3840
+ if (specifier === undefined) {
3841
+ return context.superTransformStatements(node);
3842
+ }
3843
+ const resolution = resolveGlobalTableTag(specifier, context.checker);
3844
+ if (resolution.kind === "invalid") {
3845
+ context.diagnostics.push(invalidGlobalName(specifier, resolution));
3846
+ return context.superTransformStatements(node);
3847
+ }
3848
+ if (resolution.kind === "untagged") {
3849
+ return context.superTransformStatements(node);
3850
+ }
3851
+ const rewritten = ts15.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, ts15.factory.createStringLiteral(markerRequirePath(resolution.globalName)), node.attributes);
3852
+ return context.superTransformStatements(rewritten);
3853
+ },
3854
+ [ts15.SyntaxKind.CallExpression]: (node, context) => {
3855
+ const specifier = node.arguments[0];
3856
+ if (node.expression.kind !== ts15.SyntaxKind.ImportKeyword || specifier === undefined) {
3857
+ return context.superTransformExpression(node);
3858
+ }
3859
+ const resolution = resolveGlobalTableTag(specifier, context.checker);
3860
+ if (resolution.kind === "invalid") {
3861
+ context.diagnostics.push(invalidGlobalName(specifier, resolution));
3862
+ return context.superTransformExpression(node);
3863
+ }
3864
+ if (resolution.kind === "untagged") {
3865
+ return context.superTransformExpression(node);
3866
+ }
3867
+ const rewritten = ts15.factory.updateCallExpression(node, node.expression, node.typeArguments, [
3868
+ ts15.factory.createStringLiteral(markerRequirePath(resolution.globalName)),
3869
+ ...node.arguments.slice(1)
3870
+ ]);
3871
+ return context.superTransformExpression(rewritten);
3872
+ }
3873
+ }
3874
+ };
3875
+ function rewriteGlobalAliasRequires(lua) {
3876
+ let out = "";
3877
+ let cursor = 0;
3878
+ for (const site of scanEmittedRequires(lua)) {
3879
+ if (!site.path.startsWith(GLOBAL_TABLE_REQUIRE_MARKER)) {
3880
+ continue;
3881
+ }
3882
+ if (site.callStart === undefined || site.callEnd === undefined) {
3883
+ continue;
3884
+ }
3885
+ out += lua.slice(cursor, site.callStart);
3886
+ out += `_G.${site.path.slice(GLOBAL_TABLE_REQUIRE_MARKER.length)}`;
3887
+ cursor = site.callEnd;
3888
+ }
3889
+ return out + lua.slice(cursor);
3890
+ }
3891
+ function findGlobalAliasMarkerLeak(lua) {
3892
+ for (const site of scanEmittedRequires(lua)) {
3893
+ if (site.path.startsWith(GLOBAL_TABLE_REQUIRE_MARKER)) {
3894
+ return site.path.slice(GLOBAL_TABLE_REQUIRE_MARKER.length);
3895
+ }
3896
+ }
3897
+ return;
3898
+ }
3899
+
3664
3900
  // src/transpile.ts
3665
3901
  import { readdirSync as readdirSync2, readFileSync } from "node:fs";
3666
3902
  import { createRequire } from "node:module";
@@ -3668,17 +3904,17 @@ import * as path3 from "node:path";
3668
3904
  import * as tstl2 from "typescript-to-lua";
3669
3905
 
3670
3906
  // src/go-property-direct-call.ts
3671
- import * as ts14 from "typescript";
3907
+ import * as ts16 from "typescript";
3672
3908
  var GO_PROPERTY_DIRECT_CALL_MESSAGE = "`go.property` called directly is deprecated; declare the property in `defineScript({ properties })` so it types onto `self` (the transpiler emits the registration for you).";
3673
3909
  function findDirectGoPropertyCalls(sourceFile) {
3674
3910
  const calls = [];
3675
3911
  const visit = (node) => {
3676
- if (ts14.isCallExpression(node) && ts14.isPropertyAccessExpression(node.expression) && node.expression.name.text === "property" && ts14.isIdentifier(node.expression.expression) && node.expression.expression.text === "go") {
3912
+ if (ts16.isCallExpression(node) && ts16.isPropertyAccessExpression(node.expression) && node.expression.name.text === "property" && ts16.isIdentifier(node.expression.expression) && node.expression.expression.text === "go") {
3677
3913
  calls.push(node);
3678
3914
  }
3679
- ts14.forEachChild(node, visit);
3915
+ ts16.forEachChild(node, visit);
3680
3916
  };
3681
- ts14.forEachChild(sourceFile, visit);
3917
+ ts16.forEachChild(sourceFile, visit);
3682
3918
  return calls;
3683
3919
  }
3684
3920
 
@@ -3786,6 +4022,7 @@ function collectOutputs(transpiledFiles, diagnostics, userKeys, emittedCompanion
3786
4022
  const lua = {};
3787
4023
  const sourceMaps = {};
3788
4024
  const companions = {};
4025
+ const markerLeaks = [];
3789
4026
  let lualib;
3790
4027
  for (const file of transpiledFiles) {
3791
4028
  if (isLualibBundle(file) && typeof file.lua === "string") {
@@ -3796,13 +4033,23 @@ function collectOutputs(transpiledFiles, diagnostics, userKeys, emittedCompanion
3796
4033
  if (!userSource || typeof file.lua !== "string") {
3797
4034
  continue;
3798
4035
  }
3799
- lua[userSource.fileName] = file.lua;
4036
+ const swapped = rewriteGlobalAliasRequires(file.lua);
4037
+ lua[userSource.fileName] = swapped;
4038
+ const leaked = findGlobalAliasMarkerLeak(swapped);
4039
+ if (leaked !== undefined) {
4040
+ markerLeaks.push({ file: userSource.fileName, globalName: leaked });
4041
+ }
3800
4042
  if (typeof file.luaSourceMap === "string") {
3801
4043
  sourceMaps[userSource.fileName] = file.luaSourceMap;
3802
4044
  }
3803
4045
  const companion = emittedCompanions.get(userSource.fileName);
3804
4046
  if (companion !== undefined) {
3805
- companions[userSource.fileName] = companion;
4047
+ const swappedCompanion = rewriteGlobalAliasRequires(companion);
4048
+ companions[userSource.fileName] = swappedCompanion;
4049
+ const companionLeak = findGlobalAliasMarkerLeak(swappedCompanion);
4050
+ if (companionLeak !== undefined) {
4051
+ markerLeaks.push({ file: userSource.fileName, globalName: companionLeak });
4052
+ }
3806
4053
  }
3807
4054
  }
3808
4055
  const collectedDiagnostics = diagnostics.map((d) => {
@@ -3817,6 +4064,12 @@ function collectOutputs(transpiledFiles, diagnostics, userKeys, emittedCompanion
3817
4064
  const { line, character } = d.file.getLineAndCharacterOfPosition(d.start);
3818
4065
  return { file: fileName, message, line: line + 1, column: character + 1 };
3819
4066
  });
4067
+ for (const leak of markerLeaks) {
4068
+ collectedDiagnostics.push({
4069
+ file: leak.file,
4070
+ message: `@globalTable lowering left an unrewritten require for \`${leak.globalName}\` in the emitted chunk; the output would fail to load in Defold.`
4071
+ });
4072
+ }
3820
4073
  const scanned = new Set;
3821
4074
  let timersImported = false;
3822
4075
  for (const file of transpiledFiles) {
@@ -3877,6 +4130,7 @@ function transpileVirtual(files, companionEmit, overrides = {}) {
3877
4130
  { plugin: physicsEventGuardLoweringPlugin },
3878
4131
  { plugin: messageDispatchLoweringPlugin },
3879
4132
  { plugin: timersLoweringPlugin },
4133
+ { plugin: nativeGlobalModulesPlugin },
3880
4134
  { plugin: hsmLoweringPlugin },
3881
4135
  { plugin: typeApplicationErasurePlugin },
3882
4136
  { plugin: companionEmit.plugin }
@@ -3968,6 +4222,7 @@ function compilerOptions(companionEmit) {
3968
4222
  { plugin: physicsEventGuardLoweringPlugin },
3969
4223
  { plugin: messageDispatchLoweringPlugin },
3970
4224
  { plugin: timersLoweringPlugin },
4225
+ { plugin: nativeGlobalModulesPlugin },
3971
4226
  { plugin: hsmLoweringPlugin },
3972
4227
  { plugin: typeApplicationErasurePlugin },
3973
4228
  { plugin: companionEmit.plugin }
@@ -4012,7 +4267,7 @@ function createTranspileSession() {
4012
4267
  if (cached) {
4013
4268
  return cached;
4014
4269
  }
4015
- const created = ts15.createSourceFile(fileName, content, ts15.ScriptTarget.Latest, false);
4270
+ const created = ts17.createSourceFile(fileName, content, ts17.ScriptTarget.Latest, false);
4016
4271
  sourceFileCache.set(normalized, created);
4017
4272
  return created;
4018
4273
  }
@@ -4031,7 +4286,7 @@ function createTranspileSession() {
4031
4286
  return cached;
4032
4287
  }
4033
4288
  const fileContent = readFileSync2(filePath, "utf8");
4034
- const created = ts15.createSourceFile(filePath, fileContent, ts15.ScriptTarget.Latest, false);
4289
+ const created = ts17.createSourceFile(filePath, fileContent, ts17.ScriptTarget.Latest, false);
4035
4290
  libCache.set(fileName, created);
4036
4291
  return created;
4037
4292
  }
@@ -4044,10 +4299,10 @@ function createTranspileSession() {
4044
4299
  return AMBIENT_FILES[normalized];
4045
4300
  }
4046
4301
  const host = {
4047
- fileExists: (fileName) => mergedContent(normalizeSlashes(fileName)) !== undefined || ts15.sys.fileExists(fileName),
4302
+ fileExists: (fileName) => mergedContent(normalizeSlashes(fileName)) !== undefined || ts17.sys.fileExists(fileName),
4048
4303
  getCanonicalFileName: (fileName) => fileName,
4049
4304
  getCurrentDirectory: () => "",
4050
- getDefaultLibFileName: ts15.getDefaultLibFileName,
4305
+ getDefaultLibFileName: ts17.getDefaultLibFileName,
4051
4306
  readFile: () => "",
4052
4307
  getNewLine: () => `
4053
4308
  `,
@@ -4069,15 +4324,15 @@ function createTranspileSession() {
4069
4324
  const userKeys = new Set(userFiles.keys());
4070
4325
  const rootNames = [...Object.keys(AMBIENT_FILES).map(normalizeSlashes), ...userKeys];
4071
4326
  const companionEmit = createCompanionEmitPlugin();
4072
- program = ts15.createProgram(rootNames, compilerOptions(companionEmit), host, program);
4073
- const preEmitDiagnostics = ts15.getPreEmitDiagnostics(program);
4327
+ program = ts17.createProgram(rootNames, compilerOptions(companionEmit), host, program);
4328
+ const preEmitDiagnostics = ts17.getPreEmitDiagnostics(program);
4074
4329
  const collector = createOutputCollector();
4075
4330
  const { diagnostics: transpileDiagnostics } = new tstl3.Transpiler().emit({
4076
4331
  program,
4077
4332
  writeFile: collector.writeFile
4078
4333
  });
4079
4334
  const diagnostics = [
4080
- ...ts15.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics])
4335
+ ...ts17.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics])
4081
4336
  ];
4082
4337
  return collectOutputs(collector.files, diagnostics, userKeys, companionEmit.companions);
4083
4338
  }
@@ -4087,7 +4342,7 @@ function createTranspileSession() {
4087
4342
  };
4088
4343
  }
4089
4344
  // src/text-script-property.ts
4090
- import * as ts16 from "typescript";
4345
+ import * as ts18 from "typescript";
4091
4346
  function findTextScriptProperties(program, fileNames) {
4092
4347
  const checker = program.getTypeChecker();
4093
4348
  const findings = [];
@@ -4098,7 +4353,7 @@ function findTextScriptProperties(program, fileNames) {
4098
4353
  }
4099
4354
  const located = [];
4100
4355
  const visit = (node) => {
4101
- if (ts16.isCallExpression(node)) {
4356
+ if (ts18.isCallExpression(node)) {
4102
4357
  const hooks = factoryHooks(node, checker);
4103
4358
  for (const property of hooks?.properties ?? []) {
4104
4359
  if (!isPropertiesHook(property)) {
@@ -4111,7 +4366,7 @@ function findTextScriptProperties(program, fileNames) {
4111
4366
  }
4112
4367
  }
4113
4368
  }
4114
- ts16.forEachChild(node, visit);
4369
+ ts18.forEachChild(node, visit);
4115
4370
  };
4116
4371
  visit(sourceFile);
4117
4372
  for (const call of findDirectGoPropertyCalls(sourceFile)) {
@@ -4120,7 +4375,7 @@ function findTextScriptProperties(program, fileNames) {
4120
4375
  continue;
4121
4376
  }
4122
4377
  if (mayHoldString(checker.getTypeAtLocation(value), checker)) {
4123
- const name = ts16.isStringLiteralLike(nameArgument) ? nameArgument.text : nameArgument.getText(sourceFile);
4378
+ const name = ts18.isStringLiteralLike(nameArgument) ? nameArgument.text : nameArgument.getText(sourceFile);
4124
4379
  located.push({ name, value });
4125
4380
  }
4126
4381
  }
@@ -4137,20 +4392,20 @@ function mayHoldString(type, checker, visited = new Set) {
4137
4392
  return false;
4138
4393
  }
4139
4394
  visited.add(type);
4140
- if (type.flags & ts16.TypeFlags.StringLike) {
4395
+ if (type.flags & ts18.TypeFlags.StringLike) {
4141
4396
  return true;
4142
4397
  }
4143
4398
  if (type.isUnionOrIntersection()) {
4144
4399
  return type.types.some((member) => mayHoldString(member, checker, visited));
4145
4400
  }
4146
- if (type.flags & ts16.TypeFlags.Instantiable) {
4401
+ if (type.flags & ts18.TypeFlags.Instantiable) {
4147
4402
  const constraint = checker.getBaseConstraintOfType(type);
4148
4403
  return constraint !== undefined && constraint !== type ? mayHoldString(constraint, checker, visited) : false;
4149
4404
  }
4150
4405
  return false;
4151
4406
  }
4152
4407
  // src/url-address-slots.ts
4153
- import * as ts17 from "typescript";
4408
+ import * as ts19 from "typescript";
4154
4409
  var ADDRESS_CLASSES = {
4155
4410
  "game-object": true,
4156
4411
  component: true,
@@ -4169,7 +4424,7 @@ function isFragmentCaret(slot, position) {
4169
4424
  return slot.fragmentStart !== -1 && position >= slot.fragmentStart;
4170
4425
  }
4171
4426
  function tableKey(checker, callee) {
4172
- const symbol = checker.getSymbolAtLocation(ts17.isIdentifier(callee) ? callee : callee.name);
4427
+ const symbol = checker.getSymbolAtLocation(ts19.isIdentifier(callee) ? callee : callee.name);
4173
4428
  if (!symbol)
4174
4429
  return;
4175
4430
  const fqn = checker.getFullyQualifiedName(symbol);
@@ -4177,43 +4432,43 @@ function tableKey(checker, callee) {
4177
4432
  }
4178
4433
  function parameterName(checker, call, index) {
4179
4434
  const declaration = checker.getResolvedSignature(call)?.declaration;
4180
- if (!declaration || !ts17.isFunctionLike(declaration))
4435
+ if (!declaration || !ts19.isFunctionLike(declaration))
4181
4436
  return;
4182
4437
  const parameter = declaration.parameters[index];
4183
- if (!parameter || parameter.dotDotDotToken || !ts17.isIdentifier(parameter.name))
4438
+ if (!parameter || parameter.dotDotDotToken || !ts19.isIdentifier(parameter.name))
4184
4439
  return;
4185
4440
  return parameter.name.text;
4186
4441
  }
4187
4442
  var EQUALITY_OPERATORS = new Set([
4188
- ts17.SyntaxKind.EqualsEqualsEqualsToken,
4189
- ts17.SyntaxKind.ExclamationEqualsEqualsToken,
4190
- ts17.SyntaxKind.EqualsEqualsToken,
4191
- ts17.SyntaxKind.ExclamationEqualsToken
4443
+ ts19.SyntaxKind.EqualsEqualsEqualsToken,
4444
+ ts19.SyntaxKind.ExclamationEqualsEqualsToken,
4445
+ ts19.SyntaxKind.EqualsEqualsToken,
4446
+ ts19.SyntaxKind.ExclamationEqualsToken
4192
4447
  ]);
4193
4448
  function comparisonSatisfied(checker, entry, call) {
4194
4449
  if (entry.comparedParameter === undefined)
4195
4450
  return true;
4196
4451
  let node = call;
4197
- while (ts17.isParenthesizedExpression(node.parent))
4452
+ while (ts19.isParenthesizedExpression(node.parent))
4198
4453
  node = node.parent;
4199
4454
  const comparison = node.parent;
4200
- if (!ts17.isBinaryExpression(comparison))
4455
+ if (!ts19.isBinaryExpression(comparison))
4201
4456
  return false;
4202
4457
  if (!EQUALITY_OPERATORS.has(comparison.operatorToken.kind))
4203
4458
  return false;
4204
4459
  const other = comparison.left === node ? comparison.right : comparison.left;
4205
4460
  const symbol = checker.getSymbolAtLocation(other);
4206
- return (symbol?.declarations ?? []).some((declaration) => ts17.isParameter(declaration) && ts17.isIdentifier(declaration.name) && declaration.name.text === entry.comparedParameter);
4461
+ return (symbol?.declarations ?? []).some((declaration) => ts19.isParameter(declaration) && ts19.isIdentifier(declaration.name) && declaration.name.text === entry.comparedParameter);
4207
4462
  }
4208
4463
  function classifiedEntryOfArgument(checker, table, argument) {
4209
4464
  const call = argument.parent;
4210
- if (!ts17.isCallExpression(call))
4465
+ if (!ts19.isCallExpression(call))
4211
4466
  return;
4212
4467
  const argumentIndex = call.arguments.indexOf(argument);
4213
4468
  if (argumentIndex === -1)
4214
4469
  return;
4215
4470
  const callee = call.expression;
4216
- if (!ts17.isPropertyAccessExpression(callee) && !ts17.isIdentifier(callee))
4471
+ if (!ts19.isPropertyAccessExpression(callee) && !ts19.isIdentifier(callee))
4217
4472
  return;
4218
4473
  const fqn = tableKey(checker, callee);
4219
4474
  if (fqn === undefined)
@@ -4230,10 +4485,10 @@ function classifiedEntryOfArgument(checker, table, argument) {
4230
4485
  }
4231
4486
  function slotThroughHashedCall(checker, table, literal) {
4232
4487
  const call = literal.parent;
4233
- if (!ts17.isCallExpression(call))
4488
+ if (!ts19.isCallExpression(call))
4234
4489
  return;
4235
4490
  const callee = call.expression;
4236
- if (!ts17.isPropertyAccessExpression(callee) && !ts17.isIdentifier(callee))
4491
+ if (!ts19.isPropertyAccessExpression(callee) && !ts19.isIdentifier(callee))
4237
4492
  return;
4238
4493
  if (tableKey(checker, callee) !== "hash")
4239
4494
  return;
@@ -4251,24 +4506,24 @@ function addressTextOf(checker, entry, call) {
4251
4506
  if (entry.addressParameter === undefined)
4252
4507
  return;
4253
4508
  const declaration = checker.getResolvedSignature(call)?.declaration;
4254
- if (!declaration || !ts17.isFunctionLike(declaration))
4509
+ if (!declaration || !ts19.isFunctionLike(declaration))
4255
4510
  return;
4256
- const index = declaration.parameters.findIndex((parameter) => !parameter.dotDotDotToken && ts17.isIdentifier(parameter.name) && parameter.name.text === entry.addressParameter);
4511
+ const index = declaration.parameters.findIndex((parameter) => !parameter.dotDotDotToken && ts19.isIdentifier(parameter.name) && parameter.name.text === entry.addressParameter);
4257
4512
  if (index === -1)
4258
4513
  return;
4259
4514
  const argument = call.arguments[index];
4260
- return argument && ts17.isStringLiteralLike(argument) ? argument.text : undefined;
4515
+ return argument && ts19.isStringLiteralLike(argument) ? argument.text : undefined;
4261
4516
  }
4262
4517
  function innermostLiteralAt(sourceFile, position) {
4263
4518
  let found;
4264
4519
  const visit = (node) => {
4265
4520
  if (position < node.getStart(sourceFile) || position > node.getEnd())
4266
4521
  return;
4267
- if (ts17.isStringLiteralLike(node))
4522
+ if (ts19.isStringLiteralLike(node))
4268
4523
  found = node;
4269
- ts17.forEachChild(node, visit);
4524
+ ts19.forEachChild(node, visit);
4270
4525
  };
4271
- ts17.forEachChild(sourceFile, visit);
4526
+ ts19.forEachChild(sourceFile, visit);
4272
4527
  return found;
4273
4528
  }
4274
4529
  function resolveClassifiedSlotAtPosition(input) {
@@ -4302,23 +4557,23 @@ function resolveClassifiedSlotAtPosition(input) {
4302
4557
  };
4303
4558
  }
4304
4559
  // src/url-cross-world-address.ts
4305
- import * as ts19 from "typescript";
4560
+ import * as ts21 from "typescript";
4306
4561
 
4307
4562
  // src/url-address-literals.ts
4308
- import * as ts18 from "typescript";
4563
+ import * as ts20 from "typescript";
4309
4564
  function isAmbient2(fileName) {
4310
4565
  return /[\\/]node_modules[\\/]/.test(fileName) || /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(fileName);
4311
4566
  }
4312
4567
  function referenceTargetSymbol(type) {
4313
- if ((type.flags & ts18.TypeFlags.Object) === 0)
4568
+ if ((type.flags & ts20.TypeFlags.Object) === 0)
4314
4569
  return;
4315
- if ((type.objectFlags & ts18.ObjectFlags.Reference) === 0)
4570
+ if ((type.objectFlags & ts20.ObjectFlags.Reference) === 0)
4316
4571
  return;
4317
4572
  return type.target.symbol;
4318
4573
  }
4319
4574
  function ambientHashAliasTargets(checker, anchor) {
4320
4575
  const targets = new Set;
4321
- for (const symbol of checker.getSymbolsInScope(anchor, ts18.SymbolFlags.Type)) {
4576
+ for (const symbol of checker.getSymbolsInScope(anchor, ts20.SymbolFlags.Type)) {
4322
4577
  if (symbol.name !== "Hash")
4323
4578
  continue;
4324
4579
  const target = referenceTargetSymbol(checker.getDeclaredTypeOfSymbol(symbol));
@@ -4334,7 +4589,7 @@ function canonicalHashSymbols(checker, program) {
4334
4589
  if (!anchor)
4335
4590
  return canonical;
4336
4591
  const aliased = ambientHashAliasTargets(checker, anchor);
4337
- for (const symbol of checker.getSymbolsInScope(anchor, ts18.SymbolFlags.Function)) {
4592
+ for (const symbol of checker.getSymbolsInScope(anchor, ts20.SymbolFlags.Function)) {
4338
4593
  if (symbol.name !== "hash")
4339
4594
  continue;
4340
4595
  const declaration = symbol.declarations?.[0];
@@ -4356,7 +4611,7 @@ function hashedSourceOfType(checker, type, canonical) {
4356
4611
  return source?.isStringLiteral() ? source.value : undefined;
4357
4612
  }
4358
4613
  function staticAddressTextOf(checker, node, canonical) {
4359
- return ts18.isStringLiteralLike(node) ? node.text : hashedSourceOfType(checker, checker.getTypeAtLocation(node), canonical);
4614
+ return ts20.isStringLiteralLike(node) ? node.text : hashedSourceOfType(checker, checker.getTypeAtLocation(node), canonical);
4360
4615
  }
4361
4616
 
4362
4617
  // src/url-cross-world-address.ts
@@ -4380,7 +4635,7 @@ function checkCrossWorldAddresses(input) {
4380
4635
  if (worlds.length === 0)
4381
4636
  continue;
4382
4637
  const visit = (node) => {
4383
- if (ts19.isExpression(node)) {
4638
+ if (ts21.isExpression(node)) {
4384
4639
  const entry = addressEntryOfArgument(checker, table, node);
4385
4640
  if (entry !== undefined && slotRejectsForeignSocket(entry)) {
4386
4641
  const address = staticAddressTextOf(checker, node, canonical);
@@ -4397,14 +4652,14 @@ function checkCrossWorldAddresses(input) {
4397
4652
  }
4398
4653
  }
4399
4654
  }
4400
- ts19.forEachChild(node, visit);
4655
+ ts21.forEachChild(node, visit);
4401
4656
  };
4402
- ts19.forEachChild(sourceFile, visit);
4657
+ ts21.forEachChild(sourceFile, visit);
4403
4658
  }
4404
4659
  return findings;
4405
4660
  }
4406
4661
  // src/url-fragment-reachability.ts
4407
- import * as ts20 from "typescript";
4662
+ import * as ts22 from "typescript";
4408
4663
  function pathOfKey(key) {
4409
4664
  const socket = socketOfAddress(key);
4410
4665
  return socket === undefined ? key : key.slice(socket.length + 1);
@@ -4449,7 +4704,7 @@ function checkUrlFragmentReachability(input) {
4449
4704
  if (isAmbient2(sourceFile.fileName))
4450
4705
  continue;
4451
4706
  const visit = (node) => {
4452
- if (ts20.isExpression(node) && isAddressClass(addressClassOfArgument(checker, table, node))) {
4707
+ if (ts22.isExpression(node) && isAddressClass(addressClassOfArgument(checker, table, node))) {
4453
4708
  const text = staticAddressTextOf(checker, node, canonical);
4454
4709
  if (text !== undefined) {
4455
4710
  const hash = text.indexOf("#");
@@ -4468,9 +4723,9 @@ function checkUrlFragmentReachability(input) {
4468
4723
  }
4469
4724
  }
4470
4725
  }
4471
- ts20.forEachChild(node, visit);
4726
+ ts22.forEachChild(node, visit);
4472
4727
  };
4473
- ts20.forEachChild(sourceFile, visit);
4728
+ ts22.forEachChild(sourceFile, visit);
4474
4729
  }
4475
4730
  return { kind: "checked", findings };
4476
4731
  }
@@ -4478,6 +4733,9 @@ export {
4478
4733
  ANIMATION_ASSET_EXTENSIONS,
4479
4734
  COLLECTION_REFERENCE_EXTENSIONS,
4480
4735
  COMPANION_INTERNAL_FIELD,
4736
+ DEBUG_BLOCK_BEGIN,
4737
+ DEBUG_BLOCK_END,
4738
+ DEBUG_MANAGED_BLOCK,
4481
4739
  DEFAULT_INCLUDE,
4482
4740
  GAME_PROJECT_DOCUMENT,
4483
4741
  GUI_EXTENSIONS,
@@ -4518,6 +4776,7 @@ export {
4518
4776
  displayPathOf,
4519
4777
  findEmittedRequires,
4520
4778
  findMainEntryFactoryImports,
4779
+ findManagedBootstrap,
4521
4780
  findTextScriptProperties,
4522
4781
  getProgramDiagnostics,
4523
4782
  guiScriptResourceOf,