@@ -120,6 +120,92 @@ export function transformBindingPattern(
120120 return result ;
121121}
122122
123+ export function transformBindingVariableDeclaration (
124+ context : TransformationContext ,
125+ bindingPattern : ts . BindingPattern ,
126+ initializer ?: ts . Expression
127+ ) : lua . Statement [ ] {
128+ const statements : lua . Statement [ ] = [ ] ;
129+
130+ // For object, nested or rest bindings fall back to transformBindingPattern
131+ const isComplexBindingElement = ( e : ts . ArrayBindingElement ) =>
132+ ts . isBindingElement ( e ) && ( ! ts . isIdentifier ( e . name ) || e . dotDotDotToken ) ;
133+
134+ if ( ts . isObjectBindingPattern ( bindingPattern ) || bindingPattern . elements . some ( isComplexBindingElement ) ) {
135+ let table : lua . Identifier ;
136+ if ( initializer !== undefined && ts . isIdentifier ( initializer ) ) {
137+ table = transformIdentifier ( context , initializer ) ;
138+ } else {
139+ // Contain the expression in a temporary variable
140+ table = lua . createAnonymousIdentifier ( ) ;
141+ if ( initializer ) {
142+ statements . push (
143+ lua . createVariableDeclarationStatement ( table , context . transformExpression ( initializer ) )
144+ ) ;
145+ }
146+ }
147+ statements . push ( ...transformBindingPattern ( context , bindingPattern , table ) ) ;
148+ return statements ;
149+ }
150+
151+ const vars =
152+ bindingPattern . elements . length > 0
153+ ? bindingPattern . elements . map ( e => transformArrayBindingElement ( context , e ) )
154+ : lua . createAnonymousIdentifier ( ) ;
155+
156+ if ( initializer ) {
157+ if ( isTupleReturnCall ( context , initializer ) ) {
158+ // Don't unpack @tupleReturn annotated functions
159+ statements . push (
160+ ...createLocalOrExportedOrGlobalDeclaration (
161+ context ,
162+ vars ,
163+ context . transformExpression ( initializer ) ,
164+ initializer
165+ )
166+ ) ;
167+ } else if ( ts . isArrayLiteralExpression ( initializer ) ) {
168+ // Don't unpack array literals
169+ const values =
170+ initializer . elements . length > 0
171+ ? initializer . elements . map ( e => context . transformExpression ( e ) )
172+ : lua . createNilLiteral ( ) ;
173+ statements . push ( ...createLocalOrExportedOrGlobalDeclaration ( context , vars , values , initializer ) ) ;
174+ } else {
175+ // local vars = this.transpileDestructingAssignmentValue(node.initializer);
176+ const unpackedInitializer = createUnpackCall (
177+ context ,
178+ context . transformExpression ( initializer ) ,
179+ initializer
180+ ) ;
181+ statements . push (
182+ ...createLocalOrExportedOrGlobalDeclaration ( context , vars , unpackedInitializer , initializer )
183+ ) ;
184+ }
185+ } else {
186+ statements . push (
187+ ...createLocalOrExportedOrGlobalDeclaration ( context , vars , lua . createNilLiteral ( ) , initializer )
188+ ) ;
189+ }
190+
191+ for ( const element of bindingPattern . elements ) {
192+ if ( ! ts . isOmittedExpression ( element ) && element . initializer ) {
193+ const variableName = transformIdentifier ( context , element . name as ts . Identifier ) ;
194+ const identifier = addExportToIdentifier ( context , variableName ) ;
195+ statements . push (
196+ lua . createIfStatement (
197+ lua . createBinaryExpression ( identifier , lua . createNilLiteral ( ) , lua . SyntaxKind . EqualityOperator ) ,
198+ lua . createBlock ( [
199+ lua . createAssignmentStatement ( identifier , context . transformExpression ( element . initializer ) ) ,
200+ ] )
201+ )
202+ ) ;
203+ }
204+ }
205+
206+ return statements ;
207+ }
208+
123209// TODO: FunctionVisitor<ts.VariableDeclaration>
124210export function transformVariableDeclaration (
125211 context : TransformationContext ,
@@ -137,86 +223,7 @@ export function transformVariableDeclaration(
137223 const value = statement . initializer && context . transformExpression ( statement . initializer ) ;
138224 return createLocalOrExportedOrGlobalDeclaration ( context , identifierName , value , statement ) ;
139225 } else if ( ts . isArrayBindingPattern ( statement . name ) || ts . isObjectBindingPattern ( statement . name ) ) {
140- const statements : lua . Statement [ ] = [ ] ;
141-
142- // For object, nested or rest bindings fall back to transformBindingPattern
143- if (
144- ts . isObjectBindingPattern ( statement . name ) ||
145- statement . name . elements . some ( e => ts . isBindingElement ( e ) && ( ! ts . isIdentifier ( e . name ) || e . dotDotDotToken ) )
146- ) {
147- let table : lua . Identifier ;
148- if ( statement . initializer !== undefined && ts . isIdentifier ( statement . initializer ) ) {
149- table = transformIdentifier ( context , statement . initializer ) ;
150- } else {
151- // Contain the expression in a temporary variable
152- table = lua . createAnonymousIdentifier ( ) ;
153- if ( statement . initializer ) {
154- statements . push (
155- lua . createVariableDeclarationStatement (
156- table ,
157- context . transformExpression ( statement . initializer )
158- )
159- ) ;
160- }
161- }
162- statements . push ( ...transformBindingPattern ( context , statement . name , table ) ) ;
163- return statements ;
164- }
165-
166- const vars =
167- statement . name . elements . length > 0
168- ? statement . name . elements . map ( e => transformArrayBindingElement ( context , e ) )
169- : lua . createAnonymousIdentifier ( statement . name ) ;
170-
171- if ( statement . initializer ) {
172- if ( isTupleReturnCall ( context , statement . initializer ) ) {
173- // Don't unpack @tupleReturn annotated functions
174- statements . push (
175- ...createLocalOrExportedOrGlobalDeclaration (
176- context ,
177- vars ,
178- context . transformExpression ( statement . initializer ) ,
179- statement
180- )
181- ) ;
182- } else if ( ts . isArrayLiteralExpression ( statement . initializer ) ) {
183- // Don't unpack array literals
184- const values =
185- statement . initializer . elements . length > 0
186- ? statement . initializer . elements . map ( e => context . transformExpression ( e ) )
187- : lua . createNilLiteral ( ) ;
188- statements . push ( ...createLocalOrExportedOrGlobalDeclaration ( context , vars , values , statement ) ) ;
189- } else {
190- // local vars = this.transpileDestructingAssignmentValue(node.initializer);
191- const initializer = createUnpackCall (
192- context ,
193- context . transformExpression ( statement . initializer ) ,
194- statement . initializer
195- ) ;
196- statements . push ( ...createLocalOrExportedOrGlobalDeclaration ( context , vars , initializer , statement ) ) ;
197- }
198- } else {
199- statements . push (
200- ...createLocalOrExportedOrGlobalDeclaration ( context , vars , lua . createNilLiteral ( ) , statement )
201- ) ;
202- }
203-
204- for ( const element of statement . name . elements ) {
205- if ( ! ts . isOmittedExpression ( element ) && element . initializer ) {
206- const variableName = transformIdentifier ( context , element . name as ts . Identifier ) ;
207- const identifier = addExportToIdentifier ( context , variableName ) ;
208- statements . push (
209- lua . createIfStatement (
210- lua . createBinaryExpression ( identifier , lua . createNilLiteral ( ) , lua . SyntaxKind . EqualityOperator ) ,
211- lua . createBlock ( [
212- lua . createAssignmentStatement ( identifier , context . transformExpression ( element . initializer ) ) ,
213- ] )
214- )
215- ) ;
216- }
217- }
218-
219- return statements ;
226+ return transformBindingVariableDeclaration ( context , statement . name , statement . initializer ) ;
220227 } else {
221228 return assertNever ( statement . name ) ;
222229 }
0 commit comments