X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 36 additions & 21 deletions src/LuaTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1353,31 +1353,42 @@ export class LuaTransformer {

const headerStatements = [];

// Add default parameters
const defaultValueDeclarations = parameters
.filter(declaration => declaration.initializer !== undefined)
.map(declaration => this.transformParameterDefaultValueDeclaration(declaration));
// Add default parameters and object binding patterns
const bindingPatternDeclarations: tstl.Statement[] = [];
let bindPatternIndex = 0;
for (const declaration of parameters) {
if (ts.isObjectBindingPattern(declaration.name) || ts.isArrayBindingPattern(declaration.name)) {
const identifier = tstl.createIdentifier(`____TS_bindingPattern${bindPatternIndex++}`);
if (declaration.initializer !== undefined) {
// Default binding parameter
headerStatements.push(
this.transformParameterDefaultValueDeclaration(identifier, declaration.initializer)
);
}

// Binding pattern
bindingPatternDeclarations.push(...this.statementVisitResultToArray(
this.transformBindingPattern(declaration.name, identifier)
));

headerStatements.push(...defaultValueDeclarations);
} else if (declaration.initializer !== undefined) {
// Default parameter
headerStatements.push(
this.transformParameterDefaultValueDeclaration(
this.transformIdentifier(declaration.name),
declaration.initializer
)
);
}
}

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

// Add object binding patterns
let identifierIndex = 0;
const bindingPatternDeclarations: tstl.Statement[] = [];
parameters.forEach(binding => {
if (ts.isObjectBindingPattern(binding.name) || ts.isArrayBindingPattern(binding.name)) {
const identifier = tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`);
bindingPatternDeclarations.push(...this.statementVisitResultToArray(
this.transformBindingPattern(binding.name, identifier)
));
}
});

// Binding pattern statements need to be after spread table is declared
headerStatements.push(...bindingPatternDeclarations);

const bodyStatements = this.performHoisting(this.transformStatements(body.statements));
Expand All @@ -1387,9 +1398,13 @@ export class LuaTransformer {
return [headerStatements.concat(bodyStatements), scope];
}

private transformParameterDefaultValueDeclaration(declaration: ts.ParameterDeclaration): tstl.Statement {
const parameterName = this.transformIdentifier(declaration.name as ts.Identifier);
const parameterValue = declaration.initializer ? this.transformExpression(declaration.initializer) : undefined;
private transformParameterDefaultValueDeclaration(
parameterName: tstl.Identifier,
value?: ts.Expression,
tsOriginal?: ts.Node
): tstl.Statement
{
const parameterValue = value ? this.transformExpression(value) : undefined;
const assignment = tstl.createAssignmentStatement(parameterName, parameterValue);

const nilCondition = tstl.createBinaryExpression(
Expand All @@ -1400,7 +1415,7 @@ export class LuaTransformer {

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

return tstl.createIfStatement(nilCondition, ifBlock, undefined, declaration);
return tstl.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal);
}

public transformBindingPattern(
Expand Down
35 changes: 35 additions & 0 deletions test/unit/functions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,41 @@ test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])(
},
);

test("Function default array binding parameter", () => {
const code = `
function foo([bar]: [string] = ["foobar"]) {
return bar;
}
return foo();`;

expect(util.transpileAndExecute(code)).toBe("foobar");
});

test("Function default object binding parameter", () => {
const code = `
function foo({ bar }: { bar: string } = { bar: "foobar" }) {
return bar;
}
return foo();`;

expect(util.transpileAndExecute(code)).toBe("foobar");
});

test("Function default binding parameter maintains order", () => {
const code = `
const resultsA = [{x: "foo"}, {x: "baz"}];
const resultsB = ["blah", "bar"];
let i = 0;
function a() { return resultsA[i++]; }
function b() { return resultsB[i++]; }
function foo({ x }: { x: string } = a(), y = b()) {
return x + y;
}
return foo();`;

expect(util.transpileAndExecute(code)).toBe("foobar");
});

test("Class method call", () => {
const returnValue = 4;
const source = `class TestClass {
Expand Down
X Tutup