X Tutup
Skip to content

Commit 3d63277

Browse files
tomblindPerryvw
authored andcommitted
fixed default binding pattern parameters (#589)
* fixed default binding pattern parameters fixes #530 * refactored default and binding paramaters to work in one pass
1 parent 97fa41e commit 3d63277

File tree

2 files changed

+71
-21
lines changed

2 files changed

+71
-21
lines changed

src/LuaTransformer.ts

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,31 +1381,42 @@ export class LuaTransformer {
13811381

13821382
const headerStatements = [];
13831383

1384-
// Add default parameters
1385-
const defaultValueDeclarations = parameters
1386-
.filter(declaration => declaration.initializer !== undefined)
1387-
.map(declaration => this.transformParameterDefaultValueDeclaration(declaration));
1384+
// Add default parameters and object binding patterns
1385+
const bindingPatternDeclarations: tstl.Statement[] = [];
1386+
let bindPatternIndex = 0;
1387+
for (const declaration of parameters) {
1388+
if (ts.isObjectBindingPattern(declaration.name) || ts.isArrayBindingPattern(declaration.name)) {
1389+
const identifier = tstl.createIdentifier(`____TS_bindingPattern${bindPatternIndex++}`);
1390+
if (declaration.initializer !== undefined) {
1391+
// Default binding parameter
1392+
headerStatements.push(
1393+
this.transformParameterDefaultValueDeclaration(identifier, declaration.initializer)
1394+
);
1395+
}
1396+
1397+
// Binding pattern
1398+
bindingPatternDeclarations.push(...this.statementVisitResultToArray(
1399+
this.transformBindingPattern(declaration.name, identifier)
1400+
));
13881401

1389-
headerStatements.push(...defaultValueDeclarations);
1402+
} else if (declaration.initializer !== undefined) {
1403+
// Default parameter
1404+
headerStatements.push(
1405+
this.transformParameterDefaultValueDeclaration(
1406+
this.transformIdentifier(declaration.name),
1407+
declaration.initializer
1408+
)
1409+
);
1410+
}
1411+
}
13901412

13911413
// Push spread operator here
13921414
if (spreadIdentifier) {
13931415
const spreadTable = this.wrapInTable(tstl.createDotsLiteral());
13941416
headerStatements.push(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable));
13951417
}
13961418

1397-
// Add object binding patterns
1398-
let identifierIndex = 0;
1399-
const bindingPatternDeclarations: tstl.Statement[] = [];
1400-
parameters.forEach(binding => {
1401-
if (ts.isObjectBindingPattern(binding.name) || ts.isArrayBindingPattern(binding.name)) {
1402-
const identifier = tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`);
1403-
bindingPatternDeclarations.push(...this.statementVisitResultToArray(
1404-
this.transformBindingPattern(binding.name, identifier)
1405-
));
1406-
}
1407-
});
1408-
1419+
// Binding pattern statements need to be after spread table is declared
14091420
headerStatements.push(...bindingPatternDeclarations);
14101421

14111422
const bodyStatements = this.performHoisting(this.transformStatements(body.statements));
@@ -1415,9 +1426,13 @@ export class LuaTransformer {
14151426
return [headerStatements.concat(bodyStatements), scope];
14161427
}
14171428

1418-
private transformParameterDefaultValueDeclaration(declaration: ts.ParameterDeclaration): tstl.Statement {
1419-
const parameterName = this.transformIdentifier(declaration.name as ts.Identifier);
1420-
const parameterValue = declaration.initializer ? this.transformExpression(declaration.initializer) : undefined;
1429+
private transformParameterDefaultValueDeclaration(
1430+
parameterName: tstl.Identifier,
1431+
value?: ts.Expression,
1432+
tsOriginal?: ts.Node
1433+
): tstl.Statement
1434+
{
1435+
const parameterValue = value ? this.transformExpression(value) : undefined;
14211436
const assignment = tstl.createAssignmentStatement(parameterName, parameterValue);
14221437

14231438
const nilCondition = tstl.createBinaryExpression(
@@ -1428,7 +1443,7 @@ export class LuaTransformer {
14281443

14291444
const ifBlock = tstl.createBlock([assignment]);
14301445

1431-
return tstl.createIfStatement(nilCondition, ifBlock, undefined, declaration);
1446+
return tstl.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal);
14321447
}
14331448

14341449
public transformBindingPattern(

test/unit/functions.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,41 @@ test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])(
9494
},
9595
);
9696

97+
test("Function default array binding parameter", () => {
98+
const code = `
99+
function foo([bar]: [string] = ["foobar"]) {
100+
return bar;
101+
}
102+
return foo();`;
103+
104+
expect(util.transpileAndExecute(code)).toBe("foobar");
105+
});
106+
107+
test("Function default object binding parameter", () => {
108+
const code = `
109+
function foo({ bar }: { bar: string } = { bar: "foobar" }) {
110+
return bar;
111+
}
112+
return foo();`;
113+
114+
expect(util.transpileAndExecute(code)).toBe("foobar");
115+
});
116+
117+
test("Function default binding parameter maintains order", () => {
118+
const code = `
119+
const resultsA = [{x: "foo"}, {x: "baz"}];
120+
const resultsB = ["blah", "bar"];
121+
let i = 0;
122+
function a() { return resultsA[i++]; }
123+
function b() { return resultsB[i++]; }
124+
function foo({ x }: { x: string } = a(), y = b()) {
125+
return x + y;
126+
}
127+
return foo();`;
128+
129+
expect(util.transpileAndExecute(code)).toBe("foobar");
130+
});
131+
97132
test("Class method call", () => {
98133
const returnValue = 4;
99134
const source = `class TestClass {

0 commit comments

Comments
 (0)
X Tutup