Skip to content

Commit 02b9642

Browse files
authored
validating arguments passed to lua lib functions (#484)
* validating arguments passed to lua lib functions * resolving signature in lualib transform functions instead of passing it in * formatting fixes
1 parent fbdb604 commit 02b9642

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

src/LuaTransformer.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3162,6 +3162,8 @@ export class LuaTransformer {
31623162
// If the function being called is of type owner.func, get the type of owner
31633163
const ownerType = this.checker.getTypeAtLocation(node.expression.expression);
31643164

3165+
const signature = this.checker.getResolvedSignature(node);
3166+
31653167
if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) {
31663168
return this.transformMathCallExpression(node);
31673169
}
@@ -3173,7 +3175,7 @@ export class LuaTransformer {
31733175
if (tsHelper.isStandardLibraryType(ownerType, "StringConstructor", this.program)) {
31743176
return tstl.createCallExpression(
31753177
this.transformStringExpression(node.expression.name),
3176-
this.transformArguments(node.arguments),
3178+
this.transformArguments(node.arguments, signature),
31773179
node
31783180
);
31793181
}
@@ -3207,8 +3209,6 @@ export class LuaTransformer {
32073209
return this.transformFunctionCallExpression(node);
32083210
}
32093211

3210-
const signature = this.checker.getResolvedSignature(node);
3211-
32123212
// Get the type of the function
32133213
if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) {
32143214
// Super calls take the format of super.call(self,...)
@@ -3292,7 +3292,8 @@ export class LuaTransformer {
32923292

32933293
public transformArguments<T extends ts.Expression>(
32943294
params: ts.NodeArray<ts.Expression>,
3295-
sig?: ts.Signature, context?: T
3295+
sig?: ts.Signature,
3296+
context?: T
32963297
): tstl.Expression[]
32973298
{
32983299
const parameters: tstl.Expression[] = [];
@@ -3387,7 +3388,8 @@ export class LuaTransformer {
33873388
// Transpile a Math._ property
33883389
public transformMathCallExpression(node: ts.CallExpression): tstl.Expression {
33893390
const expression = node.expression as ts.PropertyAccessExpression;
3390-
const params = this.transformArguments(node.arguments);
3391+
const signature = this.checker.getResolvedSignature(node);
3392+
const params = this.transformArguments(node.arguments, signature);
33913393
const expressionName = expression.name.escapedText as string;
33923394
switch (expressionName) {
33933395
// math.tan(x / y)
@@ -3546,7 +3548,8 @@ export class LuaTransformer {
35463548

35473549
public transformStringCallExpression(node: ts.CallExpression): tstl.Expression {
35483550
const expression = node.expression as ts.PropertyAccessExpression;
3549-
const params = this.transformArguments(node.arguments);
3551+
const signature = this.checker.getResolvedSignature(node);
3552+
const params = this.transformArguments(node.arguments, signature);
35503553
const caller = this.transformExpression(expression.expression);
35513554

35523555
const expressionName = expression.name.escapedText as string;
@@ -3690,6 +3693,7 @@ export class LuaTransformer {
36903693
// Transpile an Object._ property
36913694
public transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult {
36923695
const method = expression.expression as ts.PropertyAccessExpression;
3696+
const signature = this.checker.getResolvedSignature(expression);
36933697
const parameters = this.transformArguments(expression.arguments);
36943698
const caller = this.transformExpression(expression.expression);
36953699
const methodName = method.name.escapedText;
@@ -3715,6 +3719,7 @@ export class LuaTransformer {
37153719
public transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult {
37163720
const method = expression.expression as ts.PropertyAccessExpression;
37173721
const methodName = method.name.escapedText;
3722+
const signature = this.checker.getResolvedSignature(expression);
37183723

37193724
switch (methodName) {
37203725
case "log":
@@ -3725,7 +3730,7 @@ export class LuaTransformer {
37253730
tstl.createTableIndexExpression(
37263731
tstl.createIdentifier("string"),
37273732
tstl.createStringLiteral("format")),
3728-
this.transformArguments(expression.arguments)
3733+
this.transformArguments(expression.arguments, signature)
37293734
);
37303735
return tstl.createCallExpression(
37313736
tstl.createIdentifier("print"),
@@ -3735,10 +3740,10 @@ export class LuaTransformer {
37353740
// print([arguments])
37363741
return tstl.createCallExpression(
37373742
tstl.createIdentifier("print"),
3738-
this.transformArguments(expression.arguments)
3743+
this.transformArguments(expression.arguments, signature)
37393744
);
37403745
case "assert":
3741-
const args = this.transformArguments(expression.arguments);
3746+
const args = this.transformArguments(expression.arguments, signature);
37423747
if (expression.arguments.length > 1
37433748
&& this.isStringFormatTemplate(expression.arguments[1])) {
37443749
// assert([condition], string.format([arguments]))
@@ -3766,7 +3771,7 @@ export class LuaTransformer {
37663771
tstl.createTableIndexExpression(
37673772
tstl.createIdentifier("string"),
37683773
tstl.createStringLiteral("format")),
3769-
this.transformArguments(expression.arguments)
3774+
this.transformArguments(expression.arguments, signature)
37703775
);
37713776
const debugTracebackCall = tstl.createCallExpression(
37723777
tstl.createTableIndexExpression(
@@ -3784,7 +3789,7 @@ export class LuaTransformer {
37843789
tstl.createTableIndexExpression(
37853790
tstl.createIdentifier("debug"),
37863791
tstl.createStringLiteral("traceback")),
3787-
this.transformArguments(expression.arguments)
3792+
this.transformArguments(expression.arguments, signature)
37883793
);
37893794
return tstl.createCallExpression(
37903795
tstl.createIdentifier("print"),
@@ -3806,7 +3811,8 @@ export class LuaTransformer {
38063811
// Transpile a Symbol._ property
38073812
public transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression {
38083813
const method = expression.expression as ts.PropertyAccessExpression;
3809-
const parameters = this.transformArguments(expression.arguments);
3814+
const signature = this.checker.getResolvedSignature(expression);
3815+
const parameters = this.transformArguments(expression.arguments, signature);
38103816
const methodName = method.name.escapedText;
38113817

38123818
switch (methodName) {
@@ -3827,7 +3833,8 @@ export class LuaTransformer {
38273833

38283834
public transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression {
38293835
const expression = node.expression as ts.PropertyAccessExpression;
3830-
const params = this.transformArguments(node.arguments);
3836+
const signature = this.checker.getResolvedSignature(node);
3837+
const params = this.transformArguments(node.arguments, signature);
38313838
const caller = this.transformExpression(expression.expression);
38323839
const expressionName = expression.name.escapedText;
38333840
switch (expressionName) {
@@ -3888,7 +3895,8 @@ export class LuaTransformer {
38883895
if (tsHelper.getFunctionContextType(callerType, this.checker, this.program) === ContextType.Void) {
38893896
throw TSTLErrors.UnsupportedSelfFunctionConversion(node);
38903897
}
3891-
const params = this.transformArguments(node.arguments);
3898+
const signature = this.checker.getResolvedSignature(node);
3899+
const params = this.transformArguments(node.arguments, signature);
38923900
const caller = this.transformExpression(expression.expression);
38933901
const expressionName = expression.name.escapedText;
38943902
switch (expressionName) {

test/unit/assignments.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,29 @@ export class AssignmentTests {
663663
Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message);
664664
}
665665

666+
@Test("Valid lua lib function argument")
667+
public validLuaLibFunctionArgument(): void {
668+
const code =
669+
`let result = "";
670+
function foo(this: any, value: string) { result += value; }
671+
const a = ['foo', 'bar'];
672+
a.forEach(foo);
673+
return result;`;
674+
Expect(util.transpileAndExecute(code)).toBe("foobar");
675+
}
676+
677+
@Test("Invalid lua lib function argument")
678+
public invalidLuaLibFunctionArgument(testFunction: TestFunction, functionType: string, isSelfConversion: boolean)
679+
: void
680+
{
681+
const code =
682+
`declare function foo(this: void, value: string): void;
683+
declare const a: string[];
684+
a.forEach(foo);`;
685+
const err = TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "callbackfn");
686+
Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message);
687+
}
688+
666689
@TestCases(validTestFunctionCasts)
667690
@Test("Valid function argument with cast")
668691
public validFunctionArgumentWithCast(testFunction: TestFunction, castedFunction: string): void {

test/unit/expressions.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ export class ExpressionTests {
493493
const transformer = util.makeTestTransformer();
494494

495495
const mockNode: any = {
496+
kind: ts.SyntaxKind.CallExpression,
496497
arguments: [],
497498
caller: ts.createLiteral(false),
498499
expression: {name: ts.createIdentifier("unknownFunction"), expression: ts.createLiteral(false)},

0 commit comments

Comments
 (0)