@@ -1117,15 +1117,19 @@ namespace ts.Completions {
1117
1117
}
1118
1118
1119
1119
function addPropertySymbol ( symbol : Symbol ) {
1120
+ // For a computed property with an accessible name like `Symbol.iterator`,
1121
+ // we'll add a completion for the *name* `Symbol` instead of for the property.
1120
1122
// If this is e.g. [Symbol.iterator], add a completion for `Symbol`.
1121
- const symbolSymbol = firstDefined ( symbol . declarations , decl => {
1122
- const name = getNameOfDeclaration ( decl ) ;
1123
- const leftName = name && name . kind === SyntaxKind . ComputedPropertyName ? getLeftMostName ( name . expression ) : undefined ;
1124
- return leftName && typeChecker . getSymbolAtLocation ( leftName ) ;
1125
- } ) ;
1126
- if ( symbolSymbol ) {
1127
- symbols . push ( symbolSymbol ) ;
1128
- symbolToOriginInfoMap [ getSymbolId ( symbolSymbol ) ] = { type : "symbol-member" } ;
1123
+ const computedPropertyName = firstDefined ( symbol . declarations , decl => tryCast ( getNameOfDeclaration ( decl ) , isComputedPropertyName ) ) ;
1124
+ if ( computedPropertyName ) {
1125
+ const leftMostName = getLeftMostName ( computedPropertyName . expression ) ; // The completion is for `Symbol`, not `iterator`.
1126
+ const nameSymbol = leftMostName && typeChecker . getSymbolAtLocation ( leftMostName ) ;
1127
+ // If this is nested like for `namespace N { export const sym = Symbol(); }`, we'll add the completion for `N`.
1128
+ const firstAccessibleSymbol = nameSymbol && getFirstSymbolInChain ( nameSymbol , contextToken , typeChecker ) ;
1129
+ if ( firstAccessibleSymbol && ! symbolToOriginInfoMap [ getSymbolId ( firstAccessibleSymbol ) ] ) {
1130
+ symbols . push ( firstAccessibleSymbol ) ;
1131
+ symbolToOriginInfoMap [ getSymbolId ( firstAccessibleSymbol ) ] = { type : "symbol-member" } ;
1132
+ }
1129
1133
}
1130
1134
else {
1131
1135
symbols . push ( symbol ) ;
0 commit comments