Skip to content

Commit b211fe9

Browse files
authored
Fixed quick info display for aliased symbols in type-narrowed locations (#54763)
1 parent 2136bef commit b211fe9

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/services/symbolDisplay.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,18 +254,15 @@ export interface SymbolDisplayPartsDocumentationAndSymbolKind {
254254
tags: JSDocTagInfo[] | undefined;
255255
}
256256

257-
// TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
258-
/** @internal */
259-
export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node | undefined,
260-
location: Node, semanticMeaning = getMeaningFromLocation(location), alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind {
257+
function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node | undefined,
258+
location: Node, type: Type | undefined, semanticMeaning: SemanticMeaning, alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind {
261259
const displayParts: SymbolDisplayPart[] = [];
262260
let documentation: SymbolDisplayPart[] = [];
263261
let tags: JSDocTagInfo[] = [];
264262
const symbolFlags = getCombinedLocalAndExportSymbolFlags(symbol);
265263
let symbolKind = semanticMeaning & SemanticMeaning.Value ? getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) : ScriptElementKind.unknown;
266264
let hasAddedSymbolInfo = false;
267265
const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isInExpressionContext(location) || isThisInTypeQuery(location);
268-
let type: Type | undefined;
269266
let documentationFromAlias: SymbolDisplayPart[] | undefined;
270267
let tagsFromAlias: JSDocTagInfo[] | undefined;
271268
let hasMultipleSignatures = false;
@@ -300,7 +297,7 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: Typ
300297
}
301298

302299
let signature: Signature | undefined;
303-
type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol, location);
300+
type ??= isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol, location);
304301

305302
if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) {
306303
const right = (location.parent as PropertyAccessExpression).name;
@@ -553,12 +550,13 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: Typ
553550
isModuleWithStringLiteralName(resolvedNode) &&
554551
hasSyntacticModifier(resolvedNode, ModifierFlags.Ambient);
555552
const shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration;
556-
const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind(
553+
const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKindWorker(
557554
typeChecker,
558555
resolvedSymbol,
559556
getSourceFileOfNode(resolvedNode),
560557
resolvedNode,
561558
declarationName,
559+
type,
562560
semanticMeaning,
563561
shouldUseAliasName ? symbol : resolvedSymbol);
564562
displayParts.push(...resolvedInfo.displayParts);
@@ -858,6 +856,13 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: Typ
858856
}
859857
}
860858

859+
// TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
860+
/** @internal */
861+
export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node | undefined,
862+
location: Node, semanticMeaning = getMeaningFromLocation(location), alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind {
863+
return getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker, symbol, sourceFile, enclosingDeclaration, location, /*type*/ undefined, semanticMeaning, alias);
864+
}
865+
861866
function isLocalVariableOrFunction(symbol: Symbol) {
862867
if (symbol.parent) {
863868
return false; // This is exported symbol
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/// <reference path='fourslash.ts' />
2+
// @strict: true
3+
4+
// @Filename: modules.ts
5+
//// export declare const someEnv: string | undefined;
6+
7+
// @Filename: app.ts
8+
//// import { someEnv } from "./modules";
9+
//// declare function isString(v: any): v is string;
10+
////
11+
//// if (isString(someEnv)) {
12+
//// someEnv/*1*/.charAt(0);
13+
//// }
14+
15+
goTo.file("app.ts");
16+
goTo.marker("1");
17+
verify.quickInfoIs(`(alias) const someEnv: string\nimport someEnv`);

0 commit comments

Comments
 (0)