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
89 changes: 40 additions & 49 deletions src/Transpiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1490,29 +1490,9 @@ export abstract class LuaTranspiler {
if (!node.body) { return ""; }

let result = "";
const identifier = node.name;
const methodName = this.transpileIdentifier(identifier);
const parameters = node.parameters;
const body = node.body;
const methodName = this.transpileIdentifier(node.name);

// Build parameter string
const paramNames: string[] = [];

let spreadIdentifier = "";

// Only push parameter name to paramName array if it isn't a spread parameter
for (const param of parameters) {
const paramName = this.transpileIdentifier(param.name as ts.Identifier);

// This parameter is a spread parameter (...param)
if (!param.dotDotDotToken) {
paramNames.push(paramName);
} else {
spreadIdentifier = paramName;
// Push the spread operator into the paramNames array
paramNames.push("...");
}
}
const [paramNames, spreadIdentifier] = this.transpileParameters(node.parameters);

let prefix = this.accessPrefix(node);

Expand All @@ -1524,13 +1504,7 @@ export abstract class LuaTranspiler {
result += this.indent + prefix + `function ${methodName}(${paramNames.join(",")})\n`;

this.pushIndent();

// Push spread operator here
if (spreadIdentifier !== "") {
result += this.indent + `local ${spreadIdentifier} = { ... }\n`;
}

result += this.transpileBlock(body);
result += this.transpileFunctionBody(node.parameters, node.body, spreadIdentifier);
this.popIndent();

// Close function block
Expand All @@ -1541,21 +1515,10 @@ export abstract class LuaTranspiler {
return result;
}

public transpileMethodDeclaration(node: ts.MethodDeclaration, callPath: string): string {
// Don't transpile methods without body (overload declarations)
if (!node.body) { return ""; }

let result = "";
const identifier = node.name as ts.Identifier;
let methodName = this.transpileIdentifier(identifier);
if (methodName === "toString") {
methodName = "__tostring";
}
const parameters = node.parameters;
const body = node.body;

// Transpile a list of parameters, returns a list of transpiled parameters and an optional spread identifier
public transpileParameters(parameters: ts.NodeArray<ts.ParameterDeclaration>): [string[], string] {
// Build parameter string
const paramNames: string[] = ["self"];
const paramNames: string[] = [];

let spreadIdentifier = "";

Expand All @@ -1572,21 +1535,49 @@ export abstract class LuaTranspiler {
paramNames.push("...");
}
}
// Parameters with default values
const defaultValueParams = node.parameters.filter(declaration => declaration.initializer !== undefined);

// Build function header
result += this.indent + `function ${callPath}${methodName}(${paramNames.join(",")})\n`;
return [paramNames, spreadIdentifier];
}

this.pushIndent();
public transpileFunctionBody(parameters: ts.NodeArray<ts.ParameterDeclaration>,
body: ts.Block,
spreadIdentifier: string = ""
): string {
let result = "";

// Add default parameters
const defaultValueParams = parameters.filter(declaration => declaration.initializer !== undefined);
result += this.transpileParameterDefaultValues(defaultValueParams);

// Push spread operator here
if (spreadIdentifier !== "") {
result += this.indent + `local ${spreadIdentifier} = { ... }\n`;
}

result += this.transpileParameterDefaultValues(defaultValueParams);
result += this.transpileBlock(body);

return result;
}

public transpileMethodDeclaration(node: ts.MethodDeclaration, callPath: string): string {
// Don't transpile methods without body (overload declarations)
if (!node.body) { return ""; }

let result = "";
let methodName = this.transpileIdentifier(node.name as ts.Identifier);
if (methodName === "toString") {
methodName = "__tostring";
}

const [paramNames, spreadIdentifier] = this.transpileParameters(node.parameters);

const selfParamNames = ["self"].concat(paramNames);

// Build function header
result += this.indent + `function ${callPath}${methodName}(${selfParamNames.join(",")})\n`;

this.pushIndent();
result += this.transpileFunctionBody(node.parameters, node.body, spreadIdentifier);
this.popIndent();

// Close function block
Expand Down
13 changes: 13 additions & 0 deletions test/unit/functions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ export class FunctionTests {
Expect(result).toBe(3);
}

@Test("Function default parameter")
public functionDefaultParameter(): void {
// Transpile
const lua = util.transpileString(`function abc(defaultParam: string = "abc") { return defaultParam; }\n
return abc() + abc("def");`);

// Execute
const result = util.executeLua(lua);

// Assert
Expect(result).toBe("abcdef");
}

@TestCase([], 7)
@TestCase([5], 9)
@TestCase([1, 2], 3)
Expand Down