@defold-typescript/transpiler 0.51.0 → 0.53.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
  }
@@ -172,69 +217,73 @@ var FACTORY_SPECIFIERS = new Set([
172
217
  `${FACTORY_MODULE}/gui-script`,
173
218
  `${FACTORY_MODULE}/render-script`
174
219
  ]);
175
- function resolvesToFactoryExport(callee, checker) {
220
+ function factoryExportName(callee, checker) {
176
221
  let symbol = checker.getSymbolAtLocation(callee);
177
222
  if (symbol === undefined) {
178
- return false;
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
- if (!FACTORY_NAMES.has(symbol.getName())) {
184
- return false;
228
+ const name = symbol.getName();
229
+ if (!FACTORY_NAMES.has(name)) {
230
+ return;
185
231
  }
186
232
  const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
187
233
  if (declaration === undefined) {
188
- return false;
234
+ return;
189
235
  }
190
- return declaration.getSourceFile().fileName.includes(FACTORY_MODULE);
236
+ return declaration.getSourceFile().fileName.includes(FACTORY_MODULE) ? name : undefined;
237
+ }
238
+ function resolvesToFactoryExport(callee, checker) {
239
+ return factoryExportName(callee, checker) !== undefined;
191
240
  }
192
241
  function isThisParameter2(param) {
193
- 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;
194
243
  }
195
244
  function hookName(property) {
196
245
  const name = property.name;
197
246
  if (name === undefined) {
198
247
  return;
199
248
  }
200
- if (ts2.isIdentifier(name) || ts2.isStringLiteral(name)) {
249
+ if (ts3.isIdentifier(name) || ts3.isStringLiteral(name)) {
201
250
  return name.text;
202
251
  }
203
252
  return;
204
253
  }
205
254
  function hookFunction(property) {
206
- if (ts2.isMethodDeclaration(property) && property.body !== undefined) {
255
+ if (ts3.isMethodDeclaration(property) && property.body !== undefined) {
207
256
  return property;
208
257
  }
209
- if (ts2.isPropertyAssignment(property)) {
258
+ if (ts3.isPropertyAssignment(property)) {
210
259
  const initializer = property.initializer;
211
- if (ts2.isFunctionExpression(initializer) || ts2.isArrowFunction(initializer)) {
260
+ if (ts3.isFunctionExpression(initializer) || ts3.isArrowFunction(initializer)) {
212
261
  return initializer;
213
262
  }
214
263
  }
215
264
  return;
216
265
  }
217
266
  function dispatcherInitializer(property, checker) {
218
- if (!ts2.isPropertyAssignment(property)) {
267
+ if (!ts3.isPropertyAssignment(property)) {
219
268
  return;
220
269
  }
221
270
  const initializer = property.initializer;
222
- if (!ts2.isCallExpression(initializer)) {
271
+ if (!ts3.isCallExpression(initializer)) {
223
272
  return;
224
273
  }
225
274
  return resolvesToDispatchExport(initializer.expression, checker) ? initializer : undefined;
226
275
  }
227
276
  function transformHookBody(fn, context) {
228
- if (ts2.isBlock(fn.body)) {
277
+ if (ts3.isBlock(fn.body)) {
229
278
  return context.transformStatements(fn.body.statements);
230
279
  }
231
280
  return [createExpressionStatement(context.transformExpression(fn.body))];
232
281
  }
233
282
  function crossesFunctionBoundary(node) {
234
- 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);
235
284
  }
236
285
  function initReturnsValue(fn) {
237
- if (!ts2.isBlock(fn.body)) {
286
+ if (!ts3.isBlock(fn.body)) {
238
287
  return true;
239
288
  }
240
289
  let found = false;
@@ -242,23 +291,23 @@ function initReturnsValue(fn) {
242
291
  if (found || crossesFunctionBoundary(node)) {
243
292
  return;
244
293
  }
245
- if (ts2.isReturnStatement(node) && node.expression !== undefined) {
294
+ if (ts3.isReturnStatement(node) && node.expression !== undefined) {
246
295
  found = true;
247
296
  return;
248
297
  }
249
- ts2.forEachChild(node, visit);
298
+ ts3.forEachChild(node, visit);
250
299
  };
251
- ts2.forEachChild(fn.body, visit);
300
+ ts3.forEachChild(fn.body, visit);
252
301
  return found;
253
302
  }
254
303
  function initBuilderBody(fn, context) {
255
- if (ts2.isBlock(fn.body)) {
304
+ if (ts3.isBlock(fn.body)) {
256
305
  return context.transformStatements(fn.body.statements);
257
306
  }
258
307
  return [createReturnStatement([context.transformExpression(fn.body)])];
259
308
  }
260
309
  function emitInitMerge(fn, context, property) {
261
- 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));
262
311
  const builderParams = authorParam === undefined ? [] : [context.transformExpression(authorParam.name)];
263
312
  const builder = createFunctionExpression2(createBlock2(initBuilderBody(fn, context)), builderParams, undefined, NodeFlags2.Declaration, fn);
264
313
  const builderDecl = createVariableDeclarationStatement2(createIdentifier2("____init"), builder);
@@ -266,21 +315,30 @@ function emitInitMerge(fn, context, property) {
266
315
  const stateDecl = createVariableDeclarationStatement2(createIdentifier2("____s"), createCallExpression2(createIdentifier2("____init"), builderArgs));
267
316
  const mergeAssignment = createAssignmentStatement(createTableIndexExpression(createIdentifier2("self"), createIdentifier2("____k")), createIdentifier2("____v"));
268
317
  const forIn = createForInStatement(createBlock2([mergeAssignment]), [createIdentifier2("____k"), createIdentifier2("____v")], [createCallExpression2(createIdentifier2("pairs"), [createIdentifier2("____s")])]);
269
- const guard = createIfStatement2(createBinaryExpression2(createIdentifier2("____s"), createNilLiteral(), SyntaxKind4.InequalityOperator), createBlock2([forIn]));
318
+ const guard = createIfStatement2(createBinaryExpression2(createIdentifier2("____s"), createNilLiteral(), SyntaxKind5.InequalityOperator), createBlock2([forIn]));
270
319
  const initFn = createFunctionExpression2(createBlock2([stateDecl, guard]), [createIdentifier2("self")], undefined, NodeFlags2.Declaration, fn);
271
320
  return [builderDecl, createAssignmentStatement(createIdentifier2("init"), initFn, property)];
272
321
  }
322
+ var RESOURCE_PROPERTY_MARKERS = new Set([
323
+ "resource.atlas",
324
+ "resource.buffer",
325
+ "resource.font",
326
+ "resource.material",
327
+ "resource.render_target",
328
+ "resource.texture",
329
+ "resource.tile_source"
330
+ ]);
273
331
  function propertyMembers(property) {
274
- if (!ts2.isPropertyAssignment(property) || !ts2.isObjectLiteralExpression(property.initializer)) {
332
+ if (!ts3.isPropertyAssignment(property) || !ts3.isObjectLiteralExpression(property.initializer)) {
275
333
  return [];
276
334
  }
277
335
  const members = [];
278
336
  for (const member of property.initializer.properties) {
279
- if (!ts2.isPropertyAssignment(member)) {
337
+ if (!ts3.isPropertyAssignment(member)) {
280
338
  continue;
281
339
  }
282
340
  const key = member.name;
283
- if (!ts2.isIdentifier(key) && !ts2.isStringLiteral(key)) {
341
+ if (!ts3.isIdentifier(key) && !ts3.isStringLiteral(key)) {
284
342
  continue;
285
343
  }
286
344
  members.push({ name: key.text, initializer: member.initializer });
@@ -288,14 +346,14 @@ function propertyMembers(property) {
288
346
  return members;
289
347
  }
290
348
  function factoryHooks(expression, checker) {
291
- if (!ts2.isCallExpression(expression)) {
349
+ if (!ts3.isCallExpression(expression)) {
292
350
  return;
293
351
  }
294
352
  if (!resolvesToFactoryExport(expression.expression, checker)) {
295
353
  return;
296
354
  }
297
355
  const hooks = expression.arguments[0];
298
- if (hooks === undefined || !ts2.isObjectLiteralExpression(hooks)) {
356
+ if (hooks === undefined || !ts3.isObjectLiteralExpression(hooks)) {
299
357
  return;
300
358
  }
301
359
  return hooks;
@@ -306,11 +364,108 @@ function isPropertiesHook(property) {
306
364
  function emitPropertyRegistrations(property, context) {
307
365
  return propertyMembers(property).map(({ name, initializer }) => createExpressionStatement(createCallExpression2(createTableIndexExpression(createIdentifier2("go"), createStringLiteral2("property")), [createStringLiteral2(name), context.transformExpression(initializer)])));
308
366
  }
367
+ function scriptOnlyProperties(property, factory) {
368
+ const file = property.getSourceFile();
369
+ const start = property.getStart(file);
370
+ return {
371
+ file,
372
+ start,
373
+ length: property.getEnd() - start,
374
+ category: ts3.DiagnosticCategory.Error,
375
+ code: 0,
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\`.`
377
+ };
378
+ }
379
+ function outermostWrapper(node) {
380
+ let current = node;
381
+ while (ts3.isParenthesizedExpression(current.parent) || ts3.isAsExpression(current.parent) || ts3.isSatisfiesExpression(current.parent) || ts3.isNonNullExpression(current.parent) || ts3.isTypeAssertionExpression(current.parent)) {
382
+ current = current.parent;
383
+ }
384
+ return current;
385
+ }
386
+ function innermostExpression(node) {
387
+ let current = node;
388
+ while (ts3.isParenthesizedExpression(current) || ts3.isAsExpression(current) || ts3.isSatisfiesExpression(current) || ts3.isNonNullExpression(current) || ts3.isTypeAssertionExpression(current)) {
389
+ current = current.expression;
390
+ }
391
+ return current;
392
+ }
393
+ function globalName(symbol, checker) {
394
+ if (symbol === undefined) {
395
+ return;
396
+ }
397
+ const fqn = checker.getFullyQualifiedName(symbol);
398
+ return fqn.startsWith("global.") ? fqn.slice("global.".length) : undefined;
399
+ }
400
+ function calledGlobal(call, checker) {
401
+ const declaration = checker.getResolvedSignature(call)?.declaration;
402
+ if (declaration === undefined || !ts3.isFunctionDeclaration(declaration) || declaration.name === undefined) {
403
+ return;
404
+ }
405
+ return globalName(checker.getSymbolAtLocation(declaration.name), checker);
406
+ }
407
+ function isPropertyDefault(call, checker) {
408
+ const value = outermostWrapper(call);
409
+ const parent = value.parent;
410
+ if (ts3.isCallExpression(parent)) {
411
+ return parent.arguments[1] === value && calledGlobal(parent, checker) === "go.property";
412
+ }
413
+ const properties = parent?.parent?.parent;
414
+ if (properties === undefined || !ts3.isPropertyAssignment(properties) || !isPropertiesHook(properties)) {
415
+ return false;
416
+ }
417
+ const hooks = properties.parent;
418
+ return ts3.isObjectLiteralExpression(hooks) && factoryHooks(hooks.parent, checker) === hooks && propertyMembers(properties).some((member) => member.initializer === value);
419
+ }
420
+ function misplacedMarker(node, marker) {
421
+ const file = node.getSourceFile();
422
+ const start = node.getStart(file);
423
+ return {
424
+ file,
425
+ start,
426
+ length: node.getEnd() - start,
427
+ category: ts3.DiagnosticCategory.Error,
428
+ code: 0,
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.`
430
+ };
431
+ }
432
+ function readsAsMarker(call) {
433
+ const callee = innermostExpression(call.expression);
434
+ if (ts3.isOptionalChain(call) || ts3.isOptionalChain(callee)) {
435
+ return false;
436
+ }
437
+ if (!ts3.isPropertyAccessExpression(callee) && !(ts3.isElementAccessExpression(callee) && ts3.isStringLiteralLike(innermostExpression(callee.argumentExpression)))) {
438
+ return false;
439
+ }
440
+ const receiver = innermostExpression(callee.expression);
441
+ if (!ts3.isIdentifier(receiver) || receiver.text !== "resource") {
442
+ return false;
443
+ }
444
+ const [path] = call.arguments;
445
+ return path === undefined || ts3.isStringLiteralLike(innermostExpression(path));
446
+ }
447
+ function unreadableMarker(node, marker) {
448
+ const file = node.getSourceFile();
449
+ const start = node.getStart(file);
450
+ return {
451
+ file,
452
+ start,
453
+ length: node.getEnd() - start,
454
+ category: ts3.DiagnosticCategory.Error,
455
+ code: 0,
456
+ messageText: `\`${marker}\` in a property default must be written \`${marker}("<path>")\`, with a string literal path: Defold's build reads no other form.`
457
+ };
458
+ }
459
+ function isCallee(node) {
460
+ const callee = outermostWrapper(node);
461
+ return ts3.isCallExpression(callee.parent) && callee.parent.expression === callee;
462
+ }
309
463
  function eraseFactoryCall(expression, context) {
310
464
  const hooks = factoryHooks(expression, context.checker);
311
- if (hooks === undefined) {
465
+ if (hooks === undefined || !ts3.isCallExpression(expression)) {
312
466
  return;
313
467
  }
468
+ const factory = factoryExportName(expression.expression, context.checker);
314
469
  const registrations = [];
315
470
  const statements = [];
316
471
  for (const property of hooks.properties) {
@@ -319,7 +474,11 @@ function eraseFactoryCall(expression, context) {
319
474
  continue;
320
475
  }
321
476
  if (name === "properties") {
322
- registrations.push(...emitPropertyRegistrations(property, context));
477
+ if (factory === "defineScript") {
478
+ registrations.push(...emitPropertyRegistrations(property, context));
479
+ } else if (factory !== undefined && propertyMembers(property).length > 0) {
480
+ context.diagnostics.push(scriptOnlyProperties(property, factory));
481
+ }
323
482
  continue;
324
483
  }
325
484
  const fn = hookFunction(property);
@@ -334,14 +493,14 @@ function eraseFactoryCall(expression, context) {
334
493
  statements.push(...emitInitMerge(fn, context, property));
335
494
  continue;
336
495
  }
337
- 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));
338
497
  const fnExpression = createFunctionExpression2(createBlock2(transformHookBody(fn, context)), params, undefined, NodeFlags2.Declaration, fn);
339
498
  statements.push(createAssignmentStatement(createIdentifier2(name), fnExpression, property));
340
499
  }
341
500
  return [...registrations, ...statements];
342
501
  }
343
502
  function isFactoryOnlyImport(node) {
344
- if (!ts2.isStringLiteral(node.moduleSpecifier) || !FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
503
+ if (!ts3.isStringLiteral(node.moduleSpecifier) || !FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
345
504
  return false;
346
505
  }
347
506
  const clause = node.importClause;
@@ -352,7 +511,7 @@ function isFactoryOnlyImport(node) {
352
511
  return false;
353
512
  }
354
513
  const bindings = clause.namedBindings;
355
- if (bindings === undefined || !ts2.isNamedImports(bindings)) {
514
+ if (bindings === undefined || !ts3.isNamedImports(bindings)) {
356
515
  return false;
357
516
  }
358
517
  const runtime = bindings.elements.filter((element) => !element.isTypeOnly);
@@ -363,8 +522,8 @@ function isFactoryOnlyImport(node) {
363
522
  }
364
523
  var lifecycleErasurePlugin = {
365
524
  visitors: {
366
- [ts2.SyntaxKind.ExpressionStatement]: (node, context) => eraseFactoryCall(node.expression, context) ?? context.superTransformStatements(node),
367
- [ts2.SyntaxKind.ExportAssignment]: (node, context) => {
525
+ [ts3.SyntaxKind.ExpressionStatement]: (node, context) => eraseFactoryCall(node.expression, context) ?? context.superTransformStatements(node),
526
+ [ts3.SyntaxKind.ExportAssignment]: (node, context) => {
368
527
  if (!node.isExportEquals) {
369
528
  const erased = eraseFactoryCall(node.expression, context);
370
529
  if (erased !== undefined) {
@@ -373,19 +532,49 @@ var lifecycleErasurePlugin = {
373
532
  }
374
533
  return context.superTransformStatements(node);
375
534
  },
376
- [ts2.SyntaxKind.ImportDeclaration]: (node, context) => isFactoryOnlyImport(node) ? [] : context.superTransformStatements(node)
535
+ [ts3.SyntaxKind.ImportDeclaration]: (node, context) => isFactoryOnlyImport(node) ? [] : context.superTransformStatements(node),
536
+ [ts3.SyntaxKind.CallExpression]: (node, context) => {
537
+ const marker = node.parent === undefined ? undefined : calledGlobal(node, context.checker);
538
+ if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
539
+ if (!isPropertyDefault(node, context.checker)) {
540
+ context.diagnostics.push(misplacedMarker(node, marker));
541
+ } else if (!readsAsMarker(node)) {
542
+ context.diagnostics.push(unreadableMarker(node, marker));
543
+ }
544
+ }
545
+ return context.superTransformExpression(node);
546
+ },
547
+ [ts3.SyntaxKind.PropertyAccessExpression]: (node, context) => {
548
+ if (node.parent !== undefined && !isCallee(node)) {
549
+ const marker = globalName(context.checker.getSymbolAtLocation(node.name), context.checker);
550
+ if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
551
+ context.diagnostics.push(misplacedMarker(node, marker));
552
+ }
553
+ }
554
+ return context.superTransformExpression(node);
555
+ },
556
+ [ts3.SyntaxKind.ElementAccessExpression]: (node, context) => {
557
+ if (node.parent !== undefined && !isCallee(node)) {
558
+ const key = innermostExpression(node.argumentExpression);
559
+ const marker = ts3.isStringLiteralLike(key) ? globalName(context.checker.getPropertyOfType(context.checker.getTypeAtLocation(node.expression), key.text), context.checker) : undefined;
560
+ if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
561
+ context.diagnostics.push(misplacedMarker(node, marker));
562
+ }
563
+ }
564
+ return context.superTransformExpression(node);
565
+ }
377
566
  }
378
567
  };
379
568
 
380
569
  // src/companion-closure.ts
381
570
  var COMPANION_INTERNAL_FIELD = "____closure";
382
571
  function isAssignmentOperator(kind) {
383
- return kind >= ts3.SyntaxKind.FirstAssignment && kind <= ts3.SyntaxKind.LastAssignment;
572
+ return kind >= ts4.SyntaxKind.FirstAssignment && kind <= ts4.SyntaxKind.LastAssignment;
384
573
  }
385
574
  function isTypePosition(node) {
386
575
  let current = node.parent;
387
- while (current !== undefined && !ts3.isSourceFile(current)) {
388
- if (ts3.isTypeNode(current)) {
576
+ while (current !== undefined && !ts4.isSourceFile(current)) {
577
+ if (ts4.isTypeNode(current)) {
389
578
  return true;
390
579
  }
391
580
  current = current.parent;
@@ -397,57 +586,57 @@ function isDeclarationName(node) {
397
586
  if (parent === undefined) {
398
587
  return false;
399
588
  }
400
- if (ts3.isPropertyAccessExpression(parent)) {
589
+ if (ts4.isPropertyAccessExpression(parent)) {
401
590
  return parent.name === node;
402
591
  }
403
- if (ts3.isQualifiedName(parent)) {
592
+ if (ts4.isQualifiedName(parent)) {
404
593
  return parent.right === node;
405
594
  }
406
- 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) {
407
596
  return true;
408
597
  }
409
598
  const named = parent;
410
599
  if (named.name !== node) {
411
600
  return false;
412
601
  }
413
- 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);
414
603
  }
415
604
  function forEachReference(root, checker, visit) {
416
605
  const walk = (node) => {
417
- if (ts3.isIdentifier(node) && !isDeclarationName(node) && !isTypePosition(node)) {
606
+ if (ts4.isIdentifier(node) && !isDeclarationName(node) && !isTypePosition(node)) {
418
607
  const symbol = resolveReferencedSymbol(node, checker);
419
608
  if (symbol !== undefined) {
420
609
  visit(node, symbol);
421
610
  }
422
611
  }
423
- ts3.forEachChild(node, walk);
612
+ ts4.forEachChild(node, walk);
424
613
  };
425
614
  walk(root);
426
615
  }
427
616
  function resolveReferencedSymbol(node, checker) {
428
617
  const parent = node.parent;
429
- if (parent !== undefined && ts3.isShorthandPropertyAssignment(parent) && parent.name === node) {
618
+ if (parent !== undefined && ts4.isShorthandPropertyAssignment(parent) && parent.name === node) {
430
619
  return checker.getShorthandAssignmentValueSymbol(parent) ?? checker.getSymbolAtLocation(node);
431
620
  }
432
621
  return checker.getSymbolAtLocation(node);
433
622
  }
434
623
  function forEachAssignmentTarget(root, checker, visit) {
435
624
  const classify = (target) => {
436
- if (ts3.isParenthesizedExpression(target)) {
625
+ if (ts4.isParenthesizedExpression(target)) {
437
626
  classify(target.expression);
438
627
  return;
439
628
  }
440
- if (ts3.isPropertyAccessExpression(target) || ts3.isElementAccessExpression(target)) {
629
+ if (ts4.isPropertyAccessExpression(target) || ts4.isElementAccessExpression(target)) {
441
630
  return;
442
631
  }
443
- if (ts3.isArrayLiteralExpression(target)) {
632
+ if (ts4.isArrayLiteralExpression(target)) {
444
633
  for (const element of target.elements) {
445
- if (ts3.isOmittedExpression(element)) {
634
+ if (ts4.isOmittedExpression(element)) {
446
635
  continue;
447
636
  }
448
- if (ts3.isSpreadElement(element)) {
637
+ if (ts4.isSpreadElement(element)) {
449
638
  classify(element.expression);
450
- } else if (ts3.isBinaryExpression(element) && element.operatorToken.kind === ts3.SyntaxKind.EqualsToken) {
639
+ } else if (ts4.isBinaryExpression(element) && element.operatorToken.kind === ts4.SyntaxKind.EqualsToken) {
451
640
  classify(element.left);
452
641
  } else {
453
642
  classify(element);
@@ -455,13 +644,13 @@ function forEachAssignmentTarget(root, checker, visit) {
455
644
  }
456
645
  return;
457
646
  }
458
- if (ts3.isObjectLiteralExpression(target)) {
647
+ if (ts4.isObjectLiteralExpression(target)) {
459
648
  for (const property of target.properties) {
460
- if (ts3.isPropertyAssignment(property)) {
649
+ if (ts4.isPropertyAssignment(property)) {
461
650
  classify(property.initializer);
462
- } else if (ts3.isSpreadAssignment(property)) {
651
+ } else if (ts4.isSpreadAssignment(property)) {
463
652
  classify(property.expression);
464
- } else if (ts3.isShorthandPropertyAssignment(property)) {
653
+ } else if (ts4.isShorthandPropertyAssignment(property)) {
465
654
  const symbol = checker.getShorthandAssignmentValueSymbol(property);
466
655
  if (symbol !== undefined) {
467
656
  visit(property.name, symbol);
@@ -470,7 +659,7 @@ function forEachAssignmentTarget(root, checker, visit) {
470
659
  }
471
660
  return;
472
661
  }
473
- if (ts3.isIdentifier(target)) {
662
+ if (ts4.isIdentifier(target)) {
474
663
  const symbol = checker.getSymbolAtLocation(target);
475
664
  if (symbol !== undefined) {
476
665
  visit(target, symbol);
@@ -478,14 +667,14 @@ function forEachAssignmentTarget(root, checker, visit) {
478
667
  }
479
668
  };
480
669
  const walk = (node) => {
481
- if (ts3.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
670
+ if (ts4.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
482
671
  classify(node.left);
483
- } 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)) {
484
673
  classify(node.operand);
485
- } 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)) {
486
675
  classify(node.initializer);
487
676
  }
488
- ts3.forEachChild(node, walk);
677
+ ts4.forEachChild(node, walk);
489
678
  };
490
679
  walk(root);
491
680
  }
@@ -493,7 +682,7 @@ function collectTopLevel(sourceFile, checker) {
493
682
  const declarations = new Map;
494
683
  let order = 0;
495
684
  const add = (name, statement, node) => {
496
- if (name === undefined || !ts3.isIdentifier(name)) {
685
+ if (name === undefined || !ts4.isIdentifier(name)) {
497
686
  return;
498
687
  }
499
688
  const symbol = checker.getSymbolAtLocation(name);
@@ -503,24 +692,24 @@ function collectTopLevel(sourceFile, checker) {
503
692
  declarations.set(symbol, { name: name.text, statement, node, order: order++ });
504
693
  };
505
694
  const addBinding = (name, statement, node) => {
506
- if (ts3.isIdentifier(name)) {
695
+ if (ts4.isIdentifier(name)) {
507
696
  add(name, statement, node);
508
697
  return;
509
698
  }
510
699
  for (const element of name.elements) {
511
- if (ts3.isBindingElement(element)) {
700
+ if (ts4.isBindingElement(element)) {
512
701
  addBinding(element.name, statement, node);
513
702
  }
514
703
  }
515
704
  };
516
705
  for (const statement of sourceFile.statements) {
517
- if (ts3.isVariableStatement(statement)) {
706
+ if (ts4.isVariableStatement(statement)) {
518
707
  for (const declaration of statement.declarationList.declarations) {
519
708
  addBinding(declaration.name, statement, declaration);
520
709
  }
521
- } else if (ts3.isFunctionDeclaration(statement) || ts3.isClassDeclaration(statement) || ts3.isEnumDeclaration(statement)) {
710
+ } else if (ts4.isFunctionDeclaration(statement) || ts4.isClassDeclaration(statement) || ts4.isEnumDeclaration(statement)) {
522
711
  add(statement.name, statement, statement);
523
- } else if (ts3.isImportDeclaration(statement)) {
712
+ } else if (ts4.isImportDeclaration(statement)) {
524
713
  const clause = statement.importClause;
525
714
  if (clause === undefined) {
526
715
  continue;
@@ -530,7 +719,7 @@ function collectTopLevel(sourceFile, checker) {
530
719
  if (bindings === undefined) {
531
720
  continue;
532
721
  }
533
- if (ts3.isNamespaceImport(bindings)) {
722
+ if (ts4.isNamespaceImport(bindings)) {
534
723
  add(bindings.name, statement, statement);
535
724
  } else {
536
725
  for (const element of bindings.elements) {
@@ -542,14 +731,14 @@ function collectTopLevel(sourceFile, checker) {
542
731
  return declarations;
543
732
  }
544
733
  function hasExportModifier(statement) {
545
- 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);
546
735
  }
547
736
  function isValueSymbol(symbol, checker) {
548
737
  if (symbol === undefined) {
549
738
  return false;
550
739
  }
551
- const resolved = symbol.flags & ts3.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
552
- 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;
553
742
  }
554
743
  function collectExports(sourceFile, checker, topLevel) {
555
744
  const exported = [];
@@ -577,12 +766,12 @@ function collectExports(sourceFile, checker, topLevel) {
577
766
  take(symbol, name.text, declaration.node);
578
767
  };
579
768
  for (const statement of sourceFile.statements) {
580
- if (ts3.isExportDeclaration(statement)) {
769
+ if (ts4.isExportDeclaration(statement)) {
581
770
  if (statement.moduleSpecifier !== undefined || statement.isTypeOnly) {
582
771
  continue;
583
772
  }
584
773
  const clause = statement.exportClause;
585
- if (clause === undefined || !ts3.isNamedExports(clause)) {
774
+ if (clause === undefined || !ts4.isNamedExports(clause)) {
586
775
  continue;
587
776
  }
588
777
  for (const element of clause.elements) {
@@ -596,11 +785,11 @@ function collectExports(sourceFile, checker, topLevel) {
596
785
  if (!hasExportModifier(statement)) {
597
786
  continue;
598
787
  }
599
- if (ts3.isVariableStatement(statement)) {
788
+ if (ts4.isVariableStatement(statement)) {
600
789
  for (const declaration of statement.declarationList.declarations) {
601
790
  forEachDeclaredName(declaration.name, (name) => takeLocal(checker.getSymbolAtLocation(name), name));
602
791
  }
603
- } else if (ts3.isFunctionDeclaration(statement) || ts3.isClassDeclaration(statement) || ts3.isEnumDeclaration(statement)) {
792
+ } else if (ts4.isFunctionDeclaration(statement) || ts4.isClassDeclaration(statement) || ts4.isEnumDeclaration(statement)) {
604
793
  if (statement.name !== undefined) {
605
794
  takeLocal(checker.getSymbolAtLocation(statement.name), statement.name);
606
795
  }
@@ -609,74 +798,74 @@ function collectExports(sourceFile, checker, topLevel) {
609
798
  return exported;
610
799
  }
611
800
  function forEachDeclaredName(name, visit) {
612
- if (ts3.isIdentifier(name)) {
801
+ if (ts4.isIdentifier(name)) {
613
802
  visit(name);
614
803
  return;
615
804
  }
616
805
  for (const element of name.elements) {
617
- if (ts3.isBindingElement(element)) {
806
+ if (ts4.isBindingElement(element)) {
618
807
  forEachDeclaredName(element.name, visit);
619
808
  }
620
809
  }
621
810
  }
622
811
  function isLifecycleFactoryCall(expression, checker) {
623
- return ts3.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
812
+ return ts4.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
624
813
  }
625
814
  function isEffectFreeExpression(expression) {
626
815
  if (expression === undefined) {
627
816
  return true;
628
817
  }
629
- 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)) {
630
819
  return isEffectFreeExpression(expression.expression);
631
820
  }
632
- if (ts3.isIdentifier(expression) || ts3.isLiteralExpression(expression)) {
821
+ if (ts4.isIdentifier(expression) || ts4.isLiteralExpression(expression)) {
633
822
  return true;
634
823
  }
635
824
  switch (expression.kind) {
636
- case ts3.SyntaxKind.TrueKeyword:
637
- case ts3.SyntaxKind.FalseKeyword:
638
- case ts3.SyntaxKind.NullKeyword:
639
- case ts3.SyntaxKind.ThisKeyword:
825
+ case ts4.SyntaxKind.TrueKeyword:
826
+ case ts4.SyntaxKind.FalseKeyword:
827
+ case ts4.SyntaxKind.NullKeyword:
828
+ case ts4.SyntaxKind.ThisKeyword:
640
829
  return true;
641
830
  default:
642
831
  break;
643
832
  }
644
- if (ts3.isFunctionExpression(expression) || ts3.isArrowFunction(expression)) {
833
+ if (ts4.isFunctionExpression(expression) || ts4.isArrowFunction(expression)) {
645
834
  return true;
646
835
  }
647
- if (ts3.isPrefixUnaryExpression(expression)) {
648
- 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);
649
838
  }
650
- if (ts3.isBinaryExpression(expression)) {
839
+ if (ts4.isBinaryExpression(expression)) {
651
840
  return !isAssignmentOperator(expression.operatorToken.kind) && isEffectFreeExpression(expression.left) && isEffectFreeExpression(expression.right);
652
841
  }
653
- if (ts3.isConditionalExpression(expression)) {
842
+ if (ts4.isConditionalExpression(expression)) {
654
843
  return isEffectFreeExpression(expression.condition) && isEffectFreeExpression(expression.whenTrue) && isEffectFreeExpression(expression.whenFalse);
655
844
  }
656
- if (ts3.isArrayLiteralExpression(expression)) {
845
+ if (ts4.isArrayLiteralExpression(expression)) {
657
846
  return expression.elements.every(isEffectFreeExpression);
658
847
  }
659
- if (ts3.isObjectLiteralExpression(expression)) {
848
+ if (ts4.isObjectLiteralExpression(expression)) {
660
849
  return expression.properties.every((property) => {
661
- if (ts3.isPropertyAssignment(property)) {
850
+ if (ts4.isPropertyAssignment(property)) {
662
851
  return isEffectFreeExpression(property.initializer);
663
852
  }
664
- return ts3.isShorthandPropertyAssignment(property) || ts3.isMethodDeclaration(property);
853
+ return ts4.isShorthandPropertyAssignment(property) || ts4.isMethodDeclaration(property);
665
854
  });
666
855
  }
667
856
  return false;
668
857
  }
669
858
  function isEffectFreeStatement(statement, checker) {
670
- 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)) {
671
860
  return true;
672
861
  }
673
- if (ts3.isVariableStatement(statement)) {
862
+ if (ts4.isVariableStatement(statement)) {
674
863
  return statement.declarationList.declarations.every((declaration) => isEffectFreeExpression(declaration.initializer));
675
864
  }
676
- if (ts3.isExpressionStatement(statement)) {
865
+ if (ts4.isExpressionStatement(statement)) {
677
866
  return isLifecycleFactoryCall(statement.expression, checker) || isEffectFreeExpression(statement.expression);
678
867
  }
679
- if (ts3.isExportAssignment(statement) && !statement.isExportEquals) {
868
+ if (ts4.isExportAssignment(statement) && !statement.isExportEquals) {
680
869
  return isLifecycleFactoryCall(statement.expression, checker) || isEffectFreeExpression(statement.expression);
681
870
  }
682
871
  return false;
@@ -716,7 +905,7 @@ function computeCompanionClosure(sourceFile, checker) {
716
905
  if (declaration === undefined) {
717
906
  continue;
718
907
  }
719
- if (ts3.isImportDeclaration(declaration.statement)) {
908
+ if (ts4.isImportDeclaration(declaration.statement)) {
720
909
  importBindingSymbols.add(symbol);
721
910
  continue;
722
911
  }
@@ -736,7 +925,7 @@ function computeCompanionClosure(sourceFile, checker) {
736
925
  }
737
926
  const splits = closureStatements.size > 0;
738
927
  for (const statement of sourceFile.statements) {
739
- if (!ts3.isExportDeclaration(statement) || statement.isTypeOnly) {
928
+ if (!ts4.isExportDeclaration(statement) || statement.isTypeOnly) {
740
929
  continue;
741
930
  }
742
931
  if (statement.moduleSpecifier !== undefined) {
@@ -746,7 +935,7 @@ function computeCompanionClosure(sourceFile, checker) {
746
935
  continue;
747
936
  }
748
937
  const clause = statement.exportClause;
749
- if (clause === undefined || !ts3.isNamedExports(clause)) {
938
+ if (clause === undefined || !ts4.isNamedExports(clause)) {
750
939
  continue;
751
940
  }
752
941
  const readsMember = clause.elements.some((element) => {
@@ -769,7 +958,7 @@ function computeCompanionClosure(sourceFile, checker) {
769
958
  });
770
959
  const scriptReferences = new Map;
771
960
  for (const statement of sourceFile.statements) {
772
- if (closureStatements.has(statement) || ts3.isExportDeclaration(statement)) {
961
+ if (closureStatements.has(statement) || ts4.isExportDeclaration(statement)) {
773
962
  continue;
774
963
  }
775
964
  forEachReference(statement, checker, (node, symbol) => {
@@ -813,8 +1002,12 @@ function computeCompanionClosure(sourceFile, checker) {
813
1002
  message: `"${COMPANION_INTERNAL_FIELD}" is reserved for the companion's own internals ` + `and cannot be exported (${formatSites(sites)}). Rename the export.`
814
1003
  });
815
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);
816
1009
  for (const statement of sourceFile.statements) {
817
- if (closureStatements.has(statement) || isEffectFreeStatement(statement, checker)) {
1010
+ if (closureStatements.has(statement) || exempt.has(statement) || isEffectFreeStatement(statement, checker)) {
818
1011
  continue;
819
1012
  }
820
1013
  const start = statement.getStart(sourceFile);
@@ -826,11 +1019,12 @@ function computeCompanionClosure(sourceFile, checker) {
826
1019
  siteOf(statement, "runs in the script"),
827
1020
  siteOf(hoisted.declaration.node, "moves into the companion")
828
1021
  ];
1022
+ const name = hoisted.declaration.name;
829
1023
  violations.push({
830
1024
  kind: "initialization-order",
831
- member: hoisted.declaration.name,
1025
+ member: name,
832
1026
  sites,
833
- 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."
834
1028
  });
835
1029
  }
836
1030
  return {
@@ -839,6 +1033,7 @@ function computeCompanionClosure(sourceFile, checker) {
839
1033
  statements: sourceFile.statements.filter((statement) => closureStatements.has(statement)),
840
1034
  importBindings: ordered.filter(({ symbol }) => importBindingSymbols.has(symbol)).map(({ declaration }) => declaration.name),
841
1035
  internals: ordered.filter(({ symbol }) => !exportSet.has(symbol) && scriptReferences.has(symbol)).map(({ declaration }) => declaration.name),
1036
+ bootstrap,
842
1037
  violations
843
1038
  };
844
1039
  }
@@ -1387,7 +1582,7 @@ function readGameProjectSetting(gameProjectText, section, key) {
1387
1582
  import { existsSync, readdirSync } from "node:fs";
1388
1583
  import * as path from "node:path";
1389
1584
  import { fileURLToPath } from "node:url";
1390
- import * as ts4 from "typescript";
1585
+ import * as ts5 from "typescript";
1391
1586
  import { LuaLibFeature } from "typescript-to-lua";
1392
1587
 
1393
1588
  // src/lua-require-scan.ts
@@ -1535,7 +1730,7 @@ function isHsmRequireName(requirePath) {
1535
1730
  return hsmModuleOfRequire(requirePath) !== undefined;
1536
1731
  }
1537
1732
  function hsmModuleOfSpecifier(node) {
1538
- if (node === undefined || !ts4.isStringLiteral(node)) {
1733
+ if (node === undefined || !ts5.isStringLiteral(node)) {
1539
1734
  return;
1540
1735
  }
1541
1736
  const { text } = node;
@@ -1575,7 +1770,7 @@ function hsmClosure(chunks, compile) {
1575
1770
  return Object.fromEntries(Object.entries(selected).sort(([a], [b]) => a.localeCompare(b)));
1576
1771
  }
1577
1772
  function lowerSpecifier(module) {
1578
- return ts4.factory.createStringLiteral(`@NoResolution:${module.requireName}`);
1773
+ return ts5.factory.createStringLiteral(`@NoResolution:${module.requireName}`);
1579
1774
  }
1580
1775
  function loweredAnything(lowered) {
1581
1776
  return Array.isArray(lowered) ? lowered.length > 0 : lowered !== undefined;
@@ -1593,7 +1788,7 @@ function importSurvivesElision(node, context) {
1593
1788
  if (bindings === undefined) {
1594
1789
  return false;
1595
1790
  }
1596
- if (ts4.isNamespaceImport(bindings)) {
1791
+ if (ts5.isNamespaceImport(bindings)) {
1597
1792
  return resolver.isReferencedAliasDeclaration(bindings);
1598
1793
  }
1599
1794
  return bindings.elements.some((element) => resolver.isReferencedAliasDeclaration(element));
@@ -1606,20 +1801,20 @@ function registerLualib(module, emitted, context) {
1606
1801
  }
1607
1802
  var hsmLoweringPlugin = {
1608
1803
  visitors: {
1609
- [ts4.SyntaxKind.ImportDeclaration]: (node, context) => {
1804
+ [ts5.SyntaxKind.ImportDeclaration]: (node, context) => {
1610
1805
  const module = hsmModuleOfSpecifier(node.moduleSpecifier);
1611
1806
  if (module === undefined) {
1612
1807
  return context.superTransformStatements(node);
1613
1808
  }
1614
1809
  registerLualib(module, importSurvivesElision(node, context), context);
1615
- return context.superTransformStatements(ts4.factory.updateImportDeclaration(node, node.modifiers, node.importClause, lowerSpecifier(module), node.attributes));
1810
+ return context.superTransformStatements(ts5.factory.updateImportDeclaration(node, node.modifiers, node.importClause, lowerSpecifier(module), node.attributes));
1616
1811
  },
1617
- [ts4.SyntaxKind.ExportDeclaration]: (node, context) => {
1812
+ [ts5.SyntaxKind.ExportDeclaration]: (node, context) => {
1618
1813
  const module = hsmModuleOfSpecifier(node.moduleSpecifier);
1619
1814
  if (module === undefined) {
1620
1815
  return context.superTransformStatements(node);
1621
1816
  }
1622
- const lowered = context.superTransformStatements(ts4.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, lowerSpecifier(module), node.attributes));
1817
+ const lowered = context.superTransformStatements(ts5.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, lowerSpecifier(module), node.attributes));
1623
1818
  registerLualib(module, loweredAnything(lowered), context);
1624
1819
  return lowered;
1625
1820
  }
@@ -2139,20 +2334,20 @@ function readLibrarySceneDocuments(host, projectRoot, extensions = LIBRARY_SCENE
2139
2334
  return { documents, unreadable };
2140
2335
  }
2141
2336
  // src/main-entry-factory-imports.ts
2142
- import * as ts5 from "typescript";
2337
+ import * as ts6 from "typescript";
2143
2338
  function findMainEntryFactoryImports(fileName, source) {
2144
- const sourceFile = ts5.createSourceFile(fileName, source, ts5.ScriptTarget.Latest, true);
2339
+ const sourceFile = ts6.createSourceFile(fileName, source, ts6.ScriptTarget.Latest, true);
2145
2340
  const factories = [];
2146
2341
  for (const statement of sourceFile.statements) {
2147
- if (!ts5.isImportDeclaration(statement)) {
2342
+ if (!ts6.isImportDeclaration(statement)) {
2148
2343
  continue;
2149
2344
  }
2150
2345
  const specifier = statement.moduleSpecifier;
2151
- if (!ts5.isStringLiteral(specifier) || specifier.text !== FACTORY_MODULE) {
2346
+ if (!ts6.isStringLiteral(specifier) || specifier.text !== FACTORY_MODULE) {
2152
2347
  continue;
2153
2348
  }
2154
2349
  const bindings = statement.importClause?.namedBindings;
2155
- if (bindings === undefined || !ts5.isNamedImports(bindings)) {
2350
+ if (bindings === undefined || !ts6.isNamedImports(bindings)) {
2156
2351
  continue;
2157
2352
  }
2158
2353
  for (const element of bindings.elements) {
@@ -2225,16 +2420,16 @@ function computeOutputRel(rel, config, kind) {
2225
2420
  return baseRel.replace(/\.ts$/, SCRIPT_SUFFIX_BY_KIND[kind]);
2226
2421
  }
2227
2422
  // src/program-diagnostics.ts
2228
- import * as ts11 from "typescript";
2423
+ import * as ts12 from "typescript";
2229
2424
  import * as tstl from "typescript-to-lua";
2230
2425
 
2231
2426
  // src/message-guard-lowering.ts
2232
- import * as ts6 from "typescript";
2427
+ import * as ts7 from "typescript";
2233
2428
  import {
2234
2429
  createBinaryExpression as createBinaryExpression3,
2235
2430
  createCallExpression as createCallExpression3,
2236
2431
  createIdentifier as createIdentifier3,
2237
- SyntaxKind as SyntaxKind8
2432
+ SyntaxKind as SyntaxKind9
2238
2433
  } from "typescript-to-lua";
2239
2434
  var GUARD_MODULE = "@defold-typescript/types";
2240
2435
  var GUARD_NAME = "isMessage";
@@ -2243,7 +2438,7 @@ function resolvesToGuardExport(callee, checker) {
2243
2438
  if (symbol === undefined) {
2244
2439
  return false;
2245
2440
  }
2246
- if (symbol.flags & ts6.SymbolFlags.Alias) {
2441
+ if (symbol.flags & ts7.SymbolFlags.Alias) {
2247
2442
  symbol = checker.getAliasedSymbol(symbol);
2248
2443
  }
2249
2444
  if (symbol.getName() !== GUARD_NAME) {
@@ -2257,12 +2452,12 @@ function resolvesToGuardExport(callee, checker) {
2257
2452
  }
2258
2453
  var messageGuardLoweringPlugin = {
2259
2454
  visitors: {
2260
- [ts6.SyntaxKind.CallExpression]: (node, context) => {
2455
+ [ts7.SyntaxKind.CallExpression]: (node, context) => {
2261
2456
  const [messageIdArg, , expectedArg] = node.arguments;
2262
2457
  if (node.arguments.length === 3 && messageIdArg !== undefined && expectedArg !== undefined && resolvesToGuardExport(node.expression, context.checker)) {
2263
2458
  const messageId = context.transformExpression(messageIdArg);
2264
2459
  const expected = context.transformExpression(expectedArg);
2265
- return createBinaryExpression3(messageId, createCallExpression3(createIdentifier3("hash"), [expected]), SyntaxKind8.EqualityOperator, node);
2460
+ return createBinaryExpression3(messageId, createCallExpression3(createIdentifier3("hash"), [expected]), SyntaxKind9.EqualityOperator, node);
2266
2461
  }
2267
2462
  return context.superTransformExpression(node);
2268
2463
  }
@@ -2270,14 +2465,14 @@ var messageGuardLoweringPlugin = {
2270
2465
  };
2271
2466
 
2272
2467
  // src/physics-event-guard-lowering.ts
2273
- import * as ts7 from "typescript";
2468
+ import * as ts8 from "typescript";
2274
2469
  import {
2275
2470
  createBinaryExpression as createBinaryExpression4,
2276
2471
  createCallExpression as createCallExpression4,
2277
2472
  createIdentifier as createIdentifier4,
2278
2473
  createStringLiteral as createStringLiteral3,
2279
2474
  createTableIndexExpression as createTableIndexExpression2,
2280
- SyntaxKind as SyntaxKind10
2475
+ SyntaxKind as SyntaxKind11
2281
2476
  } from "typescript-to-lua";
2282
2477
  var GUARD_MODULE2 = "@defold-typescript/types";
2283
2478
  var GUARD_NAME2 = "isPhysicsEvent";
@@ -2286,7 +2481,7 @@ function resolvesToGuardExport2(callee, checker) {
2286
2481
  if (symbol === undefined) {
2287
2482
  return false;
2288
2483
  }
2289
- if (symbol.flags & ts7.SymbolFlags.Alias) {
2484
+ if (symbol.flags & ts8.SymbolFlags.Alias) {
2290
2485
  symbol = checker.getAliasedSymbol(symbol);
2291
2486
  }
2292
2487
  if (symbol.getName() !== GUARD_NAME2) {
@@ -2300,12 +2495,12 @@ function resolvesToGuardExport2(callee, checker) {
2300
2495
  }
2301
2496
  var physicsEventGuardLoweringPlugin = {
2302
2497
  visitors: {
2303
- [ts7.SyntaxKind.CallExpression]: (node, context) => {
2498
+ [ts8.SyntaxKind.CallExpression]: (node, context) => {
2304
2499
  const [eventArg, nameArg] = node.arguments;
2305
2500
  if (node.arguments.length === 2 && eventArg !== undefined && nameArg !== undefined && resolvesToGuardExport2(node.expression, context.checker)) {
2306
2501
  const event = context.transformExpression(eventArg);
2307
2502
  const name = context.transformExpression(nameArg);
2308
- return createBinaryExpression4(createTableIndexExpression2(event, createStringLiteral3("type")), createCallExpression4(createIdentifier4("hash"), [name]), SyntaxKind10.EqualityOperator, node);
2503
+ return createBinaryExpression4(createTableIndexExpression2(event, createStringLiteral3("type")), createCallExpression4(createIdentifier4("hash"), [name]), SyntaxKind11.EqualityOperator, node);
2309
2504
  }
2310
2505
  return context.superTransformExpression(node);
2311
2506
  }
@@ -2313,37 +2508,37 @@ var physicsEventGuardLoweringPlugin = {
2313
2508
  };
2314
2509
 
2315
2510
  // src/timers-lowering.ts
2316
- import * as ts8 from "typescript";
2511
+ import * as ts9 from "typescript";
2317
2512
  import { LuaLibFeature as LuaLibFeature2 } from "typescript-to-lua";
2318
2513
  function isTimersSpecifier(node) {
2319
- return ts8.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
2514
+ return ts9.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
2320
2515
  }
2321
2516
  function importsTimersModule(sourceFile) {
2322
- return sourceFile.statements.some((statement) => ts8.isImportDeclaration(statement) && isTimersSpecifier(statement.moduleSpecifier));
2517
+ return sourceFile.statements.some((statement) => ts9.isImportDeclaration(statement) && isTimersSpecifier(statement.moduleSpecifier));
2323
2518
  }
2324
2519
  var TIMERS_REQUIRE_PATH = `@NoResolution:${TIMERS_REQUIRE_NAME}`;
2325
2520
  var timersLoweringPlugin = {
2326
2521
  visitors: {
2327
- [ts8.SyntaxKind.ImportDeclaration]: (node, context) => {
2522
+ [ts9.SyntaxKind.ImportDeclaration]: (node, context) => {
2328
2523
  if (!isTimersSpecifier(node.moduleSpecifier)) {
2329
2524
  return context.superTransformStatements(node);
2330
2525
  }
2331
2526
  context.usedLuaLibFeatures.add(LuaLibFeature2.Promise);
2332
2527
  context.usedLuaLibFeatures.add(LuaLibFeature2.New);
2333
- const rewritten = ts8.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts8.factory.createStringLiteral(TIMERS_REQUIRE_PATH), node.attributes);
2528
+ const rewritten = ts9.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts9.factory.createStringLiteral(TIMERS_REQUIRE_PATH), node.attributes);
2334
2529
  return context.superTransformStatements(rewritten);
2335
2530
  }
2336
2531
  }
2337
2532
  };
2338
2533
 
2339
2534
  // src/type-application-erasure.ts
2340
- import * as ts9 from "typescript";
2535
+ import * as ts10 from "typescript";
2341
2536
  var TYPE_APPLICATION_APIS = new Set(["go.get", "go.set"]);
2342
2537
  function isTypeApplication(call, checker) {
2343
2538
  if (call.arguments.length !== 0)
2344
2539
  return false;
2345
2540
  const declaration = checker.getResolvedSignature(call)?.declaration;
2346
- if (declaration === undefined || !ts9.isFunctionDeclaration(declaration))
2541
+ if (declaration === undefined || !ts10.isFunctionDeclaration(declaration))
2347
2542
  return false;
2348
2543
  if (declaration.parameters.length !== 0 || declaration.typeParameters === undefined)
2349
2544
  return false;
@@ -2357,7 +2552,7 @@ function isTypeApplication(call, checker) {
2357
2552
  }
2358
2553
  var typeApplicationErasurePlugin = {
2359
2554
  visitors: {
2360
- [ts9.SyntaxKind.CallExpression]: (node, context) => {
2555
+ [ts10.SyntaxKind.CallExpression]: (node, context) => {
2361
2556
  if (isTypeApplication(node, context.checker)) {
2362
2557
  return context.transformExpression(node.expression);
2363
2558
  }
@@ -2367,10 +2562,10 @@ var typeApplicationErasurePlugin = {
2367
2562
  };
2368
2563
 
2369
2564
  // src/window-event-guard-lowering.ts
2370
- import * as ts10 from "typescript";
2565
+ import * as ts11 from "typescript";
2371
2566
  import {
2372
2567
  createBinaryExpression as createBinaryExpression5,
2373
- SyntaxKind as SyntaxKind14
2568
+ SyntaxKind as SyntaxKind15
2374
2569
  } from "typescript-to-lua";
2375
2570
  var GUARD_MODULE3 = "@defold-typescript/types";
2376
2571
  var GUARD_NAME3 = "isWindowEvent";
@@ -2379,7 +2574,7 @@ function resolvesToGuardExport3(callee, checker) {
2379
2574
  if (symbol === undefined) {
2380
2575
  return false;
2381
2576
  }
2382
- if (symbol.flags & ts10.SymbolFlags.Alias) {
2577
+ if (symbol.flags & ts11.SymbolFlags.Alias) {
2383
2578
  symbol = checker.getAliasedSymbol(symbol);
2384
2579
  }
2385
2580
  if (symbol.getName() !== GUARD_NAME3) {
@@ -2393,12 +2588,12 @@ function resolvesToGuardExport3(callee, checker) {
2393
2588
  }
2394
2589
  var windowEventGuardLoweringPlugin = {
2395
2590
  visitors: {
2396
- [ts10.SyntaxKind.CallExpression]: (node, context) => {
2591
+ [ts11.SyntaxKind.CallExpression]: (node, context) => {
2397
2592
  const [eventArg, , expectedArg] = node.arguments;
2398
2593
  if (node.arguments.length === 3 && eventArg !== undefined && expectedArg !== undefined && resolvesToGuardExport3(node.expression, context.checker)) {
2399
2594
  const event = context.transformExpression(eventArg);
2400
2595
  const expected = context.transformExpression(expectedArg);
2401
- return createBinaryExpression5(event, expected, SyntaxKind14.EqualityOperator, node);
2596
+ return createBinaryExpression5(event, expected, SyntaxKind15.EqualityOperator, node);
2402
2597
  }
2403
2598
  return context.superTransformExpression(node);
2404
2599
  }
@@ -2420,7 +2615,7 @@ function isAmbient(fileName) {
2420
2615
  return /[\\/]node_modules[\\/]/.test(fileName) || /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(fileName);
2421
2616
  }
2422
2617
  function getProgramDiagnostics(program, sourceFile) {
2423
- const { diagnostics } = tstl.getProgramTranspileResult(ts11.sys, noopWriteFile, {
2618
+ const { diagnostics } = tstl.getProgramTranspileResult(ts12.sys, noopWriteFile, {
2424
2619
  program,
2425
2620
  plugins: LUA_PLUGINS,
2426
2621
  ...sourceFile ? { sourceFiles: [sourceFile] } : {}
@@ -2991,11 +3186,11 @@ function relativeAddressesFrom(index, context) {
2991
3186
  import { readFileSync as readFileSync2 } from "node:fs";
2992
3187
  import { createRequire as createRequire2 } from "node:module";
2993
3188
  import * as path4 from "node:path";
2994
- import * as ts15 from "typescript";
3189
+ import * as ts16 from "typescript";
2995
3190
  import * as tstl3 from "typescript-to-lua";
2996
3191
 
2997
3192
  // src/companion-emit.ts
2998
- import * as ts12 from "typescript";
3193
+ import * as ts13 from "typescript";
2999
3194
  import {
3000
3195
  createAssignmentStatement as createAssignmentStatement2,
3001
3196
  createCallExpression as createCallExpression5,
@@ -3029,8 +3224,8 @@ function exportsIdentifier() {
3029
3224
  }
3030
3225
  function isRuntimeScriptSource(sourceFile, checker) {
3031
3226
  return sourceFile.statements.some((statement) => {
3032
- const expression = ts12.isExpressionStatement(statement) ? statement.expression : ts12.isExportAssignment(statement) && !statement.isExportEquals ? statement.expression : undefined;
3033
- return expression !== undefined && ts12.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
3227
+ const expression = ts13.isExpressionStatement(statement) ? statement.expression : ts13.isExportAssignment(statement) && !statement.isExportEquals ? statement.expression : undefined;
3228
+ return expression !== undefined && ts13.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
3034
3229
  });
3035
3230
  }
3036
3231
  function planFor(sourceFile, checker) {
@@ -3043,6 +3238,7 @@ function planFor(sourceFile, checker) {
3043
3238
  }
3044
3239
  return {
3045
3240
  closureStarts: new Set(closure.statements.map((statement) => statement.pos)),
3241
+ bootstrapStarts: new Set(closure.bootstrap.map((statement) => statement.pos)),
3046
3242
  internals: closure.internals,
3047
3243
  importBindings: closure.importBindings,
3048
3244
  requirePath: requirePathForRel(sourceFile.fileName)
@@ -3182,11 +3378,11 @@ function freeNames(statements) {
3182
3378
  function resolvedRequirePaths(sourceFile, checker) {
3183
3379
  const paths = new Map;
3184
3380
  for (const statement of sourceFile.statements) {
3185
- const specifier = ts12.isImportDeclaration(statement) || ts12.isExportDeclaration(statement) ? statement.moduleSpecifier : undefined;
3186
- if (specifier === undefined || !ts12.isStringLiteral(specifier)) {
3381
+ const specifier = ts13.isImportDeclaration(statement) || ts13.isExportDeclaration(statement) ? statement.moduleSpecifier : undefined;
3382
+ if (specifier === undefined || !ts13.isStringLiteral(specifier)) {
3187
3383
  continue;
3188
3384
  }
3189
- const target = checker.getSymbolAtLocation(specifier)?.declarations?.find((declaration) => ts12.isSourceFile(declaration));
3385
+ const target = checker.getSymbolAtLocation(specifier)?.declarations?.find((declaration) => ts13.isSourceFile(declaration));
3190
3386
  if (target === undefined || target.isDeclarationFile) {
3191
3387
  continue;
3192
3388
  }
@@ -3329,6 +3525,7 @@ function split(statements, owned) {
3329
3525
  function createCompanionEmitPlugin() {
3330
3526
  const plans = new Map;
3331
3527
  const owned = new Map;
3528
+ const bootstraps = new Map;
3332
3529
  const companions = new Map;
3333
3530
  function planOf(sourceFile, checker) {
3334
3531
  const key = sourceFile.fileName;
@@ -3354,12 +3551,30 @@ function createCompanionEmitPlugin() {
3354
3551
  }
3355
3552
  return statements;
3356
3553
  }
3554
+ function captureBootstrap(node, context) {
3555
+ const statements = context.superTransformStatements(node);
3556
+ const sourceFile = context.sourceFile;
3557
+ const plan = planOf(sourceFile, context.checker);
3558
+ if (plan === undefined || !plan.bootstrapStarts.has(node.pos)) {
3559
+ return statements;
3560
+ }
3561
+ let bucket = bootstraps.get(sourceFile.fileName);
3562
+ if (bucket === undefined) {
3563
+ bucket = new Set;
3564
+ bootstraps.set(sourceFile.fileName, bucket);
3565
+ }
3566
+ for (const statement of statements) {
3567
+ bucket.add(statement);
3568
+ }
3569
+ return statements;
3570
+ }
3357
3571
  const visitors = {
3358
- [ts12.SyntaxKind.VariableStatement]: capture,
3359
- [ts12.SyntaxKind.FunctionDeclaration]: capture,
3360
- [ts12.SyntaxKind.ClassDeclaration]: capture,
3361
- [ts12.SyntaxKind.EnumDeclaration]: capture,
3362
- [ts12.SyntaxKind.ExportDeclaration]: capture
3572
+ [ts13.SyntaxKind.VariableStatement]: capture,
3573
+ [ts13.SyntaxKind.FunctionDeclaration]: capture,
3574
+ [ts13.SyntaxKind.ClassDeclaration]: capture,
3575
+ [ts13.SyntaxKind.EnumDeclaration]: capture,
3576
+ [ts13.SyntaxKind.ExportDeclaration]: capture,
3577
+ [ts13.SyntaxKind.IfStatement]: captureBootstrap
3363
3578
  };
3364
3579
  let configuredNoResolvePaths = [];
3365
3580
  const plugin = {
@@ -3379,7 +3594,8 @@ function createCompanionEmitPlugin() {
3379
3594
  if (plan === undefined || bucket === undefined || bucket.size === 0) {
3380
3595
  continue;
3381
3596
  }
3382
- emitCompanion(program, emitHost, file, sourceFile, plan, bucket, companions);
3597
+ const bootstrap = bootstraps.get(sourceFile.fileName) ?? new Set;
3598
+ emitCompanion(program, emitHost, file, sourceFile, plan, bucket, bootstrap, companions);
3383
3599
  emitted.push(plan.requirePath);
3384
3600
  }
3385
3601
  if (emitted.length > 0) {
@@ -3389,7 +3605,7 @@ function createCompanionEmitPlugin() {
3389
3605
  };
3390
3606
  return { plugin, companions };
3391
3607
  }
3392
- function emitCompanion(program, emitHost, file, sourceFile, plan, owned, companions) {
3608
+ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, bootstrap, companions) {
3393
3609
  const luaAst = file.luaAst;
3394
3610
  if (luaAst === undefined) {
3395
3611
  return;
@@ -3408,12 +3624,14 @@ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, compani
3408
3624
  createReturnStatement2([exportsIdentifier()])
3409
3625
  ];
3410
3626
  const reads = new Set([EXPORTS_NAME, ...plan.internals]);
3411
- const insertAt = requireInsertionPoint(halves.script, reads);
3627
+ const rest = halves.script.filter((statement) => !bootstrap.has(statement));
3628
+ const insertAt = requireInsertionPoint(rest, reads);
3412
3629
  const scriptStatements = [
3413
- ...halves.script.slice(0, insertAt),
3630
+ ...rest.slice(0, insertAt),
3631
+ ...halves.script.filter((statement) => bootstrap.has(statement)),
3414
3632
  createVariableDeclarationStatement3(exportsIdentifier(), createCallExpression5(createIdentifier5("require"), [createStringLiteral4(plan.requirePath)])),
3415
3633
  ...plan.internals.map((name) => createVariableDeclarationStatement3(createIdentifier5(name), internalsField(name))),
3416
- ...halves.script.slice(insertAt),
3634
+ ...rest.slice(insertAt),
3417
3635
  createReturnStatement2([exportsIdentifier()])
3418
3636
  ];
3419
3637
  const features = new Set(luaAst.luaLibFeatures);
@@ -3428,7 +3646,7 @@ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, compani
3428
3646
  }
3429
3647
 
3430
3648
  // src/editor-script-erasure.ts
3431
- import * as ts13 from "typescript";
3649
+ import * as ts14 from "typescript";
3432
3650
  import {
3433
3651
  createReturnStatement as createReturnStatement3
3434
3652
  } from "typescript-to-lua";
@@ -3448,7 +3666,7 @@ function resolveEditorFactoryExport(callee, checker) {
3448
3666
  if (symbol === undefined) {
3449
3667
  return;
3450
3668
  }
3451
- if (symbol.flags & ts13.SymbolFlags.Alias) {
3669
+ if (symbol.flags & ts14.SymbolFlags.Alias) {
3452
3670
  symbol = checker.getAliasedSymbol(symbol);
3453
3671
  }
3454
3672
  const name = symbol.getName();
@@ -3462,7 +3680,7 @@ function resolveEditorFactoryExport(callee, checker) {
3462
3680
  return declaration.getSourceFile().fileName.includes(EDITOR_FACTORY_MODULE) ? name : undefined;
3463
3681
  }
3464
3682
  function lowerEditorFactoryCall(expression, context) {
3465
- if (!ts13.isCallExpression(expression)) {
3683
+ if (!ts14.isCallExpression(expression)) {
3466
3684
  return;
3467
3685
  }
3468
3686
  if (resolveEditorFactoryExport(expression.expression, context.checker) !== EDITOR_SCRIPT_FACTORY_NAME) {
@@ -3475,7 +3693,7 @@ function lowerEditorFactoryCall(expression, context) {
3475
3693
  return [createReturnStatement3([context.transformExpression(module)])];
3476
3694
  }
3477
3695
  function isEditorFactoryOnlyImport(node) {
3478
- if (!ts13.isStringLiteral(node.moduleSpecifier) || !EDITOR_FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
3696
+ if (!ts14.isStringLiteral(node.moduleSpecifier) || !EDITOR_FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
3479
3697
  return false;
3480
3698
  }
3481
3699
  const clause = node.importClause;
@@ -3486,7 +3704,7 @@ function isEditorFactoryOnlyImport(node) {
3486
3704
  return false;
3487
3705
  }
3488
3706
  const bindings = clause.namedBindings;
3489
- if (bindings === undefined || !ts13.isNamedImports(bindings)) {
3707
+ if (bindings === undefined || !ts14.isNamedImports(bindings)) {
3490
3708
  return false;
3491
3709
  }
3492
3710
  const runtime = bindings.elements.filter((element) => !element.isTypeOnly);
@@ -3497,7 +3715,7 @@ function isEditorFactoryOnlyImport(node) {
3497
3715
  }
3498
3716
  var editorScriptErasurePlugin = {
3499
3717
  visitors: {
3500
- [ts13.SyntaxKind.ExportAssignment]: (node, context) => {
3718
+ [ts14.SyntaxKind.ExportAssignment]: (node, context) => {
3501
3719
  if (!node.isExportEquals) {
3502
3720
  const lowered = lowerEditorFactoryCall(node.expression, context);
3503
3721
  if (lowered !== undefined) {
@@ -3506,14 +3724,14 @@ var editorScriptErasurePlugin = {
3506
3724
  }
3507
3725
  return context.superTransformStatements(node);
3508
3726
  },
3509
- [ts13.SyntaxKind.CallExpression]: (node, context) => {
3727
+ [ts14.SyntaxKind.CallExpression]: (node, context) => {
3510
3728
  const command = node.arguments[0];
3511
3729
  if (command !== undefined && resolveEditorFactoryExport(node.expression, context.checker) === EDITOR_COMMAND_FACTORY_NAME) {
3512
3730
  return context.transformExpression(command);
3513
3731
  }
3514
3732
  return context.superTransformExpression(node);
3515
3733
  },
3516
- [ts13.SyntaxKind.ImportDeclaration]: (node, context) => isEditorFactoryOnlyImport(node) ? [] : context.superTransformStatements(node)
3734
+ [ts14.SyntaxKind.ImportDeclaration]: (node, context) => isEditorFactoryOnlyImport(node) ? [] : context.superTransformStatements(node)
3517
3735
  }
3518
3736
  };
3519
3737
 
@@ -3524,17 +3742,17 @@ import * as path3 from "node:path";
3524
3742
  import * as tstl2 from "typescript-to-lua";
3525
3743
 
3526
3744
  // src/go-property-direct-call.ts
3527
- import * as ts14 from "typescript";
3745
+ import * as ts15 from "typescript";
3528
3746
  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).";
3529
3747
  function findDirectGoPropertyCalls(sourceFile) {
3530
3748
  const calls = [];
3531
3749
  const visit = (node) => {
3532
- if (ts14.isCallExpression(node) && ts14.isPropertyAccessExpression(node.expression) && node.expression.name.text === "property" && ts14.isIdentifier(node.expression.expression) && node.expression.expression.text === "go") {
3750
+ if (ts15.isCallExpression(node) && ts15.isPropertyAccessExpression(node.expression) && node.expression.name.text === "property" && ts15.isIdentifier(node.expression.expression) && node.expression.expression.text === "go") {
3533
3751
  calls.push(node);
3534
3752
  }
3535
- ts14.forEachChild(node, visit);
3753
+ ts15.forEachChild(node, visit);
3536
3754
  };
3537
- ts14.forEachChild(sourceFile, visit);
3755
+ ts15.forEachChild(sourceFile, visit);
3538
3756
  return calls;
3539
3757
  }
3540
3758
 
@@ -3694,6 +3912,7 @@ function collectOutputs(transpiledFiles, diagnostics, userKeys, emittedCompanion
3694
3912
  }
3695
3913
  }
3696
3914
  const hsm = hsmClosure([...Object.values(lua), ...Object.values(companions)], compileHsmModules);
3915
+ const hsmSourceMaps = hsm === undefined ? undefined : selectHsmSourceMaps(Object.keys(hsm));
3697
3916
  return {
3698
3917
  lua,
3699
3918
  sourceMaps,
@@ -3701,9 +3920,21 @@ function collectOutputs(transpiledFiles, diagnostics, userKeys, emittedCompanion
3701
3920
  ...Object.keys(companions).length > 0 ? { companions } : {},
3702
3921
  ...lualib !== undefined ? { lualib } : {},
3703
3922
  ...timersImported ? { timersRuntime: TIMERS_RUNTIME } : {},
3704
- ...hsm !== undefined ? { hsmModules: hsm } : {}
3923
+ ...hsm !== undefined ? { hsmModules: hsm } : {},
3924
+ ...hsmSourceMaps !== undefined ? { hsmSourceMaps } : {}
3705
3925
  };
3706
3926
  }
3927
+ function selectHsmSourceMaps(names) {
3928
+ const maps = compileHsmSourceMaps();
3929
+ const selected = {};
3930
+ for (const name of names) {
3931
+ const map = maps[name];
3932
+ if (map !== undefined) {
3933
+ selected[name] = map;
3934
+ }
3935
+ }
3936
+ return selected;
3937
+ }
3707
3938
  function transpileVirtual(files, companionEmit, overrides = {}) {
3708
3939
  return tstl2.transpileVirtualProject({ ...AMBIENT_FILES, ...files }, {
3709
3940
  luaTarget: tstl2.LuaTarget.Lua51,
@@ -3738,6 +3969,12 @@ function requiresLualib(lua) {
3738
3969
  return scanEmittedRequires(lua).some(({ path: requirePath }) => requirePath === "lualib_bundle");
3739
3970
  }
3740
3971
  function compileHsmModules() {
3972
+ return compileHsm().lua;
3973
+ }
3974
+ function compileHsmSourceMaps() {
3975
+ return compileHsm().sourceMaps;
3976
+ }
3977
+ function compileHsm() {
3741
3978
  if (compiledHsm !== undefined) {
3742
3979
  return compiledHsm;
3743
3980
  }
@@ -3752,6 +3989,7 @@ function compileHsmModules() {
3752
3989
  const result = transpileVirtual(files, createCompanionEmitPlugin(), { removeComments: true });
3753
3990
  const problems = result.diagnostics.map((d) => `${d.file?.fileName ?? "(project)"}: ${flattenDiagnosticMessage(d.messageText)}`);
3754
3991
  const lua = {};
3992
+ const sourceMaps = {};
3755
3993
  for (const file of result.transpiledFiles) {
3756
3994
  if (isLualibBundle(file)) {
3757
3995
  continue;
@@ -3765,14 +4003,17 @@ function compileHsmModules() {
3765
4003
  problems.push(`the compiled ${name} module requires lualib_bundle`);
3766
4004
  }
3767
4005
  lua[name] = file.lua;
4006
+ if (typeof file.luaSourceMap === "string") {
4007
+ sourceMaps[name] = file.luaSourceMap;
4008
+ }
3768
4009
  }
3769
4010
  if (problems.length > 0) {
3770
4011
  throw new Error(`@defold-typescript/transpiler: the hsm library does not compile:
3771
4012
  ${problems.join(`
3772
4013
  `)}`);
3773
4014
  }
3774
- compiledHsm = lua;
3775
- return lua;
4015
+ compiledHsm = { lua, sourceMaps };
4016
+ return compiledHsm;
3776
4017
  }
3777
4018
  function transpile(source) {
3778
4019
  const project = transpileProject({ files: { "main.ts": source } });
@@ -3845,7 +4086,7 @@ function createTranspileSession() {
3845
4086
  if (cached) {
3846
4087
  return cached;
3847
4088
  }
3848
- const created = ts15.createSourceFile(fileName, content, ts15.ScriptTarget.Latest, false);
4089
+ const created = ts16.createSourceFile(fileName, content, ts16.ScriptTarget.Latest, false);
3849
4090
  sourceFileCache.set(normalized, created);
3850
4091
  return created;
3851
4092
  }
@@ -3864,7 +4105,7 @@ function createTranspileSession() {
3864
4105
  return cached;
3865
4106
  }
3866
4107
  const fileContent = readFileSync2(filePath, "utf8");
3867
- const created = ts15.createSourceFile(filePath, fileContent, ts15.ScriptTarget.Latest, false);
4108
+ const created = ts16.createSourceFile(filePath, fileContent, ts16.ScriptTarget.Latest, false);
3868
4109
  libCache.set(fileName, created);
3869
4110
  return created;
3870
4111
  }
@@ -3877,10 +4118,10 @@ function createTranspileSession() {
3877
4118
  return AMBIENT_FILES[normalized];
3878
4119
  }
3879
4120
  const host = {
3880
- fileExists: (fileName) => mergedContent(normalizeSlashes(fileName)) !== undefined || ts15.sys.fileExists(fileName),
4121
+ fileExists: (fileName) => mergedContent(normalizeSlashes(fileName)) !== undefined || ts16.sys.fileExists(fileName),
3881
4122
  getCanonicalFileName: (fileName) => fileName,
3882
4123
  getCurrentDirectory: () => "",
3883
- getDefaultLibFileName: ts15.getDefaultLibFileName,
4124
+ getDefaultLibFileName: ts16.getDefaultLibFileName,
3884
4125
  readFile: () => "",
3885
4126
  getNewLine: () => `
3886
4127
  `,
@@ -3902,15 +4143,15 @@ function createTranspileSession() {
3902
4143
  const userKeys = new Set(userFiles.keys());
3903
4144
  const rootNames = [...Object.keys(AMBIENT_FILES).map(normalizeSlashes), ...userKeys];
3904
4145
  const companionEmit = createCompanionEmitPlugin();
3905
- program = ts15.createProgram(rootNames, compilerOptions(companionEmit), host, program);
3906
- const preEmitDiagnostics = ts15.getPreEmitDiagnostics(program);
4146
+ program = ts16.createProgram(rootNames, compilerOptions(companionEmit), host, program);
4147
+ const preEmitDiagnostics = ts16.getPreEmitDiagnostics(program);
3907
4148
  const collector = createOutputCollector();
3908
4149
  const { diagnostics: transpileDiagnostics } = new tstl3.Transpiler().emit({
3909
4150
  program,
3910
4151
  writeFile: collector.writeFile
3911
4152
  });
3912
4153
  const diagnostics = [
3913
- ...ts15.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics])
4154
+ ...ts16.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics])
3914
4155
  ];
3915
4156
  return collectOutputs(collector.files, diagnostics, userKeys, companionEmit.companions);
3916
4157
  }
@@ -3920,7 +4161,7 @@ function createTranspileSession() {
3920
4161
  };
3921
4162
  }
3922
4163
  // src/text-script-property.ts
3923
- import * as ts16 from "typescript";
4164
+ import * as ts17 from "typescript";
3924
4165
  function findTextScriptProperties(program, fileNames) {
3925
4166
  const checker = program.getTypeChecker();
3926
4167
  const findings = [];
@@ -3931,7 +4172,7 @@ function findTextScriptProperties(program, fileNames) {
3931
4172
  }
3932
4173
  const located = [];
3933
4174
  const visit = (node) => {
3934
- if (ts16.isCallExpression(node)) {
4175
+ if (ts17.isCallExpression(node)) {
3935
4176
  const hooks = factoryHooks(node, checker);
3936
4177
  for (const property of hooks?.properties ?? []) {
3937
4178
  if (!isPropertiesHook(property)) {
@@ -3944,7 +4185,7 @@ function findTextScriptProperties(program, fileNames) {
3944
4185
  }
3945
4186
  }
3946
4187
  }
3947
- ts16.forEachChild(node, visit);
4188
+ ts17.forEachChild(node, visit);
3948
4189
  };
3949
4190
  visit(sourceFile);
3950
4191
  for (const call of findDirectGoPropertyCalls(sourceFile)) {
@@ -3953,7 +4194,7 @@ function findTextScriptProperties(program, fileNames) {
3953
4194
  continue;
3954
4195
  }
3955
4196
  if (mayHoldString(checker.getTypeAtLocation(value), checker)) {
3956
- const name = ts16.isStringLiteralLike(nameArgument) ? nameArgument.text : nameArgument.getText(sourceFile);
4197
+ const name = ts17.isStringLiteralLike(nameArgument) ? nameArgument.text : nameArgument.getText(sourceFile);
3957
4198
  located.push({ name, value });
3958
4199
  }
3959
4200
  }
@@ -3970,20 +4211,20 @@ function mayHoldString(type, checker, visited = new Set) {
3970
4211
  return false;
3971
4212
  }
3972
4213
  visited.add(type);
3973
- if (type.flags & ts16.TypeFlags.StringLike) {
4214
+ if (type.flags & ts17.TypeFlags.StringLike) {
3974
4215
  return true;
3975
4216
  }
3976
4217
  if (type.isUnionOrIntersection()) {
3977
4218
  return type.types.some((member) => mayHoldString(member, checker, visited));
3978
4219
  }
3979
- if (type.flags & ts16.TypeFlags.Instantiable) {
4220
+ if (type.flags & ts17.TypeFlags.Instantiable) {
3980
4221
  const constraint = checker.getBaseConstraintOfType(type);
3981
4222
  return constraint !== undefined && constraint !== type ? mayHoldString(constraint, checker, visited) : false;
3982
4223
  }
3983
4224
  return false;
3984
4225
  }
3985
4226
  // src/url-address-slots.ts
3986
- import * as ts17 from "typescript";
4227
+ import * as ts18 from "typescript";
3987
4228
  var ADDRESS_CLASSES = {
3988
4229
  "game-object": true,
3989
4230
  component: true,
@@ -4002,7 +4243,7 @@ function isFragmentCaret(slot, position) {
4002
4243
  return slot.fragmentStart !== -1 && position >= slot.fragmentStart;
4003
4244
  }
4004
4245
  function tableKey(checker, callee) {
4005
- const symbol = checker.getSymbolAtLocation(ts17.isIdentifier(callee) ? callee : callee.name);
4246
+ const symbol = checker.getSymbolAtLocation(ts18.isIdentifier(callee) ? callee : callee.name);
4006
4247
  if (!symbol)
4007
4248
  return;
4008
4249
  const fqn = checker.getFullyQualifiedName(symbol);
@@ -4010,43 +4251,43 @@ function tableKey(checker, callee) {
4010
4251
  }
4011
4252
  function parameterName(checker, call, index) {
4012
4253
  const declaration = checker.getResolvedSignature(call)?.declaration;
4013
- if (!declaration || !ts17.isFunctionLike(declaration))
4254
+ if (!declaration || !ts18.isFunctionLike(declaration))
4014
4255
  return;
4015
4256
  const parameter = declaration.parameters[index];
4016
- if (!parameter || parameter.dotDotDotToken || !ts17.isIdentifier(parameter.name))
4257
+ if (!parameter || parameter.dotDotDotToken || !ts18.isIdentifier(parameter.name))
4017
4258
  return;
4018
4259
  return parameter.name.text;
4019
4260
  }
4020
4261
  var EQUALITY_OPERATORS = new Set([
4021
- ts17.SyntaxKind.EqualsEqualsEqualsToken,
4022
- ts17.SyntaxKind.ExclamationEqualsEqualsToken,
4023
- ts17.SyntaxKind.EqualsEqualsToken,
4024
- ts17.SyntaxKind.ExclamationEqualsToken
4262
+ ts18.SyntaxKind.EqualsEqualsEqualsToken,
4263
+ ts18.SyntaxKind.ExclamationEqualsEqualsToken,
4264
+ ts18.SyntaxKind.EqualsEqualsToken,
4265
+ ts18.SyntaxKind.ExclamationEqualsToken
4025
4266
  ]);
4026
4267
  function comparisonSatisfied(checker, entry, call) {
4027
4268
  if (entry.comparedParameter === undefined)
4028
4269
  return true;
4029
4270
  let node = call;
4030
- while (ts17.isParenthesizedExpression(node.parent))
4271
+ while (ts18.isParenthesizedExpression(node.parent))
4031
4272
  node = node.parent;
4032
4273
  const comparison = node.parent;
4033
- if (!ts17.isBinaryExpression(comparison))
4274
+ if (!ts18.isBinaryExpression(comparison))
4034
4275
  return false;
4035
4276
  if (!EQUALITY_OPERATORS.has(comparison.operatorToken.kind))
4036
4277
  return false;
4037
4278
  const other = comparison.left === node ? comparison.right : comparison.left;
4038
4279
  const symbol = checker.getSymbolAtLocation(other);
4039
- return (symbol?.declarations ?? []).some((declaration) => ts17.isParameter(declaration) && ts17.isIdentifier(declaration.name) && declaration.name.text === entry.comparedParameter);
4280
+ return (symbol?.declarations ?? []).some((declaration) => ts18.isParameter(declaration) && ts18.isIdentifier(declaration.name) && declaration.name.text === entry.comparedParameter);
4040
4281
  }
4041
4282
  function classifiedEntryOfArgument(checker, table, argument) {
4042
4283
  const call = argument.parent;
4043
- if (!ts17.isCallExpression(call))
4284
+ if (!ts18.isCallExpression(call))
4044
4285
  return;
4045
4286
  const argumentIndex = call.arguments.indexOf(argument);
4046
4287
  if (argumentIndex === -1)
4047
4288
  return;
4048
4289
  const callee = call.expression;
4049
- if (!ts17.isPropertyAccessExpression(callee) && !ts17.isIdentifier(callee))
4290
+ if (!ts18.isPropertyAccessExpression(callee) && !ts18.isIdentifier(callee))
4050
4291
  return;
4051
4292
  const fqn = tableKey(checker, callee);
4052
4293
  if (fqn === undefined)
@@ -4063,10 +4304,10 @@ function classifiedEntryOfArgument(checker, table, argument) {
4063
4304
  }
4064
4305
  function slotThroughHashedCall(checker, table, literal) {
4065
4306
  const call = literal.parent;
4066
- if (!ts17.isCallExpression(call))
4307
+ if (!ts18.isCallExpression(call))
4067
4308
  return;
4068
4309
  const callee = call.expression;
4069
- if (!ts17.isPropertyAccessExpression(callee) && !ts17.isIdentifier(callee))
4310
+ if (!ts18.isPropertyAccessExpression(callee) && !ts18.isIdentifier(callee))
4070
4311
  return;
4071
4312
  if (tableKey(checker, callee) !== "hash")
4072
4313
  return;
@@ -4084,24 +4325,24 @@ function addressTextOf(checker, entry, call) {
4084
4325
  if (entry.addressParameter === undefined)
4085
4326
  return;
4086
4327
  const declaration = checker.getResolvedSignature(call)?.declaration;
4087
- if (!declaration || !ts17.isFunctionLike(declaration))
4328
+ if (!declaration || !ts18.isFunctionLike(declaration))
4088
4329
  return;
4089
- const index = declaration.parameters.findIndex((parameter) => !parameter.dotDotDotToken && ts17.isIdentifier(parameter.name) && parameter.name.text === entry.addressParameter);
4330
+ const index = declaration.parameters.findIndex((parameter) => !parameter.dotDotDotToken && ts18.isIdentifier(parameter.name) && parameter.name.text === entry.addressParameter);
4090
4331
  if (index === -1)
4091
4332
  return;
4092
4333
  const argument = call.arguments[index];
4093
- return argument && ts17.isStringLiteralLike(argument) ? argument.text : undefined;
4334
+ return argument && ts18.isStringLiteralLike(argument) ? argument.text : undefined;
4094
4335
  }
4095
4336
  function innermostLiteralAt(sourceFile, position) {
4096
4337
  let found;
4097
4338
  const visit = (node) => {
4098
4339
  if (position < node.getStart(sourceFile) || position > node.getEnd())
4099
4340
  return;
4100
- if (ts17.isStringLiteralLike(node))
4341
+ if (ts18.isStringLiteralLike(node))
4101
4342
  found = node;
4102
- ts17.forEachChild(node, visit);
4343
+ ts18.forEachChild(node, visit);
4103
4344
  };
4104
- ts17.forEachChild(sourceFile, visit);
4345
+ ts18.forEachChild(sourceFile, visit);
4105
4346
  return found;
4106
4347
  }
4107
4348
  function resolveClassifiedSlotAtPosition(input) {
@@ -4135,23 +4376,23 @@ function resolveClassifiedSlotAtPosition(input) {
4135
4376
  };
4136
4377
  }
4137
4378
  // src/url-cross-world-address.ts
4138
- import * as ts19 from "typescript";
4379
+ import * as ts20 from "typescript";
4139
4380
 
4140
4381
  // src/url-address-literals.ts
4141
- import * as ts18 from "typescript";
4382
+ import * as ts19 from "typescript";
4142
4383
  function isAmbient2(fileName) {
4143
4384
  return /[\\/]node_modules[\\/]/.test(fileName) || /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(fileName);
4144
4385
  }
4145
4386
  function referenceTargetSymbol(type) {
4146
- if ((type.flags & ts18.TypeFlags.Object) === 0)
4387
+ if ((type.flags & ts19.TypeFlags.Object) === 0)
4147
4388
  return;
4148
- if ((type.objectFlags & ts18.ObjectFlags.Reference) === 0)
4389
+ if ((type.objectFlags & ts19.ObjectFlags.Reference) === 0)
4149
4390
  return;
4150
4391
  return type.target.symbol;
4151
4392
  }
4152
4393
  function ambientHashAliasTargets(checker, anchor) {
4153
4394
  const targets = new Set;
4154
- for (const symbol of checker.getSymbolsInScope(anchor, ts18.SymbolFlags.Type)) {
4395
+ for (const symbol of checker.getSymbolsInScope(anchor, ts19.SymbolFlags.Type)) {
4155
4396
  if (symbol.name !== "Hash")
4156
4397
  continue;
4157
4398
  const target = referenceTargetSymbol(checker.getDeclaredTypeOfSymbol(symbol));
@@ -4167,7 +4408,7 @@ function canonicalHashSymbols(checker, program) {
4167
4408
  if (!anchor)
4168
4409
  return canonical;
4169
4410
  const aliased = ambientHashAliasTargets(checker, anchor);
4170
- for (const symbol of checker.getSymbolsInScope(anchor, ts18.SymbolFlags.Function)) {
4411
+ for (const symbol of checker.getSymbolsInScope(anchor, ts19.SymbolFlags.Function)) {
4171
4412
  if (symbol.name !== "hash")
4172
4413
  continue;
4173
4414
  const declaration = symbol.declarations?.[0];
@@ -4189,7 +4430,7 @@ function hashedSourceOfType(checker, type, canonical) {
4189
4430
  return source?.isStringLiteral() ? source.value : undefined;
4190
4431
  }
4191
4432
  function staticAddressTextOf(checker, node, canonical) {
4192
- return ts18.isStringLiteralLike(node) ? node.text : hashedSourceOfType(checker, checker.getTypeAtLocation(node), canonical);
4433
+ return ts19.isStringLiteralLike(node) ? node.text : hashedSourceOfType(checker, checker.getTypeAtLocation(node), canonical);
4193
4434
  }
4194
4435
 
4195
4436
  // src/url-cross-world-address.ts
@@ -4213,7 +4454,7 @@ function checkCrossWorldAddresses(input) {
4213
4454
  if (worlds.length === 0)
4214
4455
  continue;
4215
4456
  const visit = (node) => {
4216
- if (ts19.isExpression(node)) {
4457
+ if (ts20.isExpression(node)) {
4217
4458
  const entry = addressEntryOfArgument(checker, table, node);
4218
4459
  if (entry !== undefined && slotRejectsForeignSocket(entry)) {
4219
4460
  const address = staticAddressTextOf(checker, node, canonical);
@@ -4230,14 +4471,14 @@ function checkCrossWorldAddresses(input) {
4230
4471
  }
4231
4472
  }
4232
4473
  }
4233
- ts19.forEachChild(node, visit);
4474
+ ts20.forEachChild(node, visit);
4234
4475
  };
4235
- ts19.forEachChild(sourceFile, visit);
4476
+ ts20.forEachChild(sourceFile, visit);
4236
4477
  }
4237
4478
  return findings;
4238
4479
  }
4239
4480
  // src/url-fragment-reachability.ts
4240
- import * as ts20 from "typescript";
4481
+ import * as ts21 from "typescript";
4241
4482
  function pathOfKey(key) {
4242
4483
  const socket = socketOfAddress(key);
4243
4484
  return socket === undefined ? key : key.slice(socket.length + 1);
@@ -4282,7 +4523,7 @@ function checkUrlFragmentReachability(input) {
4282
4523
  if (isAmbient2(sourceFile.fileName))
4283
4524
  continue;
4284
4525
  const visit = (node) => {
4285
- if (ts20.isExpression(node) && isAddressClass(addressClassOfArgument(checker, table, node))) {
4526
+ if (ts21.isExpression(node) && isAddressClass(addressClassOfArgument(checker, table, node))) {
4286
4527
  const text = staticAddressTextOf(checker, node, canonical);
4287
4528
  if (text !== undefined) {
4288
4529
  const hash = text.indexOf("#");
@@ -4301,9 +4542,9 @@ function checkUrlFragmentReachability(input) {
4301
4542
  }
4302
4543
  }
4303
4544
  }
4304
- ts20.forEachChild(node, visit);
4545
+ ts21.forEachChild(node, visit);
4305
4546
  };
4306
- ts20.forEachChild(sourceFile, visit);
4547
+ ts21.forEachChild(sourceFile, visit);
4307
4548
  }
4308
4549
  return { kind: "checked", findings };
4309
4550
  }
@@ -4311,6 +4552,9 @@ export {
4311
4552
  ANIMATION_ASSET_EXTENSIONS,
4312
4553
  COLLECTION_REFERENCE_EXTENSIONS,
4313
4554
  COMPANION_INTERNAL_FIELD,
4555
+ DEBUG_BLOCK_BEGIN,
4556
+ DEBUG_BLOCK_END,
4557
+ DEBUG_MANAGED_BLOCK,
4314
4558
  DEFAULT_INCLUDE,
4315
4559
  GAME_PROJECT_DOCUMENT,
4316
4560
  GUI_EXTENSIONS,
@@ -4351,6 +4595,7 @@ export {
4351
4595
  displayPathOf,
4352
4596
  findEmittedRequires,
4353
4597
  findMainEntryFactoryImports,
4598
+ findManagedBootstrap,
4354
4599
  findTextScriptProperties,
4355
4600
  getProgramDiagnostics,
4356
4601
  guiScriptResourceOf,
@@ -4379,6 +4624,7 @@ export {
4379
4624
  resolveClassifiedSlotAtPosition,
4380
4625
  resolveHsmSourceDir,
4381
4626
  rewriteEmittedRequires,
4627
+ scanEmittedRequires,
4382
4628
  slotRejectsForeignSocket,
4383
4629
  socketOfAddress,
4384
4630
  stripIncludeBase,