@@ -3118,12 +3118,7 @@ export class LuaTransformer {
31183118 indexExpression = tstl . createStringLiteral ( expression . left . name . text ) ;
31193119 } else {
31203120 // Element access
3121- indexExpression = this . transformExpression ( expression . left . argumentExpression ) ;
3122- const argType = this . checker . getTypeAtLocation ( expression . left . expression ) ;
3123- if ( tsHelper . isArrayType ( argType , this . checker , this . program ) ) {
3124- // Array access needs a +1
3125- indexExpression = this . expressionPlusOne ( indexExpression ) ;
3126- }
3121+ indexExpression = this . transformElementAccessArgument ( expression . left ) ;
31273122 }
31283123
31293124 const args = [ objExpression , indexExpression , this . transformExpression ( expression . right ) ] ;
@@ -3922,7 +3917,10 @@ export class LuaTransformer {
39223917 ) ;
39233918 } else {
39243919 const parameters = this . transformArguments ( node . arguments , signature ) ;
3925- const table = this . transformExpression ( node . expression . expression ) ;
3920+ let table = this . transformExpression ( node . expression . expression ) ;
3921+ if ( tstl . isTableExpression ( table ) ) {
3922+ table = tstl . createParenthesizedExpression ( table ) ;
3923+ }
39263924 const signatureDeclaration = signature && signature . getDeclaration ( ) ;
39273925 if (
39283926 ! signatureDeclaration ||
@@ -3959,7 +3957,10 @@ export class LuaTransformer {
39593957 return this . transformContextualCallExpression ( node , parameters ) ;
39603958 } else {
39613959 // No context
3962- const expression = this . transformExpression ( node . expression ) ;
3960+ let expression = this . transformExpression ( node . expression ) ;
3961+ if ( tstl . isTableExpression ( expression ) ) {
3962+ expression = tstl . createParenthesizedExpression ( expression ) ;
3963+ }
39633964 return tstl . createCallExpression ( expression , parameters ) ;
39643965 }
39653966 }
@@ -3976,7 +3977,10 @@ export class LuaTransformer {
39763977 tsHelper . isValidLuaIdentifier ( left . name . text )
39773978 ) {
39783979 // table:name()
3979- const table = this . transformExpression ( left . expression ) ;
3980+ let table = this . transformExpression ( left . expression ) ;
3981+ if ( tstl . isTableExpression ( table ) ) {
3982+ table = tstl . createParenthesizedExpression ( table ) ;
3983+ }
39803984 return tstl . createMethodCallExpression (
39813985 table ,
39823986 this . transformIdentifier ( left . name ) ,
@@ -3991,10 +3995,9 @@ export class LuaTransformer {
39913995
39923996 // Cache left-side if it has effects
39933997 //(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)()
3994- const argumentExpression = ts . isElementAccessExpression ( left )
3995- ? left . argumentExpression
3996- : ts . createStringLiteral ( left . name . text ) ;
3997- const argument = this . transformExpression ( argumentExpression ) ;
3998+ const argument = ts . isElementAccessExpression ( left )
3999+ ? this . transformElementAccessArgument ( left )
4000+ : tstl . createStringLiteral ( left . name . text ) ;
39984001 const selfIdentifier = tstl . createIdentifier ( "____TS_self" ) ;
39994002 const selfAssignment = tstl . createVariableDeclarationStatement ( selfIdentifier , context ) ;
40004003 const index = tstl . createTableIndexExpression ( selfIdentifier , argument ) ;
@@ -4084,7 +4087,10 @@ export class LuaTransformer {
40844087 }
40854088 }
40864089
4087- const callPath = this . transformExpression ( expression . expression ) ;
4090+ let callPath = this . transformExpression ( expression . expression ) ;
4091+ if ( tstl . isTableExpression ( callPath ) ) {
4092+ callPath = tstl . createParenthesizedExpression ( callPath ) ;
4093+ }
40884094 return tstl . createTableIndexExpression ( callPath , tstl . createStringLiteral ( property ) , expression ) ;
40894095 }
40904096
@@ -4188,7 +4194,10 @@ export class LuaTransformer {
41884194 protected transformStringProperty ( node : ts . PropertyAccessExpression ) : tstl . UnaryExpression {
41894195 switch ( node . name . escapedText ) {
41904196 case "length" :
4191- const expression = this . transformExpression ( node . expression ) ;
4197+ let expression = this . transformExpression ( node . expression ) ;
4198+ if ( ts . isTemplateExpression ( node . expression ) ) {
4199+ expression = tstl . createParenthesizedExpression ( expression ) ;
4200+ }
41924201 return tstl . createUnaryExpression ( expression , tstl . SyntaxKind . LengthOperator , node ) ;
41934202 default :
41944203 throw TSTLErrors . UnsupportedProperty ( "string" , node . name . escapedText as string , node ) ;
@@ -4199,7 +4208,10 @@ export class LuaTransformer {
41994208 protected transformArrayProperty ( node : ts . PropertyAccessExpression ) : tstl . UnaryExpression | undefined {
42004209 switch ( node . name . escapedText ) {
42014210 case "length" :
4202- const expression = this . transformExpression ( node . expression ) ;
4211+ let expression = this . transformExpression ( node . expression ) ;
4212+ if ( tstl . isTableExpression ( expression ) ) {
4213+ expression = tstl . createParenthesizedExpression ( expression ) ;
4214+ }
42034215 return tstl . createUnaryExpression ( expression , tstl . SyntaxKind . LengthOperator , node ) ;
42044216 default :
42054217 return undefined ;
@@ -4216,27 +4228,40 @@ export class LuaTransformer {
42164228 }
42174229 }
42184230
4219- public transformElementAccessExpression ( expression : ts . ElementAccessExpression ) : ExpressionVisitResult {
4220- const table = this . transformExpression ( expression . expression ) ;
4231+ protected transformElementAccessArgument ( expression : ts . ElementAccessExpression ) : tstl . Expression {
42214232 const index = this . transformExpression ( expression . argumentExpression ) ;
4233+ const argumentType = this . checker . getTypeAtLocation ( expression . argumentExpression ) ;
4234+ const type = this . checker . getTypeAtLocation ( expression . expression ) ;
4235+ if ( tsHelper . isNumberType ( argumentType ) && tsHelper . isArrayType ( type , this . checker , this . program ) ) {
4236+ return this . expressionPlusOne ( index ) ;
4237+ } else {
4238+ return index ;
4239+ }
4240+ }
4241+
4242+ public transformElementAccessExpression ( expression : ts . ElementAccessExpression ) : ExpressionVisitResult {
4243+ let table = this . transformExpression ( expression . expression ) ;
4244+ if ( tstl . isTableExpression ( table ) ) {
4245+ table = tstl . createParenthesizedExpression ( table ) ;
4246+ }
42224247
42234248 const constEnumValue = this . tryGetConstEnumValue ( expression ) ;
42244249 if ( constEnumValue ) {
42254250 return constEnumValue ;
42264251 }
42274252
4253+ const argumentType = this . checker . getTypeAtLocation ( expression . argumentExpression ) ;
42284254 const type = this . checker . getTypeAtLocation ( expression . expression ) ;
4229- if ( tsHelper . isArrayType ( type , this . checker , this . program ) ) {
4230- return tstl . createTableIndexExpression ( table , this . expressionPlusOne ( index ) , expression ) ;
4231- } else if ( tsHelper . isStringType ( type ) ) {
4255+ if ( tsHelper . isNumberType ( argumentType ) && tsHelper . isStringType ( type ) ) {
4256+ const index = this . transformExpression ( expression . argumentExpression ) ;
42324257 return tstl . createCallExpression (
42334258 tstl . createTableIndexExpression ( tstl . createIdentifier ( "string" ) , tstl . createStringLiteral ( "sub" ) ) ,
42344259 [ table , this . expressionPlusOne ( index ) , this . expressionPlusOne ( index ) ] ,
42354260 expression
42364261 ) ;
4237- } else {
4238- return tstl . createTableIndexExpression ( table , index , expression ) ;
42394262 }
4263+
4264+ return tstl . createTableIndexExpression ( table , this . transformElementAccessArgument ( expression ) , expression ) ;
42404265 }
42414266
42424267 private tryGetConstEnumValue (
@@ -4369,7 +4394,7 @@ export class LuaTransformer {
43694394 case "upper" :
43704395 // Allow lua's string instance methods
43714396 let stringVariable = this . transformExpression ( expression . expression ) ;
4372- if ( ts . isStringLiteral ( expression . expression ) ) {
4397+ if ( ts . isStringLiteralLike ( expression . expression ) ) {
43734398 // "foo":method() needs to be ("foo"):method()
43744399 stringVariable = tstl . createParenthesizedExpression ( stringVariable ) ;
43754400 }
0 commit comments