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
This commit is contained in:
ivanwonder 2023-07-22 19:06:27 +08:00 committed by Jessica Janiuk
parent f824911510
commit 104dfd4cef
2 changed files with 38 additions and 12 deletions

View file

@ -470,7 +470,7 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
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<N extends TmplAstNode|AST> {
kindModifiers: ts.ScriptElementKindModifier.none,
displayParts,
documentation,
tags,
};
} else {
return this.tsLS.getCompletionEntryDetails(
@ -579,12 +580,14 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
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<N extends TmplAstNode|AST> {
kindModifiers: ts.ScriptElementKindModifier.none,
displayParts,
documentation,
tags,
};
}
@ -832,6 +836,7 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
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<N extends TmplAstNode|AST> {
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<N extends TmplAstNode|AST> {
}
displayParts = info.displayParts;
documentation = info.documentation;
tags = info.tags;
}
return {
@ -879,6 +886,7 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
kindModifiers: ts.ScriptElementKindModifier.none,
displayParts,
documentation,
tags,
};
}

View file

@ -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,
};
}