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
|
||||
// subset of that.
|
||||
export type ParseConfigurationHost =
|
||||
export type ConfigurationHost =
|
||||
Pick<FileSystem, 'readFile'|'exists'|'lstat'|'resolve'|'join'|'dirname'|'extname'|'pwd'>;
|
||||
|
||||
export interface ParsedConfiguration {
|
||||
|
@ -119,11 +120,11 @@ export interface ParsedConfiguration {
|
|||
rootNames: string[];
|
||||
projectReferences?: readonly ts.ProjectReference[]|undefined;
|
||||
emitFlags: api.EmitFlags;
|
||||
errors: Diagnostics;
|
||||
errors: ts.Diagnostic[];
|
||||
}
|
||||
|
||||
export function calcProjectFileAndBasePath(
|
||||
project: string, host: ParseConfigurationHost = getFileSystem()):
|
||||
project: string, host: ConfigurationHost = getFileSystem()):
|
||||
{projectFile: AbsoluteFsPath, basePath: AbsoluteFsPath} {
|
||||
const absProject = host.resolve(project);
|
||||
const projectIsDir = host.lstat(absProject).isDirectory();
|
||||
|
@ -145,7 +146,7 @@ export function createNgCompilerOptions(
|
|||
|
||||
export function readConfiguration(
|
||||
project: string, existingOptions?: ts.CompilerOptions,
|
||||
host: ParseConfigurationHost = getFileSystem()): ParsedConfiguration {
|
||||
host: ConfigurationHost = getFileSystem()): ParsedConfiguration {
|
||||
try {
|
||||
const {projectFile, basePath} = calcProjectFileAndBasePath(project, host);
|
||||
|
||||
|
@ -223,11 +224,14 @@ export function readConfiguration(
|
|||
emitFlags
|
||||
};
|
||||
} catch (e) {
|
||||
const errors: Diagnostics = [{
|
||||
const errors: ts.Diagnostic[] = [{
|
||||
category: ts.DiagnosticCategory.Error,
|
||||
messageText: e.stack,
|
||||
source: api.SOURCE,
|
||||
code: api.UNKNOWN_ERROR_CODE
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
source: 'angular',
|
||||
code: api.UNKNOWN_ERROR_CODE,
|
||||
}];
|
||||
return {project: '', errors, rootNames: [], options: {}, emitFlags: api.EmitFlags.Default};
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* 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 {absoluteFrom, AbsoluteFsPath, FileStats, PathSegment, PathString} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||
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
|
||||
* than those on the adapter.
|
||||
*/
|
||||
export class LSParseConfigHost implements ParseConfigurationHost {
|
||||
private readonly host: ts.server.ServerHost = this.project.projectService.host;
|
||||
constructor(private readonly project: ts.server.Project) {}
|
||||
export class LSParseConfigHost implements ConfigurationHost {
|
||||
constructor(private readonly serverHost: ts.server.ServerHost) {}
|
||||
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 {
|
||||
const content = this.project.readFile(path);
|
||||
const content = this.serverHost.readFile(path);
|
||||
if (content === undefined) {
|
||||
throw new Error(`LanguageServiceFS#readFile called on unavailable file ${path}`);
|
||||
}
|
||||
|
@ -104,10 +105,10 @@ export class LSParseConfigHost implements ParseConfigurationHost {
|
|||
lstat(path: AbsoluteFsPath): FileStats {
|
||||
return {
|
||||
isFile: () => {
|
||||
return this.project.fileExists(path);
|
||||
return this.serverHost.fileExists(path);
|
||||
},
|
||||
isDirectory: () => {
|
||||
return this.project.directoryExists(path);
|
||||
return this.serverHost.directoryExists(path);
|
||||
},
|
||||
isSymbolicLink: () => {
|
||||
throw new Error(`LanguageServiceFS#lstat#isSymbolicLink not implemented`);
|
||||
|
@ -115,13 +116,13 @@ export class LSParseConfigHost implements ParseConfigurationHost {
|
|||
};
|
||||
}
|
||||
pwd(): AbsoluteFsPath {
|
||||
return this.project.getCurrentDirectory() as AbsoluteFsPath;
|
||||
return this.serverHost.getCurrentDirectory() as AbsoluteFsPath;
|
||||
}
|
||||
extname(path: AbsoluteFsPath|PathSegment): string {
|
||||
return p.extname(path);
|
||||
}
|
||||
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 {
|
||||
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 * as ts from 'typescript/lib/tsserverlibrary';
|
||||
|
||||
import {LanguageServiceAdapter} from './language_service_adapter';
|
||||
import {LanguageServiceAdapter} from './adapters';
|
||||
import {isExternalTemplate} from './utils';
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
* 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 {TypeCheckShimGenerator} from '@angular/compiler-cli/src/ngtsc/typecheck';
|
||||
import {OptimizeFor, TypeCheckingProgramStrategy} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
|
||||
import * as ts from 'typescript/lib/tsserverlibrary';
|
||||
|
||||
import {LanguageServiceAdapter, LSParseConfigHost} from './adapters';
|
||||
import {CompilerFactory} from './compiler_factory';
|
||||
import {DefinitionBuilder} from './definitions';
|
||||
import {LanguageServiceAdapter, LSParseConfigHost} from './language_service_adapter';
|
||||
import {QuickInfoBuilder} from './quick_info';
|
||||
import {getTargetAtPosition} from './template_target';
|
||||
import {getTemplateInfoAtPosition, isTypeScriptFile} from './utils';
|
||||
|
@ -27,7 +27,7 @@ export class LanguageService {
|
|||
private readonly parseConfigHost: LSParseConfigHost;
|
||||
|
||||
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.strategy = createTypeCheckingProgramStrategy(project);
|
||||
this.adapter = new LanguageServiceAdapter(project);
|
||||
|
@ -116,15 +116,15 @@ export class LanguageService {
|
|||
}
|
||||
}
|
||||
|
||||
export function parseNgCompilerOptions(
|
||||
project: ts.server.Project, host: ParseConfigurationHost): CompilerOptions {
|
||||
function parseNgCompilerOptions(
|
||||
project: ts.server.Project, host: ConfigurationHost): CompilerOptions {
|
||||
if (!(project instanceof ts.server.ConfiguredProject)) {
|
||||
return {};
|
||||
}
|
||||
const {options, errors} =
|
||||
readConfiguration(project.getConfigFilePath(), /* existingOptions */ undefined, host);
|
||||
if (errors.length > 0) {
|
||||
project.error(formatDiagnostics(errors));
|
||||
project.setProjectErrors(errors);
|
||||
}
|
||||
|
||||
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 {DeclarationNode} from '@angular/compiler-cli/src/ngtsc/reflection';
|
||||
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 t from '@angular/compiler/src/render3/r3_ast'; // t for template AST
|
||||
import * as ts from 'typescript';
|
||||
|
|
Loading…
Reference in New Issue