@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/companion-closure.d.ts +7 -0
- package/dist/debug-bootstrap.d.ts +21 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +488 -242
- package/dist/lifecycle-erasure.d.ts +1 -0
- package/dist/transpile.d.ts +3 -0
- package/package.json +5 -2
- package/src/companion-closure.ts +28 -6
- package/src/companion-emit.ts +35 -4
- package/src/debug-bootstrap.ts +88 -0
- package/src/hsm-builtin.ts +2 -2
- package/src/index.ts +8 -0
- package/src/lifecycle-erasure.ts +233 -8
- package/src/timers-runtime.ts +2 -2
- package/src/transpile.ts +48 -12
package/dist/index.js
CHANGED
|
@@ -1,8 +1,53 @@
|
|
|
1
1
|
// src/companion-closure.ts
|
|
2
|
-
import * as
|
|
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
|
|
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
|
|
67
|
+
SyntaxKind as SyntaxKind5
|
|
23
68
|
} from "typescript-to-lua";
|
|
24
69
|
|
|
25
70
|
// src/message-dispatch-lowering.ts
|
|
26
|
-
import * as
|
|
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
|
|
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 &
|
|
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 (
|
|
109
|
+
if (ts2.isIdentifier(name) || ts2.isStringLiteral(name)) {
|
|
65
110
|
return name.text;
|
|
66
111
|
}
|
|
67
|
-
if (
|
|
112
|
+
if (ts2.isNumericLiteral(name)) {
|
|
68
113
|
return String(Number(name.text));
|
|
69
114
|
}
|
|
70
|
-
if (
|
|
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:
|
|
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 (
|
|
136
|
+
if (ts2.isMethodDeclaration(property) && property.body !== undefined) {
|
|
92
137
|
return property;
|
|
93
138
|
}
|
|
94
|
-
if (
|
|
139
|
+
if (ts2.isPropertyAssignment(property)) {
|
|
95
140
|
const initializer = property.initializer;
|
|
96
|
-
if (
|
|
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
|
|
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 || !
|
|
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 (
|
|
165
|
+
if (ts2.isBlock(fn.body)) {
|
|
121
166
|
return context.transformStatements(fn.body.statements);
|
|
122
167
|
}
|
|
123
|
-
return context.transformStatements([
|
|
168
|
+
return context.transformStatements([ts2.factory.createExpressionStatement(fn.body)]);
|
|
124
169
|
}
|
|
125
170
|
var messageDispatchLoweringPlugin = {
|
|
126
171
|
visitors: {
|
|
127
|
-
[
|
|
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 &&
|
|
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)]),
|
|
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
|
|
220
|
+
function factoryExportName(callee, checker) {
|
|
176
221
|
let symbol = checker.getSymbolAtLocation(callee);
|
|
177
222
|
if (symbol === undefined) {
|
|
178
|
-
return
|
|
223
|
+
return;
|
|
179
224
|
}
|
|
180
|
-
if (symbol.flags &
|
|
225
|
+
if (symbol.flags & ts3.SymbolFlags.Alias) {
|
|
181
226
|
symbol = checker.getAliasedSymbol(symbol);
|
|
182
227
|
}
|
|
183
|
-
|
|
184
|
-
|
|
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
|
|
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
|
|
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 (
|
|
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 (
|
|
255
|
+
if (ts3.isMethodDeclaration(property) && property.body !== undefined) {
|
|
207
256
|
return property;
|
|
208
257
|
}
|
|
209
|
-
if (
|
|
258
|
+
if (ts3.isPropertyAssignment(property)) {
|
|
210
259
|
const initializer = property.initializer;
|
|
211
|
-
if (
|
|
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 (!
|
|
267
|
+
if (!ts3.isPropertyAssignment(property)) {
|
|
219
268
|
return;
|
|
220
269
|
}
|
|
221
270
|
const initializer = property.initializer;
|
|
222
|
-
if (!
|
|
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 (
|
|
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
|
|
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 (!
|
|
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 (
|
|
294
|
+
if (ts3.isReturnStatement(node) && node.expression !== undefined) {
|
|
246
295
|
found = true;
|
|
247
296
|
return;
|
|
248
297
|
}
|
|
249
|
-
|
|
298
|
+
ts3.forEachChild(node, visit);
|
|
250
299
|
};
|
|
251
|
-
|
|
300
|
+
ts3.forEachChild(fn.body, visit);
|
|
252
301
|
return found;
|
|
253
302
|
}
|
|
254
303
|
function initBuilderBody(fn, context) {
|
|
255
|
-
if (
|
|
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) &&
|
|
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(),
|
|
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 (!
|
|
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 (!
|
|
337
|
+
if (!ts3.isPropertyAssignment(member)) {
|
|
280
338
|
continue;
|
|
281
339
|
}
|
|
282
340
|
const key = member.name;
|
|
283
|
-
if (!
|
|
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 (!
|
|
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 || !
|
|
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
|
-
|
|
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) &&
|
|
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 (!
|
|
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 || !
|
|
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
|
-
[
|
|
367
|
-
[
|
|
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
|
-
[
|
|
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 >=
|
|
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 && !
|
|
388
|
-
if (
|
|
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 (
|
|
589
|
+
if (ts4.isPropertyAccessExpression(parent)) {
|
|
401
590
|
return parent.name === node;
|
|
402
591
|
}
|
|
403
|
-
if (
|
|
592
|
+
if (ts4.isQualifiedName(parent)) {
|
|
404
593
|
return parent.right === node;
|
|
405
594
|
}
|
|
406
|
-
if ((
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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 &&
|
|
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 (
|
|
625
|
+
if (ts4.isParenthesizedExpression(target)) {
|
|
437
626
|
classify(target.expression);
|
|
438
627
|
return;
|
|
439
628
|
}
|
|
440
|
-
if (
|
|
629
|
+
if (ts4.isPropertyAccessExpression(target) || ts4.isElementAccessExpression(target)) {
|
|
441
630
|
return;
|
|
442
631
|
}
|
|
443
|
-
if (
|
|
632
|
+
if (ts4.isArrayLiteralExpression(target)) {
|
|
444
633
|
for (const element of target.elements) {
|
|
445
|
-
if (
|
|
634
|
+
if (ts4.isOmittedExpression(element)) {
|
|
446
635
|
continue;
|
|
447
636
|
}
|
|
448
|
-
if (
|
|
637
|
+
if (ts4.isSpreadElement(element)) {
|
|
449
638
|
classify(element.expression);
|
|
450
|
-
} else if (
|
|
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 (
|
|
647
|
+
if (ts4.isObjectLiteralExpression(target)) {
|
|
459
648
|
for (const property of target.properties) {
|
|
460
|
-
if (
|
|
649
|
+
if (ts4.isPropertyAssignment(property)) {
|
|
461
650
|
classify(property.initializer);
|
|
462
|
-
} else if (
|
|
651
|
+
} else if (ts4.isSpreadAssignment(property)) {
|
|
463
652
|
classify(property.expression);
|
|
464
|
-
} else if (
|
|
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 (
|
|
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 (
|
|
670
|
+
if (ts4.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
|
|
482
671
|
classify(node.left);
|
|
483
|
-
} else if ((
|
|
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 ((
|
|
674
|
+
} else if ((ts4.isForInStatement(node) || ts4.isForOfStatement(node)) && !ts4.isVariableDeclarationList(node.initializer)) {
|
|
486
675
|
classify(node.initializer);
|
|
487
676
|
}
|
|
488
|
-
|
|
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 || !
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
710
|
+
} else if (ts4.isFunctionDeclaration(statement) || ts4.isClassDeclaration(statement) || ts4.isEnumDeclaration(statement)) {
|
|
522
711
|
add(statement.name, statement, statement);
|
|
523
|
-
} else if (
|
|
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 (
|
|
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
|
|
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 &
|
|
552
|
-
return (resolved.flags &
|
|
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 (
|
|
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 || !
|
|
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 (
|
|
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 (
|
|
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 (
|
|
801
|
+
if (ts4.isIdentifier(name)) {
|
|
613
802
|
visit(name);
|
|
614
803
|
return;
|
|
615
804
|
}
|
|
616
805
|
for (const element of name.elements) {
|
|
617
|
-
if (
|
|
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
|
|
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 (
|
|
818
|
+
if (ts4.isParenthesizedExpression(expression) || ts4.isAsExpression(expression) || ts4.isTypeAssertionExpression(expression) || ts4.isNonNullExpression(expression)) {
|
|
630
819
|
return isEffectFreeExpression(expression.expression);
|
|
631
820
|
}
|
|
632
|
-
if (
|
|
821
|
+
if (ts4.isIdentifier(expression) || ts4.isLiteralExpression(expression)) {
|
|
633
822
|
return true;
|
|
634
823
|
}
|
|
635
824
|
switch (expression.kind) {
|
|
636
|
-
case
|
|
637
|
-
case
|
|
638
|
-
case
|
|
639
|
-
case
|
|
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 (
|
|
833
|
+
if (ts4.isFunctionExpression(expression) || ts4.isArrowFunction(expression)) {
|
|
645
834
|
return true;
|
|
646
835
|
}
|
|
647
|
-
if (
|
|
648
|
-
return expression.operator !==
|
|
836
|
+
if (ts4.isPrefixUnaryExpression(expression)) {
|
|
837
|
+
return expression.operator !== ts4.SyntaxKind.PlusPlusToken && expression.operator !== ts4.SyntaxKind.MinusMinusToken && isEffectFreeExpression(expression.operand);
|
|
649
838
|
}
|
|
650
|
-
if (
|
|
839
|
+
if (ts4.isBinaryExpression(expression)) {
|
|
651
840
|
return !isAssignmentOperator(expression.operatorToken.kind) && isEffectFreeExpression(expression.left) && isEffectFreeExpression(expression.right);
|
|
652
841
|
}
|
|
653
|
-
if (
|
|
842
|
+
if (ts4.isConditionalExpression(expression)) {
|
|
654
843
|
return isEffectFreeExpression(expression.condition) && isEffectFreeExpression(expression.whenTrue) && isEffectFreeExpression(expression.whenFalse);
|
|
655
844
|
}
|
|
656
|
-
if (
|
|
845
|
+
if (ts4.isArrayLiteralExpression(expression)) {
|
|
657
846
|
return expression.elements.every(isEffectFreeExpression);
|
|
658
847
|
}
|
|
659
|
-
if (
|
|
848
|
+
if (ts4.isObjectLiteralExpression(expression)) {
|
|
660
849
|
return expression.properties.every((property) => {
|
|
661
|
-
if (
|
|
850
|
+
if (ts4.isPropertyAssignment(property)) {
|
|
662
851
|
return isEffectFreeExpression(property.initializer);
|
|
663
852
|
}
|
|
664
|
-
return
|
|
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 (
|
|
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 (
|
|
862
|
+
if (ts4.isVariableStatement(statement)) {
|
|
674
863
|
return statement.declarationList.declarations.every((declaration) => isEffectFreeExpression(declaration.initializer));
|
|
675
864
|
}
|
|
676
|
-
if (
|
|
865
|
+
if (ts4.isExpressionStatement(statement)) {
|
|
677
866
|
return isLifecycleFactoryCall(statement.expression, checker) || isEffectFreeExpression(statement.expression);
|
|
678
867
|
}
|
|
679
|
-
if (
|
|
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 (
|
|
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 (!
|
|
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 || !
|
|
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) ||
|
|
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:
|
|
1025
|
+
member: name,
|
|
832
1026
|
sites,
|
|
833
|
-
message: `top-level work
|
|
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
|
|
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 || !
|
|
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
|
|
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 (
|
|
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
|
-
[
|
|
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(
|
|
1810
|
+
return context.superTransformStatements(ts5.factory.updateImportDeclaration(node, node.modifiers, node.importClause, lowerSpecifier(module), node.attributes));
|
|
1616
1811
|
},
|
|
1617
|
-
[
|
|
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(
|
|
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
|
|
2337
|
+
import * as ts6 from "typescript";
|
|
2143
2338
|
function findMainEntryFactoryImports(fileName, source) {
|
|
2144
|
-
const sourceFile =
|
|
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 (!
|
|
2342
|
+
if (!ts6.isImportDeclaration(statement)) {
|
|
2148
2343
|
continue;
|
|
2149
2344
|
}
|
|
2150
2345
|
const specifier = statement.moduleSpecifier;
|
|
2151
|
-
if (!
|
|
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 || !
|
|
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
|
|
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
|
|
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
|
|
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 &
|
|
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
|
-
[
|
|
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]),
|
|
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
|
|
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
|
|
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 &
|
|
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
|
-
[
|
|
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]),
|
|
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
|
|
2511
|
+
import * as ts9 from "typescript";
|
|
2317
2512
|
import { LuaLibFeature as LuaLibFeature2 } from "typescript-to-lua";
|
|
2318
2513
|
function isTimersSpecifier(node) {
|
|
2319
|
-
return
|
|
2514
|
+
return ts9.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
|
|
2320
2515
|
}
|
|
2321
2516
|
function importsTimersModule(sourceFile) {
|
|
2322
|
-
return sourceFile.statements.some((statement) =>
|
|
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
|
-
[
|
|
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 =
|
|
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
|
|
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 || !
|
|
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
|
-
[
|
|
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
|
|
2565
|
+
import * as ts11 from "typescript";
|
|
2371
2566
|
import {
|
|
2372
2567
|
createBinaryExpression as createBinaryExpression5,
|
|
2373
|
-
SyntaxKind as
|
|
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 &
|
|
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
|
-
[
|
|
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,
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
3033
|
-
return expression !== undefined &&
|
|
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 =
|
|
3186
|
-
if (specifier === undefined || !
|
|
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) =>
|
|
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
|
-
[
|
|
3359
|
-
[
|
|
3360
|
-
[
|
|
3361
|
-
[
|
|
3362
|
-
[
|
|
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
|
-
|
|
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
|
|
3627
|
+
const rest = halves.script.filter((statement) => !bootstrap.has(statement));
|
|
3628
|
+
const insertAt = requireInsertionPoint(rest, reads);
|
|
3412
3629
|
const scriptStatements = [
|
|
3413
|
-
...
|
|
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
|
-
...
|
|
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
|
|
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 &
|
|
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 (!
|
|
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 (!
|
|
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 || !
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
|
|
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 (
|
|
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
|
-
|
|
3753
|
+
ts15.forEachChild(node, visit);
|
|
3536
3754
|
};
|
|
3537
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 ||
|
|
4121
|
+
fileExists: (fileName) => mergedContent(normalizeSlashes(fileName)) !== undefined || ts16.sys.fileExists(fileName),
|
|
3881
4122
|
getCanonicalFileName: (fileName) => fileName,
|
|
3882
4123
|
getCurrentDirectory: () => "",
|
|
3883
|
-
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 =
|
|
3906
|
-
const preEmitDiagnostics =
|
|
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
|
-
...
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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 =
|
|
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 &
|
|
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 &
|
|
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
|
|
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(
|
|
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 || !
|
|
4254
|
+
if (!declaration || !ts18.isFunctionLike(declaration))
|
|
4014
4255
|
return;
|
|
4015
4256
|
const parameter = declaration.parameters[index];
|
|
4016
|
-
if (!parameter || parameter.dotDotDotToken || !
|
|
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
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
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 (
|
|
4271
|
+
while (ts18.isParenthesizedExpression(node.parent))
|
|
4031
4272
|
node = node.parent;
|
|
4032
4273
|
const comparison = node.parent;
|
|
4033
|
-
if (!
|
|
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) =>
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
4307
|
+
if (!ts18.isCallExpression(call))
|
|
4067
4308
|
return;
|
|
4068
4309
|
const callee = call.expression;
|
|
4069
|
-
if (!
|
|
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 || !
|
|
4328
|
+
if (!declaration || !ts18.isFunctionLike(declaration))
|
|
4088
4329
|
return;
|
|
4089
|
-
const index = declaration.parameters.findIndex((parameter) => !parameter.dotDotDotToken &&
|
|
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 &&
|
|
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 (
|
|
4341
|
+
if (ts18.isStringLiteralLike(node))
|
|
4101
4342
|
found = node;
|
|
4102
|
-
|
|
4343
|
+
ts18.forEachChild(node, visit);
|
|
4103
4344
|
};
|
|
4104
|
-
|
|
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
|
|
4379
|
+
import * as ts20 from "typescript";
|
|
4139
4380
|
|
|
4140
4381
|
// src/url-address-literals.ts
|
|
4141
|
-
import * as
|
|
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 &
|
|
4387
|
+
if ((type.flags & ts19.TypeFlags.Object) === 0)
|
|
4147
4388
|
return;
|
|
4148
|
-
if ((type.objectFlags &
|
|
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,
|
|
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,
|
|
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
|
|
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 (
|
|
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
|
-
|
|
4474
|
+
ts20.forEachChild(node, visit);
|
|
4234
4475
|
};
|
|
4235
|
-
|
|
4476
|
+
ts20.forEachChild(sourceFile, visit);
|
|
4236
4477
|
}
|
|
4237
4478
|
return findings;
|
|
4238
4479
|
}
|
|
4239
4480
|
// src/url-fragment-reachability.ts
|
|
4240
|
-
import * as
|
|
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 (
|
|
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
|
-
|
|
4545
|
+
ts21.forEachChild(node, visit);
|
|
4305
4546
|
};
|
|
4306
|
-
|
|
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,
|