@@ -16,22 +16,24 @@ import { transformArguments } from "../call";
1616import { transformIdentifier } from "../identifier" ;
1717import { transformArrayBindingElement , transformVariableDeclaration } from "../variable-declaration" ;
1818import { transformLoopBody } from "./body" ;
19+ import { getVariableDeclarationBinding } from "./utils" ;
1920
2021function transformForOfInitializer (
2122 context : TransformationContext ,
2223 initializer : ts . ForInitializer ,
2324 expression : lua . Expression
2425) : lua . Statement | undefined {
2526 if ( ts . isVariableDeclarationList ( initializer ) ) {
27+ const binding = getVariableDeclarationBinding ( initializer ) ;
2628 // Declaration of new variable
27- if ( ts . isArrayBindingPattern ( initializer . declarations [ 0 ] . name ) ) {
28- if ( initializer . declarations [ 0 ] . name . elements . length === 0 ) {
29+ if ( ts . isArrayBindingPattern ( binding ) ) {
30+ if ( binding . elements . length === 0 ) {
2931 // Ignore empty destructuring assignment
3032 return undefined ;
3133 }
3234
3335 expression = createUnpackCall ( context , expression , initializer ) ;
34- } else if ( ts . isObjectBindingPattern ( initializer . declarations [ 0 ] . name ) ) {
36+ } else if ( ts . isObjectBindingPattern ( binding ) ) {
3537 throw UnsupportedObjectDestructuringInForOf ( initializer ) ;
3638 }
3739
@@ -90,19 +92,19 @@ function transformForRangeStatement(
9092 throw InvalidForRangeCall ( statement . initializer , "@forRange loop must declare its own control variable." ) ;
9193 }
9294
93- const controlDeclaration = statement . initializer . declarations [ 0 ] ;
94- if ( ! ts . isIdentifier ( controlDeclaration . name ) ) {
95+ const binding = getVariableDeclarationBinding ( statement . initializer ) ;
96+ if ( ! ts . isIdentifier ( binding ) ) {
9597 throw InvalidForRangeCall ( statement . initializer , "@forRange loop cannot use destructuring." ) ;
9698 }
9799
98- if ( ! isNumberType ( context , context . checker . getTypeAtLocation ( controlDeclaration ) ) ) {
100+ if ( ! isNumberType ( context , context . checker . getTypeAtLocation ( binding ) ) ) {
99101 throw InvalidForRangeCall (
100102 statement . expression ,
101103 "@forRange function must return Iterable<number> or Array<number>."
102104 ) ;
103105 }
104106
105- const control = transformIdentifier ( context , controlDeclaration . name ) ;
107+ const control = transformIdentifier ( context , binding ) ;
106108 const signature = context . checker . getResolvedSignature ( statement . expression ) ;
107109 const [ start , limit , step ] = transformArguments ( context , statement . expression . arguments , signature ) ;
108110 return lua . createForStatement ( block , control , start , limit , step , statement ) ;
@@ -121,9 +123,9 @@ function transformForOfLuaIteratorStatement(
121123 if ( ts . isVariableDeclarationList ( statement . initializer ) ) {
122124 // Variables declared in for loop
123125 // for ${initializer} in ${iterable} do
124- const initializerVariable = statement . initializer . declarations [ 0 ] . name ;
125- if ( ts . isArrayBindingPattern ( initializerVariable ) ) {
126- const identifiers = initializerVariable . elements . map ( e => transformArrayBindingElement ( context , e ) ) ;
126+ const binding = getVariableDeclarationBinding ( statement . initializer ) ;
127+ if ( ts . isArrayBindingPattern ( binding ) ) {
128+ const identifiers = binding . elements . map ( e => transformArrayBindingElement ( context , e ) ) ;
127129 if ( identifiers . length === 0 ) {
128130 identifiers . push ( lua . createAnonymousIdentifier ( ) ) ;
129131 }
@@ -160,6 +162,7 @@ function transformForOfLuaIteratorStatement(
160162 // LuaIterator (no TupleReturn)
161163 if (
162164 ts . isVariableDeclarationList ( statement . initializer ) &&
165+ statement . initializer . declarations . length > 0 &&
163166 ts . isIdentifier ( statement . initializer . declarations [ 0 ] . name )
164167 ) {
165168 // Single variable declared in for loop
@@ -191,15 +194,15 @@ function transformForOfArrayStatement(
191194 let valueVariable : lua . Identifier ;
192195 if ( ts . isVariableDeclarationList ( statement . initializer ) ) {
193196 // Declaration of new variable
194- const variables = statement . initializer . declarations [ 0 ] . name ;
195- if ( ts . isArrayBindingPattern ( variables ) || ts . isObjectBindingPattern ( variables ) ) {
197+ const binding = getVariableDeclarationBinding ( statement . initializer ) ;
198+ if ( ts . isArrayBindingPattern ( binding ) || ts . isObjectBindingPattern ( binding ) ) {
196199 valueVariable = lua . createIdentifier ( "____values" ) ;
197200 const initializer = transformForOfInitializer ( context , statement . initializer , valueVariable ) ;
198201 if ( initializer ) {
199202 block . statements . unshift ( initializer ) ;
200203 }
201204 } else {
202- valueVariable = transformIdentifier ( context , variables ) ;
205+ valueVariable = transformIdentifier ( context , binding ) ;
203206 }
204207 } else {
205208 // Assignment to existing variable
@@ -225,6 +228,7 @@ function transformForOfIteratorStatement(
225228 const iterable = context . transformExpression ( statement . expression ) ;
226229 if (
227230 ts . isVariableDeclarationList ( statement . initializer ) &&
231+ statement . initializer . declarations . length > 0 &&
228232 ts . isIdentifier ( statement . initializer . declarations [ 0 ] . name )
229233 ) {
230234 // Single variable declared in for loop
0 commit comments