@@ -1348,64 +1348,97 @@ export class LuaTransformer {
13481348 const isObjectBindingPattern = ts . isObjectBindingPattern ( pattern ) ;
13491349 for ( let index = 0 ; index < pattern . elements . length ; index ++ ) {
13501350 const element = pattern . elements [ index ] ;
1351- if ( ts . isBindingElement ( element ) ) {
1352- if ( ts . isArrayBindingPattern ( element . name ) || ts . isObjectBindingPattern ( element . name ) ) {
1353- // nested binding pattern
1354- const propertyName = isObjectBindingPattern
1355- ? element . propertyName
1356- : ts . createNumericLiteral ( String ( index + 1 ) ) ;
1357- if ( propertyName !== undefined ) {
1358- propertyAccessStack . push ( propertyName ) ;
1359- }
1360- result . push ( ...this . statementVisitResultToArray (
1361- this . transformBindingPattern ( element . name , table , propertyAccessStack )
1362- ) ) ;
1351+ if ( ts . isOmittedExpression ( element ) ) continue ;
1352+
1353+ if ( ts . isArrayBindingPattern ( element . name ) || ts . isObjectBindingPattern ( element . name ) ) {
1354+ // nested binding pattern
1355+ const propertyName = isObjectBindingPattern
1356+ ? element . propertyName
1357+ : ts . createNumericLiteral ( String ( index + 1 ) ) ;
1358+ if ( propertyName !== undefined ) {
1359+ propertyAccessStack . push ( propertyName ) ;
1360+ }
1361+ result . push ( ...this . statementVisitResultToArray (
1362+ this . transformBindingPattern ( element . name , table , propertyAccessStack )
1363+ ) ) ;
1364+ continue ;
1365+ }
1366+
1367+ // Build the path to the table
1368+ let tableExpression : tstl . Expression = table ;
1369+ propertyAccessStack . forEach ( property => {
1370+ const propertyName = ts . isPropertyName ( property )
1371+ ? this . transformPropertyName ( property )
1372+ : this . transformNumericLiteral ( property ) ;
1373+ tableExpression = tstl . createTableIndexExpression (
1374+ tableExpression ,
1375+ this . expectExpression ( propertyName )
1376+ ) ;
1377+ } ) ;
1378+
1379+ // The identifier of the new variable
1380+ const variableName = this . transformIdentifier ( element . name as ts . Identifier ) ;
1381+ // The field to extract
1382+ const propertyName = this . transformIdentifier (
1383+ ( element . propertyName || element . name ) as ts . Identifier ) ;
1384+
1385+ let expression : tstl . Expression ;
1386+ if ( element . dotDotDotToken ) {
1387+ if ( index !== pattern . elements . length - 1 ) continue ;
1388+
1389+ if ( isObjectBindingPattern ) {
1390+ const elements = pattern . elements as ts . NodeArray < ts . BindingElement > ;
1391+ const usedProperties = elements . map ( e =>
1392+ tstl . createTableFieldExpression (
1393+ tstl . createStringLiteral (
1394+ this . getIdentifierText ( ( e . propertyName || e . name ) as ts . Identifier )
1395+ )
1396+ )
1397+ ) ;
1398+
1399+ expression = this . transformLuaLibFunction (
1400+ LuaLibFeature . ObjectRest ,
1401+ undefined ,
1402+ tableExpression ,
1403+ tstl . createTableExpression ( usedProperties )
1404+ ) ;
13631405 } else {
1364- // Disallow ellipsis destructure
1365- if ( element . dotDotDotToken ) {
1366- throw TSTLErrors . ForbiddenEllipsisDestruction ( element ) ;
1367- }
1368- // Build the path to the table
1369- let tableExpression : tstl . Expression = table ;
1370- propertyAccessStack . forEach ( property => {
1371- const propertyName = ts . isPropertyName ( property )
1372- ? this . transformPropertyName ( property )
1373- : this . transformNumericLiteral ( property ) ;
1374- tableExpression = tstl . createTableIndexExpression (
1375- tableExpression ,
1376- this . expectExpression ( propertyName )
1377- ) ;
1378- } ) ;
1379- // The identifier of the new variable
1380- const variableName = this . transformIdentifier ( element . name as ts . Identifier ) ;
1381- // The field to extract
1382- const propertyName = this . transformIdentifier (
1383- ( element . propertyName || element . name ) as ts . Identifier ) ;
1384- const expression = isObjectBindingPattern
1385- ? tstl . createTableIndexExpression ( tableExpression , tstl . createStringLiteral ( propertyName . text ) )
1386- : tstl . createTableIndexExpression ( tableExpression , tstl . createNumericLiteral ( index + 1 ) ) ;
1387- result . push ( ... this . createLocalOrExportedOrGlobalDeclaration ( variableName , expression ) ) ;
1388- if ( element . initializer ) {
1389- const identifier = this . shouldExportIdentifier ( variableName )
1390- ? this . createExportedIdentifier ( variableName )
1391- : variableName ;
1392- result . push ( tstl . createIfStatement (
1393- tstl . createBinaryExpression (
1406+ expression = this . transformLuaLibFunction (
1407+ LuaLibFeature . ArraySlice ,
1408+ undefined ,
1409+ tableExpression ,
1410+ tstl . createNumericLiteral ( index )
1411+ ) ;
1412+ }
1413+ } else {
1414+ expression = tstl . createTableIndexExpression (
1415+ tableExpression ,
1416+ isObjectBindingPattern
1417+ ? tstl . createStringLiteral ( propertyName . text )
1418+ : tstl . createNumericLiteral ( index + 1 )
1419+ ) ;
1420+ }
1421+
1422+ result . push ( ... this . createLocalOrExportedOrGlobalDeclaration ( variableName , expression ) ) ;
1423+ if ( element . initializer ) {
1424+ const identifier = this . shouldExportIdentifier ( variableName )
1425+ ? this . createExportedIdentifier ( variableName )
1426+ : variableName ;
1427+ result . push ( tstl . createIfStatement (
1428+ tstl . createBinaryExpression (
1429+ identifier ,
1430+ tstl . createNilLiteral ( ) ,
1431+ tstl . SyntaxKind . EqualityOperator
1432+ ) ,
1433+ tstl . createBlock (
1434+ [
1435+ tstl . createAssignmentStatement (
13941436 identifier ,
1395- tstl . createNilLiteral ( ) ,
1396- tstl . SyntaxKind . EqualityOperator
1437+ this . transformExpression ( element . initializer )
13971438 ) ,
1398- tstl . createBlock (
1399- [
1400- tstl . createAssignmentStatement (
1401- identifier ,
1402- this . transformExpression ( element . initializer )
1403- ) ,
1404- ]
1405- )
1406- ) ) ;
1407- }
1408- }
1439+ ]
1440+ )
1441+ ) ) ;
14091442 }
14101443 }
14111444 propertyAccessStack . pop ( ) ;
@@ -1830,10 +1863,11 @@ export class LuaTransformer {
18301863 // Destructuring types
18311864
18321865 const statements : tstl . Statement [ ] = [ ] ;
1833-
1834- // For nested bindings and object bindings, fall back to transformBindingPattern
1866+ // For object, nested, omitted or rest bindings fall back to transformBindingPattern
18351867 if ( ts . isObjectBindingPattern ( statement . name )
1836- || statement . name . elements . some ( elem => ! ts . isBindingElement ( elem ) || ! ts . isIdentifier ( elem . name ) ) ) {
1868+ || statement . name . elements . some ( elem =>
1869+ ts . isOmittedExpression ( elem ) || ! ts . isIdentifier ( elem . name ) || elem . dotDotDotToken !== undefined
1870+ ) ) {
18371871 const statements = [ ] ;
18381872 let table : tstl . Identifier ;
18391873 if ( statement . initializer !== undefined && ts . isIdentifier ( statement . initializer ) ) {
@@ -1852,11 +1886,6 @@ export class LuaTransformer {
18521886 return statements ;
18531887 }
18541888
1855- // Disallow ellipsis destruction
1856- if ( statement . name . elements . some ( elem => ! ts . isBindingElement ( elem ) || elem . dotDotDotToken !== undefined ) ) {
1857- throw TSTLErrors . ForbiddenEllipsisDestruction ( statement ) ;
1858- }
1859-
18601889 const vars = statement . name . elements . length > 0
18611890 ? this . filterUndefinedAndCast (
18621891 statement . name . elements . map ( e => this . transformArrayBindingElement ( e ) ) ,
0 commit comments