refactor(language-service): Consistent naming between ts and ng LanguageService (#34888)
This commit makes the Angular Language Service interface a strict subset of TypeScript's Language Service by renaming all methods to be consistent with TypeScript's. The custom Angular `LanguageService` interface was needed before the inception of TypeScript tsserver plugin, but is now obsolete since Angular LS is a proper tsserver plugin. This allows us to easily adapt to upstream TS changes in the future, and also allows us to reuse all data types defined in TypeScript. PR Close #34888
This commit is contained in:

committed by
Matias Niemelä

parent
84d24c08e1
commit
f723a27a71
@ -12,7 +12,7 @@ import {getTemplateCompletions} from './completions';
|
||||
import {getDefinitionAndBoundSpan, getTsDefinitionAndBoundSpan} from './definitions';
|
||||
import {getDeclarationDiagnostics, getTemplateDiagnostics, ngDiagnosticToTsDiagnostic, uniqueBySpan} from './diagnostics';
|
||||
import {getHover, getTsHover} from './hover';
|
||||
import {Diagnostic, LanguageService} from './types';
|
||||
import * as ng from './types';
|
||||
import {TypeScriptServiceHost} from './typescript_host';
|
||||
|
||||
/**
|
||||
@ -20,16 +20,16 @@ import {TypeScriptServiceHost} from './typescript_host';
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function createLanguageService(host: TypeScriptServiceHost): LanguageService {
|
||||
export function createLanguageService(host: TypeScriptServiceHost) {
|
||||
return new LanguageServiceImpl(host);
|
||||
}
|
||||
|
||||
class LanguageServiceImpl implements LanguageService {
|
||||
class LanguageServiceImpl implements ng.LanguageService {
|
||||
constructor(private readonly host: TypeScriptServiceHost) {}
|
||||
|
||||
getDiagnostics(fileName: string): tss.Diagnostic[] {
|
||||
getSemanticDiagnostics(fileName: string): tss.Diagnostic[] {
|
||||
const analyzedModules = this.host.getAnalyzedModules(); // same role as 'synchronizeHostData'
|
||||
const results: Diagnostic[] = [];
|
||||
const results: ng.Diagnostic[] = [];
|
||||
const templates = this.host.getTemplates(fileName);
|
||||
|
||||
for (const template of templates) {
|
||||
@ -48,7 +48,9 @@ class LanguageServiceImpl implements LanguageService {
|
||||
return uniqueBySpan(results).map(d => ngDiagnosticToTsDiagnostic(d, sourceFile));
|
||||
}
|
||||
|
||||
getCompletionsAt(fileName: string, position: number): tss.CompletionInfo|undefined {
|
||||
getCompletionsAtPosition(
|
||||
fileName: string, position: number,
|
||||
options?: tss.GetCompletionsAtPositionOptions): tss.CompletionInfo|undefined {
|
||||
this.host.getAnalyzedModules(); // same role as 'synchronizeHostData'
|
||||
const ast = this.host.getTemplateAstAtPosition(fileName, position);
|
||||
if (!ast) {
|
||||
@ -67,7 +69,8 @@ class LanguageServiceImpl implements LanguageService {
|
||||
};
|
||||
}
|
||||
|
||||
getDefinitionAt(fileName: string, position: number): tss.DefinitionInfoAndBoundSpan|undefined {
|
||||
getDefinitionAndBoundSpan(fileName: string, position: number): tss.DefinitionInfoAndBoundSpan
|
||||
|undefined {
|
||||
this.host.getAnalyzedModules(); // same role as 'synchronizeHostData'
|
||||
const templateInfo = this.host.getTemplateAstAtPosition(fileName, position);
|
||||
if (templateInfo) {
|
||||
@ -84,7 +87,7 @@ class LanguageServiceImpl implements LanguageService {
|
||||
}
|
||||
}
|
||||
|
||||
getHoverAt(fileName: string, position: number): tss.QuickInfo|undefined {
|
||||
getQuickInfoAtPosition(fileName: string, position: number): tss.QuickInfo|undefined {
|
||||
this.host.getAnalyzedModules(); // same role as 'synchronizeHostData'
|
||||
const templateInfo = this.host.getTemplateAstAtPosition(fileName, position);
|
||||
if (templateInfo) {
|
||||
|
@ -36,7 +36,7 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
return ngLS.getCompletionsAt(fileName, position);
|
||||
return ngLS.getCompletionsAtPosition(fileName, position, options);
|
||||
}
|
||||
|
||||
function getQuickInfoAtPosition(fileName: string, position: number): tss.QuickInfo|undefined {
|
||||
@ -47,7 +47,7 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return ngLS.getHoverAt(fileName, position);
|
||||
return ngLS.getQuickInfoAtPosition(fileName, position);
|
||||
}
|
||||
|
||||
function getSemanticDiagnostics(fileName: string): tss.Diagnostic[] {
|
||||
@ -56,7 +56,7 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
|
||||
results.push(...tsLS.getSemanticDiagnostics(fileName));
|
||||
}
|
||||
// For semantic diagnostics we need to combine both TS + Angular results
|
||||
results.push(...ngLS.getDiagnostics(fileName));
|
||||
results.push(...ngLS.getSemanticDiagnostics(fileName));
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
const result = ngLS.getDefinitionAt(fileName, position);
|
||||
const result = ngLS.getDefinitionAndBoundSpan(fileName, position);
|
||||
if (!result || !result.definitions || !result.definitions.length) {
|
||||
return;
|
||||
}
|
||||
@ -85,7 +85,7 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return ngLS.getDefinitionAt(fileName, position);
|
||||
return ngLS.getDefinitionAndBoundSpan(fileName, position);
|
||||
}
|
||||
|
||||
const proxy: tss.LanguageService = Object.assign(
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {CompileDirectiveMetadata, NgAnalyzedModules, StaticSymbol} from '@angular/compiler';
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import {AstResult} from './common';
|
||||
import {BuiltinType, DeclarationKind, Definition, PipeInfo, Pipes, Signature, Span, Symbol, SymbolDeclaration, SymbolQuery, SymbolTable} from './symbols';
|
||||
|
||||
@ -354,48 +354,12 @@ export interface Hover {
|
||||
/**
|
||||
* An instance of an Angular language service created by `createLanguageService()`.
|
||||
*
|
||||
* The language service returns information about Angular templates that are included in a project
|
||||
* as defined by the `LanguageServiceHost`.
|
||||
*
|
||||
* When a method expects a `fileName` this file can either be source file in the project that
|
||||
* contains a template in a string literal or a template file referenced by the project returned
|
||||
* by `getTemplateReference()`. All other files will cause the method to return `undefined`.
|
||||
*
|
||||
* If a method takes a `position`, it is the offset of the UTF-16 code-point relative to the
|
||||
* beginning of the file reference by `fileName`.
|
||||
*
|
||||
* This interface and all interfaces and types marked as `LanguageService` types, describe a
|
||||
* particular implementation of the Angular language service and is not intended to be
|
||||
* implemented. Adding members to the interface will not be considered a breaking change as
|
||||
* defined by SemVer.
|
||||
*
|
||||
* Removing a member or making a member optional, changing a method parameters, or changing a
|
||||
* member's type will all be considered a breaking change.
|
||||
*
|
||||
* While an interface is marked as experimental breaking-changes will be allowed between minor
|
||||
* releases. After an interface is marked as stable breaking-changes will only be allowed between
|
||||
* major releases. No breaking changes are allowed between patch releases.
|
||||
* The Angular language service implements a subset of methods defined in
|
||||
* The Angular language service implements a subset of methods defined by
|
||||
* the TypeScript language service.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export interface LanguageService {
|
||||
/**
|
||||
* Returns a list of all error for all templates in the given file.
|
||||
*/
|
||||
getDiagnostics(fileName: string): ts.Diagnostic[];
|
||||
|
||||
/**
|
||||
* Return the completions at the given position.
|
||||
*/
|
||||
getCompletionsAt(fileName: string, position: number): ts.CompletionInfo|undefined;
|
||||
|
||||
/**
|
||||
* Return the definition location for the symbol at position.
|
||||
*/
|
||||
getDefinitionAt(fileName: string, position: number): ts.DefinitionInfoAndBoundSpan|undefined;
|
||||
|
||||
/**
|
||||
* Return the hover information for the symbol at position.
|
||||
*/
|
||||
getHoverAt(fileName: string, position: number): ts.QuickInfo|undefined;
|
||||
}
|
||||
export type LanguageService = Pick<
|
||||
ts.LanguageService, 'getCompletionsAtPosition'|'getDefinitionAndBoundSpan'|
|
||||
'getQuickInfoAtPosition'|'getSemanticDiagnostics'>;
|
||||
|
Reference in New Issue
Block a user