Skip to content

Commit bfba5b7

Browse files
authored
Don't output parameter initializer statement if default value is nil (#1424)
* Don't output initializer if default value is nil * Handle preceding statements in default parameter value * Update test snapshots * Changes for PR
1 parent d696418 commit bfba5b7

File tree

3 files changed

+86
-14
lines changed

3 files changed

+86
-14
lines changed

src/transformation/visitors/function.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,25 @@ import { transformBindingPattern } from "./variable-declaration";
2424
function transformParameterDefaultValueDeclaration(
2525
context: TransformationContext,
2626
parameterName: lua.Identifier,
27-
value?: ts.Expression,
27+
value: ts.Expression,
2828
tsOriginal?: ts.Node
29-
): lua.Statement {
30-
const parameterValue = value ? context.transformExpression(value) : undefined;
31-
const assignment = lua.createAssignmentStatement(parameterName, parameterValue);
29+
): lua.Statement | undefined {
30+
const { precedingStatements: statements, result: parameterValue } = transformInPrecedingStatementScope(
31+
context,
32+
() => context.transformExpression(value)
33+
);
34+
if (!lua.isNilLiteral(parameterValue)) {
35+
statements.push(lua.createAssignmentStatement(parameterName, parameterValue));
36+
}
37+
if (statements.length === 0) return undefined;
3238

3339
const nilCondition = lua.createBinaryExpression(
3440
parameterName,
3541
lua.createNilLiteral(),
3642
lua.SyntaxKind.EqualityOperator
3743
);
3844

39-
const ifBlock = lua.createBlock([assignment]);
45+
const ifBlock = lua.createBlock(statements, tsOriginal);
4046

4147
return lua.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal);
4248
}
@@ -106,7 +112,7 @@ export function transformFunctionBodyHeader(
106112
parameters: ts.NodeArray<ts.ParameterDeclaration>,
107113
spreadIdentifier?: lua.Identifier
108114
): lua.Statement[] {
109-
const headerStatements = [];
115+
const headerStatements: lua.Statement[] = [];
110116

111117
// Add default parameters and object binding patterns
112118
const bindingPatternDeclarations: lua.Statement[] = [];
@@ -116,9 +122,12 @@ export function transformFunctionBodyHeader(
116122
const identifier = lua.createIdentifier(`____bindingPattern${bindPatternIndex++}`);
117123
if (declaration.initializer !== undefined) {
118124
// Default binding parameter
119-
headerStatements.push(
120-
transformParameterDefaultValueDeclaration(context, identifier, declaration.initializer)
125+
const initializer = transformParameterDefaultValueDeclaration(
126+
context,
127+
identifier,
128+
declaration.initializer
121129
);
130+
if (initializer) headerStatements.push(initializer);
122131
}
123132

124133
// Binding pattern
@@ -129,13 +138,12 @@ export function transformFunctionBodyHeader(
129138
bindingPatternDeclarations.push(...precedingStatements, ...bindings);
130139
} else if (declaration.initializer !== undefined) {
131140
// Default parameter
132-
headerStatements.push(
133-
transformParameterDefaultValueDeclaration(
134-
context,
135-
transformIdentifier(context, declaration.name),
136-
declaration.initializer
137-
)
141+
const initializer = transformParameterDefaultValueDeclaration(
142+
context,
143+
transformIdentifier(context, declaration.name),
144+
declaration.initializer
138145
);
146+
if (initializer) headerStatements.push(initializer);
139147
}
140148
}
141149

test/unit/functions/__snapshots__/functions.spec.ts.snap

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Function default parameter with value "null" 1`] = `
4+
"local ____exports = {}
5+
function ____exports.__main(self)
6+
local function foo(self, x)
7+
return x
8+
end
9+
return foo(nil)
10+
end
11+
return ____exports"
12+
`;
13+
14+
exports[`Function default parameter with value "undefined" 1`] = `
15+
"local ____exports = {}
16+
function ____exports.__main(self)
17+
local function foo(self, x)
18+
return x
19+
end
20+
return foo(nil)
21+
end
22+
return ____exports"
23+
`;
24+
325
exports[`function.length unsupported ("5.0"): code 1`] = `
426
"local ____exports = {}
527
function ____exports.__main(self)

test/unit/functions/functions.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,48 @@ test("Function default binding parameter maintains order", () => {
107107
`.expectToMatchJsResult();
108108
});
109109

110+
test.each(["undefined", "null"])("Function default parameter with value %p", defaultValue => {
111+
util.testFunction`
112+
function foo(x = ${defaultValue}) {
113+
return x;
114+
}
115+
return foo();
116+
`
117+
.expectToMatchJsResult()
118+
.tap(builder => {
119+
const lua = builder.getMainLuaCodeChunk();
120+
expect(lua).not.toMatch("if x == nil then");
121+
})
122+
.expectLuaToMatchSnapshot();
123+
});
124+
125+
test("Function default parameter with preceding statements", () => {
126+
util.testFunction`
127+
let i = 1
128+
function foo(x = i++) {
129+
return x;
130+
}
131+
return [i, foo(), i];
132+
`.expectToMatchJsResult();
133+
});
134+
135+
test("Function default parameter with nil value and preceding statements", () => {
136+
util.testFunction`
137+
const a = new LuaTable()
138+
a.set("foo", "bar")
139+
function foo(x: any = a.set("foo", "baz")) {
140+
return x ?? "nil";
141+
}
142+
return [a.get("foo"), foo(), a.get("foo")];
143+
`
144+
.withLanguageExtensions()
145+
.tap(builder => {
146+
const lua = builder.getMainLuaCodeChunk();
147+
expect(lua).not.toMatch(" x = nil");
148+
})
149+
.expectToEqual(["bar", "nil", "baz"]);
150+
});
151+
110152
test("Class method call", () => {
111153
util.testFunction`
112154
class TestClass {

0 commit comments

Comments
 (0)