Skip to content

Commit 56fc112

Browse files
committed
add more information to quickinfo for imported symbols
1 parent e3a20e7 commit 56fc112

File tree

49 files changed

+958
-138
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+958
-138
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ internal/
5858
!tests/baselines/reference/project/nodeModules*/**/*
5959
.idea
6060
yarn.lock
61+
yarn-error.log
6162
.parallelperf.*
6263
tests/cases/user/*/package-lock.json
6364
tests/cases/user/*/node_modules/

src/services/symbolDisplay.ts

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ namespace ts.SymbolDisplay {
105105

106106
// TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
107107
export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node,
108-
location: Node, semanticMeaning = getMeaningFromLocation(location)): SymbolDisplayPartsDocumentationAndSymbolKind {
108+
location: Node, semanticMeaning = getMeaningFromLocation(location), alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind {
109109

110110
const displayParts: SymbolDisplayPart[] = [];
111111
let documentation: SymbolDisplayPart[];
@@ -115,6 +115,7 @@ namespace ts.SymbolDisplay {
115115
let hasAddedSymbolInfo: boolean;
116116
const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isExpression(location);
117117
let type: Type;
118+
let documentationFromAlias: SymbolDisplayPart[];
118119

119120
// Class at constructor site need to be shown as constructor apart from property,method, vars
120121
if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) {
@@ -243,6 +244,7 @@ namespace ts.SymbolDisplay {
243244
}
244245
}
245246
if (symbolFlags & SymbolFlags.Class && !hasAddedSymbolInfo && !isThisExpression) {
247+
addAliasPrefixIfNecessary();
246248
if (getDeclarationOfKind(symbol, SyntaxKind.ClassExpression)) {
247249
// Special case for class expressions because we would like to indicate that
248250
// the class name is local to the class body (similar to function expression)
@@ -258,14 +260,14 @@ namespace ts.SymbolDisplay {
258260
writeTypeParametersOfSymbol(symbol, sourceFile);
259261
}
260262
if ((symbolFlags & SymbolFlags.Interface) && (semanticMeaning & SemanticMeaning.Type)) {
261-
addNewLineIfDisplayPartsExist();
263+
prefixNextMeaning();
262264
displayParts.push(keywordPart(SyntaxKind.InterfaceKeyword));
263265
displayParts.push(spacePart());
264266
addFullSymbolName(symbol);
265267
writeTypeParametersOfSymbol(symbol, sourceFile);
266268
}
267269
if (symbolFlags & SymbolFlags.TypeAlias) {
268-
addNewLineIfDisplayPartsExist();
270+
prefixNextMeaning();
269271
displayParts.push(keywordPart(SyntaxKind.TypeKeyword));
270272
displayParts.push(spacePart());
271273
addFullSymbolName(symbol);
@@ -276,7 +278,7 @@ namespace ts.SymbolDisplay {
276278
addRange(displayParts, typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, TypeFormatFlags.InTypeAlias));
277279
}
278280
if (symbolFlags & SymbolFlags.Enum) {
279-
addNewLineIfDisplayPartsExist();
281+
prefixNextMeaning();
280282
if (forEach(symbol.declarations, isConstEnumDeclaration)) {
281283
displayParts.push(keywordPart(SyntaxKind.ConstKeyword));
282284
displayParts.push(spacePart());
@@ -286,15 +288,15 @@ namespace ts.SymbolDisplay {
286288
addFullSymbolName(symbol);
287289
}
288290
if (symbolFlags & SymbolFlags.Module) {
289-
addNewLineIfDisplayPartsExist();
291+
prefixNextMeaning();
290292
const declaration = getDeclarationOfKind<ModuleDeclaration>(symbol, SyntaxKind.ModuleDeclaration);
291293
const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier;
292294
displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword));
293295
displayParts.push(spacePart());
294296
addFullSymbolName(symbol);
295297
}
296298
if ((symbolFlags & SymbolFlags.TypeParameter) && (semanticMeaning & SemanticMeaning.Type)) {
297-
addNewLineIfDisplayPartsExist();
299+
prefixNextMeaning();
298300
displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
299301
displayParts.push(textPart("type parameter"));
300302
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
@@ -354,7 +356,32 @@ namespace ts.SymbolDisplay {
354356
}
355357
}
356358
if (symbolFlags & SymbolFlags.Alias) {
357-
addNewLineIfDisplayPartsExist();
359+
prefixNextMeaning();
360+
if (!hasAddedSymbolInfo) {
361+
const resolvedSymbol = typeChecker.getAliasedSymbol(symbol);
362+
if (resolvedSymbol !== symbol && resolvedSymbol.declarations && resolvedSymbol.declarations.length > 0) {
363+
const resolvedNode = resolvedSymbol.declarations[0];
364+
const declarationName = ts.getNameOfDeclaration(resolvedNode);
365+
if (declarationName) {
366+
const isExternalModuleDeclaration =
367+
ts.isModuleWithStringLiteralName(resolvedNode) &&
368+
ts.hasModifier(resolvedNode, ModifierFlags.Ambient);
369+
const shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration;
370+
const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind(
371+
typeChecker,
372+
resolvedSymbol,
373+
ts.getSourceFileOfNode(resolvedNode),
374+
resolvedNode,
375+
declarationName,
376+
semanticMeaning,
377+
shouldUseAliasName ? symbol : resolvedSymbol);
378+
displayParts.push(...resolvedInfo.displayParts);
379+
displayParts.push(lineBreakPart());
380+
documentationFromAlias = resolvedInfo.documentation;
381+
}
382+
}
383+
}
384+
358385
switch (symbol.declarations[0].kind) {
359386
case SyntaxKind.NamespaceExportDeclaration:
360387
displayParts.push(keywordPart(SyntaxKind.ExportKeyword));
@@ -400,7 +427,7 @@ namespace ts.SymbolDisplay {
400427
if (symbolKind !== ScriptElementKind.unknown) {
401428
if (type) {
402429
if (isThisExpression) {
403-
addNewLineIfDisplayPartsExist();
430+
prefixNextMeaning();
404431
displayParts.push(keywordPart(SyntaxKind.ThisKeyword));
405432
}
406433
else {
@@ -472,12 +499,24 @@ namespace ts.SymbolDisplay {
472499
}
473500
}
474501

502+
if (documentation.length === 0 && documentationFromAlias) {
503+
documentation = documentationFromAlias;
504+
}
505+
475506
return { displayParts, documentation, symbolKind, tags };
476507

477-
function addNewLineIfDisplayPartsExist() {
508+
function prefixNextMeaning() {
478509
if (displayParts.length) {
479510
displayParts.push(lineBreakPart());
480511
}
512+
addAliasPrefixIfNecessary();
513+
}
514+
515+
function addAliasPrefixIfNecessary() {
516+
if (alias) {
517+
pushTypePart(ScriptElementKind.alias);
518+
displayParts.push(spacePart());
519+
}
481520
}
482521

483522
function addInPrefix() {
@@ -486,14 +525,17 @@ namespace ts.SymbolDisplay {
486525
displayParts.push(spacePart());
487526
}
488527

489-
function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) {
490-
const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined,
528+
function addFullSymbolName(symbolToDisplay: Symbol, enclosingDeclaration?: Node) {
529+
if (alias && symbolToDisplay === symbol) {
530+
symbolToDisplay = alias;
531+
}
532+
const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined,
491533
SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing);
492534
addRange(displayParts, fullSymbolDisplayParts);
493535
}
494536

495537
function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) {
496-
addNewLineIfDisplayPartsExist();
538+
prefixNextMeaning();
497539
if (symbolKind) {
498540
pushTypePart(symbolKind);
499541
if (symbol && !some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) {

0 commit comments

Comments
 (0)