X Tutup
Skip to content

Commit 990ec68

Browse files
committed
Support NamespaceExport
1 parent fe3a60d commit 990ec68

File tree

2 files changed

+56
-20
lines changed

2 files changed

+56
-20
lines changed

src/transformation/visitors/modules/export.ts

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
createExportedIdentifier,
99
} from "../../utils/export";
1010
import { createExportsIdentifier } from "../../utils/lua-ast";
11+
import { createSafeName } from "../../utils/safe-names";
1112
import { ScopeType } from "../../utils/scope";
1213
import { transformScopeBlock } from "../block";
1314
import { transformIdentifier } from "../identifier";
@@ -36,7 +37,7 @@ export const transformExportAssignment: FunctionVisitor<ts.ExportAssignment> = (
3637
}
3738
};
3839

39-
function transformExportAllFrom(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined {
40+
function transformExportAll(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined {
4041
assert(node.moduleSpecifier);
4142

4243
if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) {
@@ -46,34 +47,62 @@ function transformExportAllFrom(context: TransformationContext, node: ts.ExportD
4647
const moduleRequire = createModuleRequire(context, node.moduleSpecifier);
4748
const tempModuleIdentifier = lua.createIdentifier("____export");
4849

50+
const result: lua.Statement[] = [];
51+
4952
const declaration = lua.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire);
53+
result.push(declaration);
54+
55+
if (node.exportClause && ts.isNamespaceExport(node.exportClause)) {
56+
const namespaceIdentifier = lua.createIdentifier(createSafeName(node.exportClause.name.text));
57+
const namespaceDeclaration = lua.createVariableDeclarationStatement(
58+
namespaceIdentifier,
59+
lua.createTableExpression()
60+
);
61+
result.push(namespaceDeclaration);
62+
}
5063

5164
const forKey = lua.createIdentifier("____exportKey");
5265
const forValue = lua.createIdentifier("____exportValue");
5366

54-
const ifBody = lua.createBlock([
55-
lua.createAssignmentStatement(
56-
lua.createTableIndexExpression(createExportsIdentifier(), lua.cloneIdentifier(forKey)),
57-
forValue
58-
),
59-
]);
67+
const left =
68+
node.exportClause && ts.isNamespaceExport(node.exportClause)
69+
? lua.createIdentifier(createSafeName(node.exportClause.name.text))
70+
: createExportsIdentifier();
71+
72+
const leftAssignment = lua.createAssignmentStatement(
73+
lua.createTableIndexExpression(lua.cloneIdentifier(left), lua.cloneIdentifier(forKey)),
74+
forValue
75+
);
76+
77+
const ifBody = lua.createBlock([leftAssignment]);
6078

6179
const ifStatement = lua.createIfStatement(
6280
lua.createBinaryExpression(forKey, lua.createStringLiteral("default"), lua.SyntaxKind.InequalityOperator),
6381
ifBody
6482
);
6583

66-
const body = lua.createBlock([ifStatement]);
67-
6884
const pairsIdentifier = lua.createIdentifier("pairs");
6985
const forIn = lua.createForInStatement(
70-
body,
86+
lua.createBlock([ifStatement]),
7187
[lua.cloneIdentifier(forKey), lua.cloneIdentifier(forValue)],
7288
[lua.createCallExpression(pairsIdentifier, [lua.cloneIdentifier(tempModuleIdentifier)])]
7389
);
7490

91+
result.push(forIn);
92+
93+
if (node.exportClause && ts.isNamespaceExport(node.exportClause)) {
94+
const assignToExports = lua.createAssignmentStatement(
95+
lua.createTableIndexExpression(
96+
createExportsIdentifier(),
97+
lua.createStringLiteral(node.exportClause.name.text)
98+
),
99+
lua.createIdentifier(createSafeName(node.exportClause.name.text))
100+
);
101+
result.push(assignToExports);
102+
}
103+
75104
// Wrap this in a DoStatement to prevent polluting the scope.
76-
return lua.createDoStatement([declaration, forIn], node);
105+
return lua.createDoStatement(result, node);
77106
}
78107

79108
const isDefaultExportSpecifier = (node: ts.ExportSpecifier) =>
@@ -137,7 +166,7 @@ export const getExported = (context: TransformationContext, exportSpecifiers: ts
137166
export const transformExportDeclaration: FunctionVisitor<ts.ExportDeclaration> = (node, context) => {
138167
if (!node.exportClause) {
139168
// export * from "...";
140-
return transformExportAllFrom(context, node);
169+
return transformExportAll(context, node);
141170
}
142171

143172
if (!context.resolver.isValueAliasDeclaration(node)) {
@@ -146,7 +175,7 @@ export const transformExportDeclaration: FunctionVisitor<ts.ExportDeclaration> =
146175

147176
if (ts.isNamespaceExport(node.exportClause)) {
148177
// export * as ns from "...";
149-
throw new Error("NamespaceExport is not supported");
178+
return transformExportAll(context, node);
150179
}
151180

152181
const exportSpecifiers = getExported(context, node.exportClause);

test/unit/modules/modules.spec.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,23 @@ test("export default function with future reference", () => {
276276
.expectToMatchJsResult();
277277
});
278278

279+
const moduleFile = `
280+
export default true;
281+
export const foo = "bar";
282+
`;
283+
279284
test("export all does not include default", () => {
280285
util.testBundle`
281286
export * from "./module";
282287
`
283-
.addExtraFile(
284-
"module.ts",
285-
`
286-
export default true;
287-
export const foo = "bar";
288-
`
289-
)
288+
.addExtraFile("module.ts", moduleFile)
290289
.expectToEqual({ foo: "bar" });
291290
});
291+
292+
test("namespace export does not include default", () => {
293+
util.testBundle`
294+
export * as result from "./module";
295+
`
296+
.addExtraFile("module.ts", moduleFile)
297+
.expectToEqual({ result: { foo: "bar" } });
298+
});

0 commit comments

Comments
 (0)
X Tutup