refactor(language-service): language_service_adapter -> adapters (#39619)
This rename is done because we know have a file system adapter over a project as well as the compiler adapter. PR Close #39619
This commit is contained in:
parent
64c3135be7
commit
d39c4bbe37
@ -108,9 +108,10 @@ export function formatDiagnostics(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Used to read configuration files. */
|
||||||
// TODO(ayazhafiz): split FileSystem into a ReadonlyFileSystem and make this a
|
// TODO(ayazhafiz): split FileSystem into a ReadonlyFileSystem and make this a
|
||||||
// subset of that.
|
// subset of that.
|
||||||
export type ParseConfigurationHost =
|
export type ConfigurationHost =
|
||||||
Pick<FileSystem, 'readFile'|'exists'|'lstat'|'resolve'|'join'|'dirname'|'extname'|'pwd'>;
|
Pick<FileSystem, 'readFile'|'exists'|'lstat'|'resolve'|'join'|'dirname'|'extname'|'pwd'>;
|
||||||
|
|
||||||
export interface ParsedConfiguration {
|
export interface ParsedConfiguration {
|
||||||
@ -119,11 +120,11 @@ export interface ParsedConfiguration {
|
|||||||
rootNames: string[];
|
rootNames: string[];
|
||||||
projectReferences?: readonly ts.ProjectReference[]|undefined;
|
projectReferences?: readonly ts.ProjectReference[]|undefined;
|
||||||
emitFlags: api.EmitFlags;
|
emitFlags: api.EmitFlags;
|
||||||
errors: Diagnostics;
|
errors: ts.Diagnostic[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calcProjectFileAndBasePath(
|
export function calcProjectFileAndBasePath(
|
||||||
project: string, host: ParseConfigurationHost = getFileSystem()):
|
project: string, host: ConfigurationHost = getFileSystem()):
|
||||||
{projectFile: AbsoluteFsPath, basePath: AbsoluteFsPath} {
|
{projectFile: AbsoluteFsPath, basePath: AbsoluteFsPath} {
|
||||||
const absProject = host.resolve(project);
|
const absProject = host.resolve(project);
|
||||||
const projectIsDir = host.lstat(absProject).isDirectory();
|
const projectIsDir = host.lstat(absProject).isDirectory();
|
||||||
@ -145,7 +146,7 @@ export function createNgCompilerOptions(
|
|||||||
|
|
||||||
export function readConfiguration(
|
export function readConfiguration(
|
||||||
project: string, existingOptions?: ts.CompilerOptions,
|
project: string, existingOptions?: ts.CompilerOptions,
|
||||||
host: ParseConfigurationHost = getFileSystem()): ParsedConfiguration {
|
host: ConfigurationHost = getFileSystem()): ParsedConfiguration {
|
||||||
try {
|
try {
|
||||||
const {projectFile, basePath} = calcProjectFileAndBasePath(project, host);
|
const {projectFile, basePath} = calcProjectFileAndBasePath(project, host);
|
||||||
|
|
||||||
@ -223,11 +224,14 @@ export function readConfiguration(
|
|||||||
emitFlags
|
emitFlags
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const errors: Diagnostics = [{
|
const errors: ts.Diagnostic[] = [{
|
||||||
category: ts.DiagnosticCategory.Error,
|
category: ts.DiagnosticCategory.Error,
|
||||||
messageText: e.stack,
|
messageText: e.stack,
|
||||||
source: api.SOURCE,
|
file: undefined,
|
||||||
code: api.UNKNOWN_ERROR_CODE
|
start: undefined,
|
||||||
|
length: undefined,
|
||||||
|
source: 'angular',
|
||||||
|
code: api.UNKNOWN_ERROR_CODE,
|
||||||
}];
|
}];
|
||||||
return {project: '', errors, rootNames: [], options: {}, emitFlags: api.EmitFlags.Default};
|
return {project: '', errors, rootNames: [], options: {}, emitFlags: api.EmitFlags.Default};
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ParseConfigurationHost} from '@angular/compiler-cli';
|
/** @fileoverview provides adapters for communicating with the ng compiler */
|
||||||
|
|
||||||
|
import {ConfigurationHost} from '@angular/compiler-cli';
|
||||||
import {NgCompilerAdapter} from '@angular/compiler-cli/src/ngtsc/core/api';
|
import {NgCompilerAdapter} from '@angular/compiler-cli/src/ngtsc/core/api';
|
||||||
import {absoluteFrom, AbsoluteFsPath, FileStats, PathSegment, PathString} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFrom, AbsoluteFsPath, FileStats, PathSegment, PathString} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {isShim} from '@angular/compiler-cli/src/ngtsc/shims';
|
import {isShim} from '@angular/compiler-cli/src/ngtsc/shims';
|
||||||
@ -88,14 +90,13 @@ export class LanguageServiceAdapter implements NgCompilerAdapter {
|
|||||||
* because signatures of calls like `FileSystem#readFile` are a bit stricter
|
* because signatures of calls like `FileSystem#readFile` are a bit stricter
|
||||||
* than those on the adapter.
|
* than those on the adapter.
|
||||||
*/
|
*/
|
||||||
export class LSParseConfigHost implements ParseConfigurationHost {
|
export class LSParseConfigHost implements ConfigurationHost {
|
||||||
private readonly host: ts.server.ServerHost = this.project.projectService.host;
|
constructor(private readonly serverHost: ts.server.ServerHost) {}
|
||||||
constructor(private readonly project: ts.server.Project) {}
|
|
||||||
exists(path: AbsoluteFsPath): boolean {
|
exists(path: AbsoluteFsPath): boolean {
|
||||||
return this.project.fileExists(path) || this.project.directoryExists(path);
|
return this.serverHost.fileExists(path) || this.serverHost.directoryExists(path);
|
||||||
}
|
}
|
||||||
readFile(path: AbsoluteFsPath): string {
|
readFile(path: AbsoluteFsPath): string {
|
||||||
const content = this.project.readFile(path);
|
const content = this.serverHost.readFile(path);
|
||||||
if (content === undefined) {
|
if (content === undefined) {
|
||||||
throw new Error(`LanguageServiceFS#readFile called on unavailable file ${path}`);
|
throw new Error(`LanguageServiceFS#readFile called on unavailable file ${path}`);
|
||||||
}
|
}
|
||||||
@ -104,10 +105,10 @@ export class LSParseConfigHost implements ParseConfigurationHost {
|
|||||||
lstat(path: AbsoluteFsPath): FileStats {
|
lstat(path: AbsoluteFsPath): FileStats {
|
||||||
return {
|
return {
|
||||||
isFile: () => {
|
isFile: () => {
|
||||||
return this.project.fileExists(path);
|
return this.serverHost.fileExists(path);
|
||||||
},
|
},
|
||||||
isDirectory: () => {
|
isDirectory: () => {
|
||||||
return this.project.directoryExists(path);
|
return this.serverHost.directoryExists(path);
|
||||||
},
|
},
|
||||||
isSymbolicLink: () => {
|
isSymbolicLink: () => {
|
||||||
throw new Error(`LanguageServiceFS#lstat#isSymbolicLink not implemented`);
|
throw new Error(`LanguageServiceFS#lstat#isSymbolicLink not implemented`);
|
||||||
@ -115,13 +116,13 @@ export class LSParseConfigHost implements ParseConfigurationHost {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
pwd(): AbsoluteFsPath {
|
pwd(): AbsoluteFsPath {
|
||||||
return this.project.getCurrentDirectory() as AbsoluteFsPath;
|
return this.serverHost.getCurrentDirectory() as AbsoluteFsPath;
|
||||||
}
|
}
|
||||||
extname(path: AbsoluteFsPath|PathSegment): string {
|
extname(path: AbsoluteFsPath|PathSegment): string {
|
||||||
return p.extname(path);
|
return p.extname(path);
|
||||||
}
|
}
|
||||||
resolve(...paths: string[]): AbsoluteFsPath {
|
resolve(...paths: string[]): AbsoluteFsPath {
|
||||||
return this.host.resolvePath(this.join(paths[0], ...paths.slice(1))) as AbsoluteFsPath;
|
return this.serverHost.resolvePath(this.join(paths[0], ...paths.slice(1))) as AbsoluteFsPath;
|
||||||
}
|
}
|
||||||
dirname<T extends PathString>(file: T): T {
|
dirname<T extends PathString>(file: T): T {
|
||||||
return p.dirname(file) as T;
|
return p.dirname(file) as T;
|
@ -12,7 +12,7 @@ import {TrackedIncrementalBuildStrategy} from '@angular/compiler-cli/src/ngtsc/i
|
|||||||
import {TypeCheckingProgramStrategy} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
import {TypeCheckingProgramStrategy} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
||||||
import * as ts from 'typescript/lib/tsserverlibrary';
|
import * as ts from 'typescript/lib/tsserverlibrary';
|
||||||
|
|
||||||
import {LanguageServiceAdapter} from './language_service_adapter';
|
import {LanguageServiceAdapter} from './adapters';
|
||||||
import {isExternalTemplate} from './utils';
|
import {isExternalTemplate} from './utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,15 +6,15 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {CompilerOptions, formatDiagnostics, ParseConfigurationHost, readConfiguration} from '@angular/compiler-cli';
|
import {CompilerOptions, ConfigurationHost, readConfiguration} from '@angular/compiler-cli';
|
||||||
import {absoluteFromSourceFile, AbsoluteFsPath} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFromSourceFile, AbsoluteFsPath} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {TypeCheckShimGenerator} from '@angular/compiler-cli/src/ngtsc/typecheck';
|
import {TypeCheckShimGenerator} from '@angular/compiler-cli/src/ngtsc/typecheck';
|
||||||
import {OptimizeFor, TypeCheckingProgramStrategy} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
import {OptimizeFor, TypeCheckingProgramStrategy} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
||||||
import * as ts from 'typescript/lib/tsserverlibrary';
|
import * as ts from 'typescript/lib/tsserverlibrary';
|
||||||
|
|
||||||
|
import {LanguageServiceAdapter, LSParseConfigHost} from './adapters';
|
||||||
import {CompilerFactory} from './compiler_factory';
|
import {CompilerFactory} from './compiler_factory';
|
||||||
import {DefinitionBuilder} from './definitions';
|
import {DefinitionBuilder} from './definitions';
|
||||||
import {LanguageServiceAdapter, LSParseConfigHost} from './language_service_adapter';
|
|
||||||
import {QuickInfoBuilder} from './quick_info';
|
import {QuickInfoBuilder} from './quick_info';
|
||||||
import {getTargetAtPosition} from './template_target';
|
import {getTargetAtPosition} from './template_target';
|
||||||
import {getTemplateInfoAtPosition, isTypeScriptFile} from './utils';
|
import {getTemplateInfoAtPosition, isTypeScriptFile} from './utils';
|
||||||
@ -27,7 +27,7 @@ export class LanguageService {
|
|||||||
private readonly parseConfigHost: LSParseConfigHost;
|
private readonly parseConfigHost: LSParseConfigHost;
|
||||||
|
|
||||||
constructor(project: ts.server.Project, private readonly tsLS: ts.LanguageService) {
|
constructor(project: ts.server.Project, private readonly tsLS: ts.LanguageService) {
|
||||||
this.parseConfigHost = new LSParseConfigHost(project);
|
this.parseConfigHost = new LSParseConfigHost(project.projectService.host);
|
||||||
this.options = parseNgCompilerOptions(project, this.parseConfigHost);
|
this.options = parseNgCompilerOptions(project, this.parseConfigHost);
|
||||||
this.strategy = createTypeCheckingProgramStrategy(project);
|
this.strategy = createTypeCheckingProgramStrategy(project);
|
||||||
this.adapter = new LanguageServiceAdapter(project);
|
this.adapter = new LanguageServiceAdapter(project);
|
||||||
@ -116,15 +116,15 @@ export class LanguageService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseNgCompilerOptions(
|
function parseNgCompilerOptions(
|
||||||
project: ts.server.Project, host: ParseConfigurationHost): CompilerOptions {
|
project: ts.server.Project, host: ConfigurationHost): CompilerOptions {
|
||||||
if (!(project instanceof ts.server.ConfiguredProject)) {
|
if (!(project instanceof ts.server.ConfiguredProject)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const {options, errors} =
|
const {options, errors} =
|
||||||
readConfiguration(project.getConfigFilePath(), /* existingOptions */ undefined, host);
|
readConfiguration(project.getConfigFilePath(), /* existingOptions */ undefined, host);
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
project.error(formatDiagnostics(errors));
|
project.setProjectErrors(errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
@ -1,41 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as ts from 'typescript/lib/tsserverlibrary';
|
|
||||||
|
|
||||||
import {LanguageServiceAdapter} from '../../language_service_adapter';
|
|
||||||
|
|
||||||
import {MockService, setup, TEST_TEMPLATE} from './mock_host';
|
|
||||||
|
|
||||||
describe('Language service adapter', () => {
|
|
||||||
let project: ts.server.Project;
|
|
||||||
let service: MockService;
|
|
||||||
|
|
||||||
beforeAll(() => {
|
|
||||||
const {project: _project, service: _service} = setup();
|
|
||||||
project = _project;
|
|
||||||
service = _service;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should mark template dirty if it has not seen the template before', () => {
|
|
||||||
const adapter = new LanguageServiceAdapter(project);
|
|
||||||
expect(adapter.isTemplateDirty(TEST_TEMPLATE)).toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not mark template dirty if template has not changed', () => {
|
|
||||||
const adapter = new LanguageServiceAdapter(project);
|
|
||||||
adapter.readResource(TEST_TEMPLATE);
|
|
||||||
expect(adapter.isTemplateDirty(TEST_TEMPLATE)).toBeFalse();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should mark template dirty if template has changed', () => {
|
|
||||||
const adapter = new LanguageServiceAdapter(project);
|
|
||||||
service.overwrite(TEST_TEMPLATE, '<p>Hello World</p>');
|
|
||||||
expect(adapter.isTemplateDirty(TEST_TEMPLATE)).toBeTrue();
|
|
||||||
});
|
|
||||||
});
|
|
@ -10,6 +10,7 @@ import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core';
|
|||||||
import {isExternalResource} from '@angular/compiler-cli/src/ngtsc/metadata';
|
import {isExternalResource} from '@angular/compiler-cli/src/ngtsc/metadata';
|
||||||
import {DeclarationNode} from '@angular/compiler-cli/src/ngtsc/reflection';
|
import {DeclarationNode} from '@angular/compiler-cli/src/ngtsc/reflection';
|
||||||
import {DirectiveSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
import {DirectiveSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
||||||
|
import {Diagnostic as ngDiagnostic, isNgDiagnostic} from '@angular/compiler-cli/src/transformers/api';
|
||||||
import * as e from '@angular/compiler/src/expression_parser/ast'; // e for expression AST
|
import * as e from '@angular/compiler/src/expression_parser/ast'; // e for expression AST
|
||||||
import * as t from '@angular/compiler/src/render3/r3_ast'; // t for template AST
|
import * as t from '@angular/compiler/src/render3/r3_ast'; // t for template AST
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user