From 104dfd4cefe4a4e807891486a0aaa8329c40813e Mon Sep 17 00:00:00 2001 From: ivanwonder Date: Sat, 22 Jul 2023 19:06:27 +0800 Subject: [PATCH] refactor(language-service): support showing tags info in the completion (#51140) The Angular VSCode extension will support showing the tags info in this [PR][1], so the language service can return the tags info now. [1]: https://github.com/angular/vscode-ng-language-service/pull/1904 PR Close #51140 --- packages/language-service/src/completions.ts | 10 ++++- .../language-service/src/display_parts.ts | 40 ++++++++++++++----- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/language-service/src/completions.ts b/packages/language-service/src/completions.ts index a4fc649bf9d..1aef09ca470 100644 --- a/packages/language-service/src/completions.ts +++ b/packages/language-service/src/completions.ts @@ -470,7 +470,7 @@ export class CompletionBuilder { return undefined; } - const {kind, displayParts, documentation} = + const {kind, displayParts, documentation, tags} = getSymbolDisplayInfo(this.tsLS, this.typeChecker, symbol); return { kind: unsafeCastDisplayInfoKindToScriptElementKind(kind), @@ -478,6 +478,7 @@ export class CompletionBuilder { kindModifiers: ts.ScriptElementKindModifier.none, displayParts, documentation, + tags, }; } else { return this.tsLS.getCompletionEntryDetails( @@ -579,12 +580,14 @@ export class CompletionBuilder { const directive = tagMap.get(entryName)!; let displayParts: ts.SymbolDisplayPart[]; let documentation: ts.SymbolDisplayPart[]|undefined = undefined; + let tags: ts.JSDocTagInfo[]|undefined = undefined; if (directive === null) { displayParts = []; } else { const displayInfo = getDirectiveDisplayInfo(this.tsLS, directive); displayParts = displayInfo.displayParts; documentation = displayInfo.documentation; + tags = displayInfo.tags; } return { @@ -593,6 +596,7 @@ export class CompletionBuilder { kindModifiers: ts.ScriptElementKindModifier.none, displayParts, documentation, + tags, }; } @@ -832,6 +836,7 @@ export class CompletionBuilder { const completion = attrTable.get(name)!; let displayParts: ts.SymbolDisplayPart[]; let documentation: ts.SymbolDisplayPart[]|undefined = undefined; + let tags: ts.JSDocTagInfo[]|undefined = undefined; let info: DisplayInfo|null; switch (completion.kind) { case AttributeCompletionKind.DomEvent: @@ -846,6 +851,7 @@ export class CompletionBuilder { info = getDirectiveDisplayInfo(this.tsLS, completion.directive); displayParts = info.displayParts; documentation = info.documentation; + tags = info.tags; break; case AttributeCompletionKind.StructuralDirectiveAttribute: case AttributeCompletionKind.DirectiveInput: @@ -871,6 +877,7 @@ export class CompletionBuilder { } displayParts = info.displayParts; documentation = info.documentation; + tags = info.tags; } return { @@ -879,6 +886,7 @@ export class CompletionBuilder { kindModifiers: ts.ScriptElementKindModifier.none, displayParts, documentation, + tags, }; } diff --git a/packages/language-service/src/display_parts.ts b/packages/language-service/src/display_parts.ts index 15eef06f251..0ee7afc1a96 100644 --- a/packages/language-service/src/display_parts.ts +++ b/packages/language-service/src/display_parts.ts @@ -43,6 +43,7 @@ export interface DisplayInfo { kind: DisplayInfoKind; displayParts: ts.SymbolDisplayPart[]; documentation: ts.SymbolDisplayPart[]|undefined; + tags: ts.JSDocTagInfo[]|undefined; } export function getSymbolDisplayInfo( @@ -61,13 +62,14 @@ export function getSymbolDisplayInfo( const displayParts = createDisplayParts( symbol.declaration.name, kind, /* containerName */ undefined, typeChecker.typeToString(symbol.tsType)); - const documentation = symbol.kind === SymbolKind.Reference ? - getDocumentationFromTypeDefAtLocation(tsLS, symbol.targetLocation) : - getDocumentationFromTypeDefAtLocation(tsLS, symbol.initializerLocation); + const quickInfo = symbol.kind === SymbolKind.Reference ? + getQuickInfoFromTypeDefAtLocation(tsLS, symbol.targetLocation) : + getQuickInfoFromTypeDefAtLocation(tsLS, symbol.initializerLocation); return { kind, displayParts, - documentation, + documentation: quickInfo?.documentation, + tags: quickInfo?.tags, }; } @@ -121,15 +123,14 @@ export function unsafeCastDisplayInfoKindToScriptElementKind(kind: DisplayInfoKi return kind as string as ts.ScriptElementKind; } -function getDocumentationFromTypeDefAtLocation( - tsLS: ts.LanguageService, tcbLocation: TcbLocation): ts.SymbolDisplayPart[]|undefined { +function getQuickInfoFromTypeDefAtLocation( + tsLS: ts.LanguageService, tcbLocation: TcbLocation): ts.QuickInfo|undefined { const typeDefs = tsLS.getTypeDefinitionAtPosition(tcbLocation.tcbPath, tcbLocation.positionInFile); if (typeDefs === undefined || typeDefs.length === 0) { return undefined; } - return tsLS.getQuickInfoAtPosition(typeDefs[0].fileName, typeDefs[0].textSpan.start) - ?.documentation; + return tsLS.getQuickInfoAtPosition(typeDefs[0].fileName, typeDefs[0].textSpan.start); } export function getDirectiveDisplayInfo( @@ -137,12 +138,22 @@ export function getDirectiveDisplayInfo( const kind = dir.isComponent ? DisplayInfoKind.COMPONENT : DisplayInfoKind.DIRECTIVE; const decl = dir.tsSymbol.declarations.find(ts.isClassDeclaration); if (decl === undefined || decl.name === undefined) { - return {kind, displayParts: [], documentation: []}; + return { + kind, + displayParts: [], + documentation: [], + tags: undefined, + }; } const res = tsLS.getQuickInfoAtPosition(decl.getSourceFile().fileName, decl.name.getStart()); if (res === undefined) { - return {kind, displayParts: [], documentation: []}; + return { + kind, + displayParts: [], + documentation: [], + tags: undefined, + }; } const displayParts = @@ -152,6 +163,7 @@ export function getDirectiveDisplayInfo( kind, displayParts, documentation: res.documentation, + tags: res.tags, }; } @@ -167,7 +179,12 @@ export function getTsSymbolDisplayInfo( } const res = tsLS.getQuickInfoAtPosition(decl.getSourceFile().fileName, decl.name.getStart()); if (res === undefined) { - return {kind, displayParts: [], documentation: []}; + return { + kind, + displayParts: [], + documentation: [], + tags: undefined, + }; } const type = checker.getDeclaredTypeOfSymbol(symbol); @@ -179,5 +196,6 @@ export function getTsSymbolDisplayInfo( kind, displayParts, documentation: res.documentation, + tags: res.tags, }; }