@@ -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