@@ -993,7 +993,18 @@ module ts {
993993            } 
994994
995995            function  emitBindingPattern ( bindingPattern : BindingPattern )  { 
996-                 emitCommaList ( bindingPattern . elements ,  emitBindingElement ) ; 
996+                 // Only select non-omitted expression from the bindingPattern's elements. 
997+                 // We have to do this to avoid emitting trailing commas. 
998+                 // For example: 
999+                 //      original: var [, c,,] = [ 2,3,4] 
1000+                 //      emitted: declare var c: number; // instead of declare var c:number, ; 
1001+                 let  elements : Node [ ]  =  [ ] ; 
1002+                 for  ( let  element  of  bindingPattern . elements )  { 
1003+                     if  ( element . kind  !==  SyntaxKind . OmittedExpression ) { 
1004+                         elements . push ( element ) ; 
1005+                     } 
1006+                 } 
1007+                 emitCommaList ( elements ,  emitBindingElement ) ; 
9971008            } 
9981009
9991010            function  emitBindingElement ( bindingElement : BindingElement )  { 
@@ -1291,7 +1302,10 @@ module ts {
12911302                write ( "..." ) ; 
12921303            } 
12931304            if  ( isBindingPattern ( node . name ) )  { 
1294-                 write ( "_"  +  indexOf ( ( < FunctionLikeDeclaration > node . parent ) . parameters ,  node ) ) ; 
1305+                 // For bindingPattern, we can't simply writeTextOfNode from the source file 
1306+                 // because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted. 
1307+                 // Therefore, we will have to recursively emit each element in the bindingPattern. 
1308+                 emitBindingPattern ( < BindingPattern > node . name ) ; 
12951309            } 
12961310            else  { 
12971311                writeTextOfNode ( currentSourceFile ,  node . name ) ; 
@@ -1311,72 +1325,146 @@ module ts {
13111325            } 
13121326
13131327            function  getParameterDeclarationTypeVisibilityError ( symbolAccesibilityResult : SymbolAccessiblityResult ) : SymbolAccessibilityDiagnostic  { 
1314-                 let  diagnosticMessage : DiagnosticMessage ; 
1328+                 let  diagnosticMessage : DiagnosticMessage  =  getParameterDeclarationTypeVisibilityDiagnosticMessage ( symbolAccesibilityResult ) ; 
1329+                 return  diagnosticMessage  !==  undefined  ? { 
1330+                     diagnosticMessage, 
1331+                     errorNode : node , 
1332+                     typeName : node . name 
1333+                 }  : undefined ; 
1334+             } 
1335+ 
1336+             function  getParameterDeclarationTypeVisibilityDiagnosticMessage ( symbolAccesibilityResult : SymbolAccessiblityResult ) : DiagnosticMessage  { 
13151337                switch  ( node . parent . kind )  { 
13161338                    case  SyntaxKind . Constructor :
1317-                         diagnosticMessage   =  symbolAccesibilityResult . errorModuleName  ?
1339+                         return  symbolAccesibilityResult . errorModuleName  ?
13181340                            symbolAccesibilityResult . accessibility  ===  SymbolAccessibility . CannotBeNamed  ?
13191341                                Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named  :
13201342                                Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2  :
13211343                            Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1 ; 
1322-                         break ; 
13231344
13241345                    case  SyntaxKind . ConstructSignature :
13251346                        // Interfaces cannot have parameter types that cannot be named 
1326-                         diagnosticMessage   =  symbolAccesibilityResult . errorModuleName  ?
1347+                         return  symbolAccesibilityResult . errorModuleName  ?
13271348                            Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2  :
13281349                            Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1 ; 
1329-                         break ; 
13301350
13311351                    case  SyntaxKind . CallSignature :
13321352                        // Interfaces cannot have parameter types that cannot be named 
1333-                         diagnosticMessage   =  symbolAccesibilityResult . errorModuleName  ?
1353+                         return  symbolAccesibilityResult . errorModuleName  ?
13341354                            Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2  :
13351355                            Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1 ; 
1336-                         break ; 
13371356
13381357                    case  SyntaxKind . MethodDeclaration :
13391358                    case  SyntaxKind . MethodSignature :
13401359                        if  ( node . parent . flags  &  NodeFlags . Static )  { 
1341-                             diagnosticMessage   =  symbolAccesibilityResult . errorModuleName  ?
1360+                             return  symbolAccesibilityResult . errorModuleName  ?
13421361                                symbolAccesibilityResult . accessibility  ===  SymbolAccessibility . CannotBeNamed  ?
13431362                                    Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named  :
13441363                                    Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2  :
13451364                                Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1 ; 
13461365                        } 
13471366                        else  if  ( node . parent . parent . kind  ===  SyntaxKind . ClassDeclaration )  { 
1348-                             diagnosticMessage   =  symbolAccesibilityResult . errorModuleName  ?
1367+                               return  symbolAccesibilityResult . errorModuleName  ?
13491368                                symbolAccesibilityResult . accessibility  ===  SymbolAccessibility . CannotBeNamed  ?
13501369                                    Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named  :
13511370                                    Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2  :
13521371                                Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1 ; 
13531372                        } 
13541373                        else  { 
13551374                            // Interfaces cannot have parameter types that cannot be named 
1356-                             diagnosticMessage   =  symbolAccesibilityResult . errorModuleName  ?
1375+                             return  symbolAccesibilityResult . errorModuleName  ?
13571376                                Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2  :
13581377                                Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1 ; 
13591378                        } 
1360-                         break ; 
13611379
13621380                    case  SyntaxKind . FunctionDeclaration :
1363-                         diagnosticMessage   =  symbolAccesibilityResult . errorModuleName  ?
1381+                         return  symbolAccesibilityResult . errorModuleName  ?
13641382                            symbolAccesibilityResult . accessibility  ===  SymbolAccessibility . CannotBeNamed  ?
13651383                                Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named  :
13661384                                Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2  :
13671385                            Diagnostics . Parameter_0_of_exported_function_has_or_is_using_private_name_1 ; 
1368-                         break ; 
13691386
13701387                    default :
13711388                        Debug . fail ( "This is unknown parent for parameter: "  +  node . parent . kind ) ; 
13721389                } 
1390+             } 
13731391
1374-                 return  { 
1375-                     diagnosticMessage, 
1376-                     errorNode : node , 
1377-                     typeName : node . name 
1378-                 } ; 
1392+             function  emitBindingPattern ( bindingPattern : BindingPattern )  { 
1393+                 // We have to explicitly emit square bracket and bracket because these tokens are not store inside the node. 
1394+                 if  ( bindingPattern . kind  ===  SyntaxKind . ObjectBindingPattern )  { 
1395+                     write ( "{" ) ; 
1396+                     emitCommaList ( bindingPattern . elements ,  emitBindingElement ) ; 
1397+                     write ( "}" ) ; 
1398+                 } 
1399+                 else  if  ( bindingPattern . kind  ===  SyntaxKind . ArrayBindingPattern )  { 
1400+                     write ( "[" ) ; 
1401+                     let  elements  =  bindingPattern . elements ; 
1402+                     emitCommaList ( elements ,  emitBindingElement ) ; 
1403+                     if  ( elements  &&  elements . hasTrailingComma )  { 
1404+                         write ( ", " ) ; 
1405+                     } 
1406+                     write ( "]" ) ; 
1407+                 } 
13791408            } 
1409+ 
1410+             function  emitBindingElement ( bindingElement : BindingElement )  { 
1411+                 function  getBindingElementTypeVisibilityError ( symbolAccesibilityResult : SymbolAccessiblityResult ) : SymbolAccessibilityDiagnostic  { 
1412+                     let  diagnosticMessage  =  getParameterDeclarationTypeVisibilityDiagnosticMessage ( symbolAccesibilityResult ) ; 
1413+                     return  diagnosticMessage  !==  undefined  ? { 
1414+                         diagnosticMessage, 
1415+                         errorNode : bindingElement , 
1416+                         typeName : bindingElement . name 
1417+                     }  : undefined ; 
1418+                 } 
1419+ 
1420+                 if  ( bindingElement . kind  ===  SyntaxKind . OmittedExpression )  { 
1421+                     // If bindingElement is an omittedExpression (i.e. containing elision), 
1422+                     // we will emit blank space (although this may differ from users' original code, 
1423+                     // it allows emitSeparatedList to write separator appropriately) 
1424+                     // Example: 
1425+                     //      original: function foo([, x, ,]) {} 
1426+                     //      emit    : function foo([ , x,  , ]) {} 
1427+                     write ( " " ) ; 
1428+                 } 
1429+                 else  if  ( bindingElement . kind  ===  SyntaxKind . BindingElement )  { 
1430+                     if  ( bindingElement . propertyName )  { 
1431+                         // bindingElement has propertyName property in the following case: 
1432+                         //      { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y" 
1433+                         // We have to explicitly emit the propertyName before descending into its binding elements. 
1434+                         // Example: 
1435+                         //      original: function foo({y: [a,b,c]}) {} 
1436+                         //      emit    : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void; 
1437+                         writeTextOfNode ( currentSourceFile ,  bindingElement . propertyName ) ; 
1438+                         write ( ": " ) ; 
1439+ 
1440+                         // If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern 
1441+                         emitBindingPattern ( < BindingPattern > bindingElement . name ) ; 
1442+                     } 
1443+                     else  if  ( bindingElement . name )  { 
1444+                         if  ( isBindingPattern ( bindingElement . name ) )  { 
1445+                             // If it is a nested binding pattern, we will recursively descend into each element and emit each one separately. 
1446+                             // In the case of rest element, we will omit rest element. 
1447+                             // Example: 
1448+                             //      original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {} 
1449+                             //      emit    : declare function foo([a, [[b]], c]: [number, [[string]], number]): void; 
1450+                             //      original with rest: function foo([a, ...c]) {} 
1451+                             //      emit              : declare function foo([a, ...c]): void; 
1452+                             emitBindingPattern ( < BindingPattern > bindingElement . name ) ; 
1453+                         } 
1454+                         else  { 
1455+                             Debug . assert ( bindingElement . name . kind  ===  SyntaxKind . Identifier ) ; 
1456+                             // If the node is just an identifier, we will simply emit the text associated with the node's name 
1457+                             // Example: 
1458+                             //      original: function foo({y = 10, x}) {} 
1459+                             //      emit    : declare function foo({y, x}: {number, any}): void; 
1460+                             if  ( bindingElement . dotDotDotToken )  { 
1461+                                 write ( "..." ) ; 
1462+                             } 
1463+                             writeTextOfNode ( currentSourceFile ,  bindingElement . name ) ; 
1464+                         } 
1465+                     } 
1466+                 } 
1467+             }  
13801468        } 
13811469
13821470        function  emitNode ( node : Node )  { 
0 commit comments