Skip to content

Commit a108957

Browse files
committed
State that multi can only be used in return statements
1 parent e3c1e9b commit a108957

6 files changed

Lines changed: 35 additions & 72 deletions

File tree

src/transformation/utils/diagnostics.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ export const unsupportedVarDeclaration = createDiagnosticFactory(
129129

130130
export const unknownHelperKind = createDiagnosticFactory((kind: string) => `Unknown helper kind "${kind}".`);
131131

132-
export const unsupportedMultiHelperFunctionPosition = createDiagnosticFactory(
133-
"The $multi() function cannot be used here."
132+
export const invalidMultiFunctionUse = createDiagnosticFactory(
133+
"The $multi function must be called in return statements."
134134
);
135135

136136
export const invalidMultiReturnToNonArrayBindingPattern = createDiagnosticFactory(

src/transformation/visitors/helpers/multi.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
invalidMultiReturnToNonArrayBindingPattern,
1616
invalidMultiReturnToNonArrayLiteral,
1717
unsupportedMultiFunctionAssignment,
18-
unsupportedMultiHelperFunctionPosition,
18+
invalidMultiFunctionUse,
1919
} from "../../../transformation/utils/diagnostics";
2020

2121
const isMultiHelperDeclaration = (context: TransformationContext) => (declaration: ts.Declaration): boolean =>
@@ -159,7 +159,7 @@ export function findMultiHelperAssignmentViolations(
159159
if (valueSymbol) {
160160
const declaration = valueSymbol.valueDeclaration;
161161
if (declaration && isMultiHelperDeclaration(context)(declaration)) {
162-
context.diagnostics.push(unsupportedMultiHelperFunctionPosition(element));
162+
context.diagnostics.push(invalidMultiFunctionUse(element));
163163
return element;
164164
}
165165
}

src/transformation/visitors/identifier.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as lua from "../../LuaAST";
33
import { transformBuiltinIdentifierExpression } from "../builtins";
44
import { FunctionVisitor, TransformationContext } from "../context";
55
import { isForRangeType } from "../utils/annotations";
6-
import { invalidForRangeCall, unsupportedMultiHelperFunctionPosition } from "../utils/diagnostics";
6+
import { invalidForRangeCall, invalidMultiFunctionUse } from "../utils/diagnostics";
77
import { createExportedIdentifier, getSymbolExportScope } from "../utils/export";
88
import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names";
99
import { getIdentifierSymbolId } from "../utils/symbols";
@@ -12,7 +12,7 @@ import { isMultiHelperNode } from "./helpers/multi";
1212

1313
export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier {
1414
if (isMultiHelperNode(context, identifier)) {
15-
context.diagnostics.push(unsupportedMultiHelperFunctionPosition(identifier));
15+
context.diagnostics.push(invalidMultiFunctionUse(identifier));
1616
return lua.createAnonymousIdentifier(identifier);
1717
}
1818

src/transformation/visitors/literal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as ts from "typescript";
22
import * as lua from "../../LuaAST";
33
import { assertNever } from "../../utils";
44
import { FunctionVisitor, TransformationContext, Visitors } from "../context";
5-
import { unsupportedAccessorInObjectLiteral, unsupportedMultiHelperFunctionPosition } from "../utils/diagnostics";
5+
import { unsupportedAccessorInObjectLiteral, invalidMultiFunctionUse } from "../utils/diagnostics";
66
import { createExportedIdentifier, getSymbolExportScope } from "../utils/export";
77
import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib";
88
import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names";
@@ -65,7 +65,7 @@ const transformNumericLiteralExpression: FunctionVisitor<ts.NumericLiteral> = ex
6565
const transformObjectLiteralExpression: FunctionVisitor<ts.ObjectLiteralExpression> = (expression, context) => {
6666
const violations = findMultiHelperAssignmentViolations(context, expression);
6767
if (violations.length > 0) {
68-
context.diagnostics.push(...violations.map(e => unsupportedMultiHelperFunctionPosition(e)));
68+
context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e)));
6969
return lua.createNilLiteral(expression);
7070
}
7171

test/unit/helpers/__snapshots__/multi.spec.ts.snap

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
exports[`invalid $multi call ($multi()): code 1`] = `"____(_G)"`;
44

5-
exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi() function cannot be used here."`;
5+
exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in return statements."`;
66

77
exports[`invalid $multi call ($multi): code 1`] = `"local ____ = ____"`;
88

9-
exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi() function cannot be used here."`;
9+
exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in return statements."`;
1010

1111
exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = `
1212
"local function ____(____, ____bindingPattern0)
@@ -17,19 +17,11 @@ exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = `
1717
end"
1818
`;
1919

20-
exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi() function cannot be used here."`;
20+
exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in return statements."`;
2121

2222
exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = nil"`;
2323

24-
exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi() function cannot be used here."`;
25-
26-
exports[`invalid $multi call ([] = $multi()): code 1`] = `""`;
27-
28-
exports[`invalid $multi call ([] = $multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: There must be one or more elements specified here."`;
29-
30-
exports[`invalid $multi call (const [] = $multi();): code 1`] = `""`;
31-
32-
exports[`invalid $multi call (const [] = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: There must be one or more elements specified here."`;
24+
exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in return statements."`;
3325

3426
exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = `""`;
3527

@@ -42,27 +34,3 @@ exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts
4234
exports[`invalid $multi call (const a = $multi();): code 1`] = `""`;
4335

4436
exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`;
45-
46-
exports[`unsupported $multi call ($multi()): code 1`] = `
47-
"local ____exports = {}
48-
function ____exports.__main(self)
49-
____(nil)
50-
end
51-
return ____exports"
52-
`;
53-
54-
exports[`unsupported $multi call ($multi): code 1`] = `
55-
"local ____exports = {}
56-
function ____exports.__main(self)
57-
local ____ = ____
58-
end
59-
return ____exports"
60-
`;
61-
62-
exports[`unsupported $multi call (({ $multi });): code 1`] = `
63-
"local ____exports = {}
64-
function ____exports.__main(self)
65-
local ____ = nil
66-
end
67-
return ____exports"
68-
`;

test/unit/helpers/multi.spec.ts

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,36 @@ import * as path from "path";
22
import * as util from "../../util";
33
import * as tstl from "../../../src";
44
import {
5-
unsupportedMultiHelperFunctionPosition,
5+
invalidMultiFunctionUse,
66
invalidMultiReturnToNonArrayBindingPattern,
77
invalidMultiReturnArrayBindingPatternElementInitializer,
8-
invalidMultiReturnToEmptyPatternOrArrayLiteral,
98
} from "../../../src/transformation/utils/diagnostics";
109

1110
const multiProjectOptions: tstl.CompilerOptions = {
1211
types: [path.resolve(__dirname, "../../../helpers")],
1312
};
1413

1514
test.each<[string, any]>([
16-
["let a; [a] = $multi();", undefined],
17-
["const [a] = $multi();", undefined],
18-
["const [a] = $multi(1);", 1],
19-
["const ar = [1]; const [a] = $multi(...ar);", 1],
20-
["const _ = null, [a] = $multi(1);", 1],
15+
["$multi()", undefined],
16+
["$multi(true)", true],
17+
["$multi(1, 2)", 1],
18+
])("$multi call on return statement (%s)", (expression, result) => {
19+
util.testFunction`
20+
return ${expression};
21+
`
22+
.setOptions(multiProjectOptions)
23+
.expectToEqual(result);
24+
});
25+
26+
test.each<[string, any]>([
27+
["let a; [a] = $multi()", undefined],
28+
["const [a] = $multi()", undefined],
29+
["const [a] = $multi(1)", 1],
30+
["const ar = [1]; const [a] = $multi(...ar)", 1],
31+
["const _ = null, [a] = $multi(1)", 1],
2132
["let a; for (const [a] = $multi(1, 2); false; 1) {}", undefined],
2233
["let a; for ([a] = $multi(1, 2); false; 1) {}", 1],
23-
])("valid $multi call and assign (%s)", (statement, result) => {
34+
])("$multi returning call (%s)", (statement, result) => {
2435
util.testModule`
2536
${statement}
2637
export { a };
@@ -31,14 +42,12 @@ test.each<[string, any]>([
3142
});
3243

3344
test.each<[string, number[]]>([
34-
["$multi", [unsupportedMultiHelperFunctionPosition.code]],
35-
["$multi()", [unsupportedMultiHelperFunctionPosition.code]],
36-
["({ $multi });", [unsupportedMultiHelperFunctionPosition.code]],
37-
["[] = $multi()", [invalidMultiReturnToEmptyPatternOrArrayLiteral.code]],
38-
["const [] = $multi();", [invalidMultiReturnToEmptyPatternOrArrayLiteral.code]],
45+
["$multi", [invalidMultiFunctionUse.code]],
46+
["$multi()", [invalidMultiFunctionUse.code]],
47+
["({ $multi });", [invalidMultiFunctionUse.code]],
3948
["const a = $multi();", [invalidMultiReturnToNonArrayBindingPattern.code]],
4049
["const {} = $multi();", [invalidMultiReturnToNonArrayBindingPattern.code]],
41-
["([a] = $multi(1)) => {}", [unsupportedMultiHelperFunctionPosition.code]],
50+
["([a] = $multi(1)) => {}", [invalidMultiFunctionUse.code]],
4251
["const [a = 0] = $multi()", [invalidMultiReturnArrayBindingPatternElementInitializer.code]],
4352
])("invalid $multi call (%s)", (statement, diagnostics) => {
4453
util.testModule`
@@ -48,20 +57,6 @@ test.each<[string, number[]]>([
4857
.expectDiagnosticsToMatchSnapshot(diagnostics);
4958
});
5059

51-
test.each<[string, any]>([
52-
["return $multi();", undefined],
53-
["return $multi(1);", 1],
54-
])("valid $multi call return statement (%s)", (statement, result) => {
55-
util.testModule`
56-
export const [a] = (function() {
57-
${statement}
58-
})();
59-
`
60-
.setOptions(multiProjectOptions)
61-
.setReturnExport("a")
62-
.expectToEqual(result);
63-
});
64-
6560
test("$multi helper call with destructuring assignment side effects", () => {
6661
util.testModule`
6762
let a;

0 commit comments

Comments
 (0)