@@ -13,6 +13,7 @@ import { transformIdentifier } from "./identifier";
1313import { isMultiReturnCall } from "./language-extensions/multi" ;
1414import { transformPropertyName } from "./literal" ;
1515import { moveToPrecedingTemp } from "./expression-list" ;
16+ import { isStringType } from "../utils/typescript" ;
1617
1718export function transformArrayBindingElement (
1819 context : TransformationContext ,
@@ -40,7 +41,8 @@ export function transformBindingPattern(
4041 context : TransformationContext ,
4142 pattern : ts . BindingPattern ,
4243 table : lua . Expression ,
43- propertyAccessStack : ts . PropertyName [ ] = [ ]
44+ propertyAccessStack : ts . PropertyName [ ] = [ ] ,
45+ isStringBinding = false
4446) : lua . Statement [ ] {
4547 const result : lua . Statement [ ] = [ ] ;
4648
@@ -125,10 +127,21 @@ export function transformBindingPattern(
125127 ) ;
126128 }
127129 } else {
128- expression = lua . createTableIndexExpression (
129- tableExpression ,
130- ts . isObjectBindingPattern ( pattern ) ? propertyName : lua . createNumericLiteral ( index + 1 )
131- ) ;
130+ if ( isStringBinding ) {
131+ // don't add 1 to index stringaccess already takes care of that
132+ expression = transformLuaLibFunction (
133+ context ,
134+ LuaLibFeature . StringAccess ,
135+ pattern ,
136+ table ,
137+ lua . createNumericLiteral ( index )
138+ ) ;
139+ } else {
140+ expression = lua . createTableIndexExpression (
141+ tableExpression ,
142+ ts . isObjectBindingPattern ( pattern ) ? propertyName : lua . createNumericLiteral ( index + 1 )
143+ ) ;
144+ }
132145 }
133146
134147 result . push ( ...createLocalOrExportedOrGlobalDeclaration ( context , variableName , expression ) ) ;
@@ -153,36 +166,67 @@ export function transformBindingPattern(
153166 return result ;
154167}
155168
156- export function transformBindingVariableDeclaration (
169+ function requiresComplexBindingVariableDeclaration (
157170 context : TransformationContext ,
158171 bindingPattern : ts . BindingPattern ,
159172 initializer ?: ts . Expression
160- ) : lua . Statement [ ] {
161- const statements : lua . Statement [ ] = [ ] ;
162-
163- // For object, nested or rest bindings fall back to transformBindingPattern
173+ ) : boolean {
174+ // For object, strings, nested or rest bindings fall back to transformBindingPattern
164175 const isComplexBindingElement = ( e : ts . ArrayBindingElement ) =>
165176 ts . isBindingElement ( e ) && ( ! ts . isIdentifier ( e . name ) || e . dotDotDotToken ) ;
166177
167- if ( ts . isObjectBindingPattern ( bindingPattern ) || bindingPattern . elements . some ( isComplexBindingElement ) ) {
168- let table : lua . Expression ;
169- if ( initializer ) {
170- // Contain the expression in a temporary variable
171- let expression = context . transformExpression ( initializer ) ;
172- if ( isMultiReturnCall ( context , initializer ) ) {
173- expression = wrapInTable ( expression ) ;
174- }
175- const { precedingStatements : moveStatements , result : movedExpr } = transformInPrecedingStatementScope (
176- context ,
177- ( ) => moveToPrecedingTemp ( context , expression , initializer )
178- ) ;
179- statements . push ( ...moveStatements ) ;
180- table = movedExpr ;
181- } else {
182- table = lua . createAnonymousIdentifier ( ) ;
178+ const hasStringInitializer = initializer && isStringType ( context , context . checker . getTypeAtLocation ( initializer ) ) ;
179+
180+ return (
181+ ts . isObjectBindingPattern ( bindingPattern ) ||
182+ bindingPattern . elements . some ( isComplexBindingElement ) ||
183+ Boolean ( hasStringInitializer )
184+ ) ;
185+ }
186+ function transformComplexBindingVariableDeclaration (
187+ context : TransformationContext ,
188+ bindingPattern : ts . BindingPattern ,
189+ initializer ?: ts . Expression
190+ ) : lua . Statement [ ] {
191+ const statements : lua . Statement [ ] = [ ] ;
192+
193+ let table : lua . Expression ;
194+ if ( initializer ) {
195+ // Contain the expression in a temporary variable
196+ let expression = context . transformExpression ( initializer ) ;
197+ if ( isMultiReturnCall ( context , initializer ) ) {
198+ expression = wrapInTable ( expression ) ;
183199 }
184- statements . push ( ...transformBindingPattern ( context , bindingPattern , table ) ) ;
185- return statements ;
200+ const { precedingStatements : moveStatements , result : movedExpr } = transformInPrecedingStatementScope (
201+ context ,
202+ ( ) => moveToPrecedingTemp ( context , expression , initializer )
203+ ) ;
204+ statements . push ( ...moveStatements ) ;
205+ table = movedExpr ;
206+ } else {
207+ table = lua . createAnonymousIdentifier ( ) ;
208+ }
209+ statements . push (
210+ ...transformBindingPattern (
211+ context ,
212+ bindingPattern ,
213+ table ,
214+ [ ] ,
215+ initializer && isStringType ( context , context . checker . getTypeAtLocation ( initializer ) )
216+ )
217+ ) ;
218+ return statements ;
219+ }
220+
221+ export function transformBindingVariableDeclaration (
222+ context : TransformationContext ,
223+ bindingPattern : ts . BindingPattern ,
224+ initializer ?: ts . Expression
225+ ) : lua . Statement [ ] {
226+ const statements : lua . Statement [ ] = [ ] ;
227+
228+ if ( requiresComplexBindingVariableDeclaration ( context , bindingPattern , initializer ) ) {
229+ return transformComplexBindingVariableDeclaration ( context , bindingPattern , initializer ) ;
186230 }
187231
188232 const vars =
@@ -208,6 +252,12 @@ export function transformBindingVariableDeclaration(
208252 ? initializer . elements . map ( e => context . transformExpression ( e ) )
209253 : lua . createNilLiteral ( ) ;
210254 statements . push ( ...createLocalOrExportedOrGlobalDeclaration ( context , vars , values , initializer ) ) ;
255+ } else if ( ts . isStringLiteral ( initializer ) ) {
256+ const values =
257+ initializer . text . length > 0
258+ ? Array . from ( initializer . text ) . map ( c => lua . createStringLiteral ( c ) )
259+ : lua . createNilLiteral ( ) ;
260+ statements . push ( ...createLocalOrExportedOrGlobalDeclaration ( context , vars , values , initializer ) ) ;
211261 } else {
212262 // local vars = this.transpileDestructingAssignmentValue(node.initializer);
213263 const unpackedInitializer = createUnpackCall (
0 commit comments