fix(language-service): Make Definition and QuickInfo compatible with TS LS (#31972)

Now that the Angular LS is a proper tsserver plugin, it does not make
sense for it to maintain its own language service API.

This is part one of the effort to remove our custom LanguageService
interface.
This interface is cumbersome because we have to do two transformations:
  ng def -> ts def -> lsp definition

The TS LS interface is more comprehensive, so this allows the Angular LS
to return more information.

PR Close #31972
This commit is contained in:
Keen Yee Liau
2019-08-01 13:07:32 -07:00
committed by Alex Rickabaugh
parent e906a4f0d8
commit a8e2ee1343
10 changed files with 442 additions and 260 deletions

View File

@ -6,23 +6,42 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {TemplateInfo} from './common';
import {locateSymbol} from './locate_symbol';
import {Hover, HoverTextSection, Symbol} from './types';
export function getHover(info: TemplateInfo): Hover|undefined {
const result = locateSymbol(info);
if (result) {
return {text: hoverTextOf(result.symbol), span: result.span};
// Reverse mappings of enum would generate strings
const SYMBOL_SPACE = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.space];
const SYMBOL_PUNC = ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.punctuation];
export function getHover(info: TemplateInfo): ts.QuickInfo|undefined {
const symbolInfo = locateSymbol(info);
if (!symbolInfo) {
return;
}
const {symbol, span} = symbolInfo;
const containerDisplayParts: ts.SymbolDisplayPart[] = symbol.container ?
[
{text: symbol.container.name, kind: symbol.container.kind},
{text: '.', kind: SYMBOL_PUNC},
] :
[];
return {
kind: symbol.kind as ts.ScriptElementKind,
kindModifiers: '', // kindModifier info not available on 'ng.Symbol'
textSpan: {
start: span.start,
length: span.end - span.start,
},
// this would generate a string like '(property) ClassX.propY'
// 'kind' in displayParts does not really matter because it's dropped when
// displayParts get converted to string.
displayParts: [
{text: '(', kind: SYMBOL_PUNC}, {text: symbol.kind, kind: symbol.kind},
{text: ')', kind: SYMBOL_PUNC}, {text: ' ', kind: SYMBOL_SPACE}, ...containerDisplayParts,
{text: symbol.name, kind: symbol.kind},
// TODO: Append type info as well, but Symbol doesn't expose that!
// Ideally hover text should be like '(property) ClassX.propY: string'
],
};
}
function hoverTextOf(symbol: Symbol): HoverTextSection[] {
const result: HoverTextSection[] =
[{text: symbol.kind}, {text: ' '}, {text: symbol.name, language: symbol.language}];
const container = symbol.container;
if (container) {
result.push({text: ' of '}, {text: container.name, language: container.language});
}
return result;
}