@defold-typescript/transpiler 0.40.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -1
- package/dist/index.js +184 -235
- package/dist/lifecycle-erasure.d.ts +7 -0
- package/dist/project-resources.d.ts +2 -1
- package/dist/text-script-property.d.ts +16 -0
- package/dist/type-application-erasure.d.ts +3 -0
- package/package.json +2 -2
- package/src/index.ts +7 -1
- package/src/lifecycle-erasure.ts +51 -22
- package/src/program-diagnostics.ts +2 -2
- package/src/project-resources.ts +20 -7
- package/src/session.ts +2 -2
- package/src/text-script-property.ts +100 -0
- package/src/transpile.ts +2 -2
- package/src/type-application-erasure.ts +34 -0
- package/dist/array-index-option-lowering.d.ts +0 -6
- package/src/array-index-option-lowering.ts +0 -212
package/dist/index.js
CHANGED
|
@@ -270,11 +270,11 @@ function emitInitMerge(fn, context, property) {
|
|
|
270
270
|
const initFn = createFunctionExpression2(createBlock2([stateDecl, guard]), [createIdentifier2("self")], undefined, NodeFlags2.Declaration, fn);
|
|
271
271
|
return [builderDecl, createAssignmentStatement(createIdentifier2("init"), initFn, property)];
|
|
272
272
|
}
|
|
273
|
-
function
|
|
273
|
+
function propertyMembers(property) {
|
|
274
274
|
if (!ts2.isPropertyAssignment(property) || !ts2.isObjectLiteralExpression(property.initializer)) {
|
|
275
275
|
return [];
|
|
276
276
|
}
|
|
277
|
-
const
|
|
277
|
+
const members = [];
|
|
278
278
|
for (const member of property.initializer.properties) {
|
|
279
279
|
if (!ts2.isPropertyAssignment(member)) {
|
|
280
280
|
continue;
|
|
@@ -283,21 +283,34 @@ function emitPropertyRegistrations(property, context) {
|
|
|
283
283
|
if (!ts2.isIdentifier(key) && !ts2.isStringLiteral(key)) {
|
|
284
284
|
continue;
|
|
285
285
|
}
|
|
286
|
-
|
|
286
|
+
members.push({ name: key.text, initializer: member.initializer });
|
|
287
287
|
}
|
|
288
|
-
return
|
|
288
|
+
return members;
|
|
289
289
|
}
|
|
290
|
-
function
|
|
290
|
+
function factoryHooks(expression, checker) {
|
|
291
291
|
if (!ts2.isCallExpression(expression)) {
|
|
292
292
|
return;
|
|
293
293
|
}
|
|
294
|
-
if (!resolvesToFactoryExport(expression.expression,
|
|
294
|
+
if (!resolvesToFactoryExport(expression.expression, checker)) {
|
|
295
295
|
return;
|
|
296
296
|
}
|
|
297
297
|
const hooks = expression.arguments[0];
|
|
298
298
|
if (hooks === undefined || !ts2.isObjectLiteralExpression(hooks)) {
|
|
299
299
|
return;
|
|
300
300
|
}
|
|
301
|
+
return hooks;
|
|
302
|
+
}
|
|
303
|
+
function isPropertiesHook(property) {
|
|
304
|
+
return hookName(property) === "properties";
|
|
305
|
+
}
|
|
306
|
+
function emitPropertyRegistrations(property, context) {
|
|
307
|
+
return propertyMembers(property).map(({ name, initializer }) => createExpressionStatement(createCallExpression2(createTableIndexExpression(createIdentifier2("go"), createStringLiteral2("property")), [createStringLiteral2(name), context.transformExpression(initializer)])));
|
|
308
|
+
}
|
|
309
|
+
function eraseFactoryCall(expression, context) {
|
|
310
|
+
const hooks = factoryHooks(expression, context.checker);
|
|
311
|
+
if (hooks === undefined) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
301
314
|
const registrations = [];
|
|
302
315
|
const statements = [];
|
|
303
316
|
for (const property of hooks.properties) {
|
|
@@ -1675,9 +1688,13 @@ function buildInputActionIndex(documents) {
|
|
|
1675
1688
|
}
|
|
1676
1689
|
// src/project-resources.ts
|
|
1677
1690
|
var SCAFFOLDED_DEFIGNORE_LINES = ["/node_modules", "/.defold-types", "/.vscode"];
|
|
1678
|
-
function
|
|
1691
|
+
function parseDefignore(text) {
|
|
1692
|
+
return text.split(`
|
|
1693
|
+
`).map((line) => line.trim()).filter((line) => line !== "").map((line) => line.startsWith("/") ? line : `/${line}`);
|
|
1694
|
+
}
|
|
1695
|
+
function isDefignoredPath(displayPath, lines = SCAFFOLDED_DEFIGNORE_LINES) {
|
|
1679
1696
|
const rooted = `/${displayPath.replace(/^\/+/, "")}`;
|
|
1680
|
-
return
|
|
1697
|
+
return lines.some((line) => rooted === line || rooted.startsWith(`${line}/`));
|
|
1681
1698
|
}
|
|
1682
1699
|
|
|
1683
1700
|
// src/scene-documents.ts
|
|
@@ -2061,176 +2078,13 @@ function computeOutputRel(rel, config, kind) {
|
|
|
2061
2078
|
import * as ts9 from "typescript";
|
|
2062
2079
|
import * as tstl from "typescript-to-lua";
|
|
2063
2080
|
|
|
2064
|
-
// src/
|
|
2081
|
+
// src/message-guard-lowering.ts
|
|
2065
2082
|
import * as ts5 from "typescript";
|
|
2066
2083
|
import {
|
|
2067
2084
|
createBinaryExpression as createBinaryExpression3,
|
|
2068
|
-
createNumericLiteral,
|
|
2069
|
-
getOriginalPos,
|
|
2070
|
-
isCallExpression as isCallExpression3,
|
|
2071
|
-
isNumericLiteral as isNumericLiteral3,
|
|
2072
|
-
isStringLiteral as isStringLiteral5,
|
|
2073
|
-
isTableExpression,
|
|
2074
|
-
SyntaxKind as SyntaxKind7,
|
|
2075
|
-
setNodePosition
|
|
2076
|
-
} from "typescript-to-lua";
|
|
2077
|
-
var ONE_BASED_INDEX_OPTION_APIS = new Set([
|
|
2078
|
-
"go.get",
|
|
2079
|
-
"go.set",
|
|
2080
|
-
"gui.get",
|
|
2081
|
-
"gui.set"
|
|
2082
|
-
]);
|
|
2083
|
-
var INDEX_OPTION_VARIABLE_MESSAGE = "`options.index` is zero-based and is converted to Defold's 1-based index only in an object literal written at the call; pass the options inline.";
|
|
2084
|
-
var INDEX_OPTION_SPREAD_MESSAGE = "A spread carrying `index` cannot be converted to Defold's 1-based index; write `index` explicitly after the spread.";
|
|
2085
|
-
var INDEX_OPTION_UNDEFINED_MESSAGE = "`options.index` may be undefined here, so it cannot be converted to Defold's 1-based index; pass a number, or leave `index` out.";
|
|
2086
|
-
var OPTIONS_PARAMETER = "options";
|
|
2087
|
-
var INDEX_KEY = "index";
|
|
2088
|
-
var loweredLiterals = new WeakSet;
|
|
2089
|
-
function oneBasedApi(declaration, checker) {
|
|
2090
|
-
let node = declaration;
|
|
2091
|
-
while (node !== undefined && !ts5.isFunctionDeclaration(node))
|
|
2092
|
-
node = node.parent;
|
|
2093
|
-
if (node?.name === undefined)
|
|
2094
|
-
return false;
|
|
2095
|
-
const symbol = checker.getSymbolAtLocation(node.name);
|
|
2096
|
-
if (symbol === undefined)
|
|
2097
|
-
return false;
|
|
2098
|
-
const fqn = checker.getFullyQualifiedName(symbol);
|
|
2099
|
-
return fqn.startsWith("global.") && ONE_BASED_INDEX_OPTION_APIS.has(fqn.slice("global.".length));
|
|
2100
|
-
}
|
|
2101
|
-
function optionsArgument(call, checker) {
|
|
2102
|
-
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
2103
|
-
if (declaration === undefined || !ts5.isFunctionLike(declaration))
|
|
2104
|
-
return;
|
|
2105
|
-
if (!oneBasedApi(declaration, checker))
|
|
2106
|
-
return;
|
|
2107
|
-
const index = declaration.parameters.findIndex((parameter) => parameter.dotDotDotToken === undefined && ts5.isIdentifier(parameter.name) && parameter.name.text === OPTIONS_PARAMETER);
|
|
2108
|
-
return index === -1 ? undefined : call.arguments[index];
|
|
2109
|
-
}
|
|
2110
|
-
function unwrap(expression) {
|
|
2111
|
-
let current = expression;
|
|
2112
|
-
while (ts5.isParenthesizedExpression(current) || ts5.isAsExpression(current) || ts5.isSatisfiesExpression(current) || ts5.isNonNullExpression(current) || ts5.isTypeAssertionExpression(current)) {
|
|
2113
|
-
current = current.expression;
|
|
2114
|
-
}
|
|
2115
|
-
return current;
|
|
2116
|
-
}
|
|
2117
|
-
function someConstituent(type, predicate) {
|
|
2118
|
-
return type.isUnion() ? type.types.some(predicate) : predicate(type);
|
|
2119
|
-
}
|
|
2120
|
-
function carriesIndex(type) {
|
|
2121
|
-
return someConstituent(type, (t) => t.getProperty(INDEX_KEY) !== undefined);
|
|
2122
|
-
}
|
|
2123
|
-
function admitsUndefined(type) {
|
|
2124
|
-
return someConstituent(type, (t) => (t.flags & (ts5.TypeFlags.Undefined | ts5.TypeFlags.Void)) !== 0);
|
|
2125
|
-
}
|
|
2126
|
-
function propertyName(property, checker) {
|
|
2127
|
-
const name = property.name;
|
|
2128
|
-
if (name === undefined)
|
|
2129
|
-
return;
|
|
2130
|
-
if (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name)) {
|
|
2131
|
-
return name.text;
|
|
2132
|
-
}
|
|
2133
|
-
if (ts5.isComputedPropertyName(name)) {
|
|
2134
|
-
const type = checker.getTypeAtLocation(name.expression);
|
|
2135
|
-
if (type.isStringLiteral())
|
|
2136
|
-
return type.value;
|
|
2137
|
-
}
|
|
2138
|
-
return;
|
|
2139
|
-
}
|
|
2140
|
-
function indexValueType(property, checker) {
|
|
2141
|
-
if (ts5.isPropertyAssignment(property))
|
|
2142
|
-
return checker.getTypeAtLocation(property.initializer);
|
|
2143
|
-
if (ts5.isShorthandPropertyAssignment(property))
|
|
2144
|
-
return checker.getTypeAtLocation(property.name);
|
|
2145
|
-
return;
|
|
2146
|
-
}
|
|
2147
|
-
function rejection(node, messageText) {
|
|
2148
|
-
const file = node.getSourceFile();
|
|
2149
|
-
const start = node.getStart(file);
|
|
2150
|
-
return {
|
|
2151
|
-
file,
|
|
2152
|
-
start,
|
|
2153
|
-
length: node.getEnd() - start,
|
|
2154
|
-
category: ts5.DiagnosticCategory.Error,
|
|
2155
|
-
code: 0,
|
|
2156
|
-
messageText
|
|
2157
|
-
};
|
|
2158
|
-
}
|
|
2159
|
-
function rejectOptions(options, checker) {
|
|
2160
|
-
const literal = unwrap(options);
|
|
2161
|
-
if (!ts5.isObjectLiteralExpression(literal)) {
|
|
2162
|
-
return carriesIndex(checker.getTypeAtLocation(literal)) ? rejection(options, INDEX_OPTION_VARIABLE_MESSAGE) : undefined;
|
|
2163
|
-
}
|
|
2164
|
-
let uncoveredSpread;
|
|
2165
|
-
let explicitIndex;
|
|
2166
|
-
for (const property of literal.properties) {
|
|
2167
|
-
if (ts5.isSpreadAssignment(property)) {
|
|
2168
|
-
if (carriesIndex(checker.getTypeAtLocation(property.expression)))
|
|
2169
|
-
uncoveredSpread = property;
|
|
2170
|
-
} else if (propertyName(property, checker) === INDEX_KEY) {
|
|
2171
|
-
uncoveredSpread = undefined;
|
|
2172
|
-
explicitIndex = property;
|
|
2173
|
-
}
|
|
2174
|
-
}
|
|
2175
|
-
if (uncoveredSpread !== undefined)
|
|
2176
|
-
return rejection(uncoveredSpread, INDEX_OPTION_SPREAD_MESSAGE);
|
|
2177
|
-
const valueType = explicitIndex && indexValueType(explicitIndex, checker);
|
|
2178
|
-
if (explicitIndex !== undefined && valueType !== undefined && admitsUndefined(valueType)) {
|
|
2179
|
-
return rejection(explicitIndex, INDEX_OPTION_UNDEFINED_MESSAGE);
|
|
2180
|
-
}
|
|
2181
|
-
return;
|
|
2182
|
-
}
|
|
2183
|
-
function plusOne(value) {
|
|
2184
|
-
if (isNumericLiteral3(value)) {
|
|
2185
|
-
return setNodePosition(createNumericLiteral(value.value + 1), getOriginalPos(value));
|
|
2186
|
-
}
|
|
2187
|
-
return setNodePosition(createBinaryExpression3(value, createNumericLiteral(1), SyntaxKind7.AdditionOperator), getOriginalPos(value));
|
|
2188
|
-
}
|
|
2189
|
-
function offsetEffectiveIndexField(tables) {
|
|
2190
|
-
for (const field of tables.flatMap((table) => table.fields).reverse()) {
|
|
2191
|
-
if (field.key !== undefined && isStringLiteral5(field.key) && field.key.value === INDEX_KEY) {
|
|
2192
|
-
field.value = plusOne(field.value);
|
|
2193
|
-
return;
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
}
|
|
2197
|
-
var arrayIndexOptionLoweringPlugin = {
|
|
2198
|
-
visitors: {
|
|
2199
|
-
[ts5.SyntaxKind.CallExpression]: (node, context) => {
|
|
2200
|
-
const options = optionsArgument(node, context.checker);
|
|
2201
|
-
if (options !== undefined) {
|
|
2202
|
-
const diagnostic = rejectOptions(options, context.checker);
|
|
2203
|
-
if (diagnostic !== undefined) {
|
|
2204
|
-
context.diagnostics.push(diagnostic);
|
|
2205
|
-
} else {
|
|
2206
|
-
const literal = unwrap(options);
|
|
2207
|
-
if (ts5.isObjectLiteralExpression(literal))
|
|
2208
|
-
loweredLiterals.add(literal);
|
|
2209
|
-
}
|
|
2210
|
-
}
|
|
2211
|
-
return context.superTransformExpression(node);
|
|
2212
|
-
},
|
|
2213
|
-
[ts5.SyntaxKind.ObjectLiteralExpression]: (node, context) => {
|
|
2214
|
-
const result = context.superTransformExpression(node);
|
|
2215
|
-
if (!loweredLiterals.has(node))
|
|
2216
|
-
return result;
|
|
2217
|
-
if (isTableExpression(result)) {
|
|
2218
|
-
offsetEffectiveIndexField([result]);
|
|
2219
|
-
} else if (isCallExpression3(result)) {
|
|
2220
|
-
offsetEffectiveIndexField(result.params.filter(isTableExpression));
|
|
2221
|
-
}
|
|
2222
|
-
return result;
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
};
|
|
2226
|
-
|
|
2227
|
-
// src/message-guard-lowering.ts
|
|
2228
|
-
import * as ts6 from "typescript";
|
|
2229
|
-
import {
|
|
2230
|
-
createBinaryExpression as createBinaryExpression4,
|
|
2231
2085
|
createCallExpression as createCallExpression3,
|
|
2232
2086
|
createIdentifier as createIdentifier3,
|
|
2233
|
-
SyntaxKind as
|
|
2087
|
+
SyntaxKind as SyntaxKind7
|
|
2234
2088
|
} from "typescript-to-lua";
|
|
2235
2089
|
var GUARD_MODULE = "@defold-typescript/types";
|
|
2236
2090
|
var GUARD_NAME = "isMessage";
|
|
@@ -2239,7 +2093,7 @@ function resolvesToGuardExport(callee, checker) {
|
|
|
2239
2093
|
if (symbol === undefined) {
|
|
2240
2094
|
return false;
|
|
2241
2095
|
}
|
|
2242
|
-
if (symbol.flags &
|
|
2096
|
+
if (symbol.flags & ts5.SymbolFlags.Alias) {
|
|
2243
2097
|
symbol = checker.getAliasedSymbol(symbol);
|
|
2244
2098
|
}
|
|
2245
2099
|
if (symbol.getName() !== GUARD_NAME) {
|
|
@@ -2253,12 +2107,12 @@ function resolvesToGuardExport(callee, checker) {
|
|
|
2253
2107
|
}
|
|
2254
2108
|
var messageGuardLoweringPlugin = {
|
|
2255
2109
|
visitors: {
|
|
2256
|
-
[
|
|
2110
|
+
[ts5.SyntaxKind.CallExpression]: (node, context) => {
|
|
2257
2111
|
const [messageIdArg, , expectedArg] = node.arguments;
|
|
2258
2112
|
if (node.arguments.length === 3 && messageIdArg !== undefined && expectedArg !== undefined && resolvesToGuardExport(node.expression, context.checker)) {
|
|
2259
2113
|
const messageId = context.transformExpression(messageIdArg);
|
|
2260
2114
|
const expected = context.transformExpression(expectedArg);
|
|
2261
|
-
return
|
|
2115
|
+
return createBinaryExpression3(messageId, createCallExpression3(createIdentifier3("hash"), [expected]), SyntaxKind7.EqualityOperator, node);
|
|
2262
2116
|
}
|
|
2263
2117
|
return context.superTransformExpression(node);
|
|
2264
2118
|
}
|
|
@@ -2266,34 +2120,64 @@ var messageGuardLoweringPlugin = {
|
|
|
2266
2120
|
};
|
|
2267
2121
|
|
|
2268
2122
|
// src/timers-lowering.ts
|
|
2269
|
-
import * as
|
|
2123
|
+
import * as ts6 from "typescript";
|
|
2270
2124
|
import { LuaLibFeature } from "typescript-to-lua";
|
|
2271
2125
|
function isTimersSpecifier(node) {
|
|
2272
|
-
return
|
|
2126
|
+
return ts6.isStringLiteral(node) && node.text === TIMERS_MODULE_SPECIFIER;
|
|
2273
2127
|
}
|
|
2274
2128
|
function importsTimersModule(sourceFile) {
|
|
2275
|
-
return sourceFile.statements.some((statement) =>
|
|
2129
|
+
return sourceFile.statements.some((statement) => ts6.isImportDeclaration(statement) && isTimersSpecifier(statement.moduleSpecifier));
|
|
2276
2130
|
}
|
|
2277
2131
|
var TIMERS_REQUIRE_PATH = `@NoResolution:${TIMERS_REQUIRE_NAME}`;
|
|
2278
2132
|
var timersLoweringPlugin = {
|
|
2279
2133
|
visitors: {
|
|
2280
|
-
[
|
|
2134
|
+
[ts6.SyntaxKind.ImportDeclaration]: (node, context) => {
|
|
2281
2135
|
if (!isTimersSpecifier(node.moduleSpecifier)) {
|
|
2282
2136
|
return context.superTransformStatements(node);
|
|
2283
2137
|
}
|
|
2284
2138
|
context.usedLuaLibFeatures.add(LuaLibFeature.Promise);
|
|
2285
2139
|
context.usedLuaLibFeatures.add(LuaLibFeature.New);
|
|
2286
|
-
const rewritten =
|
|
2140
|
+
const rewritten = ts6.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts6.factory.createStringLiteral(TIMERS_REQUIRE_PATH), node.attributes);
|
|
2287
2141
|
return context.superTransformStatements(rewritten);
|
|
2288
2142
|
}
|
|
2289
2143
|
}
|
|
2290
2144
|
};
|
|
2291
2145
|
|
|
2146
|
+
// src/type-application-erasure.ts
|
|
2147
|
+
import * as ts7 from "typescript";
|
|
2148
|
+
var TYPE_APPLICATION_APIS = new Set(["go.get", "go.set"]);
|
|
2149
|
+
function isTypeApplication(call, checker) {
|
|
2150
|
+
if (call.arguments.length !== 0)
|
|
2151
|
+
return false;
|
|
2152
|
+
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
2153
|
+
if (declaration === undefined || !ts7.isFunctionDeclaration(declaration))
|
|
2154
|
+
return false;
|
|
2155
|
+
if (declaration.parameters.length !== 0 || declaration.typeParameters === undefined)
|
|
2156
|
+
return false;
|
|
2157
|
+
if (declaration.name === undefined)
|
|
2158
|
+
return false;
|
|
2159
|
+
const symbol = checker.getSymbolAtLocation(declaration.name);
|
|
2160
|
+
if (symbol === undefined)
|
|
2161
|
+
return false;
|
|
2162
|
+
const fqn = checker.getFullyQualifiedName(symbol);
|
|
2163
|
+
return fqn.startsWith("global.") && TYPE_APPLICATION_APIS.has(fqn.slice("global.".length));
|
|
2164
|
+
}
|
|
2165
|
+
var typeApplicationErasurePlugin = {
|
|
2166
|
+
visitors: {
|
|
2167
|
+
[ts7.SyntaxKind.CallExpression]: (node, context) => {
|
|
2168
|
+
if (isTypeApplication(node, context.checker)) {
|
|
2169
|
+
return context.transformExpression(node.expression);
|
|
2170
|
+
}
|
|
2171
|
+
return context.superTransformExpression(node);
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
2175
|
+
|
|
2292
2176
|
// src/window-event-guard-lowering.ts
|
|
2293
2177
|
import * as ts8 from "typescript";
|
|
2294
2178
|
import {
|
|
2295
|
-
createBinaryExpression as
|
|
2296
|
-
SyntaxKind as
|
|
2179
|
+
createBinaryExpression as createBinaryExpression4,
|
|
2180
|
+
SyntaxKind as SyntaxKind11
|
|
2297
2181
|
} from "typescript-to-lua";
|
|
2298
2182
|
var GUARD_MODULE2 = "@defold-typescript/types";
|
|
2299
2183
|
var GUARD_NAME2 = "isWindowEvent";
|
|
@@ -2321,7 +2205,7 @@ var windowEventGuardLoweringPlugin = {
|
|
|
2321
2205
|
if (node.arguments.length === 3 && eventArg !== undefined && expectedArg !== undefined && resolvesToGuardExport2(node.expression, context.checker)) {
|
|
2322
2206
|
const event = context.transformExpression(eventArg);
|
|
2323
2207
|
const expected = context.transformExpression(expectedArg);
|
|
2324
|
-
return
|
|
2208
|
+
return createBinaryExpression4(event, expected, SyntaxKind11.EqualityOperator, node);
|
|
2325
2209
|
}
|
|
2326
2210
|
return context.superTransformExpression(node);
|
|
2327
2211
|
}
|
|
@@ -2335,7 +2219,7 @@ var LUA_PLUGINS = [
|
|
|
2335
2219
|
windowEventGuardLoweringPlugin,
|
|
2336
2220
|
messageDispatchLoweringPlugin,
|
|
2337
2221
|
timersLoweringPlugin,
|
|
2338
|
-
|
|
2222
|
+
typeApplicationErasurePlugin
|
|
2339
2223
|
];
|
|
2340
2224
|
var noopWriteFile = () => {};
|
|
2341
2225
|
function isAmbient(fileName) {
|
|
@@ -2930,18 +2814,18 @@ import {
|
|
|
2930
2814
|
createTableIndexExpression as createTableIndexExpression2,
|
|
2931
2815
|
createVariableDeclarationStatement as createVariableDeclarationStatement3,
|
|
2932
2816
|
isBlock as isBlock3,
|
|
2933
|
-
isCallExpression as
|
|
2817
|
+
isCallExpression as isCallExpression4,
|
|
2934
2818
|
isDoStatement,
|
|
2935
2819
|
isForInStatement as isForInStatement2,
|
|
2936
2820
|
isForStatement,
|
|
2937
2821
|
isFunctionDefinition,
|
|
2938
2822
|
isFunctionExpression as isFunctionExpression4,
|
|
2939
|
-
isIdentifier as
|
|
2823
|
+
isIdentifier as isIdentifier4,
|
|
2940
2824
|
isMethodCallExpression,
|
|
2941
2825
|
isRepeatStatement,
|
|
2942
2826
|
isReturnStatement as isReturnStatement2,
|
|
2943
|
-
isStringLiteral as
|
|
2944
|
-
isTableExpression
|
|
2827
|
+
isStringLiteral as isStringLiteral6,
|
|
2828
|
+
isTableExpression,
|
|
2945
2829
|
isVariableDeclarationStatement,
|
|
2946
2830
|
LuaPrinter
|
|
2947
2831
|
} from "typescript-to-lua";
|
|
@@ -3013,7 +2897,7 @@ function freeNames(statements) {
|
|
|
3013
2897
|
if (node === undefined) {
|
|
3014
2898
|
return;
|
|
3015
2899
|
}
|
|
3016
|
-
if (
|
|
2900
|
+
if (isIdentifier4(node)) {
|
|
3017
2901
|
if (!isBound(node.text)) {
|
|
3018
2902
|
free.add(node.text);
|
|
3019
2903
|
}
|
|
@@ -3119,14 +3003,14 @@ function resolvedRequirePaths(sourceFile, checker) {
|
|
|
3119
3003
|
function resolveMovedRequires(statements, paths) {
|
|
3120
3004
|
for (const statement of statements) {
|
|
3121
3005
|
forEachLuaNode(statement, (node) => {
|
|
3122
|
-
if (!
|
|
3006
|
+
if (!isCallExpression4(node) || !isIdentifier4(node.expression)) {
|
|
3123
3007
|
return;
|
|
3124
3008
|
}
|
|
3125
3009
|
if (node.expression.text !== "require" || node.params.length !== 1) {
|
|
3126
3010
|
return;
|
|
3127
3011
|
}
|
|
3128
3012
|
const [argument] = node.params;
|
|
3129
|
-
if (argument === undefined || !
|
|
3013
|
+
if (argument === undefined || !isStringLiteral6(argument)) {
|
|
3130
3014
|
return;
|
|
3131
3015
|
}
|
|
3132
3016
|
const resolved = paths.get(argument.value);
|
|
@@ -3142,14 +3026,14 @@ function withResolvedRequire(statement, paths) {
|
|
|
3142
3026
|
}
|
|
3143
3027
|
const name = statement.left[0];
|
|
3144
3028
|
const [value] = statement.right ?? [];
|
|
3145
|
-
if (name === undefined || value === undefined || !
|
|
3029
|
+
if (name === undefined || value === undefined || !isCallExpression4(value)) {
|
|
3146
3030
|
return statement;
|
|
3147
3031
|
}
|
|
3148
|
-
if (!
|
|
3032
|
+
if (!isIdentifier4(value.expression) || value.expression.text !== "require") {
|
|
3149
3033
|
return statement;
|
|
3150
3034
|
}
|
|
3151
3035
|
const [argument] = value.params;
|
|
3152
|
-
if (argument === undefined || !
|
|
3036
|
+
if (argument === undefined || !isStringLiteral6(argument)) {
|
|
3153
3037
|
return statement;
|
|
3154
3038
|
}
|
|
3155
3039
|
const resolved = paths.get(argument.value);
|
|
@@ -3185,7 +3069,7 @@ function copiedPrelude(halves, importBindings) {
|
|
|
3185
3069
|
function namesIdentifier(statement, names) {
|
|
3186
3070
|
let found = false;
|
|
3187
3071
|
forEachLuaNode(statement, (node) => {
|
|
3188
|
-
if (
|
|
3072
|
+
if (isIdentifier4(node) && names.has(node.text)) {
|
|
3189
3073
|
found = true;
|
|
3190
3074
|
}
|
|
3191
3075
|
});
|
|
@@ -3196,14 +3080,14 @@ function isExportsTableInit(statement) {
|
|
|
3196
3080
|
return false;
|
|
3197
3081
|
}
|
|
3198
3082
|
const [single] = statement.right ?? [];
|
|
3199
|
-
return statement.left[0]?.text === EXPORTS_NAME && single !== undefined &&
|
|
3083
|
+
return statement.left[0]?.text === EXPORTS_NAME && single !== undefined && isTableExpression(single);
|
|
3200
3084
|
}
|
|
3201
3085
|
function isExportsReturn(statement) {
|
|
3202
3086
|
if (!isReturnStatement2(statement) || statement.expressions.length !== 1) {
|
|
3203
3087
|
return false;
|
|
3204
3088
|
}
|
|
3205
3089
|
const [single] = statement.expressions;
|
|
3206
|
-
return single !== undefined &&
|
|
3090
|
+
return single !== undefined && isIdentifier4(single) && single.text === EXPORTS_NAME;
|
|
3207
3091
|
}
|
|
3208
3092
|
function isHoistedNameDeclaration(statement) {
|
|
3209
3093
|
return isVariableDeclarationStatement(statement) && statement.right === undefined;
|
|
@@ -3631,7 +3515,7 @@ function transpileProject(input) {
|
|
|
3631
3515
|
{ plugin: windowEventGuardLoweringPlugin },
|
|
3632
3516
|
{ plugin: messageDispatchLoweringPlugin },
|
|
3633
3517
|
{ plugin: timersLoweringPlugin },
|
|
3634
|
-
{ plugin:
|
|
3518
|
+
{ plugin: typeApplicationErasurePlugin },
|
|
3635
3519
|
{ plugin: companionEmit.plugin }
|
|
3636
3520
|
]
|
|
3637
3521
|
});
|
|
@@ -3662,7 +3546,7 @@ function compilerOptions(companionEmit) {
|
|
|
3662
3546
|
{ plugin: windowEventGuardLoweringPlugin },
|
|
3663
3547
|
{ plugin: messageDispatchLoweringPlugin },
|
|
3664
3548
|
{ plugin: timersLoweringPlugin },
|
|
3665
|
-
{ plugin:
|
|
3549
|
+
{ plugin: typeApplicationErasurePlugin },
|
|
3666
3550
|
{ plugin: companionEmit.plugin }
|
|
3667
3551
|
]
|
|
3668
3552
|
};
|
|
@@ -3779,8 +3663,71 @@ function createTranspileSession() {
|
|
|
3779
3663
|
getProgram: () => program
|
|
3780
3664
|
};
|
|
3781
3665
|
}
|
|
3782
|
-
// src/
|
|
3666
|
+
// src/text-script-property.ts
|
|
3783
3667
|
import * as ts14 from "typescript";
|
|
3668
|
+
function findTextScriptProperties(program, fileNames) {
|
|
3669
|
+
const checker = program.getTypeChecker();
|
|
3670
|
+
const findings = [];
|
|
3671
|
+
for (const file of fileNames) {
|
|
3672
|
+
const sourceFile = program.getSourceFile(file);
|
|
3673
|
+
if (sourceFile === undefined) {
|
|
3674
|
+
continue;
|
|
3675
|
+
}
|
|
3676
|
+
const located = [];
|
|
3677
|
+
const visit = (node) => {
|
|
3678
|
+
if (ts14.isCallExpression(node)) {
|
|
3679
|
+
const hooks = factoryHooks(node, checker);
|
|
3680
|
+
for (const property of hooks?.properties ?? []) {
|
|
3681
|
+
if (!isPropertiesHook(property)) {
|
|
3682
|
+
continue;
|
|
3683
|
+
}
|
|
3684
|
+
for (const { name, initializer } of propertyMembers(property)) {
|
|
3685
|
+
if (mayHoldString(checker.getTypeAtLocation(initializer), checker)) {
|
|
3686
|
+
located.push({ name, value: initializer });
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
}
|
|
3691
|
+
ts14.forEachChild(node, visit);
|
|
3692
|
+
};
|
|
3693
|
+
visit(sourceFile);
|
|
3694
|
+
for (const call of findDirectGoPropertyCalls(sourceFile)) {
|
|
3695
|
+
const [nameArgument, value] = call.arguments;
|
|
3696
|
+
if (nameArgument === undefined || value === undefined) {
|
|
3697
|
+
continue;
|
|
3698
|
+
}
|
|
3699
|
+
if (mayHoldString(checker.getTypeAtLocation(value), checker)) {
|
|
3700
|
+
const name = ts14.isStringLiteralLike(nameArgument) ? nameArgument.text : nameArgument.getText(sourceFile);
|
|
3701
|
+
located.push({ name, value });
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
located.sort((left, right) => left.value.getStart(sourceFile) - right.value.getStart(sourceFile));
|
|
3705
|
+
for (const { name, value } of located) {
|
|
3706
|
+
const position = sourceFile.getLineAndCharacterOfPosition(value.getStart(sourceFile));
|
|
3707
|
+
findings.push({ name, file, line: position.line + 1, column: position.character + 1 });
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
return findings;
|
|
3711
|
+
}
|
|
3712
|
+
function mayHoldString(type, checker, visited = new Set) {
|
|
3713
|
+
if (visited.has(type)) {
|
|
3714
|
+
return false;
|
|
3715
|
+
}
|
|
3716
|
+
visited.add(type);
|
|
3717
|
+
if (type.flags & ts14.TypeFlags.StringLike) {
|
|
3718
|
+
return true;
|
|
3719
|
+
}
|
|
3720
|
+
if (type.isUnionOrIntersection()) {
|
|
3721
|
+
return type.types.some((member) => mayHoldString(member, checker, visited));
|
|
3722
|
+
}
|
|
3723
|
+
if (type.flags & ts14.TypeFlags.Instantiable) {
|
|
3724
|
+
const constraint = checker.getBaseConstraintOfType(type);
|
|
3725
|
+
return constraint !== undefined && constraint !== type ? mayHoldString(constraint, checker, visited) : false;
|
|
3726
|
+
}
|
|
3727
|
+
return false;
|
|
3728
|
+
}
|
|
3729
|
+
// src/url-address-slots.ts
|
|
3730
|
+
import * as ts15 from "typescript";
|
|
3784
3731
|
var ADDRESS_CLASSES = {
|
|
3785
3732
|
"game-object": true,
|
|
3786
3733
|
component: true,
|
|
@@ -3799,7 +3746,7 @@ function isFragmentCaret(slot, position) {
|
|
|
3799
3746
|
return slot.fragmentStart !== -1 && position >= slot.fragmentStart;
|
|
3800
3747
|
}
|
|
3801
3748
|
function tableKey(checker, callee) {
|
|
3802
|
-
const symbol = checker.getSymbolAtLocation(
|
|
3749
|
+
const symbol = checker.getSymbolAtLocation(ts15.isIdentifier(callee) ? callee : callee.name);
|
|
3803
3750
|
if (!symbol)
|
|
3804
3751
|
return;
|
|
3805
3752
|
const fqn = checker.getFullyQualifiedName(symbol);
|
|
@@ -3807,43 +3754,43 @@ function tableKey(checker, callee) {
|
|
|
3807
3754
|
}
|
|
3808
3755
|
function parameterName(checker, call, index) {
|
|
3809
3756
|
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
3810
|
-
if (!declaration || !
|
|
3757
|
+
if (!declaration || !ts15.isFunctionLike(declaration))
|
|
3811
3758
|
return;
|
|
3812
3759
|
const parameter = declaration.parameters[index];
|
|
3813
|
-
if (!parameter || parameter.dotDotDotToken || !
|
|
3760
|
+
if (!parameter || parameter.dotDotDotToken || !ts15.isIdentifier(parameter.name))
|
|
3814
3761
|
return;
|
|
3815
3762
|
return parameter.name.text;
|
|
3816
3763
|
}
|
|
3817
3764
|
var EQUALITY_OPERATORS = new Set([
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3765
|
+
ts15.SyntaxKind.EqualsEqualsEqualsToken,
|
|
3766
|
+
ts15.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
3767
|
+
ts15.SyntaxKind.EqualsEqualsToken,
|
|
3768
|
+
ts15.SyntaxKind.ExclamationEqualsToken
|
|
3822
3769
|
]);
|
|
3823
3770
|
function comparisonSatisfied(checker, entry, call) {
|
|
3824
3771
|
if (entry.comparedParameter === undefined)
|
|
3825
3772
|
return true;
|
|
3826
3773
|
let node = call;
|
|
3827
|
-
while (
|
|
3774
|
+
while (ts15.isParenthesizedExpression(node.parent))
|
|
3828
3775
|
node = node.parent;
|
|
3829
3776
|
const comparison = node.parent;
|
|
3830
|
-
if (!
|
|
3777
|
+
if (!ts15.isBinaryExpression(comparison))
|
|
3831
3778
|
return false;
|
|
3832
3779
|
if (!EQUALITY_OPERATORS.has(comparison.operatorToken.kind))
|
|
3833
3780
|
return false;
|
|
3834
3781
|
const other = comparison.left === node ? comparison.right : comparison.left;
|
|
3835
3782
|
const symbol = checker.getSymbolAtLocation(other);
|
|
3836
|
-
return (symbol?.declarations ?? []).some((declaration) =>
|
|
3783
|
+
return (symbol?.declarations ?? []).some((declaration) => ts15.isParameter(declaration) && ts15.isIdentifier(declaration.name) && declaration.name.text === entry.comparedParameter);
|
|
3837
3784
|
}
|
|
3838
3785
|
function classifiedEntryOfArgument(checker, table, argument) {
|
|
3839
3786
|
const call = argument.parent;
|
|
3840
|
-
if (!
|
|
3787
|
+
if (!ts15.isCallExpression(call))
|
|
3841
3788
|
return;
|
|
3842
3789
|
const argumentIndex = call.arguments.indexOf(argument);
|
|
3843
3790
|
if (argumentIndex === -1)
|
|
3844
3791
|
return;
|
|
3845
3792
|
const callee = call.expression;
|
|
3846
|
-
if (!
|
|
3793
|
+
if (!ts15.isPropertyAccessExpression(callee) && !ts15.isIdentifier(callee))
|
|
3847
3794
|
return;
|
|
3848
3795
|
const fqn = tableKey(checker, callee);
|
|
3849
3796
|
if (fqn === undefined)
|
|
@@ -3860,10 +3807,10 @@ function classifiedEntryOfArgument(checker, table, argument) {
|
|
|
3860
3807
|
}
|
|
3861
3808
|
function slotThroughHashedCall(checker, table, literal) {
|
|
3862
3809
|
const call = literal.parent;
|
|
3863
|
-
if (!
|
|
3810
|
+
if (!ts15.isCallExpression(call))
|
|
3864
3811
|
return;
|
|
3865
3812
|
const callee = call.expression;
|
|
3866
|
-
if (!
|
|
3813
|
+
if (!ts15.isPropertyAccessExpression(callee) && !ts15.isIdentifier(callee))
|
|
3867
3814
|
return;
|
|
3868
3815
|
if (tableKey(checker, callee) !== "hash")
|
|
3869
3816
|
return;
|
|
@@ -3881,24 +3828,24 @@ function addressTextOf(checker, entry, call) {
|
|
|
3881
3828
|
if (entry.addressParameter === undefined)
|
|
3882
3829
|
return;
|
|
3883
3830
|
const declaration = checker.getResolvedSignature(call)?.declaration;
|
|
3884
|
-
if (!declaration || !
|
|
3831
|
+
if (!declaration || !ts15.isFunctionLike(declaration))
|
|
3885
3832
|
return;
|
|
3886
|
-
const index = declaration.parameters.findIndex((parameter) => !parameter.dotDotDotToken &&
|
|
3833
|
+
const index = declaration.parameters.findIndex((parameter) => !parameter.dotDotDotToken && ts15.isIdentifier(parameter.name) && parameter.name.text === entry.addressParameter);
|
|
3887
3834
|
if (index === -1)
|
|
3888
3835
|
return;
|
|
3889
3836
|
const argument = call.arguments[index];
|
|
3890
|
-
return argument &&
|
|
3837
|
+
return argument && ts15.isStringLiteralLike(argument) ? argument.text : undefined;
|
|
3891
3838
|
}
|
|
3892
3839
|
function innermostLiteralAt(sourceFile, position) {
|
|
3893
3840
|
let found;
|
|
3894
3841
|
const visit = (node) => {
|
|
3895
3842
|
if (position < node.getStart(sourceFile) || position > node.getEnd())
|
|
3896
3843
|
return;
|
|
3897
|
-
if (
|
|
3844
|
+
if (ts15.isStringLiteralLike(node))
|
|
3898
3845
|
found = node;
|
|
3899
|
-
|
|
3846
|
+
ts15.forEachChild(node, visit);
|
|
3900
3847
|
};
|
|
3901
|
-
|
|
3848
|
+
ts15.forEachChild(sourceFile, visit);
|
|
3902
3849
|
return found;
|
|
3903
3850
|
}
|
|
3904
3851
|
function resolveClassifiedSlotAtPosition(input) {
|
|
@@ -3932,23 +3879,23 @@ function resolveClassifiedSlotAtPosition(input) {
|
|
|
3932
3879
|
};
|
|
3933
3880
|
}
|
|
3934
3881
|
// src/url-cross-world-address.ts
|
|
3935
|
-
import * as
|
|
3882
|
+
import * as ts17 from "typescript";
|
|
3936
3883
|
|
|
3937
3884
|
// src/url-address-literals.ts
|
|
3938
|
-
import * as
|
|
3885
|
+
import * as ts16 from "typescript";
|
|
3939
3886
|
function isAmbient2(fileName) {
|
|
3940
3887
|
return /[\\/]node_modules[\\/]/.test(fileName) || /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(fileName);
|
|
3941
3888
|
}
|
|
3942
3889
|
function referenceTargetSymbol(type) {
|
|
3943
|
-
if ((type.flags &
|
|
3890
|
+
if ((type.flags & ts16.TypeFlags.Object) === 0)
|
|
3944
3891
|
return;
|
|
3945
|
-
if ((type.objectFlags &
|
|
3892
|
+
if ((type.objectFlags & ts16.ObjectFlags.Reference) === 0)
|
|
3946
3893
|
return;
|
|
3947
3894
|
return type.target.symbol;
|
|
3948
3895
|
}
|
|
3949
3896
|
function ambientHashAliasTargets(checker, anchor) {
|
|
3950
3897
|
const targets = new Set;
|
|
3951
|
-
for (const symbol of checker.getSymbolsInScope(anchor,
|
|
3898
|
+
for (const symbol of checker.getSymbolsInScope(anchor, ts16.SymbolFlags.Type)) {
|
|
3952
3899
|
if (symbol.name !== "Hash")
|
|
3953
3900
|
continue;
|
|
3954
3901
|
const target = referenceTargetSymbol(checker.getDeclaredTypeOfSymbol(symbol));
|
|
@@ -3964,7 +3911,7 @@ function canonicalHashSymbols(checker, program) {
|
|
|
3964
3911
|
if (!anchor)
|
|
3965
3912
|
return canonical;
|
|
3966
3913
|
const aliased = ambientHashAliasTargets(checker, anchor);
|
|
3967
|
-
for (const symbol of checker.getSymbolsInScope(anchor,
|
|
3914
|
+
for (const symbol of checker.getSymbolsInScope(anchor, ts16.SymbolFlags.Function)) {
|
|
3968
3915
|
if (symbol.name !== "hash")
|
|
3969
3916
|
continue;
|
|
3970
3917
|
const declaration = symbol.declarations?.[0];
|
|
@@ -3986,7 +3933,7 @@ function hashedSourceOfType(checker, type, canonical) {
|
|
|
3986
3933
|
return source?.isStringLiteral() ? source.value : undefined;
|
|
3987
3934
|
}
|
|
3988
3935
|
function staticAddressTextOf(checker, node, canonical) {
|
|
3989
|
-
return
|
|
3936
|
+
return ts16.isStringLiteralLike(node) ? node.text : hashedSourceOfType(checker, checker.getTypeAtLocation(node), canonical);
|
|
3990
3937
|
}
|
|
3991
3938
|
|
|
3992
3939
|
// src/url-cross-world-address.ts
|
|
@@ -4010,7 +3957,7 @@ function checkCrossWorldAddresses(input) {
|
|
|
4010
3957
|
if (worlds.length === 0)
|
|
4011
3958
|
continue;
|
|
4012
3959
|
const visit = (node) => {
|
|
4013
|
-
if (
|
|
3960
|
+
if (ts17.isExpression(node)) {
|
|
4014
3961
|
const entry = addressEntryOfArgument(checker, table, node);
|
|
4015
3962
|
if (entry !== undefined && slotRejectsForeignSocket(entry)) {
|
|
4016
3963
|
const address = staticAddressTextOf(checker, node, canonical);
|
|
@@ -4027,14 +3974,14 @@ function checkCrossWorldAddresses(input) {
|
|
|
4027
3974
|
}
|
|
4028
3975
|
}
|
|
4029
3976
|
}
|
|
4030
|
-
|
|
3977
|
+
ts17.forEachChild(node, visit);
|
|
4031
3978
|
};
|
|
4032
|
-
|
|
3979
|
+
ts17.forEachChild(sourceFile, visit);
|
|
4033
3980
|
}
|
|
4034
3981
|
return findings;
|
|
4035
3982
|
}
|
|
4036
3983
|
// src/url-fragment-reachability.ts
|
|
4037
|
-
import * as
|
|
3984
|
+
import * as ts18 from "typescript";
|
|
4038
3985
|
function pathOfKey(key) {
|
|
4039
3986
|
const socket = socketOfAddress(key);
|
|
4040
3987
|
return socket === undefined ? key : key.slice(socket.length + 1);
|
|
@@ -4079,7 +4026,7 @@ function checkUrlFragmentReachability(input) {
|
|
|
4079
4026
|
if (isAmbient2(sourceFile.fileName))
|
|
4080
4027
|
continue;
|
|
4081
4028
|
const visit = (node) => {
|
|
4082
|
-
if (
|
|
4029
|
+
if (ts18.isExpression(node) && isAddressClass(addressClassOfArgument(checker, table, node))) {
|
|
4083
4030
|
const text = staticAddressTextOf(checker, node, canonical);
|
|
4084
4031
|
if (text !== undefined) {
|
|
4085
4032
|
const hash = text.indexOf("#");
|
|
@@ -4098,9 +4045,9 @@ function checkUrlFragmentReachability(input) {
|
|
|
4098
4045
|
}
|
|
4099
4046
|
}
|
|
4100
4047
|
}
|
|
4101
|
-
|
|
4048
|
+
ts18.forEachChild(node, visit);
|
|
4102
4049
|
};
|
|
4103
|
-
|
|
4050
|
+
ts18.forEachChild(sourceFile, visit);
|
|
4104
4051
|
}
|
|
4105
4052
|
return { kind: "checked", findings };
|
|
4106
4053
|
}
|
|
@@ -4145,6 +4092,7 @@ export {
|
|
|
4145
4092
|
displayPathOf,
|
|
4146
4093
|
findEmittedRequires,
|
|
4147
4094
|
findMainEntryFactoryImports,
|
|
4095
|
+
findTextScriptProperties,
|
|
4148
4096
|
getProgramDiagnostics,
|
|
4149
4097
|
guiScriptResourceOf,
|
|
4150
4098
|
guiScriptResourcesOf,
|
|
@@ -4156,6 +4104,7 @@ export {
|
|
|
4156
4104
|
libraryIncludedEntries,
|
|
4157
4105
|
listProjectResourcePaths,
|
|
4158
4106
|
parseBuildConfig,
|
|
4107
|
+
parseDefignore,
|
|
4159
4108
|
parseSceneTextFormat,
|
|
4160
4109
|
projectRelativeBase,
|
|
4161
4110
|
readGameProjectDependencies,
|