@@ -1291,8 +1291,10 @@ module ts {
12911291 write ( "..." ) ;
12921292 }
12931293 if ( isBindingPattern ( node . name ) ) {
1294- // By emitting binding pattern as binding pattern in function parameters, language service can provide better signature help
1295- write ( getTextOfNode ( node . name ) ) ;
1294+ // For bindingPattern, we can't simply writeTextOfNode from the source file
1295+ // because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted.
1296+ // Therefore, we will have to recursively emit each element in the bindingPattern.
1297+ emitBindingPattern ( < BindingPattern > node . name ) ;
12961298 }
12971299 else {
12981300 writeTextOfNode ( currentSourceFile , node . name ) ;
@@ -1312,72 +1314,127 @@ module ts {
13121314 }
13131315
13141316 function getParameterDeclarationTypeVisibilityError ( symbolAccesibilityResult : SymbolAccessiblityResult ) : SymbolAccessibilityDiagnostic {
1315- let diagnosticMessage : DiagnosticMessage ;
1317+ let diagnosticMessage : DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage ( symbolAccesibilityResult ) ;
1318+ return diagnosticMessage !== undefined ? {
1319+ diagnosticMessage,
1320+ errorNode : node ,
1321+ typeName : node . name
1322+ } : undefined ;
1323+ }
1324+
1325+ function getParameterDeclarationTypeVisibilityDiagnosticMessage ( symbolAccesibilityResult : SymbolAccessiblityResult ) {
13161326 switch ( node . parent . kind ) {
13171327 case SyntaxKind . Constructor :
1318- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1328+ return symbolAccesibilityResult . errorModuleName ?
13191329 symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
13201330 Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
13211331 Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
13221332 Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1 ;
1323- break ;
13241333
13251334 case SyntaxKind . ConstructSignature :
13261335 // Interfaces cannot have parameter types that cannot be named
1327- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1336+ return symbolAccesibilityResult . errorModuleName ?
13281337 Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
13291338 Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1 ;
1330- break ;
13311339
13321340 case SyntaxKind . CallSignature :
13331341 // Interfaces cannot have parameter types that cannot be named
1334- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1342+ return symbolAccesibilityResult . errorModuleName ?
13351343 Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
13361344 Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1 ;
1337- break ;
13381345
13391346 case SyntaxKind . MethodDeclaration :
13401347 case SyntaxKind . MethodSignature :
13411348 if ( node . parent . flags & NodeFlags . Static ) {
1342- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1349+ return symbolAccesibilityResult . errorModuleName ?
13431350 symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
13441351 Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
13451352 Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
13461353 Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1 ;
13471354 }
13481355 else if ( node . parent . parent . kind === SyntaxKind . ClassDeclaration ) {
1349- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1356+ return symbolAccesibilityResult . errorModuleName ?
13501357 symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
13511358 Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
13521359 Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
13531360 Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1 ;
13541361 }
13551362 else {
13561363 // Interfaces cannot have parameter types that cannot be named
1357- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1364+ return symbolAccesibilityResult . errorModuleName ?
13581365 Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
13591366 Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1 ;
13601367 }
1361- break ;
13621368
13631369 case SyntaxKind . FunctionDeclaration :
1364- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1370+ return symbolAccesibilityResult . errorModuleName ?
13651371 symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
13661372 Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
13671373 Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
13681374 Diagnostics . Parameter_0_of_exported_function_has_or_is_using_private_name_1 ;
1369- break ;
13701375
13711376 default :
13721377 Debug . fail ( "This is unknown parent for parameter: " + node . parent . kind ) ;
13731378 }
1379+ }
13741380
1375- return {
1376- diagnosticMessage,
1377- errorNode : node ,
1378- typeName : node . name
1379- } ;
1381+ function emitBindingPattern ( bindingPattern : BindingPattern ) {
1382+ // We have to explicitly emit square bracket and bracket because these tokens are not store inside the node.
1383+ if ( bindingPattern . kind === SyntaxKind . ObjectBindingPattern ) {
1384+ write ( "{" ) ;
1385+ emitCommaList ( bindingPattern . elements , emitBindingElement ) ;
1386+ write ( "}" ) ;
1387+ }
1388+ else if ( bindingPattern . kind === SyntaxKind . ArrayBindingPattern ) {
1389+ write ( "[" ) ;
1390+ emitCommaList ( bindingPattern . elements , emitBindingElement ) ;
1391+ write ( "]" ) ;
1392+ }
13801393 }
1394+
1395+ function emitBindingElement ( bindingElement : BindingElement ) {
1396+ function getBindingElementTypeVisibilityError ( symbolAccesibilityResult : SymbolAccessiblityResult ) : SymbolAccessibilityDiagnostic {
1397+ let diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage ( symbolAccesibilityResult ) ;
1398+ return diagnosticMessage !== undefined ? {
1399+ diagnosticMessage,
1400+ errorNode : bindingElement ,
1401+ typeName : bindingElement . name
1402+ } : undefined ;
1403+ }
1404+
1405+ if ( bindingElement . propertyName ) {
1406+ // bindingElement has propertyName property in the following case:
1407+ // { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y"
1408+ // We have to explicitly emit the propertyName before descending into its binding elements.
1409+ // Example:
1410+ // original: function foo({y: [a,b,c]}) {}
1411+ // emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
1412+ writeTextOfNode ( currentSourceFile , bindingElement . propertyName ) ;
1413+ write ( ": " ) ;
1414+
1415+ // If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern
1416+ emitBindingPattern ( < BindingPattern > bindingElement . name ) ;
1417+ }
1418+ else if ( bindingElement . name ) {
1419+ if ( isBindingPattern ( bindingElement . name ) ) {
1420+ // If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
1421+ // In the case of rest element, we will omit rest element.
1422+ // Example:
1423+ // original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {}
1424+ // emit : declare function foo([a, [[b]], c]: [number, [[string]], number]): void;
1425+ // original with rest: function foo([a ...c]) {}
1426+ // emit : declare function foo([a, c]): void;
1427+ emitBindingPattern ( < BindingPattern > bindingElement . name ) ;
1428+ }
1429+ else {
1430+ // If the node is just an identifier, we will simply emit the text associated with the node's name
1431+ // Example:
1432+ // original: function foo({y = 10, x}) {}
1433+ // emit : declare function foo({y, x}: {number, any}): void;
1434+ writeTextOfNode ( currentSourceFile , bindingElement . name ) ;
1435+ }
1436+ }
1437+ }
13811438 }
13821439
13831440 function emitNode ( node : Node ) {
0 commit comments