@@ -1291,8 +1291,10 @@ module ts {
1291
1291
write ( "..." ) ;
1292
1292
}
1293
1293
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 ) ;
1296
1298
}
1297
1299
else {
1298
1300
writeTextOfNode ( currentSourceFile , node . name ) ;
@@ -1312,72 +1314,127 @@ module ts {
1312
1314
}
1313
1315
1314
1316
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 ) {
1316
1326
switch ( node . parent . kind ) {
1317
1327
case SyntaxKind . Constructor :
1318
- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1328
+ return symbolAccesibilityResult . errorModuleName ?
1319
1329
symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
1320
1330
Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
1321
1331
Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
1322
1332
Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1 ;
1323
- break ;
1324
1333
1325
1334
case SyntaxKind . ConstructSignature :
1326
1335
// Interfaces cannot have parameter types that cannot be named
1327
- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1336
+ return symbolAccesibilityResult . errorModuleName ?
1328
1337
Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
1329
1338
Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1 ;
1330
- break ;
1331
1339
1332
1340
case SyntaxKind . CallSignature :
1333
1341
// Interfaces cannot have parameter types that cannot be named
1334
- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1342
+ return symbolAccesibilityResult . errorModuleName ?
1335
1343
Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
1336
1344
Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1 ;
1337
- break ;
1338
1345
1339
1346
case SyntaxKind . MethodDeclaration :
1340
1347
case SyntaxKind . MethodSignature :
1341
1348
if ( node . parent . flags & NodeFlags . Static ) {
1342
- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1349
+ return symbolAccesibilityResult . errorModuleName ?
1343
1350
symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
1344
1351
Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
1345
1352
Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
1346
1353
Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1 ;
1347
1354
}
1348
1355
else if ( node . parent . parent . kind === SyntaxKind . ClassDeclaration ) {
1349
- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1356
+ return symbolAccesibilityResult . errorModuleName ?
1350
1357
symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
1351
1358
Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
1352
1359
Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
1353
1360
Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1 ;
1354
1361
}
1355
1362
else {
1356
1363
// Interfaces cannot have parameter types that cannot be named
1357
- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1364
+ return symbolAccesibilityResult . errorModuleName ?
1358
1365
Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
1359
1366
Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1 ;
1360
1367
}
1361
- break ;
1362
1368
1363
1369
case SyntaxKind . FunctionDeclaration :
1364
- diagnosticMessage = symbolAccesibilityResult . errorModuleName ?
1370
+ return symbolAccesibilityResult . errorModuleName ?
1365
1371
symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ?
1366
1372
Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
1367
1373
Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
1368
1374
Diagnostics . Parameter_0_of_exported_function_has_or_is_using_private_name_1 ;
1369
- break ;
1370
1375
1371
1376
default :
1372
1377
Debug . fail ( "This is unknown parent for parameter: " + node . parent . kind ) ;
1373
1378
}
1379
+ }
1374
1380
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
+ }
1380
1393
}
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
+ }
1381
1438
}
1382
1439
1383
1440
function emitNode ( node : Node ) {
0 commit comments