diff --git a/goldens/circular-deps/packages.json b/goldens/circular-deps/packages.json index 06e4b0d60b..cae92bc971 100644 --- a/goldens/circular-deps/packages.json +++ b/goldens/circular-deps/packages.json @@ -382,12 +382,6 @@ "packages/forms/src/directives/validators.ts", "packages/forms/src/validators.ts" ], - [ - "packages/language-service/src/completions.ts", - "packages/language-service/src/template.ts", - "packages/language-service/src/typescript_host.ts", - "packages/language-service/src/language_service.ts" - ], [ "packages/language-service/src/template.ts", "packages/language-service/src/typescript_host.ts" diff --git a/packages/language-service/BUILD.bazel b/packages/language-service/BUILD.bazel index 1f2f3338dc..4a741ba60c 100644 --- a/packages/language-service/BUILD.bazel +++ b/packages/language-service/BUILD.bazel @@ -2,11 +2,20 @@ load("//tools:defaults.bzl", "pkg_npm", "ts_library") package(default_visibility = ["//visibility:public"]) +ts_library( + name = "api", + srcs = [ + "api.ts", + ], + deps = [ + "@npm//typescript", + ], +) + ts_library( name = "language-service", - srcs = glob( + srcs = ["index.ts"] + glob( [ - "*.ts", "src/**/*.ts", ], exclude = [ @@ -14,6 +23,7 @@ ts_library( ], ), deps = [ + ":api", ":ts_utils", "//packages:types", "//packages/compiler", diff --git a/packages/language-service/api.ts b/packages/language-service/api.ts new file mode 100644 index 0000000000..b74bc200d2 --- /dev/null +++ b/packages/language-service/api.ts @@ -0,0 +1,42 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +/** + * @module + * @description + * Entry point for all public APIs of the language service package. + */ + +import * as ts from 'typescript'; + +export type GetTcbResponse = { + /** + * The filename of the SourceFile this typecheck block belongs to. + * The filename is entirely opaque and unstable, useful only for debugging + * purposes. + */ + fileName: string, + /** The content of the SourceFile this typecheck block belongs to. */ + content: string, + /** + * Spans over node(s) in the typecheck block corresponding to the + * TS code generated for template node under the current cursor position. + * + * When the cursor position is over a source for which there is no generated + * code, `selections` is empty. + */ + selections: ts.TextSpan[], +}|undefined; + +/** + * `NgLanguageService` describes an instance of an Angular language service, + * whose API surface is a strict superset of TypeScript's language service. + */ +export interface NgLanguageService extends ts.LanguageService { + getTcb(fileName: string, position: number): GetTcbResponse; +} diff --git a/packages/language-service/index.ts b/packages/language-service/index.ts index 89b3d0566a..0ed58aaa34 100644 --- a/packages/language-service/index.ts +++ b/packages/language-service/index.ts @@ -6,4 +6,5 @@ * found in the LICENSE file at https://angular.io/license */ -export * from './language-service'; +export * from './api'; +export {create, getExternalFiles} from './src/ts_plugin'; diff --git a/packages/language-service/ivy/BUILD.bazel b/packages/language-service/ivy/BUILD.bazel index 0a7aa1cb78..e87b920172 100644 --- a/packages/language-service/ivy/BUILD.bazel +++ b/packages/language-service/ivy/BUILD.bazel @@ -20,6 +20,7 @@ ts_library( "//packages/compiler-cli/src/ngtsc/typecheck", "//packages/compiler-cli/src/ngtsc/typecheck/api", "//packages/compiler-cli/src/ngtsc/util", + "//packages/language-service:api", "@npm//@types/node", "@npm//typescript", ], diff --git a/packages/language-service/ivy/language_service.ts b/packages/language-service/ivy/language_service.ts index 1b3a199b48..a69135b3f2 100644 --- a/packages/language-service/ivy/language_service.ts +++ b/packages/language-service/ivy/language_service.ts @@ -15,6 +15,7 @@ import {TypeCheckShimGenerator} from '@angular/compiler-cli/src/ngtsc/typecheck' import {OptimizeFor, TypeCheckingProgramStrategy} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; import {findFirstMatchingNode} from '@angular/compiler-cli/src/ngtsc/typecheck/src/comments'; import * as ts from 'typescript/lib/tsserverlibrary'; +import {GetTcbResponse} from '../api'; import {LanguageServiceAdapter, LSParseConfigHost} from './adapters'; import {CompilerFactory} from './compiler_factory'; @@ -25,25 +26,6 @@ import {ReferencesAndRenameBuilder} from './references'; import {getTargetAtPosition, TargetContext, TargetNodeKind} from './template_target'; import {getTemplateInfoAtPosition, isTypeScriptFile} from './utils'; -export type GetTcbResponse = { - /** - * The filename of the SourceFile this typecheck block belongs to. - * The filename is entirely opaque and unstable, useful only for debugging - * purposes. - */ - fileName: string, - /** The content of the SourceFile this typecheck block belongs to. */ - content: string, - /** - * Spans over node(s) in the typecheck block corresponding to the - * TS code generated for template node under the current cursor position. - * - * When the cursor position is over a source for which there is no generated - * code, `selections` is empty. - */ - selections: ts.TextSpan[], -}|undefined; - export class LanguageService { private options: CompilerOptions; readonly compilerFactory: CompilerFactory; diff --git a/packages/language-service/ivy/ts_plugin.ts b/packages/language-service/ivy/ts_plugin.ts index 89f4c27a13..a4c9b08e5e 100644 --- a/packages/language-service/ivy/ts_plugin.ts +++ b/packages/language-service/ivy/ts_plugin.ts @@ -7,11 +7,8 @@ */ import * as ts from 'typescript/lib/tsserverlibrary'; -import {GetTcbResponse, LanguageService} from './language_service'; - -export interface NgLanguageService extends ts.LanguageService { - getTcb(fileName: string, position: number): GetTcbResponse; -} +import {GetTcbResponse, NgLanguageService} from '../api'; +import {LanguageService} from './language_service'; export function create(info: ts.server.PluginCreateInfo): NgLanguageService { const {project, languageService: tsLS, config} = info; diff --git a/packages/language-service/language-service.ts b/packages/language-service/language-service.ts deleted file mode 100644 index 4b37605cf5..0000000000 --- a/packages/language-service/language-service.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -/// - -/** - * @module - * @description - * Entry point for all public APIs of the language service package. - */ -export {createLanguageService} from './src/language_service'; -export * from './src/ts_plugin'; -export {Declaration, Definition, Diagnostic, LanguageService, LanguageServiceHost, Span, TemplateSource} from './src/types'; -export {TypeScriptServiceHost, createLanguageServiceFromTypescript} from './src/typescript_host'; diff --git a/packages/language-service/src/language_service.ts b/packages/language-service/src/language_service.ts index 177a73f0d6..b26f499471 100644 --- a/packages/language-service/src/language_service.ts +++ b/packages/language-service/src/language_service.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import * as path from 'path'; import * as tss from 'typescript/lib/tsserverlibrary'; import {getTemplateCompletions} from './completions'; diff --git a/packages/language-service/src/ts_plugin.ts b/packages/language-service/src/ts_plugin.ts index 4320a7d553..fea31a3e28 100644 --- a/packages/language-service/src/ts_plugin.ts +++ b/packages/language-service/src/ts_plugin.ts @@ -7,6 +7,7 @@ */ import * as tss from 'typescript/lib/tsserverlibrary'; +import {NgLanguageService} from '../api'; import {createLanguageService} from './language_service'; import {TypeScriptServiceHost} from './typescript_host'; @@ -41,7 +42,7 @@ export function getExternalFiles(project: tss.server.Project): string[] { }); } -export function create(info: tss.server.PluginCreateInfo): tss.LanguageService { +export function create(info: tss.server.PluginCreateInfo): NgLanguageService { const {languageService: tsLS, languageServiceHost: tsLSHost, config, project} = info; // This plugin could operate under two different modes: // 1. TS + Angular @@ -135,6 +136,11 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService { return undefined; } + function getTcb(fileName: string, position: number) { + // Not implemented in VE Language Service + return undefined; + } + return { // First clone the original TS language service ...tsLS, @@ -147,5 +153,6 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService { getTypeDefinitionAtPosition, getReferencesAtPosition, findRenameLocations, + getTcb, }; } diff --git a/packages/language-service/src/typescript_host.ts b/packages/language-service/src/typescript_host.ts index 934501daf9..f3d24ca88a 100644 --- a/packages/language-service/src/typescript_host.ts +++ b/packages/language-service/src/typescript_host.ts @@ -11,21 +11,10 @@ import {SchemaMetadata, ViewEncapsulation, ɵConsole as Console} from '@angular/ import * as path from 'path'; import * as tss from 'typescript/lib/tsserverlibrary'; -import {createLanguageService} from './language_service'; import {ReflectorHost} from './reflector_host'; import {ExternalTemplate, InlineTemplate} from './template'; import {findTightestNode, getClassDeclFromDecoratorProp, getDirectiveClassLike, getPropertyAssignmentFromValue} from './ts_utils'; -import {AstResult, Declaration, DeclarationError, DiagnosticMessageChain, LanguageService, LanguageServiceHost, Span, TemplateSource} from './types'; - -/** - * Create a `LanguageServiceHost` - */ -export function createLanguageServiceFromTypescript( - host: tss.LanguageServiceHost, service: tss.LanguageService): LanguageService { - const ngHost = new TypeScriptServiceHost(host, service); - const ngServer = createLanguageService(ngHost); - return ngServer; -} +import {AstResult, Declaration, DeclarationError, DiagnosticMessageChain, LanguageServiceHost, Span, TemplateSource} from './types'; /** * The language service never needs the normalized versions of the metadata. To avoid parsing