@@ -1489,19 +1489,6 @@ namespace ts {
1489
1489
}
1490
1490
}
1491
1491
1492
- function getSymbolAtLocationForQuickInfo ( node : Node , checker : TypeChecker ) : Symbol | undefined {
1493
- if ( ( isIdentifier ( node ) || isStringLiteral ( node ) )
1494
- && isPropertyAssignment ( node . parent )
1495
- && node . parent . name === node ) {
1496
- const type = checker . getContextualType ( node . parent . parent ) ;
1497
- const property = type && checker . getPropertyOfType ( type , getTextOfIdentifierOrLiteral ( node ) ) ;
1498
- if ( property ) {
1499
- return property ;
1500
- }
1501
- }
1502
- return checker . getSymbolAtLocation ( node ) ;
1503
- }
1504
-
1505
1492
/// Goto definition
1506
1493
function getDefinitionAtPosition ( fileName : string , position : number ) : DefinitionInfo [ ] | undefined {
1507
1494
synchronizeHostData ( ) ;
@@ -2187,28 +2174,60 @@ namespace ts {
2187
2174
*/
2188
2175
/* @internal */
2189
2176
export function getContainingObjectLiteralElement ( node : Node ) : ObjectLiteralElementWithName | undefined {
2177
+ const element = getContainingObjectLiteralElementWorker ( node ) ;
2178
+ return element && ( isObjectLiteralExpression ( element . parent ) || isJsxAttributes ( element . parent ) ) ? element as ObjectLiteralElementWithName : undefined ;
2179
+ }
2180
+ function getContainingObjectLiteralElementWorker ( node : Node ) : ObjectLiteralElement | undefined {
2190
2181
switch ( node . kind ) {
2191
2182
case SyntaxKind . StringLiteral :
2192
2183
case SyntaxKind . NumericLiteral :
2193
2184
if ( node . parent . kind === SyntaxKind . ComputedPropertyName ) {
2194
- return isObjectLiteralElement ( node . parent . parent ) ? node . parent . parent as ObjectLiteralElementWithName : undefined ;
2185
+ return isObjectLiteralElement ( node . parent . parent ) ? node . parent . parent : undefined ;
2195
2186
}
2196
2187
// falls through
2197
2188
case SyntaxKind . Identifier :
2198
2189
return isObjectLiteralElement ( node . parent ) &&
2199
2190
( node . parent . parent . kind === SyntaxKind . ObjectLiteralExpression || node . parent . parent . kind === SyntaxKind . JsxAttributes ) &&
2200
- node . parent . name === node ? node . parent as ObjectLiteralElementWithName : undefined ;
2191
+ node . parent . name === node ? node . parent : undefined ;
2201
2192
}
2202
2193
return undefined ;
2203
2194
}
2195
+
2204
2196
/* @internal */
2205
- export type ObjectLiteralElementWithName = ObjectLiteralElement & { name : PropertyName } ;
2197
+ export type ObjectLiteralElementWithName = ObjectLiteralElement & { name : PropertyName ; parent : ObjectLiteralExpression | JsxAttributes } ;
2198
+
2199
+ function getSymbolAtLocationForQuickInfo ( node : Node , checker : TypeChecker ) : Symbol | undefined {
2200
+ const object = getContainingObjectLiteralElement ( node ) ;
2201
+ if ( object ) {
2202
+ const contextualType = checker . getContextualType ( object . parent ) ;
2203
+ const properties = contextualType && getPropertySymbolsFromContextualType ( object , checker , contextualType , /*unionSymbolOk*/ false ) ;
2204
+ if ( properties && properties . length === 1 ) {
2205
+ return first ( properties ) ;
2206
+ }
2207
+ }
2208
+ return checker . getSymbolAtLocation ( node ) ;
2209
+ }
2206
2210
2211
+ /** Gets all symbols for one property. Does not get symbols for every property. */
2207
2212
/* @internal */
2208
- export function getPropertySymbolsFromContextualType ( typeChecker : TypeChecker , node : ObjectLiteralElement ) : Symbol [ ] {
2209
- const objectLiteral = < ObjectLiteralExpression | JsxAttributes > node . parent ;
2210
- const contextualType = typeChecker . getContextualType ( objectLiteral ) ! ; // TODO: GH#18217
2211
- return getPropertySymbolsFromType ( contextualType , node . name ! ) ! ; // TODO: GH#18217
2213
+ export function getPropertySymbolsFromContextualType ( node : ObjectLiteralElementWithName , checker : TypeChecker , contextualType : Type , unionSymbolOk : boolean ) : ReadonlyArray < Symbol > {
2214
+ const name = getNameFromPropertyName ( node . name ) ;
2215
+ if ( ! name ) return emptyArray ;
2216
+ if ( ! contextualType . isUnion ( ) ) {
2217
+ const symbol = contextualType . getProperty ( name ) ;
2218
+ return symbol ? [ symbol ] : emptyArray ;
2219
+ }
2220
+
2221
+ const discriminatedPropertySymbols = mapDefined ( contextualType . types , t => isObjectLiteralExpression ( node . parent ) && checker . isTypeInvalidDueToUnionDiscriminant ( t , node . parent ) ? undefined : t . getProperty ( name ) ) ;
2222
+ if ( unionSymbolOk && ( discriminatedPropertySymbols . length === 0 || discriminatedPropertySymbols . length === contextualType . types . length ) ) {
2223
+ const symbol = contextualType . getProperty ( name ) ;
2224
+ if ( symbol ) return [ symbol ] ;
2225
+ }
2226
+ if ( discriminatedPropertySymbols . length === 0 ) {
2227
+ // Bad discriminant -- do again without discriminating
2228
+ return mapDefined ( contextualType . types , t => t . getProperty ( name ) ) ;
2229
+ }
2230
+ return discriminatedPropertySymbols ;
2212
2231
}
2213
2232
2214
2233
/* @internal */
0 commit comments