@defold-typescript/transpiler 0.52.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 +2 -0
- package/dist/index.js +328 -250
- 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/index.ts +7 -0
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
|
}
|
|
@@ -177,7 +222,7 @@ function factoryExportName(callee, checker) {
|
|
|
177
222
|
if (symbol === undefined) {
|
|
178
223
|
return;
|
|
179
224
|
}
|
|
180
|
-
if (symbol.flags &
|
|
225
|
+
if (symbol.flags & ts3.SymbolFlags.Alias) {
|
|
181
226
|
symbol = checker.getAliasedSymbol(symbol);
|
|
182
227
|
}
|
|
183
228
|
const name = symbol.getName();
|
|
@@ -194,51 +239,51 @@ function resolvesToFactoryExport(callee, checker) {
|
|
|
194
239
|
return factoryExportName(callee, checker) !== undefined;
|
|
195
240
|
}
|
|
196
241
|
function isThisParameter2(param) {
|
|
197
|
-
return
|
|
242
|
+
return ts3.isIdentifier(param.name) && ts3.identifierToKeywordKind(param.name) === ts3.SyntaxKind.ThisKeyword;
|
|
198
243
|
}
|
|
199
244
|
function hookName(property) {
|
|
200
245
|
const name = property.name;
|
|
201
246
|
if (name === undefined) {
|
|
202
247
|
return;
|
|
203
248
|
}
|
|
204
|
-
if (
|
|
249
|
+
if (ts3.isIdentifier(name) || ts3.isStringLiteral(name)) {
|
|
205
250
|
return name.text;
|
|
206
251
|
}
|
|
207
252
|
return;
|
|
208
253
|
}
|
|
209
254
|
function hookFunction(property) {
|
|
210
|
-
if (
|
|
255
|
+
if (ts3.isMethodDeclaration(property) && property.body !== undefined) {
|
|
211
256
|
return property;
|
|
212
257
|
}
|
|
213
|
-
if (
|
|
258
|
+
if (ts3.isPropertyAssignment(property)) {
|
|
214
259
|
const initializer = property.initializer;
|
|
215
|
-
if (
|
|
260
|
+
if (ts3.isFunctionExpression(initializer) || ts3.isArrowFunction(initializer)) {
|
|
216
261
|
return initializer;
|
|
217
262
|
}
|
|
218
263
|
}
|
|
219
264
|
return;
|
|
220
265
|
}
|
|
221
266
|
function dispatcherInitializer(property, checker) {
|
|
222
|
-
if (!
|
|
267
|
+
if (!ts3.isPropertyAssignment(property)) {
|
|
223
268
|
return;
|
|
224
269
|
}
|
|
225
270
|
const initializer = property.initializer;
|
|
226
|
-
if (!
|
|
271
|
+
if (!ts3.isCallExpression(initializer)) {
|
|
227
272
|
return;
|
|
228
273
|
}
|
|
229
274
|
return resolvesToDispatchExport(initializer.expression, checker) ? initializer : undefined;
|
|
230
275
|
}
|
|
231
276
|
function transformHookBody(fn, context) {
|
|
232
|
-
if (
|
|
277
|
+
if (ts3.isBlock(fn.body)) {
|
|
233
278
|
return context.transformStatements(fn.body.statements);
|
|
234
279
|
}
|
|
235
280
|
return [createExpressionStatement(context.transformExpression(fn.body))];
|
|
236
281
|
}
|
|
237
282
|
function crossesFunctionBoundary(node) {
|
|
238
|
-
return
|
|
283
|
+
return ts3.isFunctionDeclaration(node) || ts3.isFunctionExpression(node) || ts3.isArrowFunction(node) || ts3.isMethodDeclaration(node) || ts3.isGetAccessorDeclaration(node) || ts3.isSetAccessorDeclaration(node);
|
|
239
284
|
}
|
|
240
285
|
function initReturnsValue(fn) {
|
|
241
|
-
if (!
|
|
286
|
+
if (!ts3.isBlock(fn.body)) {
|
|
242
287
|
return true;
|
|
243
288
|
}
|
|
244
289
|
let found = false;
|
|
@@ -246,23 +291,23 @@ function initReturnsValue(fn) {
|
|
|
246
291
|
if (found || crossesFunctionBoundary(node)) {
|
|
247
292
|
return;
|
|
248
293
|
}
|
|
249
|
-
if (
|
|
294
|
+
if (ts3.isReturnStatement(node) && node.expression !== undefined) {
|
|
250
295
|
found = true;
|
|
251
296
|
return;
|
|
252
297
|
}
|
|
253
|
-
|
|
298
|
+
ts3.forEachChild(node, visit);
|
|
254
299
|
};
|
|
255
|
-
|
|
300
|
+
ts3.forEachChild(fn.body, visit);
|
|
256
301
|
return found;
|
|
257
302
|
}
|
|
258
303
|
function initBuilderBody(fn, context) {
|
|
259
|
-
if (
|
|
304
|
+
if (ts3.isBlock(fn.body)) {
|
|
260
305
|
return context.transformStatements(fn.body.statements);
|
|
261
306
|
}
|
|
262
307
|
return [createReturnStatement([context.transformExpression(fn.body)])];
|
|
263
308
|
}
|
|
264
309
|
function emitInitMerge(fn, context, property) {
|
|
265
|
-
const authorParam = fn.parameters.find((param) => !isThisParameter2(param) &&
|
|
310
|
+
const authorParam = fn.parameters.find((param) => !isThisParameter2(param) && ts3.isIdentifier(param.name));
|
|
266
311
|
const builderParams = authorParam === undefined ? [] : [context.transformExpression(authorParam.name)];
|
|
267
312
|
const builder = createFunctionExpression2(createBlock2(initBuilderBody(fn, context)), builderParams, undefined, NodeFlags2.Declaration, fn);
|
|
268
313
|
const builderDecl = createVariableDeclarationStatement2(createIdentifier2("____init"), builder);
|
|
@@ -270,7 +315,7 @@ function emitInitMerge(fn, context, property) {
|
|
|
270
315
|
const stateDecl = createVariableDeclarationStatement2(createIdentifier2("____s"), createCallExpression2(createIdentifier2("____init"), builderArgs));
|
|
271
316
|
const mergeAssignment = createAssignmentStatement(createTableIndexExpression(createIdentifier2("self"), createIdentifier2("____k")), createIdentifier2("____v"));
|
|
272
317
|
const forIn = createForInStatement(createBlock2([mergeAssignment]), [createIdentifier2("____k"), createIdentifier2("____v")], [createCallExpression2(createIdentifier2("pairs"), [createIdentifier2("____s")])]);
|
|
273
|
-
const guard = createIfStatement2(createBinaryExpression2(createIdentifier2("____s"), createNilLiteral(),
|
|
318
|
+
const guard = createIfStatement2(createBinaryExpression2(createIdentifier2("____s"), createNilLiteral(), SyntaxKind5.InequalityOperator), createBlock2([forIn]));
|
|
274
319
|
const initFn = createFunctionExpression2(createBlock2([stateDecl, guard]), [createIdentifier2("self")], undefined, NodeFlags2.Declaration, fn);
|
|
275
320
|
return [builderDecl, createAssignmentStatement(createIdentifier2("init"), initFn, property)];
|
|
276
321
|
}
|
|
@@ -284,16 +329,16 @@ var RESOURCE_PROPERTY_MARKERS = new Set([
|
|
|
284
329
|
"resource.tile_source"
|
|
285
330
|
]);
|
|
286
331
|
function propertyMembers(property) {
|
|
287
|
-
if (!
|
|
332
|
+
if (!ts3.isPropertyAssignment(property) || !ts3.isObjectLiteralExpression(property.initializer)) {
|
|
288
333
|
return [];
|
|
289
334
|
}
|
|
290
335
|
const members = [];
|
|
291
336
|
for (const member of property.initializer.properties) {
|
|
292
|
-
if (!
|
|
337
|
+
if (!ts3.isPropertyAssignment(member)) {
|
|
293
338
|
continue;
|
|
294
339
|
}
|
|
295
340
|
const key = member.name;
|
|
296
|
-
if (!
|
|
341
|
+
if (!ts3.isIdentifier(key) && !ts3.isStringLiteral(key)) {
|
|
297
342
|
continue;
|
|
298
343
|
}
|
|
299
344
|
members.push({ name: key.text, initializer: member.initializer });
|
|
@@ -301,14 +346,14 @@ function propertyMembers(property) {
|
|
|
301
346
|
return members;
|
|
302
347
|
}
|
|
303
348
|
function factoryHooks(expression, checker) {
|
|
304
|
-
if (!
|
|
349
|
+
if (!ts3.isCallExpression(expression)) {
|
|
305
350
|
return;
|
|
306
351
|
}
|
|
307
352
|
if (!resolvesToFactoryExport(expression.expression, checker)) {
|
|
308
353
|
return;
|
|
309
354
|
}
|
|
310
355
|
const hooks = expression.arguments[0];
|
|
311
|
-
if (hooks === undefined || !
|
|
356
|
+
if (hooks === undefined || !ts3.isObjectLiteralExpression(hooks)) {
|
|
312
357
|
return;
|
|
313
358
|
}
|
|
314
359
|
return hooks;
|
|
@@ -326,21 +371,21 @@ function scriptOnlyProperties(property, factory) {
|
|
|
326
371
|
file,
|
|
327
372
|
start,
|
|
328
373
|
length: property.getEnd() - start,
|
|
329
|
-
category:
|
|
374
|
+
category: ts3.DiagnosticCategory.Error,
|
|
330
375
|
code: 0,
|
|
331
376
|
messageText: `\`${factory}\` cannot declare \`properties\`: Defold builds \`go.property\` only in \`.script\` files. Declare the property in a \`defineScript\` and send its value with \`msg.post\`.`
|
|
332
377
|
};
|
|
333
378
|
}
|
|
334
379
|
function outermostWrapper(node) {
|
|
335
380
|
let current = node;
|
|
336
|
-
while (
|
|
381
|
+
while (ts3.isParenthesizedExpression(current.parent) || ts3.isAsExpression(current.parent) || ts3.isSatisfiesExpression(current.parent) || ts3.isNonNullExpression(current.parent) || ts3.isTypeAssertionExpression(current.parent)) {
|
|
337
382
|
current = current.parent;
|
|
338
383
|
}
|
|
339
384
|
return current;
|
|
340
385
|
}
|
|
341
386
|
function innermostExpression(node) {
|
|
342
387
|
let current = node;
|
|
343
|
-
while (
|
|
388
|
+
while (ts3.isParenthesizedExpression(current) || ts3.isAsExpression(current) || ts3.isSatisfiesExpression(current) || ts3.isNonNullExpression(current) || ts3.isTypeAssertionExpression(current)) {
|
|
344
389
|
current = current.expression;
|
|
345
390
|
}
|
|
346
391
|
return current;
|
|
@@ -354,7 +399,7 @@ function globalName(symbol, checker) {
|
|
|
354
399
|
}
|
|
355
400
|
function calledGlobal(call, checker) {
|
|
356
401
|
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
357
|
-
if (declaration === undefined || !
|
|
402
|
+
if (declaration === undefined || !ts3.isFunctionDeclaration(declaration) || declaration.name === undefined) {
|
|
358
403
|
return;
|
|
359
404
|
}
|
|
360
405
|
return globalName(checker.getSymbolAtLocation(declaration.name), checker);
|
|
@@ -362,15 +407,15 @@ function calledGlobal(call, checker) {
|
|
|
362
407
|
function isPropertyDefault(call, checker) {
|
|
363
408
|
const value = outermostWrapper(call);
|
|
364
409
|
const parent = value.parent;
|
|
365
|
-
if (
|
|
410
|
+
if (ts3.isCallExpression(parent)) {
|
|
366
411
|
return parent.arguments[1] === value && calledGlobal(parent, checker) === "go.property";
|
|
367
412
|
}
|
|
368
413
|
const properties = parent?.parent?.parent;
|
|
369
|
-
if (properties === undefined || !
|
|
414
|
+
if (properties === undefined || !ts3.isPropertyAssignment(properties) || !isPropertiesHook(properties)) {
|
|
370
415
|
return false;
|
|
371
416
|
}
|
|
372
417
|
const hooks = properties.parent;
|
|
373
|
-
return
|
|
418
|
+
return ts3.isObjectLiteralExpression(hooks) && factoryHooks(hooks.parent, checker) === hooks && propertyMembers(properties).some((member) => member.initializer === value);
|
|
374
419
|
}
|
|
375
420
|
function misplacedMarker(node, marker) {
|
|
376
421
|
const file = node.getSourceFile();
|
|
@@ -379,25 +424,25 @@ function misplacedMarker(node, marker) {
|
|
|
379
424
|
file,
|
|
380
425
|
start,
|
|
381
426
|
length: node.getEnd() - start,
|
|
382
|
-
category:
|
|
427
|
+
category: ts3.DiagnosticCategory.Error,
|
|
383
428
|
code: 0,
|
|
384
429
|
messageText: `\`${marker}\` is a build-time marker: Defold's build reads it only in a \`go.property\` default, and the engine binds no such function. Use it as a \`defineScript\` \`properties\` default.`
|
|
385
430
|
};
|
|
386
431
|
}
|
|
387
432
|
function readsAsMarker(call) {
|
|
388
433
|
const callee = innermostExpression(call.expression);
|
|
389
|
-
if (
|
|
434
|
+
if (ts3.isOptionalChain(call) || ts3.isOptionalChain(callee)) {
|
|
390
435
|
return false;
|
|
391
436
|
}
|
|
392
|
-
if (!
|
|
437
|
+
if (!ts3.isPropertyAccessExpression(callee) && !(ts3.isElementAccessExpression(callee) && ts3.isStringLiteralLike(innermostExpression(callee.argumentExpression)))) {
|
|
393
438
|
return false;
|
|
394
439
|
}
|
|
395
440
|
const receiver = innermostExpression(callee.expression);
|
|
396
|
-
if (!
|
|
441
|
+
if (!ts3.isIdentifier(receiver) || receiver.text !== "resource") {
|
|
397
442
|
return false;
|
|
398
443
|
}
|
|
399
444
|
const [path] = call.arguments;
|
|
400
|
-
return path === undefined ||
|
|
445
|
+
return path === undefined || ts3.isStringLiteralLike(innermostExpression(path));
|
|
401
446
|
}
|
|
402
447
|
function unreadableMarker(node, marker) {
|
|
403
448
|
const file = node.getSourceFile();
|
|
@@ -406,18 +451,18 @@ function unreadableMarker(node, marker) {
|
|
|
406
451
|
file,
|
|
407
452
|
start,
|
|
408
453
|
length: node.getEnd() - start,
|
|
409
|
-
category:
|
|
454
|
+
category: ts3.DiagnosticCategory.Error,
|
|
410
455
|
code: 0,
|
|
411
456
|
messageText: `\`${marker}\` in a property default must be written \`${marker}("<path>")\`, with a string literal path: Defold's build reads no other form.`
|
|
412
457
|
};
|
|
413
458
|
}
|
|
414
459
|
function isCallee(node) {
|
|
415
460
|
const callee = outermostWrapper(node);
|
|
416
|
-
return
|
|
461
|
+
return ts3.isCallExpression(callee.parent) && callee.parent.expression === callee;
|
|
417
462
|
}
|
|
418
463
|
function eraseFactoryCall(expression, context) {
|
|
419
464
|
const hooks = factoryHooks(expression, context.checker);
|
|
420
|
-
if (hooks === undefined || !
|
|
465
|
+
if (hooks === undefined || !ts3.isCallExpression(expression)) {
|
|
421
466
|
return;
|
|
422
467
|
}
|
|
423
468
|
const factory = factoryExportName(expression.expression, context.checker);
|
|
@@ -448,14 +493,14 @@ function eraseFactoryCall(expression, context) {
|
|
|
448
493
|
statements.push(...emitInitMerge(fn, context, property));
|
|
449
494
|
continue;
|
|
450
495
|
}
|
|
451
|
-
const params = fn.parameters.filter((param) => !isThisParameter2(param) &&
|
|
496
|
+
const params = fn.parameters.filter((param) => !isThisParameter2(param) && ts3.isIdentifier(param.name)).map((param) => context.transformExpression(param.name));
|
|
452
497
|
const fnExpression = createFunctionExpression2(createBlock2(transformHookBody(fn, context)), params, undefined, NodeFlags2.Declaration, fn);
|
|
453
498
|
statements.push(createAssignmentStatement(createIdentifier2(name), fnExpression, property));
|
|
454
499
|
}
|
|
455
500
|
return [...registrations, ...statements];
|
|
456
501
|
}
|
|
457
502
|
function isFactoryOnlyImport(node) {
|
|
458
|
-
if (!
|
|
503
|
+
if (!ts3.isStringLiteral(node.moduleSpecifier) || !FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
|
|
459
504
|
return false;
|
|
460
505
|
}
|
|
461
506
|
const clause = node.importClause;
|
|
@@ -466,7 +511,7 @@ function isFactoryOnlyImport(node) {
|
|
|
466
511
|
return false;
|
|
467
512
|
}
|
|
468
513
|
const bindings = clause.namedBindings;
|
|
469
|
-
if (bindings === undefined || !
|
|
514
|
+
if (bindings === undefined || !ts3.isNamedImports(bindings)) {
|
|
470
515
|
return false;
|
|
471
516
|
}
|
|
472
517
|
const runtime = bindings.elements.filter((element) => !element.isTypeOnly);
|
|
@@ -477,8 +522,8 @@ function isFactoryOnlyImport(node) {
|
|
|
477
522
|
}
|
|
478
523
|
var lifecycleErasurePlugin = {
|
|
479
524
|
visitors: {
|
|
480
|
-
[
|
|
481
|
-
[
|
|
525
|
+
[ts3.SyntaxKind.ExpressionStatement]: (node, context) => eraseFactoryCall(node.expression, context) ?? context.superTransformStatements(node),
|
|
526
|
+
[ts3.SyntaxKind.ExportAssignment]: (node, context) => {
|
|
482
527
|
if (!node.isExportEquals) {
|
|
483
528
|
const erased = eraseFactoryCall(node.expression, context);
|
|
484
529
|
if (erased !== undefined) {
|
|
@@ -487,8 +532,8 @@ var lifecycleErasurePlugin = {
|
|
|
487
532
|
}
|
|
488
533
|
return context.superTransformStatements(node);
|
|
489
534
|
},
|
|
490
|
-
[
|
|
491
|
-
[
|
|
535
|
+
[ts3.SyntaxKind.ImportDeclaration]: (node, context) => isFactoryOnlyImport(node) ? [] : context.superTransformStatements(node),
|
|
536
|
+
[ts3.SyntaxKind.CallExpression]: (node, context) => {
|
|
492
537
|
const marker = node.parent === undefined ? undefined : calledGlobal(node, context.checker);
|
|
493
538
|
if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
|
|
494
539
|
if (!isPropertyDefault(node, context.checker)) {
|
|
@@ -499,7 +544,7 @@ var lifecycleErasurePlugin = {
|
|
|
499
544
|
}
|
|
500
545
|
return context.superTransformExpression(node);
|
|
501
546
|
},
|
|
502
|
-
[
|
|
547
|
+
[ts3.SyntaxKind.PropertyAccessExpression]: (node, context) => {
|
|
503
548
|
if (node.parent !== undefined && !isCallee(node)) {
|
|
504
549
|
const marker = globalName(context.checker.getSymbolAtLocation(node.name), context.checker);
|
|
505
550
|
if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
|
|
@@ -508,10 +553,10 @@ var lifecycleErasurePlugin = {
|
|
|
508
553
|
}
|
|
509
554
|
return context.superTransformExpression(node);
|
|
510
555
|
},
|
|
511
|
-
[
|
|
556
|
+
[ts3.SyntaxKind.ElementAccessExpression]: (node, context) => {
|
|
512
557
|
if (node.parent !== undefined && !isCallee(node)) {
|
|
513
558
|
const key = innermostExpression(node.argumentExpression);
|
|
514
|
-
const marker =
|
|
559
|
+
const marker = ts3.isStringLiteralLike(key) ? globalName(context.checker.getPropertyOfType(context.checker.getTypeAtLocation(node.expression), key.text), context.checker) : undefined;
|
|
515
560
|
if (marker !== undefined && RESOURCE_PROPERTY_MARKERS.has(marker)) {
|
|
516
561
|
context.diagnostics.push(misplacedMarker(node, marker));
|
|
517
562
|
}
|
|
@@ -524,12 +569,12 @@ var lifecycleErasurePlugin = {
|
|
|
524
569
|
// src/companion-closure.ts
|
|
525
570
|
var COMPANION_INTERNAL_FIELD = "____closure";
|
|
526
571
|
function isAssignmentOperator(kind) {
|
|
527
|
-
return kind >=
|
|
572
|
+
return kind >= ts4.SyntaxKind.FirstAssignment && kind <= ts4.SyntaxKind.LastAssignment;
|
|
528
573
|
}
|
|
529
574
|
function isTypePosition(node) {
|
|
530
575
|
let current = node.parent;
|
|
531
|
-
while (current !== undefined && !
|
|
532
|
-
if (
|
|
576
|
+
while (current !== undefined && !ts4.isSourceFile(current)) {
|
|
577
|
+
if (ts4.isTypeNode(current)) {
|
|
533
578
|
return true;
|
|
534
579
|
}
|
|
535
580
|
current = current.parent;
|
|
@@ -541,57 +586,57 @@ function isDeclarationName(node) {
|
|
|
541
586
|
if (parent === undefined) {
|
|
542
587
|
return false;
|
|
543
588
|
}
|
|
544
|
-
if (
|
|
589
|
+
if (ts4.isPropertyAccessExpression(parent)) {
|
|
545
590
|
return parent.name === node;
|
|
546
591
|
}
|
|
547
|
-
if (
|
|
592
|
+
if (ts4.isQualifiedName(parent)) {
|
|
548
593
|
return parent.right === node;
|
|
549
594
|
}
|
|
550
|
-
if ((
|
|
595
|
+
if ((ts4.isBindingElement(parent) || ts4.isImportSpecifier(parent) || ts4.isExportSpecifier(parent)) && parent.propertyName === node) {
|
|
551
596
|
return true;
|
|
552
597
|
}
|
|
553
598
|
const named = parent;
|
|
554
599
|
if (named.name !== node) {
|
|
555
600
|
return false;
|
|
556
601
|
}
|
|
557
|
-
return
|
|
602
|
+
return ts4.isVariableDeclaration(parent) || ts4.isFunctionDeclaration(parent) || ts4.isClassDeclaration(parent) || ts4.isEnumDeclaration(parent) || ts4.isEnumMember(parent) || ts4.isParameter(parent) || ts4.isBindingElement(parent) || ts4.isImportClause(parent) || ts4.isImportSpecifier(parent) || ts4.isNamespaceImport(parent) || ts4.isPropertyAssignment(parent) || ts4.isPropertyDeclaration(parent) || ts4.isPropertySignature(parent) || ts4.isMethodDeclaration(parent) || ts4.isMethodSignature(parent) || ts4.isTypeAliasDeclaration(parent) || ts4.isInterfaceDeclaration(parent) || ts4.isGetAccessor(parent) || ts4.isSetAccessor(parent);
|
|
558
603
|
}
|
|
559
604
|
function forEachReference(root, checker, visit) {
|
|
560
605
|
const walk = (node) => {
|
|
561
|
-
if (
|
|
606
|
+
if (ts4.isIdentifier(node) && !isDeclarationName(node) && !isTypePosition(node)) {
|
|
562
607
|
const symbol = resolveReferencedSymbol(node, checker);
|
|
563
608
|
if (symbol !== undefined) {
|
|
564
609
|
visit(node, symbol);
|
|
565
610
|
}
|
|
566
611
|
}
|
|
567
|
-
|
|
612
|
+
ts4.forEachChild(node, walk);
|
|
568
613
|
};
|
|
569
614
|
walk(root);
|
|
570
615
|
}
|
|
571
616
|
function resolveReferencedSymbol(node, checker) {
|
|
572
617
|
const parent = node.parent;
|
|
573
|
-
if (parent !== undefined &&
|
|
618
|
+
if (parent !== undefined && ts4.isShorthandPropertyAssignment(parent) && parent.name === node) {
|
|
574
619
|
return checker.getShorthandAssignmentValueSymbol(parent) ?? checker.getSymbolAtLocation(node);
|
|
575
620
|
}
|
|
576
621
|
return checker.getSymbolAtLocation(node);
|
|
577
622
|
}
|
|
578
623
|
function forEachAssignmentTarget(root, checker, visit) {
|
|
579
624
|
const classify = (target) => {
|
|
580
|
-
if (
|
|
625
|
+
if (ts4.isParenthesizedExpression(target)) {
|
|
581
626
|
classify(target.expression);
|
|
582
627
|
return;
|
|
583
628
|
}
|
|
584
|
-
if (
|
|
629
|
+
if (ts4.isPropertyAccessExpression(target) || ts4.isElementAccessExpression(target)) {
|
|
585
630
|
return;
|
|
586
631
|
}
|
|
587
|
-
if (
|
|
632
|
+
if (ts4.isArrayLiteralExpression(target)) {
|
|
588
633
|
for (const element of target.elements) {
|
|
589
|
-
if (
|
|
634
|
+
if (ts4.isOmittedExpression(element)) {
|
|
590
635
|
continue;
|
|
591
636
|
}
|
|
592
|
-
if (
|
|
637
|
+
if (ts4.isSpreadElement(element)) {
|
|
593
638
|
classify(element.expression);
|
|
594
|
-
} else if (
|
|
639
|
+
} else if (ts4.isBinaryExpression(element) && element.operatorToken.kind === ts4.SyntaxKind.EqualsToken) {
|
|
595
640
|
classify(element.left);
|
|
596
641
|
} else {
|
|
597
642
|
classify(element);
|
|
@@ -599,13 +644,13 @@ function forEachAssignmentTarget(root, checker, visit) {
|
|
|
599
644
|
}
|
|
600
645
|
return;
|
|
601
646
|
}
|
|
602
|
-
if (
|
|
647
|
+
if (ts4.isObjectLiteralExpression(target)) {
|
|
603
648
|
for (const property of target.properties) {
|
|
604
|
-
if (
|
|
649
|
+
if (ts4.isPropertyAssignment(property)) {
|
|
605
650
|
classify(property.initializer);
|
|
606
|
-
} else if (
|
|
651
|
+
} else if (ts4.isSpreadAssignment(property)) {
|
|
607
652
|
classify(property.expression);
|
|
608
|
-
} else if (
|
|
653
|
+
} else if (ts4.isShorthandPropertyAssignment(property)) {
|
|
609
654
|
const symbol = checker.getShorthandAssignmentValueSymbol(property);
|
|
610
655
|
if (symbol !== undefined) {
|
|
611
656
|
visit(property.name, symbol);
|
|
@@ -614,7 +659,7 @@ function forEachAssignmentTarget(root, checker, visit) {
|
|
|
614
659
|
}
|
|
615
660
|
return;
|
|
616
661
|
}
|
|
617
|
-
if (
|
|
662
|
+
if (ts4.isIdentifier(target)) {
|
|
618
663
|
const symbol = checker.getSymbolAtLocation(target);
|
|
619
664
|
if (symbol !== undefined) {
|
|
620
665
|
visit(target, symbol);
|
|
@@ -622,14 +667,14 @@ function forEachAssignmentTarget(root, checker, visit) {
|
|
|
622
667
|
}
|
|
623
668
|
};
|
|
624
669
|
const walk = (node) => {
|
|
625
|
-
if (
|
|
670
|
+
if (ts4.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) {
|
|
626
671
|
classify(node.left);
|
|
627
|
-
} else if ((
|
|
672
|
+
} else if ((ts4.isPrefixUnaryExpression(node) || ts4.isPostfixUnaryExpression(node)) && (node.operator === ts4.SyntaxKind.PlusPlusToken || node.operator === ts4.SyntaxKind.MinusMinusToken)) {
|
|
628
673
|
classify(node.operand);
|
|
629
|
-
} else if ((
|
|
674
|
+
} else if ((ts4.isForInStatement(node) || ts4.isForOfStatement(node)) && !ts4.isVariableDeclarationList(node.initializer)) {
|
|
630
675
|
classify(node.initializer);
|
|
631
676
|
}
|
|
632
|
-
|
|
677
|
+
ts4.forEachChild(node, walk);
|
|
633
678
|
};
|
|
634
679
|
walk(root);
|
|
635
680
|
}
|
|
@@ -637,7 +682,7 @@ function collectTopLevel(sourceFile, checker) {
|
|
|
637
682
|
const declarations = new Map;
|
|
638
683
|
let order = 0;
|
|
639
684
|
const add = (name, statement, node) => {
|
|
640
|
-
if (name === undefined || !
|
|
685
|
+
if (name === undefined || !ts4.isIdentifier(name)) {
|
|
641
686
|
return;
|
|
642
687
|
}
|
|
643
688
|
const symbol = checker.getSymbolAtLocation(name);
|
|
@@ -647,24 +692,24 @@ function collectTopLevel(sourceFile, checker) {
|
|
|
647
692
|
declarations.set(symbol, { name: name.text, statement, node, order: order++ });
|
|
648
693
|
};
|
|
649
694
|
const addBinding = (name, statement, node) => {
|
|
650
|
-
if (
|
|
695
|
+
if (ts4.isIdentifier(name)) {
|
|
651
696
|
add(name, statement, node);
|
|
652
697
|
return;
|
|
653
698
|
}
|
|
654
699
|
for (const element of name.elements) {
|
|
655
|
-
if (
|
|
700
|
+
if (ts4.isBindingElement(element)) {
|
|
656
701
|
addBinding(element.name, statement, node);
|
|
657
702
|
}
|
|
658
703
|
}
|
|
659
704
|
};
|
|
660
705
|
for (const statement of sourceFile.statements) {
|
|
661
|
-
if (
|
|
706
|
+
if (ts4.isVariableStatement(statement)) {
|
|
662
707
|
for (const declaration of statement.declarationList.declarations) {
|
|
663
708
|
addBinding(declaration.name, statement, declaration);
|
|
664
709
|
}
|
|
665
|
-
} else if (
|
|
710
|
+
} else if (ts4.isFunctionDeclaration(statement) || ts4.isClassDeclaration(statement) || ts4.isEnumDeclaration(statement)) {
|
|
666
711
|
add(statement.name, statement, statement);
|
|
667
|
-
} else if (
|
|
712
|
+
} else if (ts4.isImportDeclaration(statement)) {
|
|
668
713
|
const clause = statement.importClause;
|
|
669
714
|
if (clause === undefined) {
|
|
670
715
|
continue;
|
|
@@ -674,7 +719,7 @@ function collectTopLevel(sourceFile, checker) {
|
|
|
674
719
|
if (bindings === undefined) {
|
|
675
720
|
continue;
|
|
676
721
|
}
|
|
677
|
-
if (
|
|
722
|
+
if (ts4.isNamespaceImport(bindings)) {
|
|
678
723
|
add(bindings.name, statement, statement);
|
|
679
724
|
} else {
|
|
680
725
|
for (const element of bindings.elements) {
|
|
@@ -686,14 +731,14 @@ function collectTopLevel(sourceFile, checker) {
|
|
|
686
731
|
return declarations;
|
|
687
732
|
}
|
|
688
733
|
function hasExportModifier(statement) {
|
|
689
|
-
return
|
|
734
|
+
return ts4.canHaveModifiers(statement) && (ts4.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts4.SyntaxKind.ExportKeyword);
|
|
690
735
|
}
|
|
691
736
|
function isValueSymbol(symbol, checker) {
|
|
692
737
|
if (symbol === undefined) {
|
|
693
738
|
return false;
|
|
694
739
|
}
|
|
695
|
-
const resolved = symbol.flags &
|
|
696
|
-
return (resolved.flags &
|
|
740
|
+
const resolved = symbol.flags & ts4.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
741
|
+
return (resolved.flags & ts4.SymbolFlags.Value) !== 0;
|
|
697
742
|
}
|
|
698
743
|
function collectExports(sourceFile, checker, topLevel) {
|
|
699
744
|
const exported = [];
|
|
@@ -721,12 +766,12 @@ function collectExports(sourceFile, checker, topLevel) {
|
|
|
721
766
|
take(symbol, name.text, declaration.node);
|
|
722
767
|
};
|
|
723
768
|
for (const statement of sourceFile.statements) {
|
|
724
|
-
if (
|
|
769
|
+
if (ts4.isExportDeclaration(statement)) {
|
|
725
770
|
if (statement.moduleSpecifier !== undefined || statement.isTypeOnly) {
|
|
726
771
|
continue;
|
|
727
772
|
}
|
|
728
773
|
const clause = statement.exportClause;
|
|
729
|
-
if (clause === undefined || !
|
|
774
|
+
if (clause === undefined || !ts4.isNamedExports(clause)) {
|
|
730
775
|
continue;
|
|
731
776
|
}
|
|
732
777
|
for (const element of clause.elements) {
|
|
@@ -740,11 +785,11 @@ function collectExports(sourceFile, checker, topLevel) {
|
|
|
740
785
|
if (!hasExportModifier(statement)) {
|
|
741
786
|
continue;
|
|
742
787
|
}
|
|
743
|
-
if (
|
|
788
|
+
if (ts4.isVariableStatement(statement)) {
|
|
744
789
|
for (const declaration of statement.declarationList.declarations) {
|
|
745
790
|
forEachDeclaredName(declaration.name, (name) => takeLocal(checker.getSymbolAtLocation(name), name));
|
|
746
791
|
}
|
|
747
|
-
} else if (
|
|
792
|
+
} else if (ts4.isFunctionDeclaration(statement) || ts4.isClassDeclaration(statement) || ts4.isEnumDeclaration(statement)) {
|
|
748
793
|
if (statement.name !== undefined) {
|
|
749
794
|
takeLocal(checker.getSymbolAtLocation(statement.name), statement.name);
|
|
750
795
|
}
|
|
@@ -753,74 +798,74 @@ function collectExports(sourceFile, checker, topLevel) {
|
|
|
753
798
|
return exported;
|
|
754
799
|
}
|
|
755
800
|
function forEachDeclaredName(name, visit) {
|
|
756
|
-
if (
|
|
801
|
+
if (ts4.isIdentifier(name)) {
|
|
757
802
|
visit(name);
|
|
758
803
|
return;
|
|
759
804
|
}
|
|
760
805
|
for (const element of name.elements) {
|
|
761
|
-
if (
|
|
806
|
+
if (ts4.isBindingElement(element)) {
|
|
762
807
|
forEachDeclaredName(element.name, visit);
|
|
763
808
|
}
|
|
764
809
|
}
|
|
765
810
|
}
|
|
766
811
|
function isLifecycleFactoryCall(expression, checker) {
|
|
767
|
-
return
|
|
812
|
+
return ts4.isCallExpression(expression) && resolvesToFactoryExport(expression.expression, checker);
|
|
768
813
|
}
|
|
769
814
|
function isEffectFreeExpression(expression) {
|
|
770
815
|
if (expression === undefined) {
|
|
771
816
|
return true;
|
|
772
817
|
}
|
|
773
|
-
if (
|
|
818
|
+
if (ts4.isParenthesizedExpression(expression) || ts4.isAsExpression(expression) || ts4.isTypeAssertionExpression(expression) || ts4.isNonNullExpression(expression)) {
|
|
774
819
|
return isEffectFreeExpression(expression.expression);
|
|
775
820
|
}
|
|
776
|
-
if (
|
|
821
|
+
if (ts4.isIdentifier(expression) || ts4.isLiteralExpression(expression)) {
|
|
777
822
|
return true;
|
|
778
823
|
}
|
|
779
824
|
switch (expression.kind) {
|
|
780
|
-
case
|
|
781
|
-
case
|
|
782
|
-
case
|
|
783
|
-
case
|
|
825
|
+
case ts4.SyntaxKind.TrueKeyword:
|
|
826
|
+
case ts4.SyntaxKind.FalseKeyword:
|
|
827
|
+
case ts4.SyntaxKind.NullKeyword:
|
|
828
|
+
case ts4.SyntaxKind.ThisKeyword:
|
|
784
829
|
return true;
|
|
785
830
|
default:
|
|
786
831
|
break;
|
|
787
832
|
}
|
|
788
|
-
if (
|
|
833
|
+
if (ts4.isFunctionExpression(expression) || ts4.isArrowFunction(expression)) {
|
|
789
834
|
return true;
|
|
790
835
|
}
|
|
791
|
-
if (
|
|
792
|
-
return expression.operator !==
|
|
836
|
+
if (ts4.isPrefixUnaryExpression(expression)) {
|
|
837
|
+
return expression.operator !== ts4.SyntaxKind.PlusPlusToken && expression.operator !== ts4.SyntaxKind.MinusMinusToken && isEffectFreeExpression(expression.operand);
|
|
793
838
|
}
|
|
794
|
-
if (
|
|
839
|
+
if (ts4.isBinaryExpression(expression)) {
|
|
795
840
|
return !isAssignmentOperator(expression.operatorToken.kind) && isEffectFreeExpression(expression.left) && isEffectFreeExpression(expression.right);
|
|
796
841
|
}
|
|
797
|
-
if (
|
|
842
|
+
if (ts4.isConditionalExpression(expression)) {
|
|
798
843
|
return isEffectFreeExpression(expression.condition) && isEffectFreeExpression(expression.whenTrue) && isEffectFreeExpression(expression.whenFalse);
|
|
799
844
|
}
|
|
800
|
-
if (
|
|
845
|
+
if (ts4.isArrayLiteralExpression(expression)) {
|
|
801
846
|
return expression.elements.every(isEffectFreeExpression);
|
|
802
847
|
}
|
|
803
|
-
if (
|
|
848
|
+
if (ts4.isObjectLiteralExpression(expression)) {
|
|
804
849
|
return expression.properties.every((property) => {
|
|
805
|
-
if (
|
|
850
|
+
if (ts4.isPropertyAssignment(property)) {
|
|
806
851
|
return isEffectFreeExpression(property.initializer);
|
|
807
852
|
}
|
|
808
|
-
return
|
|
853
|
+
return ts4.isShorthandPropertyAssignment(property) || ts4.isMethodDeclaration(property);
|
|
809
854
|
});
|
|
810
855
|
}
|
|
811
856
|
return false;
|
|
812
857
|
}
|
|
813
858
|
function isEffectFreeStatement(statement, checker) {
|
|
814
|
-
if (
|
|
859
|
+
if (ts4.isImportDeclaration(statement) || ts4.isInterfaceDeclaration(statement) || ts4.isTypeAliasDeclaration(statement) || ts4.isFunctionDeclaration(statement) || ts4.isExportDeclaration(statement)) {
|
|
815
860
|
return true;
|
|
816
861
|
}
|
|
817
|
-
if (
|
|
862
|
+
if (ts4.isVariableStatement(statement)) {
|
|
818
863
|
return statement.declarationList.declarations.every((declaration) => isEffectFreeExpression(declaration.initializer));
|
|
819
864
|
}
|
|
820
|
-
if (
|
|
865
|
+
if (ts4.isExpressionStatement(statement)) {
|
|
821
866
|
return isLifecycleFactoryCall(statement.expression, checker) || isEffectFreeExpression(statement.expression);
|
|
822
867
|
}
|
|
823
|
-
if (
|
|
868
|
+
if (ts4.isExportAssignment(statement) && !statement.isExportEquals) {
|
|
824
869
|
return isLifecycleFactoryCall(statement.expression, checker) || isEffectFreeExpression(statement.expression);
|
|
825
870
|
}
|
|
826
871
|
return false;
|
|
@@ -860,7 +905,7 @@ function computeCompanionClosure(sourceFile, checker) {
|
|
|
860
905
|
if (declaration === undefined) {
|
|
861
906
|
continue;
|
|
862
907
|
}
|
|
863
|
-
if (
|
|
908
|
+
if (ts4.isImportDeclaration(declaration.statement)) {
|
|
864
909
|
importBindingSymbols.add(symbol);
|
|
865
910
|
continue;
|
|
866
911
|
}
|
|
@@ -880,7 +925,7 @@ function computeCompanionClosure(sourceFile, checker) {
|
|
|
880
925
|
}
|
|
881
926
|
const splits = closureStatements.size > 0;
|
|
882
927
|
for (const statement of sourceFile.statements) {
|
|
883
|
-
if (!
|
|
928
|
+
if (!ts4.isExportDeclaration(statement) || statement.isTypeOnly) {
|
|
884
929
|
continue;
|
|
885
930
|
}
|
|
886
931
|
if (statement.moduleSpecifier !== undefined) {
|
|
@@ -890,7 +935,7 @@ function computeCompanionClosure(sourceFile, checker) {
|
|
|
890
935
|
continue;
|
|
891
936
|
}
|
|
892
937
|
const clause = statement.exportClause;
|
|
893
|
-
if (clause === undefined || !
|
|
938
|
+
if (clause === undefined || !ts4.isNamedExports(clause)) {
|
|
894
939
|
continue;
|
|
895
940
|
}
|
|
896
941
|
const readsMember = clause.elements.some((element) => {
|
|
@@ -913,7 +958,7 @@ function computeCompanionClosure(sourceFile, checker) {
|
|
|
913
958
|
});
|
|
914
959
|
const scriptReferences = new Map;
|
|
915
960
|
for (const statement of sourceFile.statements) {
|
|
916
|
-
if (closureStatements.has(statement) ||
|
|
961
|
+
if (closureStatements.has(statement) || ts4.isExportDeclaration(statement)) {
|
|
917
962
|
continue;
|
|
918
963
|
}
|
|
919
964
|
forEachReference(statement, checker, (node, symbol) => {
|
|
@@ -957,8 +1002,12 @@ function computeCompanionClosure(sourceFile, checker) {
|
|
|
957
1002
|
message: `"${COMPANION_INTERNAL_FIELD}" is reserved for the companion's own internals ` + `and cannot be exported (${formatSites(sites)}). Rename the export.`
|
|
958
1003
|
});
|
|
959
1004
|
}
|
|
1005
|
+
const managed = findManagedBootstrap(sourceFile);
|
|
1006
|
+
const bootstrap = managed?.canonical === true ? managed.statements : [];
|
|
1007
|
+
const editedBlock = new Set(managed?.canonical === false ? managed.statements : []);
|
|
1008
|
+
const exempt = new Set(bootstrap);
|
|
960
1009
|
for (const statement of sourceFile.statements) {
|
|
961
|
-
if (closureStatements.has(statement) || isEffectFreeStatement(statement, checker)) {
|
|
1010
|
+
if (closureStatements.has(statement) || exempt.has(statement) || isEffectFreeStatement(statement, checker)) {
|
|
962
1011
|
continue;
|
|
963
1012
|
}
|
|
964
1013
|
const start = statement.getStart(sourceFile);
|
|
@@ -970,11 +1019,12 @@ function computeCompanionClosure(sourceFile, checker) {
|
|
|
970
1019
|
siteOf(statement, "runs in the script"),
|
|
971
1020
|
siteOf(hoisted.declaration.node, "moves into the companion")
|
|
972
1021
|
];
|
|
1022
|
+
const name = hoisted.declaration.name;
|
|
973
1023
|
violations.push({
|
|
974
1024
|
kind: "initialization-order",
|
|
975
|
-
member:
|
|
1025
|
+
member: name,
|
|
976
1026
|
sites,
|
|
977
|
-
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."
|
|
978
1028
|
});
|
|
979
1029
|
}
|
|
980
1030
|
return {
|
|
@@ -983,6 +1033,7 @@ function computeCompanionClosure(sourceFile, checker) {
|
|
|
983
1033
|
statements: sourceFile.statements.filter((statement) => closureStatements.has(statement)),
|
|
984
1034
|
importBindings: ordered.filter(({ symbol }) => importBindingSymbols.has(symbol)).map(({ declaration }) => declaration.name),
|
|
985
1035
|
internals: ordered.filter(({ symbol }) => !exportSet.has(symbol) && scriptReferences.has(symbol)).map(({ declaration }) => declaration.name),
|
|
1036
|
+
bootstrap,
|
|
986
1037
|
violations
|
|
987
1038
|
};
|
|
988
1039
|
}
|
|
@@ -1531,7 +1582,7 @@ function readGameProjectSetting(gameProjectText, section, key) {
|
|
|
1531
1582
|
import { existsSync, readdirSync } from "node:fs";
|
|
1532
1583
|
import * as path from "node:path";
|
|
1533
1584
|
import { fileURLToPath } from "node:url";
|
|
1534
|
-
import * as
|
|
1585
|
+
import * as ts5 from "typescript";
|
|
1535
1586
|
import { LuaLibFeature } from "typescript-to-lua";
|
|
1536
1587
|
|
|
1537
1588
|
// src/lua-require-scan.ts
|
|
@@ -1679,7 +1730,7 @@ function isHsmRequireName(requirePath) {
|
|
|
1679
1730
|
return hsmModuleOfRequire(requirePath) !== undefined;
|
|
1680
1731
|
}
|
|
1681
1732
|
function hsmModuleOfSpecifier(node) {
|
|
1682
|
-
if (node === undefined || !
|
|
1733
|
+
if (node === undefined || !ts5.isStringLiteral(node)) {
|
|
1683
1734
|
return;
|
|
1684
1735
|
}
|
|
1685
1736
|
const { text } = node;
|
|
@@ -1719,7 +1770,7 @@ function hsmClosure(chunks, compile) {
|
|
|
1719
1770
|
return Object.fromEntries(Object.entries(selected).sort(([a], [b]) => a.localeCompare(b)));
|
|
1720
1771
|
}
|
|
1721
1772
|
function lowerSpecifier(module) {
|
|
1722
|
-
return
|
|
1773
|
+
return ts5.factory.createStringLiteral(`@NoResolution:${module.requireName}`);
|
|
1723
1774
|
}
|
|
1724
1775
|
function loweredAnything(lowered) {
|
|
1725
1776
|
return Array.isArray(lowered) ? lowered.length > 0 : lowered !== undefined;
|
|
@@ -1737,7 +1788,7 @@ function importSurvivesElision(node, context) {
|
|
|
1737
1788
|
if (bindings === undefined) {
|
|
1738
1789
|
return false;
|
|
1739
1790
|
}
|
|
1740
|
-
if (
|
|
1791
|
+
if (ts5.isNamespaceImport(bindings)) {
|
|
1741
1792
|
return resolver.isReferencedAliasDeclaration(bindings);
|
|
1742
1793
|
}
|
|
1743
1794
|
return bindings.elements.some((element) => resolver.isReferencedAliasDeclaration(element));
|
|
@@ -1750,20 +1801,20 @@ function registerLualib(module, emitted, context) {
|
|
|
1750
1801
|
}
|
|
1751
1802
|
var hsmLoweringPlugin = {
|
|
1752
1803
|
visitors: {
|
|
1753
|
-
[
|
|
1804
|
+
[ts5.SyntaxKind.ImportDeclaration]: (node, context) => {
|
|
1754
1805
|
const module = hsmModuleOfSpecifier(node.moduleSpecifier);
|
|
1755
1806
|
if (module === undefined) {
|
|
1756
1807
|
return context.superTransformStatements(node);
|
|
1757
1808
|
}
|
|
1758
1809
|
registerLualib(module, importSurvivesElision(node, context), context);
|
|
1759
|
-
return context.superTransformStatements(
|
|
1810
|
+
return context.superTransformStatements(ts5.factory.updateImportDeclaration(node, node.modifiers, node.importClause, lowerSpecifier(module), node.attributes));
|
|
1760
1811
|
},
|
|
1761
|
-
[
|
|
1812
|
+
[ts5.SyntaxKind.ExportDeclaration]: (node, context) => {
|
|
1762
1813
|
const module = hsmModuleOfSpecifier(node.moduleSpecifier);
|
|
1763
1814
|
if (module === undefined) {
|
|
1764
1815
|
return context.superTransformStatements(node);
|
|
1765
1816
|
}
|
|
1766
|
-
const lowered = context.superTransformStatements(
|
|
1817
|
+
const lowered = context.superTransformStatements(ts5.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, lowerSpecifier(module), node.attributes));
|
|
1767
1818
|
registerLualib(module, loweredAnything(lowered), context);
|
|
1768
1819
|
return lowered;
|
|
1769
1820
|
}
|
|
@@ -2283,20 +2334,20 @@ function readLibrarySceneDocuments(host, projectRoot, extensions = LIBRARY_SCENE
|
|
|
2283
2334
|
return { documents, unreadable };
|
|
2284
2335
|
}
|
|
2285
2336
|
// src/main-entry-factory-imports.ts
|
|
2286
|
-
import * as
|
|
2337
|
+
import * as ts6 from "typescript";
|
|
2287
2338
|
function findMainEntryFactoryImports(fileName, source) {
|
|
2288
|
-
const sourceFile =
|
|
2339
|
+
const sourceFile = ts6.createSourceFile(fileName, source, ts6.ScriptTarget.Latest, true);
|
|
2289
2340
|
const factories = [];
|
|
2290
2341
|
for (const statement of sourceFile.statements) {
|
|
2291
|
-
if (!
|
|
2342
|
+
if (!ts6.isImportDeclaration(statement)) {
|
|
2292
2343
|
continue;
|
|
2293
2344
|
}
|
|
2294
2345
|
const specifier = statement.moduleSpecifier;
|
|
2295
|
-
if (!
|
|
2346
|
+
if (!ts6.isStringLiteral(specifier) || specifier.text !== FACTORY_MODULE) {
|
|
2296
2347
|
continue;
|
|
2297
2348
|
}
|
|
2298
2349
|
const bindings = statement.importClause?.namedBindings;
|
|
2299
|
-
if (bindings === undefined || !
|
|
2350
|
+
if (bindings === undefined || !ts6.isNamedImports(bindings)) {
|
|
2300
2351
|
continue;
|
|
2301
2352
|
}
|
|
2302
2353
|
for (const element of bindings.elements) {
|
|
@@ -2369,16 +2420,16 @@ function computeOutputRel(rel, config, kind) {
|
|
|
2369
2420
|
return baseRel.replace(/\.ts$/, SCRIPT_SUFFIX_BY_KIND[kind]);
|
|
2370
2421
|
}
|
|
2371
2422
|
// src/program-diagnostics.ts
|
|
2372
|
-
import * as
|
|
2423
|
+
import * as ts12 from "typescript";
|
|
2373
2424
|
import * as tstl from "typescript-to-lua";
|
|
2374
2425
|
|
|
2375
2426
|
// src/message-guard-lowering.ts
|
|
2376
|
-
import * as
|
|
2427
|
+
import * as ts7 from "typescript";
|
|
2377
2428
|
import {
|
|
2378
2429
|
createBinaryExpression as createBinaryExpression3,
|
|
2379
2430
|
createCallExpression as createCallExpression3,
|
|
2380
2431
|
createIdentifier as createIdentifier3,
|
|
2381
|
-
SyntaxKind as
|
|
2432
|
+
SyntaxKind as SyntaxKind9
|
|
2382
2433
|
} from "typescript-to-lua";
|
|
2383
2434
|
var GUARD_MODULE = "@defold-typescript/types";
|
|
2384
2435
|
var GUARD_NAME = "isMessage";
|
|
@@ -2387,7 +2438,7 @@ function resolvesToGuardExport(callee, checker) {
|
|
|
2387
2438
|
if (symbol === undefined) {
|
|
2388
2439
|
return false;
|
|
2389
2440
|
}
|
|
2390
|
-
if (symbol.flags &
|
|
2441
|
+
if (symbol.flags & ts7.SymbolFlags.Alias) {
|
|
2391
2442
|
symbol = checker.getAliasedSymbol(symbol);
|
|
2392
2443
|
}
|
|
2393
2444
|
if (symbol.getName() !== GUARD_NAME) {
|
|
@@ -2401,12 +2452,12 @@ function resolvesToGuardExport(callee, checker) {
|
|
|
2401
2452
|
}
|
|
2402
2453
|
var messageGuardLoweringPlugin = {
|
|
2403
2454
|
visitors: {
|
|
2404
|
-
[
|
|
2455
|
+
[ts7.SyntaxKind.CallExpression]: (node, context) => {
|
|
2405
2456
|
const [messageIdArg, , expectedArg] = node.arguments;
|
|
2406
2457
|
if (node.arguments.length === 3 && messageIdArg !== undefined && expectedArg !== undefined && resolvesToGuardExport(node.expression, context.checker)) {
|
|
2407
2458
|
const messageId = context.transformExpression(messageIdArg);
|
|
2408
2459
|
const expected = context.transformExpression(expectedArg);
|
|
2409
|
-
return createBinaryExpression3(messageId, createCallExpression3(createIdentifier3("hash"), [expected]),
|
|
2460
|
+
return createBinaryExpression3(messageId, createCallExpression3(createIdentifier3("hash"), [expected]), SyntaxKind9.EqualityOperator, node);
|
|
2410
2461
|
}
|
|
2411
2462
|
return context.superTransformExpression(node);
|
|
2412
2463
|
}
|
|
@@ -2414,14 +2465,14 @@ var messageGuardLoweringPlugin = {
|
|
|
2414
2465
|
};
|
|
2415
2466
|
|
|
2416
2467
|
// src/physics-event-guard-lowering.ts
|
|
2417
|
-
import * as
|
|
2468
|
+
import * as ts8 from "typescript";
|
|
2418
2469
|
import {
|
|
2419
2470
|
createBinaryExpression as createBinaryExpression4,
|
|
2420
2471
|
createCallExpression as createCallExpression4,
|
|
2421
2472
|
createIdentifier as createIdentifier4,
|
|
2422
2473
|
createStringLiteral as createStringLiteral3,
|
|
2423
2474
|
createTableIndexExpression as createTableIndexExpression2,
|
|
2424
|
-
SyntaxKind as
|
|
2475
|
+
SyntaxKind as SyntaxKind11
|
|
2425
2476
|
} from "typescript-to-lua";
|
|
2426
2477
|
var GUARD_MODULE2 = "@defold-typescript/types";
|
|
2427
2478
|
var GUARD_NAME2 = "isPhysicsEvent";
|
|
@@ -2430,7 +2481,7 @@ function resolvesToGuardExport2(callee, checker) {
|
|
|
2430
2481
|
if (symbol === undefined) {
|
|
2431
2482
|
return false;
|
|
2432
2483
|
}
|
|
2433
|
-
if (symbol.flags &
|
|
2484
|
+
if (symbol.flags & ts8.SymbolFlags.Alias) {
|
|
2434
2485
|
symbol = checker.getAliasedSymbol(symbol);
|
|
2435
2486
|
}
|
|
2436
2487
|
if (symbol.getName() !== GUARD_NAME2) {
|
|
@@ -2444,12 +2495,12 @@ function resolvesToGuardExport2(callee, checker) {
|
|
|
2444
2495
|
}
|
|
2445
2496
|
var physicsEventGuardLoweringPlugin = {
|
|
2446
2497
|
visitors: {
|
|
2447
|
-
[
|
|
2498
|
+
[ts8.SyntaxKind.CallExpression]: (node, context) => {
|
|
2448
2499
|
const [eventArg, nameArg] = node.arguments;
|
|
2449
2500
|
if (node.arguments.length === 2 && eventArg !== undefined && nameArg !== undefined && resolvesToGuardExport2(node.expression, context.checker)) {
|
|
2450
2501
|
const event = context.transformExpression(eventArg);
|
|
2451
2502
|
const name = context.transformExpression(nameArg);
|
|
2452
|
-
return createBinaryExpression4(createTableIndexExpression2(event, createStringLiteral3("type")), createCallExpression4(createIdentifier4("hash"), [name]),
|
|
2503
|
+
return createBinaryExpression4(createTableIndexExpression2(event, createStringLiteral3("type")), createCallExpression4(createIdentifier4("hash"), [name]), SyntaxKind11.EqualityOperator, node);
|
|
2453
2504
|
}
|
|
2454
2505
|
return context.superTransformExpression(node);
|
|
2455
2506
|
}
|
|
@@ -2457,37 +2508,37 @@ var physicsEventGuardLoweringPlugin = {
|
|
|
2457
2508
|
};
|
|
2458
2509
|
|
|
2459
2510
|
// src/timers-lowering.ts
|
|
2460
|
-
import * as
|
|
2511
|
+
import * as ts9 from "typescript";
|
|
2461
2512
|
import { LuaLibFeature as LuaLibFeature2 } from "typescript-to-lua";
|
|
2462
2513
|
function isTimersSpecifier(node) {
|
|
2463
|
-
return
|
|
2514
|
+
return ts9.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
|
|
2464
2515
|
}
|
|
2465
2516
|
function importsTimersModule(sourceFile) {
|
|
2466
|
-
return sourceFile.statements.some((statement) =>
|
|
2517
|
+
return sourceFile.statements.some((statement) => ts9.isImportDeclaration(statement) && isTimersSpecifier(statement.moduleSpecifier));
|
|
2467
2518
|
}
|
|
2468
2519
|
var TIMERS_REQUIRE_PATH = `@NoResolution:${TIMERS_REQUIRE_NAME}`;
|
|
2469
2520
|
var timersLoweringPlugin = {
|
|
2470
2521
|
visitors: {
|
|
2471
|
-
[
|
|
2522
|
+
[ts9.SyntaxKind.ImportDeclaration]: (node, context) => {
|
|
2472
2523
|
if (!isTimersSpecifier(node.moduleSpecifier)) {
|
|
2473
2524
|
return context.superTransformStatements(node);
|
|
2474
2525
|
}
|
|
2475
2526
|
context.usedLuaLibFeatures.add(LuaLibFeature2.Promise);
|
|
2476
2527
|
context.usedLuaLibFeatures.add(LuaLibFeature2.New);
|
|
2477
|
-
const rewritten =
|
|
2528
|
+
const rewritten = ts9.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts9.factory.createStringLiteral(TIMERS_REQUIRE_PATH), node.attributes);
|
|
2478
2529
|
return context.superTransformStatements(rewritten);
|
|
2479
2530
|
}
|
|
2480
2531
|
}
|
|
2481
2532
|
};
|
|
2482
2533
|
|
|
2483
2534
|
// src/type-application-erasure.ts
|
|
2484
|
-
import * as
|
|
2535
|
+
import * as ts10 from "typescript";
|
|
2485
2536
|
var TYPE_APPLICATION_APIS = new Set(["go.get", "go.set"]);
|
|
2486
2537
|
function isTypeApplication(call, checker) {
|
|
2487
2538
|
if (call.arguments.length !== 0)
|
|
2488
2539
|
return false;
|
|
2489
2540
|
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
2490
|
-
if (declaration === undefined || !
|
|
2541
|
+
if (declaration === undefined || !ts10.isFunctionDeclaration(declaration))
|
|
2491
2542
|
return false;
|
|
2492
2543
|
if (declaration.parameters.length !== 0 || declaration.typeParameters === undefined)
|
|
2493
2544
|
return false;
|
|
@@ -2501,7 +2552,7 @@ function isTypeApplication(call, checker) {
|
|
|
2501
2552
|
}
|
|
2502
2553
|
var typeApplicationErasurePlugin = {
|
|
2503
2554
|
visitors: {
|
|
2504
|
-
[
|
|
2555
|
+
[ts10.SyntaxKind.CallExpression]: (node, context) => {
|
|
2505
2556
|
if (isTypeApplication(node, context.checker)) {
|
|
2506
2557
|
return context.transformExpression(node.expression);
|
|
2507
2558
|
}
|
|
@@ -2511,10 +2562,10 @@ var typeApplicationErasurePlugin = {
|
|
|
2511
2562
|
};
|
|
2512
2563
|
|
|
2513
2564
|
// src/window-event-guard-lowering.ts
|
|
2514
|
-
import * as
|
|
2565
|
+
import * as ts11 from "typescript";
|
|
2515
2566
|
import {
|
|
2516
2567
|
createBinaryExpression as createBinaryExpression5,
|
|
2517
|
-
SyntaxKind as
|
|
2568
|
+
SyntaxKind as SyntaxKind15
|
|
2518
2569
|
} from "typescript-to-lua";
|
|
2519
2570
|
var GUARD_MODULE3 = "@defold-typescript/types";
|
|
2520
2571
|
var GUARD_NAME3 = "isWindowEvent";
|
|
@@ -2523,7 +2574,7 @@ function resolvesToGuardExport3(callee, checker) {
|
|
|
2523
2574
|
if (symbol === undefined) {
|
|
2524
2575
|
return false;
|
|
2525
2576
|
}
|
|
2526
|
-
if (symbol.flags &
|
|
2577
|
+
if (symbol.flags & ts11.SymbolFlags.Alias) {
|
|
2527
2578
|
symbol = checker.getAliasedSymbol(symbol);
|
|
2528
2579
|
}
|
|
2529
2580
|
if (symbol.getName() !== GUARD_NAME3) {
|
|
@@ -2537,12 +2588,12 @@ function resolvesToGuardExport3(callee, checker) {
|
|
|
2537
2588
|
}
|
|
2538
2589
|
var windowEventGuardLoweringPlugin = {
|
|
2539
2590
|
visitors: {
|
|
2540
|
-
[
|
|
2591
|
+
[ts11.SyntaxKind.CallExpression]: (node, context) => {
|
|
2541
2592
|
const [eventArg, , expectedArg] = node.arguments;
|
|
2542
2593
|
if (node.arguments.length === 3 && eventArg !== undefined && expectedArg !== undefined && resolvesToGuardExport3(node.expression, context.checker)) {
|
|
2543
2594
|
const event = context.transformExpression(eventArg);
|
|
2544
2595
|
const expected = context.transformExpression(expectedArg);
|
|
2545
|
-
return createBinaryExpression5(event, expected,
|
|
2596
|
+
return createBinaryExpression5(event, expected, SyntaxKind15.EqualityOperator, node);
|
|
2546
2597
|
}
|
|
2547
2598
|
return context.superTransformExpression(node);
|
|
2548
2599
|
}
|
|
@@ -2564,7 +2615,7 @@ function isAmbient(fileName) {
|
|
|
2564
2615
|
return /[\\/]node_modules[\\/]/.test(fileName) || /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(fileName);
|
|
2565
2616
|
}
|
|
2566
2617
|
function getProgramDiagnostics(program, sourceFile) {
|
|
2567
|
-
const { diagnostics } = tstl.getProgramTranspileResult(
|
|
2618
|
+
const { diagnostics } = tstl.getProgramTranspileResult(ts12.sys, noopWriteFile, {
|
|
2568
2619
|
program,
|
|
2569
2620
|
plugins: LUA_PLUGINS,
|
|
2570
2621
|
...sourceFile ? { sourceFiles: [sourceFile] } : {}
|
|
@@ -3135,11 +3186,11 @@ function relativeAddressesFrom(index, context) {
|
|
|
3135
3186
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
3136
3187
|
import { createRequire as createRequire2 } from "node:module";
|
|
3137
3188
|
import * as path4 from "node:path";
|
|
3138
|
-
import * as
|
|
3189
|
+
import * as ts16 from "typescript";
|
|
3139
3190
|
import * as tstl3 from "typescript-to-lua";
|
|
3140
3191
|
|
|
3141
3192
|
// src/companion-emit.ts
|
|
3142
|
-
import * as
|
|
3193
|
+
import * as ts13 from "typescript";
|
|
3143
3194
|
import {
|
|
3144
3195
|
createAssignmentStatement as createAssignmentStatement2,
|
|
3145
3196
|
createCallExpression as createCallExpression5,
|
|
@@ -3173,8 +3224,8 @@ function exportsIdentifier() {
|
|
|
3173
3224
|
}
|
|
3174
3225
|
function isRuntimeScriptSource(sourceFile, checker) {
|
|
3175
3226
|
return sourceFile.statements.some((statement) => {
|
|
3176
|
-
const expression =
|
|
3177
|
-
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);
|
|
3178
3229
|
});
|
|
3179
3230
|
}
|
|
3180
3231
|
function planFor(sourceFile, checker) {
|
|
@@ -3187,6 +3238,7 @@ function planFor(sourceFile, checker) {
|
|
|
3187
3238
|
}
|
|
3188
3239
|
return {
|
|
3189
3240
|
closureStarts: new Set(closure.statements.map((statement) => statement.pos)),
|
|
3241
|
+
bootstrapStarts: new Set(closure.bootstrap.map((statement) => statement.pos)),
|
|
3190
3242
|
internals: closure.internals,
|
|
3191
3243
|
importBindings: closure.importBindings,
|
|
3192
3244
|
requirePath: requirePathForRel(sourceFile.fileName)
|
|
@@ -3326,11 +3378,11 @@ function freeNames(statements) {
|
|
|
3326
3378
|
function resolvedRequirePaths(sourceFile, checker) {
|
|
3327
3379
|
const paths = new Map;
|
|
3328
3380
|
for (const statement of sourceFile.statements) {
|
|
3329
|
-
const specifier =
|
|
3330
|
-
if (specifier === undefined || !
|
|
3381
|
+
const specifier = ts13.isImportDeclaration(statement) || ts13.isExportDeclaration(statement) ? statement.moduleSpecifier : undefined;
|
|
3382
|
+
if (specifier === undefined || !ts13.isStringLiteral(specifier)) {
|
|
3331
3383
|
continue;
|
|
3332
3384
|
}
|
|
3333
|
-
const target = checker.getSymbolAtLocation(specifier)?.declarations?.find((declaration) =>
|
|
3385
|
+
const target = checker.getSymbolAtLocation(specifier)?.declarations?.find((declaration) => ts13.isSourceFile(declaration));
|
|
3334
3386
|
if (target === undefined || target.isDeclarationFile) {
|
|
3335
3387
|
continue;
|
|
3336
3388
|
}
|
|
@@ -3473,6 +3525,7 @@ function split(statements, owned) {
|
|
|
3473
3525
|
function createCompanionEmitPlugin() {
|
|
3474
3526
|
const plans = new Map;
|
|
3475
3527
|
const owned = new Map;
|
|
3528
|
+
const bootstraps = new Map;
|
|
3476
3529
|
const companions = new Map;
|
|
3477
3530
|
function planOf(sourceFile, checker) {
|
|
3478
3531
|
const key = sourceFile.fileName;
|
|
@@ -3498,12 +3551,30 @@ function createCompanionEmitPlugin() {
|
|
|
3498
3551
|
}
|
|
3499
3552
|
return statements;
|
|
3500
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
|
+
}
|
|
3501
3571
|
const visitors = {
|
|
3502
|
-
[
|
|
3503
|
-
[
|
|
3504
|
-
[
|
|
3505
|
-
[
|
|
3506
|
-
[
|
|
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
|
|
3507
3578
|
};
|
|
3508
3579
|
let configuredNoResolvePaths = [];
|
|
3509
3580
|
const plugin = {
|
|
@@ -3523,7 +3594,8 @@ function createCompanionEmitPlugin() {
|
|
|
3523
3594
|
if (plan === undefined || bucket === undefined || bucket.size === 0) {
|
|
3524
3595
|
continue;
|
|
3525
3596
|
}
|
|
3526
|
-
|
|
3597
|
+
const bootstrap = bootstraps.get(sourceFile.fileName) ?? new Set;
|
|
3598
|
+
emitCompanion(program, emitHost, file, sourceFile, plan, bucket, bootstrap, companions);
|
|
3527
3599
|
emitted.push(plan.requirePath);
|
|
3528
3600
|
}
|
|
3529
3601
|
if (emitted.length > 0) {
|
|
@@ -3533,7 +3605,7 @@ function createCompanionEmitPlugin() {
|
|
|
3533
3605
|
};
|
|
3534
3606
|
return { plugin, companions };
|
|
3535
3607
|
}
|
|
3536
|
-
function emitCompanion(program, emitHost, file, sourceFile, plan, owned, companions) {
|
|
3608
|
+
function emitCompanion(program, emitHost, file, sourceFile, plan, owned, bootstrap, companions) {
|
|
3537
3609
|
const luaAst = file.luaAst;
|
|
3538
3610
|
if (luaAst === undefined) {
|
|
3539
3611
|
return;
|
|
@@ -3552,12 +3624,14 @@ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, compani
|
|
|
3552
3624
|
createReturnStatement2([exportsIdentifier()])
|
|
3553
3625
|
];
|
|
3554
3626
|
const reads = new Set([EXPORTS_NAME, ...plan.internals]);
|
|
3555
|
-
const
|
|
3627
|
+
const rest = halves.script.filter((statement) => !bootstrap.has(statement));
|
|
3628
|
+
const insertAt = requireInsertionPoint(rest, reads);
|
|
3556
3629
|
const scriptStatements = [
|
|
3557
|
-
...
|
|
3630
|
+
...rest.slice(0, insertAt),
|
|
3631
|
+
...halves.script.filter((statement) => bootstrap.has(statement)),
|
|
3558
3632
|
createVariableDeclarationStatement3(exportsIdentifier(), createCallExpression5(createIdentifier5("require"), [createStringLiteral4(plan.requirePath)])),
|
|
3559
3633
|
...plan.internals.map((name) => createVariableDeclarationStatement3(createIdentifier5(name), internalsField(name))),
|
|
3560
|
-
...
|
|
3634
|
+
...rest.slice(insertAt),
|
|
3561
3635
|
createReturnStatement2([exportsIdentifier()])
|
|
3562
3636
|
];
|
|
3563
3637
|
const features = new Set(luaAst.luaLibFeatures);
|
|
@@ -3572,7 +3646,7 @@ function emitCompanion(program, emitHost, file, sourceFile, plan, owned, compani
|
|
|
3572
3646
|
}
|
|
3573
3647
|
|
|
3574
3648
|
// src/editor-script-erasure.ts
|
|
3575
|
-
import * as
|
|
3649
|
+
import * as ts14 from "typescript";
|
|
3576
3650
|
import {
|
|
3577
3651
|
createReturnStatement as createReturnStatement3
|
|
3578
3652
|
} from "typescript-to-lua";
|
|
@@ -3592,7 +3666,7 @@ function resolveEditorFactoryExport(callee, checker) {
|
|
|
3592
3666
|
if (symbol === undefined) {
|
|
3593
3667
|
return;
|
|
3594
3668
|
}
|
|
3595
|
-
if (symbol.flags &
|
|
3669
|
+
if (symbol.flags & ts14.SymbolFlags.Alias) {
|
|
3596
3670
|
symbol = checker.getAliasedSymbol(symbol);
|
|
3597
3671
|
}
|
|
3598
3672
|
const name = symbol.getName();
|
|
@@ -3606,7 +3680,7 @@ function resolveEditorFactoryExport(callee, checker) {
|
|
|
3606
3680
|
return declaration.getSourceFile().fileName.includes(EDITOR_FACTORY_MODULE) ? name : undefined;
|
|
3607
3681
|
}
|
|
3608
3682
|
function lowerEditorFactoryCall(expression, context) {
|
|
3609
|
-
if (!
|
|
3683
|
+
if (!ts14.isCallExpression(expression)) {
|
|
3610
3684
|
return;
|
|
3611
3685
|
}
|
|
3612
3686
|
if (resolveEditorFactoryExport(expression.expression, context.checker) !== EDITOR_SCRIPT_FACTORY_NAME) {
|
|
@@ -3619,7 +3693,7 @@ function lowerEditorFactoryCall(expression, context) {
|
|
|
3619
3693
|
return [createReturnStatement3([context.transformExpression(module)])];
|
|
3620
3694
|
}
|
|
3621
3695
|
function isEditorFactoryOnlyImport(node) {
|
|
3622
|
-
if (!
|
|
3696
|
+
if (!ts14.isStringLiteral(node.moduleSpecifier) || !EDITOR_FACTORY_SPECIFIERS.has(node.moduleSpecifier.text)) {
|
|
3623
3697
|
return false;
|
|
3624
3698
|
}
|
|
3625
3699
|
const clause = node.importClause;
|
|
@@ -3630,7 +3704,7 @@ function isEditorFactoryOnlyImport(node) {
|
|
|
3630
3704
|
return false;
|
|
3631
3705
|
}
|
|
3632
3706
|
const bindings = clause.namedBindings;
|
|
3633
|
-
if (bindings === undefined || !
|
|
3707
|
+
if (bindings === undefined || !ts14.isNamedImports(bindings)) {
|
|
3634
3708
|
return false;
|
|
3635
3709
|
}
|
|
3636
3710
|
const runtime = bindings.elements.filter((element) => !element.isTypeOnly);
|
|
@@ -3641,7 +3715,7 @@ function isEditorFactoryOnlyImport(node) {
|
|
|
3641
3715
|
}
|
|
3642
3716
|
var editorScriptErasurePlugin = {
|
|
3643
3717
|
visitors: {
|
|
3644
|
-
[
|
|
3718
|
+
[ts14.SyntaxKind.ExportAssignment]: (node, context) => {
|
|
3645
3719
|
if (!node.isExportEquals) {
|
|
3646
3720
|
const lowered = lowerEditorFactoryCall(node.expression, context);
|
|
3647
3721
|
if (lowered !== undefined) {
|
|
@@ -3650,14 +3724,14 @@ var editorScriptErasurePlugin = {
|
|
|
3650
3724
|
}
|
|
3651
3725
|
return context.superTransformStatements(node);
|
|
3652
3726
|
},
|
|
3653
|
-
[
|
|
3727
|
+
[ts14.SyntaxKind.CallExpression]: (node, context) => {
|
|
3654
3728
|
const command = node.arguments[0];
|
|
3655
3729
|
if (command !== undefined && resolveEditorFactoryExport(node.expression, context.checker) === EDITOR_COMMAND_FACTORY_NAME) {
|
|
3656
3730
|
return context.transformExpression(command);
|
|
3657
3731
|
}
|
|
3658
3732
|
return context.superTransformExpression(node);
|
|
3659
3733
|
},
|
|
3660
|
-
[
|
|
3734
|
+
[ts14.SyntaxKind.ImportDeclaration]: (node, context) => isEditorFactoryOnlyImport(node) ? [] : context.superTransformStatements(node)
|
|
3661
3735
|
}
|
|
3662
3736
|
};
|
|
3663
3737
|
|
|
@@ -3668,17 +3742,17 @@ import * as path3 from "node:path";
|
|
|
3668
3742
|
import * as tstl2 from "typescript-to-lua";
|
|
3669
3743
|
|
|
3670
3744
|
// src/go-property-direct-call.ts
|
|
3671
|
-
import * as
|
|
3745
|
+
import * as ts15 from "typescript";
|
|
3672
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).";
|
|
3673
3747
|
function findDirectGoPropertyCalls(sourceFile) {
|
|
3674
3748
|
const calls = [];
|
|
3675
3749
|
const visit = (node) => {
|
|
3676
|
-
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") {
|
|
3677
3751
|
calls.push(node);
|
|
3678
3752
|
}
|
|
3679
|
-
|
|
3753
|
+
ts15.forEachChild(node, visit);
|
|
3680
3754
|
};
|
|
3681
|
-
|
|
3755
|
+
ts15.forEachChild(sourceFile, visit);
|
|
3682
3756
|
return calls;
|
|
3683
3757
|
}
|
|
3684
3758
|
|
|
@@ -4012,7 +4086,7 @@ function createTranspileSession() {
|
|
|
4012
4086
|
if (cached) {
|
|
4013
4087
|
return cached;
|
|
4014
4088
|
}
|
|
4015
|
-
const created =
|
|
4089
|
+
const created = ts16.createSourceFile(fileName, content, ts16.ScriptTarget.Latest, false);
|
|
4016
4090
|
sourceFileCache.set(normalized, created);
|
|
4017
4091
|
return created;
|
|
4018
4092
|
}
|
|
@@ -4031,7 +4105,7 @@ function createTranspileSession() {
|
|
|
4031
4105
|
return cached;
|
|
4032
4106
|
}
|
|
4033
4107
|
const fileContent = readFileSync2(filePath, "utf8");
|
|
4034
|
-
const created =
|
|
4108
|
+
const created = ts16.createSourceFile(filePath, fileContent, ts16.ScriptTarget.Latest, false);
|
|
4035
4109
|
libCache.set(fileName, created);
|
|
4036
4110
|
return created;
|
|
4037
4111
|
}
|
|
@@ -4044,10 +4118,10 @@ function createTranspileSession() {
|
|
|
4044
4118
|
return AMBIENT_FILES[normalized];
|
|
4045
4119
|
}
|
|
4046
4120
|
const host = {
|
|
4047
|
-
fileExists: (fileName) => mergedContent(normalizeSlashes(fileName)) !== undefined ||
|
|
4121
|
+
fileExists: (fileName) => mergedContent(normalizeSlashes(fileName)) !== undefined || ts16.sys.fileExists(fileName),
|
|
4048
4122
|
getCanonicalFileName: (fileName) => fileName,
|
|
4049
4123
|
getCurrentDirectory: () => "",
|
|
4050
|
-
getDefaultLibFileName:
|
|
4124
|
+
getDefaultLibFileName: ts16.getDefaultLibFileName,
|
|
4051
4125
|
readFile: () => "",
|
|
4052
4126
|
getNewLine: () => `
|
|
4053
4127
|
`,
|
|
@@ -4069,15 +4143,15 @@ function createTranspileSession() {
|
|
|
4069
4143
|
const userKeys = new Set(userFiles.keys());
|
|
4070
4144
|
const rootNames = [...Object.keys(AMBIENT_FILES).map(normalizeSlashes), ...userKeys];
|
|
4071
4145
|
const companionEmit = createCompanionEmitPlugin();
|
|
4072
|
-
program =
|
|
4073
|
-
const preEmitDiagnostics =
|
|
4146
|
+
program = ts16.createProgram(rootNames, compilerOptions(companionEmit), host, program);
|
|
4147
|
+
const preEmitDiagnostics = ts16.getPreEmitDiagnostics(program);
|
|
4074
4148
|
const collector = createOutputCollector();
|
|
4075
4149
|
const { diagnostics: transpileDiagnostics } = new tstl3.Transpiler().emit({
|
|
4076
4150
|
program,
|
|
4077
4151
|
writeFile: collector.writeFile
|
|
4078
4152
|
});
|
|
4079
4153
|
const diagnostics = [
|
|
4080
|
-
...
|
|
4154
|
+
...ts16.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics])
|
|
4081
4155
|
];
|
|
4082
4156
|
return collectOutputs(collector.files, diagnostics, userKeys, companionEmit.companions);
|
|
4083
4157
|
}
|
|
@@ -4087,7 +4161,7 @@ function createTranspileSession() {
|
|
|
4087
4161
|
};
|
|
4088
4162
|
}
|
|
4089
4163
|
// src/text-script-property.ts
|
|
4090
|
-
import * as
|
|
4164
|
+
import * as ts17 from "typescript";
|
|
4091
4165
|
function findTextScriptProperties(program, fileNames) {
|
|
4092
4166
|
const checker = program.getTypeChecker();
|
|
4093
4167
|
const findings = [];
|
|
@@ -4098,7 +4172,7 @@ function findTextScriptProperties(program, fileNames) {
|
|
|
4098
4172
|
}
|
|
4099
4173
|
const located = [];
|
|
4100
4174
|
const visit = (node) => {
|
|
4101
|
-
if (
|
|
4175
|
+
if (ts17.isCallExpression(node)) {
|
|
4102
4176
|
const hooks = factoryHooks(node, checker);
|
|
4103
4177
|
for (const property of hooks?.properties ?? []) {
|
|
4104
4178
|
if (!isPropertiesHook(property)) {
|
|
@@ -4111,7 +4185,7 @@ function findTextScriptProperties(program, fileNames) {
|
|
|
4111
4185
|
}
|
|
4112
4186
|
}
|
|
4113
4187
|
}
|
|
4114
|
-
|
|
4188
|
+
ts17.forEachChild(node, visit);
|
|
4115
4189
|
};
|
|
4116
4190
|
visit(sourceFile);
|
|
4117
4191
|
for (const call of findDirectGoPropertyCalls(sourceFile)) {
|
|
@@ -4120,7 +4194,7 @@ function findTextScriptProperties(program, fileNames) {
|
|
|
4120
4194
|
continue;
|
|
4121
4195
|
}
|
|
4122
4196
|
if (mayHoldString(checker.getTypeAtLocation(value), checker)) {
|
|
4123
|
-
const name =
|
|
4197
|
+
const name = ts17.isStringLiteralLike(nameArgument) ? nameArgument.text : nameArgument.getText(sourceFile);
|
|
4124
4198
|
located.push({ name, value });
|
|
4125
4199
|
}
|
|
4126
4200
|
}
|
|
@@ -4137,20 +4211,20 @@ function mayHoldString(type, checker, visited = new Set) {
|
|
|
4137
4211
|
return false;
|
|
4138
4212
|
}
|
|
4139
4213
|
visited.add(type);
|
|
4140
|
-
if (type.flags &
|
|
4214
|
+
if (type.flags & ts17.TypeFlags.StringLike) {
|
|
4141
4215
|
return true;
|
|
4142
4216
|
}
|
|
4143
4217
|
if (type.isUnionOrIntersection()) {
|
|
4144
4218
|
return type.types.some((member) => mayHoldString(member, checker, visited));
|
|
4145
4219
|
}
|
|
4146
|
-
if (type.flags &
|
|
4220
|
+
if (type.flags & ts17.TypeFlags.Instantiable) {
|
|
4147
4221
|
const constraint = checker.getBaseConstraintOfType(type);
|
|
4148
4222
|
return constraint !== undefined && constraint !== type ? mayHoldString(constraint, checker, visited) : false;
|
|
4149
4223
|
}
|
|
4150
4224
|
return false;
|
|
4151
4225
|
}
|
|
4152
4226
|
// src/url-address-slots.ts
|
|
4153
|
-
import * as
|
|
4227
|
+
import * as ts18 from "typescript";
|
|
4154
4228
|
var ADDRESS_CLASSES = {
|
|
4155
4229
|
"game-object": true,
|
|
4156
4230
|
component: true,
|
|
@@ -4169,7 +4243,7 @@ function isFragmentCaret(slot, position) {
|
|
|
4169
4243
|
return slot.fragmentStart !== -1 && position >= slot.fragmentStart;
|
|
4170
4244
|
}
|
|
4171
4245
|
function tableKey(checker, callee) {
|
|
4172
|
-
const symbol = checker.getSymbolAtLocation(
|
|
4246
|
+
const symbol = checker.getSymbolAtLocation(ts18.isIdentifier(callee) ? callee : callee.name);
|
|
4173
4247
|
if (!symbol)
|
|
4174
4248
|
return;
|
|
4175
4249
|
const fqn = checker.getFullyQualifiedName(symbol);
|
|
@@ -4177,43 +4251,43 @@ function tableKey(checker, callee) {
|
|
|
4177
4251
|
}
|
|
4178
4252
|
function parameterName(checker, call, index) {
|
|
4179
4253
|
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
4180
|
-
if (!declaration || !
|
|
4254
|
+
if (!declaration || !ts18.isFunctionLike(declaration))
|
|
4181
4255
|
return;
|
|
4182
4256
|
const parameter = declaration.parameters[index];
|
|
4183
|
-
if (!parameter || parameter.dotDotDotToken || !
|
|
4257
|
+
if (!parameter || parameter.dotDotDotToken || !ts18.isIdentifier(parameter.name))
|
|
4184
4258
|
return;
|
|
4185
4259
|
return parameter.name.text;
|
|
4186
4260
|
}
|
|
4187
4261
|
var EQUALITY_OPERATORS = new Set([
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4262
|
+
ts18.SyntaxKind.EqualsEqualsEqualsToken,
|
|
4263
|
+
ts18.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
4264
|
+
ts18.SyntaxKind.EqualsEqualsToken,
|
|
4265
|
+
ts18.SyntaxKind.ExclamationEqualsToken
|
|
4192
4266
|
]);
|
|
4193
4267
|
function comparisonSatisfied(checker, entry, call) {
|
|
4194
4268
|
if (entry.comparedParameter === undefined)
|
|
4195
4269
|
return true;
|
|
4196
4270
|
let node = call;
|
|
4197
|
-
while (
|
|
4271
|
+
while (ts18.isParenthesizedExpression(node.parent))
|
|
4198
4272
|
node = node.parent;
|
|
4199
4273
|
const comparison = node.parent;
|
|
4200
|
-
if (!
|
|
4274
|
+
if (!ts18.isBinaryExpression(comparison))
|
|
4201
4275
|
return false;
|
|
4202
4276
|
if (!EQUALITY_OPERATORS.has(comparison.operatorToken.kind))
|
|
4203
4277
|
return false;
|
|
4204
4278
|
const other = comparison.left === node ? comparison.right : comparison.left;
|
|
4205
4279
|
const symbol = checker.getSymbolAtLocation(other);
|
|
4206
|
-
return (symbol?.declarations ?? []).some((declaration) =>
|
|
4280
|
+
return (symbol?.declarations ?? []).some((declaration) => ts18.isParameter(declaration) && ts18.isIdentifier(declaration.name) && declaration.name.text === entry.comparedParameter);
|
|
4207
4281
|
}
|
|
4208
4282
|
function classifiedEntryOfArgument(checker, table, argument) {
|
|
4209
4283
|
const call = argument.parent;
|
|
4210
|
-
if (!
|
|
4284
|
+
if (!ts18.isCallExpression(call))
|
|
4211
4285
|
return;
|
|
4212
4286
|
const argumentIndex = call.arguments.indexOf(argument);
|
|
4213
4287
|
if (argumentIndex === -1)
|
|
4214
4288
|
return;
|
|
4215
4289
|
const callee = call.expression;
|
|
4216
|
-
if (!
|
|
4290
|
+
if (!ts18.isPropertyAccessExpression(callee) && !ts18.isIdentifier(callee))
|
|
4217
4291
|
return;
|
|
4218
4292
|
const fqn = tableKey(checker, callee);
|
|
4219
4293
|
if (fqn === undefined)
|
|
@@ -4230,10 +4304,10 @@ function classifiedEntryOfArgument(checker, table, argument) {
|
|
|
4230
4304
|
}
|
|
4231
4305
|
function slotThroughHashedCall(checker, table, literal) {
|
|
4232
4306
|
const call = literal.parent;
|
|
4233
|
-
if (!
|
|
4307
|
+
if (!ts18.isCallExpression(call))
|
|
4234
4308
|
return;
|
|
4235
4309
|
const callee = call.expression;
|
|
4236
|
-
if (!
|
|
4310
|
+
if (!ts18.isPropertyAccessExpression(callee) && !ts18.isIdentifier(callee))
|
|
4237
4311
|
return;
|
|
4238
4312
|
if (tableKey(checker, callee) !== "hash")
|
|
4239
4313
|
return;
|
|
@@ -4251,24 +4325,24 @@ function addressTextOf(checker, entry, call) {
|
|
|
4251
4325
|
if (entry.addressParameter === undefined)
|
|
4252
4326
|
return;
|
|
4253
4327
|
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
4254
|
-
if (!declaration || !
|
|
4328
|
+
if (!declaration || !ts18.isFunctionLike(declaration))
|
|
4255
4329
|
return;
|
|
4256
|
-
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);
|
|
4257
4331
|
if (index === -1)
|
|
4258
4332
|
return;
|
|
4259
4333
|
const argument = call.arguments[index];
|
|
4260
|
-
return argument &&
|
|
4334
|
+
return argument && ts18.isStringLiteralLike(argument) ? argument.text : undefined;
|
|
4261
4335
|
}
|
|
4262
4336
|
function innermostLiteralAt(sourceFile, position) {
|
|
4263
4337
|
let found;
|
|
4264
4338
|
const visit = (node) => {
|
|
4265
4339
|
if (position < node.getStart(sourceFile) || position > node.getEnd())
|
|
4266
4340
|
return;
|
|
4267
|
-
if (
|
|
4341
|
+
if (ts18.isStringLiteralLike(node))
|
|
4268
4342
|
found = node;
|
|
4269
|
-
|
|
4343
|
+
ts18.forEachChild(node, visit);
|
|
4270
4344
|
};
|
|
4271
|
-
|
|
4345
|
+
ts18.forEachChild(sourceFile, visit);
|
|
4272
4346
|
return found;
|
|
4273
4347
|
}
|
|
4274
4348
|
function resolveClassifiedSlotAtPosition(input) {
|
|
@@ -4302,23 +4376,23 @@ function resolveClassifiedSlotAtPosition(input) {
|
|
|
4302
4376
|
};
|
|
4303
4377
|
}
|
|
4304
4378
|
// src/url-cross-world-address.ts
|
|
4305
|
-
import * as
|
|
4379
|
+
import * as ts20 from "typescript";
|
|
4306
4380
|
|
|
4307
4381
|
// src/url-address-literals.ts
|
|
4308
|
-
import * as
|
|
4382
|
+
import * as ts19 from "typescript";
|
|
4309
4383
|
function isAmbient2(fileName) {
|
|
4310
4384
|
return /[\\/]node_modules[\\/]/.test(fileName) || /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(fileName);
|
|
4311
4385
|
}
|
|
4312
4386
|
function referenceTargetSymbol(type) {
|
|
4313
|
-
if ((type.flags &
|
|
4387
|
+
if ((type.flags & ts19.TypeFlags.Object) === 0)
|
|
4314
4388
|
return;
|
|
4315
|
-
if ((type.objectFlags &
|
|
4389
|
+
if ((type.objectFlags & ts19.ObjectFlags.Reference) === 0)
|
|
4316
4390
|
return;
|
|
4317
4391
|
return type.target.symbol;
|
|
4318
4392
|
}
|
|
4319
4393
|
function ambientHashAliasTargets(checker, anchor) {
|
|
4320
4394
|
const targets = new Set;
|
|
4321
|
-
for (const symbol of checker.getSymbolsInScope(anchor,
|
|
4395
|
+
for (const symbol of checker.getSymbolsInScope(anchor, ts19.SymbolFlags.Type)) {
|
|
4322
4396
|
if (symbol.name !== "Hash")
|
|
4323
4397
|
continue;
|
|
4324
4398
|
const target = referenceTargetSymbol(checker.getDeclaredTypeOfSymbol(symbol));
|
|
@@ -4334,7 +4408,7 @@ function canonicalHashSymbols(checker, program) {
|
|
|
4334
4408
|
if (!anchor)
|
|
4335
4409
|
return canonical;
|
|
4336
4410
|
const aliased = ambientHashAliasTargets(checker, anchor);
|
|
4337
|
-
for (const symbol of checker.getSymbolsInScope(anchor,
|
|
4411
|
+
for (const symbol of checker.getSymbolsInScope(anchor, ts19.SymbolFlags.Function)) {
|
|
4338
4412
|
if (symbol.name !== "hash")
|
|
4339
4413
|
continue;
|
|
4340
4414
|
const declaration = symbol.declarations?.[0];
|
|
@@ -4356,7 +4430,7 @@ function hashedSourceOfType(checker, type, canonical) {
|
|
|
4356
4430
|
return source?.isStringLiteral() ? source.value : undefined;
|
|
4357
4431
|
}
|
|
4358
4432
|
function staticAddressTextOf(checker, node, canonical) {
|
|
4359
|
-
return
|
|
4433
|
+
return ts19.isStringLiteralLike(node) ? node.text : hashedSourceOfType(checker, checker.getTypeAtLocation(node), canonical);
|
|
4360
4434
|
}
|
|
4361
4435
|
|
|
4362
4436
|
// src/url-cross-world-address.ts
|
|
@@ -4380,7 +4454,7 @@ function checkCrossWorldAddresses(input) {
|
|
|
4380
4454
|
if (worlds.length === 0)
|
|
4381
4455
|
continue;
|
|
4382
4456
|
const visit = (node) => {
|
|
4383
|
-
if (
|
|
4457
|
+
if (ts20.isExpression(node)) {
|
|
4384
4458
|
const entry = addressEntryOfArgument(checker, table, node);
|
|
4385
4459
|
if (entry !== undefined && slotRejectsForeignSocket(entry)) {
|
|
4386
4460
|
const address = staticAddressTextOf(checker, node, canonical);
|
|
@@ -4397,14 +4471,14 @@ function checkCrossWorldAddresses(input) {
|
|
|
4397
4471
|
}
|
|
4398
4472
|
}
|
|
4399
4473
|
}
|
|
4400
|
-
|
|
4474
|
+
ts20.forEachChild(node, visit);
|
|
4401
4475
|
};
|
|
4402
|
-
|
|
4476
|
+
ts20.forEachChild(sourceFile, visit);
|
|
4403
4477
|
}
|
|
4404
4478
|
return findings;
|
|
4405
4479
|
}
|
|
4406
4480
|
// src/url-fragment-reachability.ts
|
|
4407
|
-
import * as
|
|
4481
|
+
import * as ts21 from "typescript";
|
|
4408
4482
|
function pathOfKey(key) {
|
|
4409
4483
|
const socket = socketOfAddress(key);
|
|
4410
4484
|
return socket === undefined ? key : key.slice(socket.length + 1);
|
|
@@ -4449,7 +4523,7 @@ function checkUrlFragmentReachability(input) {
|
|
|
4449
4523
|
if (isAmbient2(sourceFile.fileName))
|
|
4450
4524
|
continue;
|
|
4451
4525
|
const visit = (node) => {
|
|
4452
|
-
if (
|
|
4526
|
+
if (ts21.isExpression(node) && isAddressClass(addressClassOfArgument(checker, table, node))) {
|
|
4453
4527
|
const text = staticAddressTextOf(checker, node, canonical);
|
|
4454
4528
|
if (text !== undefined) {
|
|
4455
4529
|
const hash = text.indexOf("#");
|
|
@@ -4468,9 +4542,9 @@ function checkUrlFragmentReachability(input) {
|
|
|
4468
4542
|
}
|
|
4469
4543
|
}
|
|
4470
4544
|
}
|
|
4471
|
-
|
|
4545
|
+
ts21.forEachChild(node, visit);
|
|
4472
4546
|
};
|
|
4473
|
-
|
|
4547
|
+
ts21.forEachChild(sourceFile, visit);
|
|
4474
4548
|
}
|
|
4475
4549
|
return { kind: "checked", findings };
|
|
4476
4550
|
}
|
|
@@ -4478,6 +4552,9 @@ export {
|
|
|
4478
4552
|
ANIMATION_ASSET_EXTENSIONS,
|
|
4479
4553
|
COLLECTION_REFERENCE_EXTENSIONS,
|
|
4480
4554
|
COMPANION_INTERNAL_FIELD,
|
|
4555
|
+
DEBUG_BLOCK_BEGIN,
|
|
4556
|
+
DEBUG_BLOCK_END,
|
|
4557
|
+
DEBUG_MANAGED_BLOCK,
|
|
4481
4558
|
DEFAULT_INCLUDE,
|
|
4482
4559
|
GAME_PROJECT_DOCUMENT,
|
|
4483
4560
|
GUI_EXTENSIONS,
|
|
@@ -4518,6 +4595,7 @@ export {
|
|
|
4518
4595
|
displayPathOf,
|
|
4519
4596
|
findEmittedRequires,
|
|
4520
4597
|
findMainEntryFactoryImports,
|
|
4598
|
+
findManagedBootstrap,
|
|
4521
4599
|
findTextScriptProperties,
|
|
4522
4600
|
getProgramDiagnostics,
|
|
4523
4601
|
guiScriptResourceOf,
|