Skip to content

Commit c0a6918

Browse files
committed
Merge branch 'master' into function-validation-bug
2 parents e6375bf + b40b43c commit c0a6918

File tree

20 files changed

+242
-77
lines changed

20 files changed

+242
-77
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/dist
22
/coverage
33
/test/translation/transformation/characterEscapeSequence.ts
4+
/test/translation/transformation/exportStatement.ts
45
/benchmark/dist
56
/test/transpile/module-resolution/**/node_modules
67
/test/transpile/module-resolution/**/dist

package-lock.json

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"node": ">=16.10.0"
4343
},
4444
"peerDependencies": {
45-
"typescript": "5.5.2"
45+
"typescript": "5.6.2"
4646
},
4747
"dependencies": {
4848
"@typescript-to-lua/language-extensions": "1.19.0",
@@ -67,10 +67,10 @@
6767
"jest-circus": "^29.5.0",
6868
"lua-types": "^2.13.0",
6969
"lua-wasm-bindings": "^0.3.1",
70-
"prettier": "^2.8.4",
70+
"prettier": "^2.8.8",
7171
"ts-jest": "^29.1.0",
7272
"ts-node": "^10.9.1",
73-
"typescript": "^5.5.2",
73+
"typescript": "^5.6.2",
7474
"typescript-eslint": "^7.13.1"
7575
}
7676
}

src/lualib/ArrayFrom.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ export function __TS__ArrayFrom(
2828
result.push(v);
2929
}
3030
} else {
31-
for (const [i, v] of arrayLikeIterator(arrayLike)) {
32-
result.push(mapFn.call(thisArg, v, i - 1));
31+
let i = 0;
32+
for (const [, v] of arrayLikeIterator(arrayLike)) {
33+
result.push(mapFn.call(thisArg, v, i++));
3334
}
3435
}
3536
return result;

src/lualib/Using.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export function __TS__Using<TArgs extends Disposable[], TReturn>(
22
this: undefined,
3-
cb: (...args: TArgs) => TReturn,
3+
cb: (this: void, ...args: TArgs) => TReturn,
44
...args: TArgs
55
): TReturn {
66
let thrownError;

src/transformation/pre-transformers/using-transformer.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function usingTransformer(context: TransformationContext): ts.Transformer
1818
ts.setParent(node2, parent[parent.length - 1]);
1919
parent.push(node2);
2020
ts.visitEachChild(node2, setParent, ctx);
21-
parent.push();
21+
parent.pop();
2222
return node2;
2323
}
2424
ts.visitEachChild(updatedBlock, setParent, ctx);
@@ -74,12 +74,13 @@ function transformBlockWithUsing(
7474
);
7575

7676
const callback = ts.factory.createFunctionExpression(
77-
undefined,
77+
// Put async keyword in front of callback when we are in an async using
78+
isAwaitUsing ? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)] : undefined,
7879
undefined,
7980
undefined,
8081
undefined,
8182
variableNames,
82-
undefined,
83+
ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), // Required for TS to not freak out trying to infer the type of synthetic nodes
8384
callbackBody
8485
);
8586

src/transformation/visitors/access.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
unsupportedOptionalCompileMembersOnly,
1010
} from "../utils/diagnostics";
1111
import { getExtensionKindForNode } from "../utils/language-extensions";
12-
import { addToNumericExpression } from "../utils/lua-ast";
12+
import { addToNumericExpression, createExportsIdentifier } from "../utils/lua-ast";
1313
import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib";
1414
import { isArrayType, isNumberType, isStringType } from "../utils/typescript";
1515
import { tryGetConstEnumValue } from "./enum";
@@ -24,6 +24,7 @@ import {
2424
} from "./optional-chaining";
2525
import { SyntaxKind } from "typescript";
2626
import { getCustomNameFromSymbol } from "./identifier";
27+
import { getSymbolExportScope, isSymbolExported } from "../utils/export";
2728

2829
function addOneToArrayAccessArgument(
2930
context: TransformationContext,
@@ -138,6 +139,7 @@ export function transformPropertyAccessExpressionWithCapture(
138139
if (isOptionalLeft) {
139140
context.diagnostics.push(unsupportedOptionalCompileMembersOnly(node));
140141
}
142+
141143
if (ts.isPropertyAccessExpression(node.expression)) {
142144
// in case of ...x.enum.y transform to ...x.y
143145
const expression = lua.createTableIndexExpression(
@@ -147,7 +149,21 @@ export function transformPropertyAccessExpressionWithCapture(
147149
);
148150
return { expression };
149151
} else {
150-
return { expression: lua.createIdentifier(property, node) };
152+
// Check if we need to account for enum being exported int his file
153+
if (
154+
isSymbolExported(context, type.symbol) &&
155+
getSymbolExportScope(context, type.symbol) === node.expression.getSourceFile()
156+
) {
157+
return {
158+
expression: lua.createTableIndexExpression(
159+
createExportsIdentifier(),
160+
lua.createStringLiteral(property),
161+
node
162+
),
163+
};
164+
} else {
165+
return { expression: lua.createIdentifier(property, node) };
166+
}
151167
}
152168
}
153169

src/transformation/visitors/modules/export.ts

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,12 @@ import * as ts from "typescript";
22
import * as lua from "../../../LuaAST";
33
import { assert } from "../../../utils";
44
import { FunctionVisitor, TransformationContext } from "../../context";
5-
import {
6-
createDefaultExportExpression,
7-
createDefaultExportStringLiteral,
8-
createExportedIdentifier,
9-
} from "../../utils/export";
5+
import { createDefaultExportExpression, createDefaultExportStringLiteral } from "../../utils/export";
106
import { createExportsIdentifier } from "../../utils/lua-ast";
11-
import { ScopeType } from "../../utils/scope";
12-
import { transformScopeBlock } from "../block";
13-
import { transformIdentifier } from "../identifier";
14-
import { createShorthandIdentifier } from "../literal";
7+
import { createShorthandIdentifier, transformPropertyName } from "../literal";
158
import { createModuleRequire } from "./import";
9+
import { createSafeName } from "../../utils/safe-names";
10+
import * as path from "path";
1611

1712
export const transformExportAssignment: FunctionVisitor<ts.ExportAssignment> = (node, context) => {
1813
if (!context.resolver.isValueAliasDeclaration(node)) {
@@ -101,20 +96,37 @@ function transformExportAll(context: TransformationContext, node: ts.ExportDecla
10196
}
10297

10398
const isDefaultExportSpecifier = (node: ts.ExportSpecifier) =>
104-
(node.name && ts.identifierToKeywordKind(node.name) === ts.SyntaxKind.DefaultKeyword) ||
105-
(node.propertyName && ts.identifierToKeywordKind(node.propertyName) === ts.SyntaxKind.DefaultKeyword);
99+
(node.name &&
100+
ts.isIdentifier(node.name) &&
101+
ts.identifierToKeywordKind(node.name) === ts.SyntaxKind.DefaultKeyword) ||
102+
(node.propertyName &&
103+
ts.isIdentifier(node.propertyName) &&
104+
ts.identifierToKeywordKind(node.propertyName) === ts.SyntaxKind.DefaultKeyword);
106105

107106
function transformExportSpecifier(context: TransformationContext, node: ts.ExportSpecifier): lua.AssignmentStatement {
108-
const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node);
109-
const exportedIdentifier = node.propertyName ? node.propertyName : node.name;
110-
const exportedExpression = createShorthandIdentifier(context, exportedSymbol, exportedIdentifier);
107+
const exportedName = node.name;
108+
const exportedValue = node.propertyName ?? node.name;
109+
let rhs: lua.Expression;
110+
if (ts.isIdentifier(exportedValue)) {
111+
const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node);
112+
rhs = createShorthandIdentifier(context, exportedSymbol, exportedValue);
113+
} else {
114+
rhs = lua.createStringLiteral(exportedName.text, exportedValue);
115+
}
111116

112-
const isDefault = isDefaultExportSpecifier(node);
113-
const exportAssignmentLeftHandSide = isDefault
114-
? createDefaultExportExpression(node)
115-
: createExportedIdentifier(context, transformIdentifier(context, node.name));
117+
if (isDefaultExportSpecifier(node)) {
118+
const lhs = createDefaultExportExpression(node);
119+
return lua.createAssignmentStatement(lhs, rhs, node);
120+
} else {
121+
const exportsTable = createExportsIdentifier();
122+
const lhs = lua.createTableIndexExpression(
123+
exportsTable,
124+
lua.createStringLiteral(exportedName.text),
125+
exportedName
126+
);
116127

117-
return lua.createAssignmentStatement(exportAssignmentLeftHandSide, exportedExpression, node);
128+
return lua.createAssignmentStatement(lhs, rhs, node);
129+
}
118130
}
119131

120132
function transformExportSpecifiersFrom(
@@ -123,32 +135,32 @@ function transformExportSpecifiersFrom(
123135
moduleSpecifier: ts.Expression,
124136
exportSpecifiers: ts.ExportSpecifier[]
125137
): lua.Statement {
126-
// First transpile as import clause
127-
const importClause = ts.factory.createImportClause(
128-
false,
129-
undefined,
130-
ts.factory.createNamedImports(
131-
exportSpecifiers.map(s => ts.factory.createImportSpecifier(statement.isTypeOnly, s.propertyName, s.name))
132-
)
133-
);
138+
const result: lua.Statement[] = [];
134139

135-
const importDeclaration = ts.factory.createImportDeclaration(statement.modifiers, importClause, moduleSpecifier);
140+
const importPath = ts.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text.replace(/"/g, "") : "module";
136141

137-
// Wrap in block to prevent imports from hoisting out of `do` statement
138-
const [block] = transformScopeBlock(context, ts.factory.createBlock([importDeclaration]), ScopeType.Block);
139-
const result = block.statements;
142+
// Create the require statement to extract values.
143+
// local ____module = require("module")
144+
const importUniqueName = lua.createIdentifier(createSafeName(path.basename(importPath)));
145+
const requireCall = createModuleRequire(context, moduleSpecifier);
146+
result.push(lua.createVariableDeclarationStatement(importUniqueName, requireCall, statement));
140147

141-
// Now the module is imported, add the imports to the export table
142148
for (const specifier of exportSpecifiers) {
143-
result.push(
144-
lua.createAssignmentStatement(
145-
createExportedIdentifier(context, transformIdentifier(context, specifier.name)),
146-
transformIdentifier(context, specifier.name)
147-
)
149+
// Assign to exports table
150+
const exportsTable = createExportsIdentifier();
151+
const exportedName = specifier.name;
152+
const exportedNameTransformed = transformPropertyName(context, exportedName);
153+
const lhs = lua.createTableIndexExpression(exportsTable, exportedNameTransformed, exportedName);
154+
155+
const exportedValue = specifier.propertyName ?? specifier.name;
156+
const rhs = lua.createTableIndexExpression(
157+
lua.cloneIdentifier(importUniqueName),
158+
transformPropertyName(context, exportedValue),
159+
specifier
148160
);
161+
result.push(lua.createAssignmentStatement(lhs, rhs, specifier));
149162
}
150163

151-
// Wrap this in a DoStatement to prevent polluting the scope.
152164
return lua.createDoStatement(result, statement);
153165
}
154166

src/transformation/visitors/optional-chaining.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,19 @@ export function transformOptionalChainWithCapture(
166166
return result;
167167
}
168168
);
169+
170+
// handle super calls by passing self as context
171+
function getLeftMostChainItem(node: ts.Node): ts.Node {
172+
if (ts.isPropertyAccessExpression(node)) {
173+
return getLeftMostChainItem(node.expression);
174+
} else {
175+
return node;
176+
}
177+
}
178+
if (getLeftMostChainItem(tsLeftExpression).kind === ts.SyntaxKind.SuperKeyword) {
179+
capturedThisValue = lua.createIdentifier("self");
180+
}
181+
169182
// handle context
170183
if (rightContextualCall) {
171184
if (capturedThisValue) {

test/translation/__snapshots__/transformation.spec.ts.snap

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,20 @@ do
4141
end
4242
do
4343
local ____xyz = require("xyz")
44-
local abc = ____xyz.abc
45-
local def = ____xyz.def
46-
____exports.abc = abc
47-
____exports.def = def
44+
____exports.abc = ____xyz.abc
45+
____exports.def = ____xyz.def
4846
end
4947
do
5048
local ____xyz = require("xyz")
51-
local def = ____xyz.abc
52-
____exports.def = def
49+
____exports.def = ____xyz.abc
50+
end
51+
do
52+
local ____bla = require("bla")
53+
____exports.bar = ____bla["123"]
54+
end
55+
do
56+
local ____bla = require("bla")
57+
____exports["123"] = ____bla.foo
5358
end
5459
return ____exports"
5560
`;

0 commit comments

Comments
 (0)