refactor(compiler-cli): update to use new file-system interfaces (#40281)

Now that `ReadonlyFileSystem` and `PathManipulation` interfaces are
available, this commit updates the compiler-cli to use these more
focussed interfaces.

PR Close #40281
This commit is contained in:
Pete Bacon Darwin 2020-12-30 17:03:41 +00:00 committed by Andrew Scott
parent 80b1ba9f95
commit d100a15998
62 changed files with 285 additions and 272 deletions

View File

@ -6,14 +6,14 @@
* found in the LICENSE file at https://angular.io/license
*/
import {LinkerOptions} from '../..';
import {FileSystem} from '../../../src/ngtsc/file_system';
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
export interface LinkerPluginOptions extends Partial<LinkerOptions> {
/**
* File-system, used to load up the input source-map and content.
*/
fileSystem: FileSystem;
fileSystem: ReadonlyFileSystem;
/**
* Logger used by the linker.

View File

@ -5,7 +5,7 @@
* 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 {FileSystem} from '../../../src/ngtsc/file_system';
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {SourceFileLoader} from '../../../src/ngtsc/sourcemaps';
import {AstFactory} from '../../../src/ngtsc/translator';
@ -20,11 +20,12 @@ export class LinkerEnvironment<TStatement, TExpression> {
this.options.sourceMapping ? new SourceFileLoader(this.fileSystem, this.logger, {}) : null;
private constructor(
readonly fileSystem: FileSystem, readonly logger: Logger, readonly host: AstHost<TExpression>,
readonly factory: AstFactory<TStatement, TExpression>, readonly options: LinkerOptions) {}
readonly fileSystem: ReadonlyFileSystem, readonly logger: Logger,
readonly host: AstHost<TExpression>, readonly factory: AstFactory<TStatement, TExpression>,
readonly options: LinkerOptions) {}
static create<TStatement, TExpression>(
fileSystem: FileSystem, logger: Logger, host: AstHost<TExpression>,
fileSystem: ReadonlyFileSystem, logger: Logger, host: AstHost<TExpression>,
factory: AstFactory<TStatement, TExpression>,
options: Partial<LinkerOptions>): LinkerEnvironment<TStatement, TExpression> {
return new LinkerEnvironment(fileSystem, logger, host, factory, {

View File

@ -12,7 +12,7 @@ import {ParsedConfiguration} from '../../..';
import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, PipeDecoratorHandler, ReferencesRegistry, ResourceLoader} from '../../../src/ngtsc/annotations';
import {CycleAnalyzer, ImportGraph} from '../../../src/ngtsc/cycles';
import {isFatalDiagnosticError} from '../../../src/ngtsc/diagnostics';
import {absoluteFrom, absoluteFromSourceFile, dirname, FileSystem, LogicalFileSystem, resolve} from '../../../src/ngtsc/file_system';
import {absoluteFromSourceFile, LogicalFileSystem, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteModuleStrategy, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, NOOP_DEFAULT_IMPORT_RECORDER, PrivateExportAliasingHost, Reexport, ReferenceEmitter} from '../../../src/ngtsc/imports';
import {CompoundMetadataReader, CompoundMetadataRegistry, DtsMetadataReader, InjectableClassRegistry, LocalMetadataRegistry, ResourceRegistry} from '../../../src/ngtsc/metadata';
import {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator';
@ -36,16 +36,16 @@ import {isWithinPackage, NOOP_DEPENDENCY_TRACKER} from './util';
* Simple class that resolves and loads files directly from the filesystem.
*/
class NgccResourceLoader implements ResourceLoader {
constructor(private fs: FileSystem) {}
constructor(private fs: ReadonlyFileSystem) {}
canPreload = false;
preload(): undefined|Promise<void> {
throw new Error('Not implemented.');
}
load(url: string): string {
return this.fs.readFile(resolve(url));
return this.fs.readFile(this.fs.resolve(url));
}
resolve(url: string, containingFile: string): string {
return resolve(dirname(absoluteFrom(containingFile)), url);
return this.fs.resolve(this.fs.dirname(containingFile), url);
}
}
@ -139,7 +139,7 @@ export class DecorationAnalyzer {
];
constructor(
private fs: FileSystem, private bundle: EntryPointBundle,
private fs: ReadonlyFileSystem, private bundle: EntryPointBundle,
private reflectionHost: NgccReflectionHost, private referencesRegistry: ReferencesRegistry,
private diagnosticHandler: (error: ts.Diagnostic) => void = () => {},
private tsConfig: ParsedConfiguration|null = null) {}

View File

@ -8,7 +8,7 @@
*/
import * as yargs from 'yargs';
import {resolve, setFileSystem, NodeJSFileSystem} from '../../src/ngtsc/file_system';
import {setFileSystem, NodeJSFileSystem} from '../../src/ngtsc/file_system';
import {ConsoleLogger, LogLevel} from '../../src/ngtsc/logging';
import {NgccOptions} from './ngcc_options';
@ -115,9 +115,10 @@ export function parseCommandLineOptions(args: string[]): NgccOptions {
process.exit(1);
}
setFileSystem(new NodeJSFileSystem());
const fs = new NodeJSFileSystem();
setFileSystem(fs);
const baseSourcePath = resolve(options.s || './node_modules');
const baseSourcePath = fs.resolve(options.s || './node_modules');
const propertiesToConsider = options.p;
const targetEntryPointPath = options.t;
const compileAllFormats = !options['first-only'];

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathSegment, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {EntryPoint} from '../packages/entry_point';
import {resolveFileWithPostfixes} from '../utils';
@ -32,7 +32,7 @@ export function createDependencyInfo(): DependencyInfo {
}
export abstract class DependencyHostBase implements DependencyHost {
constructor(protected fs: FileSystem, protected moduleResolver: ModuleResolver) {}
constructor(protected fs: ReadonlyFileSystem, protected moduleResolver: ModuleResolver) {}
/**
* Find all the dependencies for the entry-point at the given path.

View File

@ -8,7 +8,7 @@
import {DepGraph} from 'dependency-graph';
import {AbsoluteFsPath, FileSystem, resolve} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {NgccConfiguration} from '../packages/configuration';
import {EntryPoint, EntryPointFormat, getEntryPointFormat, SUPPORTED_FORMAT_PROPERTIES} from '../packages/entry_point';
@ -84,7 +84,7 @@ export interface SortedEntryPointsInfo extends DependencyDiagnostics {
*/
export class DependencyResolver {
constructor(
private fs: FileSystem, private logger: Logger, private config: NgccConfiguration,
private fs: ReadonlyFileSystem, private logger: Logger, private config: NgccConfiguration,
private hosts: Partial<Record<EntryPointFormat, DependencyHost>>,
private typingsHost: DependencyHost) {}
/**
@ -212,7 +212,7 @@ export class DependencyResolver {
const format = getEntryPointFormat(this.fs, entryPoint, property);
if (format === undefined) continue;
return {format, path: resolve(entryPoint.path, formatPath)};
return {format, path: this.fs.resolve(entryPoint.path, formatPath)};
}
throw new Error(

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {PathMappings} from '../path_mappings';
import {EsmDependencyHost} from './esm_dependency_host';
import {ModuleResolver} from './module_resolver';
@ -14,7 +14,7 @@ import {ModuleResolver} from './module_resolver';
* Helper functions for computing dependencies via typings files.
*/
export class DtsDependencyHost extends EsmDependencyHost {
constructor(fs: FileSystem, pathMappings?: PathMappings) {
constructor(fs: ReadonlyFileSystem, pathMappings?: PathMappings) {
super(
fs, new ModuleResolver(fs, pathMappings, ['', '.d.ts', '/index.d.ts', '.js', '/index.js']),
false);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {DependencyHostBase} from './dependency_host';
import {ModuleResolver} from './module_resolver';
@ -15,7 +15,8 @@ import {ModuleResolver} from './module_resolver';
*/
export class EsmDependencyHost extends DependencyHostBase {
constructor(
fs: FileSystem, moduleResolver: ModuleResolver, private scanImportExpressions = true) {
fs: ReadonlyFileSystem, moduleResolver: ModuleResolver,
private scanImportExpressions = true) {
super(fs, moduleResolver);
}
// By skipping trivia here we don't have to account for it in the processing below

View File

@ -5,7 +5,7 @@
* 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 {absoluteFrom, AbsoluteFsPath, dirname, FileSystem, isRoot, join, resolve} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {PathMappings} from '../path_mappings';
import {isRelativePath, resolveFileWithPostfixes} from '../utils';
@ -25,9 +25,9 @@ import {isRelativePath, resolveFileWithPostfixes} from '../utils';
export class ModuleResolver {
private pathMappings: ProcessedPathMapping[];
constructor(private fs: FileSystem, pathMappings?: PathMappings, readonly relativeExtensions = [
'', '.js', '/index.js'
]) {
constructor(
private fs: ReadonlyFileSystem, pathMappings?: PathMappings,
readonly relativeExtensions = ['', '.js', '/index.js']) {
this.pathMappings = pathMappings ? this.processPathMappings(pathMappings) : [];
}
@ -54,7 +54,7 @@ export class ModuleResolver {
* Convert the `pathMappings` into a collection of `PathMapper` functions.
*/
private processPathMappings(pathMappings: PathMappings): ProcessedPathMapping[] {
const baseUrl = absoluteFrom(pathMappings.baseUrl);
const baseUrl = this.fs.resolve(pathMappings.baseUrl);
return Object.keys(pathMappings.paths).map(pathPattern => {
const matcher = splitOnStar(pathPattern);
const templates = pathMappings.paths[pathPattern].map(splitOnStar);
@ -71,7 +71,7 @@ export class ModuleResolver {
*/
private resolveAsRelativePath(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null {
const resolvedPath = resolveFileWithPostfixes(
this.fs, resolve(dirname(fromPath), moduleName), this.relativeExtensions);
this.fs, this.fs.resolve(this.fs.dirname(fromPath), moduleName), this.relativeExtensions);
return resolvedPath && new ResolvedRelativeModule(resolvedPath);
}
@ -115,13 +115,13 @@ export class ModuleResolver {
*/
private resolveAsEntryPoint(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null {
let folder = fromPath;
while (!isRoot(folder)) {
folder = dirname(folder);
while (!this.fs.isRoot(folder)) {
folder = this.fs.dirname(folder);
if (folder.endsWith('node_modules')) {
// Skip up if the folder already ends in node_modules
folder = dirname(folder);
folder = this.fs.dirname(folder);
}
const modulePath = resolve(folder, 'node_modules', moduleName);
const modulePath = this.fs.resolve(folder, 'node_modules', moduleName);
if (this.isEntryPoint(modulePath)) {
return new ResolvedExternalModule(modulePath);
} else if (this.resolveAsRelativePath(modulePath, fromPath)) {
@ -138,7 +138,7 @@ export class ModuleResolver {
* This is achieved by checking for the existence of `${modulePath}/package.json`.
*/
private isEntryPoint(modulePath: AbsoluteFsPath): boolean {
return this.fs.exists(join(modulePath, 'package.json'));
return this.fs.exists(this.fs.join(modulePath, 'package.json'));
}
/**
@ -203,7 +203,7 @@ export class ModuleResolver {
*/
private computeMappedTemplates(mapping: ProcessedPathMapping, match: string) {
return mapping.templates.map(
template => resolve(mapping.baseUrl, template.prefix + match + template.postfix));
template => this.fs.resolve(mapping.baseUrl, template.prefix + match + template.postfix));
}
/**
@ -212,9 +212,9 @@ export class ModuleResolver {
*/
private findPackagePath(path: AbsoluteFsPath): AbsoluteFsPath|null {
let folder = path;
while (!isRoot(folder)) {
folder = dirname(folder);
if (this.fs.exists(join(folder, 'package.json'))) {
while (!this.fs.isRoot(folder)) {
folder = this.fs.dirname(folder);
if (this.fs.exists(this.fs.join(folder, 'package.json'))) {
return folder;
}
}

View File

@ -5,9 +5,8 @@
* 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 {AbsoluteFsPath, FileSystem, PathSegment} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathSegment, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {EntryPointWithDependencies} from '../dependencies/dependency_host';
import {DependencyResolver} from '../dependencies/dependency_resolver';
import {NgccConfiguration} from '../packages/configuration';
@ -20,7 +19,7 @@ import {NGCC_DIRECTORY} from '../writing/new_entry_point_file_writer';
*/
export class EntryPointCollector {
constructor(
private fs: FileSystem, private config: NgccConfiguration, private logger: Logger,
private fs: ReadonlyFileSystem, private config: NgccConfiguration, private logger: Logger,
private resolver: DependencyResolver) {}
/**

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {ParsedConfiguration} from '../../../src/perform_compile';
@ -32,12 +32,13 @@ export class ProgramBasedEntryPointFinder extends TracingEntryPointFinder {
private entryPointsWithDependencies: Map<AbsoluteFsPath, EntryPointWithDependencies>|null = null;
constructor(
fs: FileSystem, config: NgccConfiguration, logger: Logger, resolver: DependencyResolver,
private entryPointCollector: EntryPointCollector,
fs: ReadonlyFileSystem, config: NgccConfiguration, logger: Logger,
resolver: DependencyResolver, private entryPointCollector: EntryPointCollector,
private entryPointManifest: EntryPointManifest, basePath: AbsoluteFsPath,
private tsConfig: ParsedConfiguration, projectPath: AbsoluteFsPath) {
super(
fs, config, logger, resolver, basePath, getPathMappingsFromTsConfig(tsConfig, projectPath));
fs, config, logger, resolver, basePath,
getPathMappingsFromTsConfig(fs, tsConfig, projectPath));
}
/**

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem, join, PathSegment, relative, relativeFrom} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathSegment, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {EntryPointWithDependencies} from '../dependencies/dependency_host';
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
@ -25,8 +25,8 @@ import {TracingEntryPointFinder} from './tracing_entry_point_finder';
*/
export class TargetedEntryPointFinder extends TracingEntryPointFinder {
constructor(
fs: FileSystem, config: NgccConfiguration, logger: Logger, resolver: DependencyResolver,
basePath: AbsoluteFsPath, pathMappings: PathMappings|undefined,
fs: ReadonlyFileSystem, config: NgccConfiguration, logger: Logger,
resolver: DependencyResolver, basePath: AbsoluteFsPath, pathMappings: PathMappings|undefined,
private targetPath: AbsoluteFsPath) {
super(fs, config, logger, resolver, basePath, pathMappings);
}
@ -162,14 +162,14 @@ export class TargetedEntryPointFinder extends TracingEntryPointFinder {
private computePackagePathFromContainingPath(
entryPointPath: AbsoluteFsPath, containingPath: AbsoluteFsPath): AbsoluteFsPath|null {
let packagePath = containingPath;
const segments = this.splitPath(relative(containingPath, entryPointPath));
let nodeModulesIndex = segments.lastIndexOf(relativeFrom('node_modules'));
const segments = this.splitPath(this.fs.relative(containingPath, entryPointPath));
let nodeModulesIndex = segments.lastIndexOf('node_modules' as PathSegment);
// If there are no `node_modules` in the relative path between the `basePath` and the
// `entryPointPath` then just try the `basePath` as the `packagePath`.
// (This can be the case with path-mapped entry-points.)
if (nodeModulesIndex === -1) {
if (this.fs.exists(join(packagePath, 'package.json'))) {
if (this.fs.exists(this.fs.join(packagePath, 'package.json'))) {
return packagePath;
}
}
@ -177,7 +177,7 @@ export class TargetedEntryPointFinder extends TracingEntryPointFinder {
// Start the search at the deepest nested `node_modules` folder that is below the `basePath`
// but above the `entryPointPath`, if there are any.
while (nodeModulesIndex >= 0) {
packagePath = join(packagePath, segments.shift()!);
packagePath = this.fs.join(packagePath, segments.shift()!);
nodeModulesIndex--;
}
@ -185,8 +185,8 @@ export class TargetedEntryPointFinder extends TracingEntryPointFinder {
// initial candidate `packagePath` is either a `node_modules` folder or the `basePath` with
// no `package.json`.
for (const segment of segments) {
packagePath = join(packagePath, segment);
if (this.fs.exists(join(packagePath, 'package.json'))) {
packagePath = this.fs.join(packagePath, segment);
if (this.fs.exists(this.fs.join(packagePath, 'package.json'))) {
return packagePath;
}
}
@ -207,12 +207,12 @@ export class TargetedEntryPointFinder extends TracingEntryPointFinder {
containerPath = this.fs.dirname(containerPath);
}
if (this.fs.exists(join(packagePath, 'package.json'))) {
if (this.fs.exists(this.fs.join(packagePath, 'package.json'))) {
// The directory directly below `node_modules` is a package - use it
return packagePath;
} else if (
this.fs.basename(packagePath).startsWith('@') &&
this.fs.exists(join(scopedPackagePath, 'package.json'))) {
this.fs.exists(this.fs.join(scopedPackagePath, 'package.json'))) {
// The directory directly below the `node_modules` is a scope and the directory directly
// below that is a scoped package - use it
return scopedPackagePath;

View File

@ -5,9 +5,8 @@
* 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 {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathManipulation, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {EntryPointWithDependencies} from '../dependencies/dependency_host';
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
import {NgccConfiguration} from '../packages/configuration';
@ -36,9 +35,9 @@ export abstract class TracingEntryPointFinder implements EntryPointFinder {
private basePaths: AbsoluteFsPath[]|null = null;
constructor(
protected fs: FileSystem, protected config: NgccConfiguration, protected logger: Logger,
protected resolver: DependencyResolver, protected basePath: AbsoluteFsPath,
protected pathMappings: PathMappings|undefined) {}
protected fs: ReadonlyFileSystem, protected config: NgccConfiguration,
protected logger: Logger, protected resolver: DependencyResolver,
protected basePath: AbsoluteFsPath, protected pathMappings: PathMappings|undefined) {}
/**
* Search for Angular package entry-points.

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, getFileSystem, isRoot, resolve} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, getFileSystem, PathManipulation} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {PathMappings} from '../path_mappings';
@ -34,7 +34,7 @@ export function getBasePaths(
const fs = getFileSystem();
const basePaths = [sourceDirectory];
if (pathMappings) {
const baseUrl = resolve(pathMappings.baseUrl);
const baseUrl = fs.resolve(pathMappings.baseUrl);
if (fs.isRoot(baseUrl)) {
logger.warn(
`The provided pathMappings baseUrl is the root path ${baseUrl}.\n` +
@ -58,7 +58,7 @@ export function getBasePaths(
}));
}
const dedupedBasePaths = dedupePaths(basePaths);
const dedupedBasePaths = dedupePaths(fs, basePaths);
// We want to ensure that the `sourceDirectory` is included when it is a node_modules folder.
// Otherwise our entry-point finding algorithm would fail to walk that folder.
@ -103,10 +103,10 @@ export function trackDuration<T = void>(task: () => T extends Promise<unknown>?
* (Note that we do not get `d` even though `d/e` and `d/f` share a base directory, since `d` is not
* one of the base paths.)
*/
export function dedupePaths(paths: AbsoluteFsPath[]): AbsoluteFsPath[] {
function dedupePaths(fs: PathManipulation, paths: AbsoluteFsPath[]): AbsoluteFsPath[] {
const root: Node = {children: new Map()};
for (const path of paths) {
addPath(root, path);
addPath(fs, root, path);
}
return flattenTree(root);
}
@ -114,9 +114,9 @@ export function dedupePaths(paths: AbsoluteFsPath[]): AbsoluteFsPath[] {
/**
* Add a path (defined by the `segments`) to the current `node` in the tree.
*/
function addPath(root: Node, path: AbsoluteFsPath): void {
function addPath(fs: PathManipulation, root: Node, path: AbsoluteFsPath): void {
let node = root;
if (!isRoot(path)) {
if (!fs.isRoot(path)) {
const segments = path.split('/');
for (let index = 0; index < segments.length; index++) {
if (isLeaf(node)) {

View File

@ -5,7 +5,7 @@
* 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 {FileSystem} from '../../../../src/ngtsc/file_system';
import {PathManipulation} from '../../../../src/ngtsc/file_system';
import {Logger} from '../../../../src/ngtsc/logging';
import {AsyncLocker} from '../../locking/async_locker';
import {FileWriter} from '../../writing/file_writer';
@ -21,7 +21,7 @@ import {ClusterMaster} from './master';
*/
export class ClusterExecutor implements Executor {
constructor(
private workerCount: number, private fileSystem: FileSystem, private logger: Logger,
private workerCount: number, private fileSystem: PathManipulation, private logger: Logger,
private fileWriter: FileWriter, private pkgJsonUpdater: PackageJsonUpdater,
private lockFile: AsyncLocker,
private createTaskCompletedCallback: CreateTaskCompletedCallback) {}

View File

@ -10,7 +10,7 @@
import * as cluster from 'cluster';
import {AbsoluteFsPath, FileSystem} from '../../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathManipulation} from '../../../../src/ngtsc/file_system';
import {Logger} from '../../../../src/ngtsc/logging';
import {FileWriter} from '../../writing/file_writer';
import {PackageJsonUpdater} from '../../writing/package_json_updater';
@ -35,7 +35,7 @@ export class ClusterMaster {
private remainingRespawnAttempts = 3;
constructor(
private maxWorkerCount: number, private fileSystem: FileSystem, private logger: Logger,
private maxWorkerCount: number, private fileSystem: PathManipulation, private logger: Logger,
private fileWriter: FileWriter, private pkgJsonUpdater: PackageJsonUpdater,
analyzeEntryPoints: AnalyzeEntryPointsFn,
createTaskCompletedCallback: CreateTaskCompletedCallback) {

View File

@ -5,7 +5,7 @@
* 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 {FileSystem, resolve} from '../../../../src/ngtsc/file_system';
import {PathManipulation, ReadonlyFileSystem} from '../../../../src/ngtsc/file_system';
import {Logger} from '../../../../src/ngtsc/logging';
import {markAsProcessed} from '../../packages/build_marker';
import {getEntryPointFormat, PackageJsonFormatProperties} from '../../packages/entry_point';
@ -46,11 +46,11 @@ export function composeTaskCompletedCallbacks(
*
* @param pkgJsonUpdater The service used to update the package.json
*/
export function createMarkAsProcessedHandler(pkgJsonUpdater: PackageJsonUpdater):
TaskCompletedHandler {
export function createMarkAsProcessedHandler(
fs: PathManipulation, pkgJsonUpdater: PackageJsonUpdater): TaskCompletedHandler {
return (task: Task): void => {
const {entryPoint, formatPropertiesToMarkAsProcessed, processDts} = task;
const packageJsonPath = resolve(entryPoint.path, 'package.json');
const packageJsonPath = fs.resolve(entryPoint.path, 'package.json');
const propsToMarkAsProcessed: PackageJsonFormatProperties[] =
[...formatPropertiesToMarkAsProcessed];
if (processDts) {
@ -64,7 +64,7 @@ export function createMarkAsProcessedHandler(pkgJsonUpdater: PackageJsonUpdater)
/**
* Create a handler that will throw an error.
*/
export function createThrowErrorHandler(fs: FileSystem): TaskCompletedHandler {
export function createThrowErrorHandler(fs: ReadonlyFileSystem): TaskCompletedHandler {
return (task: Task, message: string|null): void => {
const format = getEntryPointFormat(fs, task.entryPoint, task.formatProperty);
throw new Error(
@ -78,7 +78,7 @@ export function createThrowErrorHandler(fs: FileSystem): TaskCompletedHandler {
* Create a handler that logs an error and marks the task as failed.
*/
export function createLogErrorHandler(
logger: Logger, fs: FileSystem, taskQueue: TaskQueue): TaskCompletedHandler {
logger: Logger, fs: ReadonlyFileSystem, taskQueue: TaskQueue): TaskCompletedHandler {
return (task: Task, message: string|null): void => {
taskQueue.markAsFailed(task);
const format = getEntryPointFormat(fs, task.entryPoint, task.formatProperty);

View File

@ -5,9 +5,9 @@
* 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 {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathManipulation} from '../../../src/ngtsc/file_system';
export function getLockFilePath(fs: FileSystem) {
export function getLockFilePath(fs: PathManipulation) {
return fs.resolve(require.resolve('@angular/compiler-cli/ngcc'), '../__ngcc_lock_file__');
}

View File

@ -8,7 +8,7 @@
/// <reference types="node" />
import {AbsoluteFsPath, FileSystem, resolve} from '../../src/ngtsc/file_system';
import {AbsoluteFsPath, FileSystem, ReadonlyFileSystem} from '../../src/ngtsc/file_system';
import {Logger} from '../../src/ngtsc/logging';
import {ParsedConfiguration} from '../../src/perform_compile';
@ -78,8 +78,9 @@ export function mainNgcc(options: AsyncNgccOptions|SyncNgccOptions): void|Promis
// Bail out early if the work is already done.
const supportedPropertiesToConsider = ensureSupportedProperties(propertiesToConsider);
const absoluteTargetEntryPointPath =
targetEntryPointPath !== undefined ? resolve(basePath, targetEntryPointPath) : null;
const absoluteTargetEntryPointPath = targetEntryPointPath !== undefined ?
fileSystem.resolve(basePath, targetEntryPointPath) :
null;
const finder = getEntryPointFinder(
fileSystem, logger, dependencyResolver, config, entryPointManifest, absBasePath,
absoluteTargetEntryPointPath, pathMappings,
@ -140,9 +141,10 @@ function ensureSupportedProperties(properties: string[]): EntryPointJsonProperty
function getCreateTaskCompletedCallback(
pkgJsonUpdater: PackageJsonUpdater, errorOnFailedEntryPoint: boolean, logger: Logger,
fileSystem: FileSystem): CreateTaskCompletedCallback {
fileSystem: ReadonlyFileSystem): CreateTaskCompletedCallback {
return taskQueue => composeTaskCompletedCallbacks({
[TaskProcessingOutcome.Processed]: createMarkAsProcessedHandler(pkgJsonUpdater),
[TaskProcessingOutcome.Processed]:
createMarkAsProcessedHandler(fileSystem, pkgJsonUpdater),
[TaskProcessingOutcome.Failed]:
errorOnFailedEntryPoint ? createThrowErrorHandler(fileSystem) :
createLogErrorHandler(logger, fileSystem, taskQueue),
@ -175,7 +177,7 @@ function getExecutor(
}
function getDependencyResolver(
fileSystem: FileSystem, logger: Logger, config: NgccConfiguration,
fileSystem: ReadonlyFileSystem, logger: Logger, config: NgccConfiguration,
pathMappings: PathMappings|undefined): DependencyResolver {
const moduleResolver = new ModuleResolver(fileSystem, pathMappings);
const esmDependencyHost = new EsmDependencyHost(fileSystem, moduleResolver);
@ -193,7 +195,7 @@ function getDependencyResolver(
}
function getEntryPointFinder(
fs: FileSystem, logger: Logger, resolver: DependencyResolver, config: NgccConfiguration,
fs: ReadonlyFileSystem, logger: Logger, resolver: DependencyResolver, config: NgccConfiguration,
entryPointManifest: EntryPointManifest, basePath: AbsoluteFsPath,
absoluteTargetEntryPointPath: AbsoluteFsPath|null, pathMappings: PathMappings|undefined,
tsConfig: ParsedConfiguration|null, projectPath: AbsoluteFsPath): EntryPointFinder {

View File

@ -7,7 +7,7 @@
*/
import * as os from 'os';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '../../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, PathManipulation} from '../../src/ngtsc/file_system';
import {ConsoleLogger, Logger, LogLevel} from '../../src/ngtsc/logging';
import {ParsedConfiguration, readConfiguration} from '../../src/perform_compile';
@ -175,7 +175,7 @@ export function getSharedSetup(options: NgccOptions): SharedSetup&RequiredNgccOp
compileAllFormats = true,
createNewEntryPointFormats = false,
logger = new ConsoleLogger(LogLevel.info),
pathMappings = getPathMappingsFromTsConfig(tsConfig, projectPath),
pathMappings = getPathMappingsFromTsConfig(fileSystem, tsConfig, projectPath),
async = false,
errorOnFailedEntryPoint = false,
enableI18nLegacyMessageIdFormat = true,
@ -239,7 +239,7 @@ export function clearTsConfigCache() {
}
function checkForSolutionStyleTsConfig(
fileSystem: FileSystem, logger: Logger, projectPath: AbsoluteFsPath,
fileSystem: PathManipulation, logger: Logger, projectPath: AbsoluteFsPath,
tsConfigPath: string|null|undefined, tsConfig: ParsedConfiguration|null): void {
if (tsConfigPath !== null && !tsConfigPath && tsConfig !== null &&
tsConfig.rootNames.length === 0 && tsConfig.projectReferences !== undefined &&

View File

@ -7,7 +7,7 @@
*/
import * as ts from 'typescript';
import {AbsoluteFsPath, dirname, FileSystem, resolve} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {patchTsGetExpandoInitializer, restoreGetExpandoInitializer} from './patch_ts_expando_initializer';
@ -34,10 +34,10 @@ export interface BundleProgram {
* Create a bundle program.
*/
export function makeBundleProgram(
fs: FileSystem, isCore: boolean, pkg: AbsoluteFsPath, path: AbsoluteFsPath, r3FileName: string,
options: ts.CompilerOptions, host: ts.CompilerHost,
fs: ReadonlyFileSystem, isCore: boolean, pkg: AbsoluteFsPath, path: AbsoluteFsPath,
r3FileName: string, options: ts.CompilerOptions, host: ts.CompilerHost,
additionalFiles: AbsoluteFsPath[] = []): BundleProgram {
const r3SymbolsPath = isCore ? findR3SymbolsPath(fs, dirname(path), r3FileName) : null;
const r3SymbolsPath = isCore ? findR3SymbolsPath(fs, fs.dirname(path), r3FileName) : null;
let rootPaths =
r3SymbolsPath ? [path, r3SymbolsPath, ...additionalFiles] : [path, ...additionalFiles];
@ -58,8 +58,8 @@ export function makeBundleProgram(
* Search the given directory hierarchy to find the path to the `r3_symbols` file.
*/
export function findR3SymbolsPath(
fs: FileSystem, directory: AbsoluteFsPath, filename: string): AbsoluteFsPath|null {
const r3SymbolsFilePath = resolve(directory, filename);
fs: ReadonlyFileSystem, directory: AbsoluteFsPath, filename: string): AbsoluteFsPath|null {
const r3SymbolsFilePath = fs.resolve(directory, filename);
if (fs.exists(r3SymbolsFilePath)) {
return r3SymbolsFilePath;
}
@ -72,12 +72,12 @@ export function findR3SymbolsPath(
.filter(p => p !== 'node_modules')
// Only interested in directories (and only those that are not symlinks)
.filter(p => {
const stat = fs.lstat(resolve(directory, p));
const stat = fs.lstat(fs.resolve(directory, p));
return stat.isDirectory() && !stat.isSymbolicLink();
});
for (const subDirectory of subDirectories) {
const r3SymbolsFilePath = findR3SymbolsPath(fs, resolve(directory, subDirectory), filename);
const r3SymbolsFilePath = findR3SymbolsPath(fs, fs.resolve(directory, subDirectory), filename);
if (r3SymbolsFilePath) {
return r3SymbolsFilePath;
}

View File

@ -9,7 +9,7 @@ import {createHash} from 'crypto';
import {satisfies} from 'semver';
import * as vm from 'vm';
import {AbsoluteFsPath, dirname, FileSystem, join, resolve} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathManipulation, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {PackageJsonFormatPropertiesMap} from './entry_point';
@ -186,13 +186,14 @@ export class ProcessedNgccPackageConfig implements Omit<RawNgccPackageConfig, 'e
*/
ignorableDeepImportMatchers: RegExp[];
constructor(packagePath: AbsoluteFsPath, {
constructor(fs: PathManipulation, packagePath: AbsoluteFsPath, {
entryPoints = {},
ignorableDeepImportMatchers = [],
}: RawNgccPackageConfig) {
const absolutePathEntries: [AbsoluteFsPath, NgccEntryPointConfig][] =
Object.entries(entryPoints).map(([relativePath,
config]) => [resolve(packagePath, relativePath), config]);
Object.entries(entryPoints).map(([
relativePath, config
]) => [fs.resolve(packagePath, relativePath), config]);
this.packagePath = packagePath;
this.entryPoints = new Map(absolutePathEntries);
@ -230,7 +231,7 @@ export class NgccConfiguration {
private cache = new Map<string, VersionedPackageConfig>();
readonly hash: string;
constructor(private fs: FileSystem, baseDir: AbsoluteFsPath) {
constructor(private fs: ReadonlyFileSystem, baseDir: AbsoluteFsPath) {
this.defaultConfig = this.processProjectConfig(DEFAULT_NGCC_CONFIG);
this.projectConfig = this.processProjectConfig(this.loadProjectConfig(baseDir));
this.hash = this.computeHash();
@ -261,7 +262,7 @@ export class NgccConfiguration {
getPackageConfig(packageName: string, packagePath: AbsoluteFsPath, version: string|null):
ProcessedNgccPackageConfig {
const rawPackageConfig = this.getRawPackageConfig(packageName, packagePath, version);
return new ProcessedNgccPackageConfig(packagePath, rawPackageConfig);
return new ProcessedNgccPackageConfig(this.fs, packagePath, rawPackageConfig);
}
private getRawPackageConfig(
@ -320,7 +321,7 @@ export class NgccConfiguration {
}
private loadProjectConfig(baseDir: AbsoluteFsPath): NgccProjectConfig {
const configFilePath = join(baseDir, NGCC_CONFIG_FILENAME);
const configFilePath = this.fs.join(baseDir, NGCC_CONFIG_FILENAME);
if (this.fs.exists(configFilePath)) {
try {
return this.evalSrcFile(configFilePath);
@ -334,7 +335,7 @@ export class NgccConfiguration {
private loadPackageConfig(packagePath: AbsoluteFsPath, version: string|null):
VersionedPackageConfig|null {
const configFilePath = join(packagePath, NGCC_CONFIG_FILENAME);
const configFilePath = this.fs.join(packagePath, NGCC_CONFIG_FILENAME);
if (this.fs.exists(configFilePath)) {
try {
const packageConfig = this.evalSrcFile(configFilePath);
@ -357,7 +358,7 @@ export class NgccConfiguration {
module: {exports: theExports},
exports: theExports,
require,
__dirname: dirname(srcPath),
__dirname: this.fs.dirname(srcPath),
__filename: srcPath
};
vm.runInNewContext(src, sandbox, {filename: srcPath});

View File

@ -5,11 +5,9 @@
* 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 {relative} from 'canonical-path';
import {basename} from 'path';
import * as ts from 'typescript';
import {AbsoluteFsPath, FileSystem, join, resolve} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathManipulation, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {parseStatementForUmdModule} from '../host/umd_host';
import {resolveFileWithPostfixes} from '../utils';
@ -130,10 +128,10 @@ export type GetEntryPointResult =
* entry-point.
*/
export function getEntryPointInfo(
fs: FileSystem, config: NgccConfiguration, logger: Logger, packagePath: AbsoluteFsPath,
fs: ReadonlyFileSystem, config: NgccConfiguration, logger: Logger, packagePath: AbsoluteFsPath,
entryPointPath: AbsoluteFsPath): GetEntryPointResult {
const packagePackageJsonPath = resolve(packagePath, 'package.json');
const entryPointPackageJsonPath = resolve(entryPointPath, 'package.json');
const packagePackageJsonPath = fs.resolve(packagePath, 'package.json');
const entryPointPackageJsonPath = fs.resolve(entryPointPath, 'package.json');
const loadedPackagePackageJson = loadPackageJson(fs, packagePackageJsonPath);
const loadedEntryPointPackageJson = (packagePackageJsonPath === entryPointPackageJsonPath) ?
loadedPackagePackageJson :
@ -163,7 +161,7 @@ export function getEntryPointInfo(
return IGNORED_ENTRY_POINT;
} else {
entryPointPackageJson = mergeConfigAndPackageJson(
loadedEntryPointPackageJson, entryPointConfig, packagePath, entryPointPath);
fs, loadedEntryPointPackageJson, entryPointConfig, packagePath, entryPointPath);
}
const typings = entryPointPackageJson.typings || entryPointPackageJson.types ||
@ -176,7 +174,8 @@ export function getEntryPointInfo(
// An entry-point is assumed to be compiled by Angular if there is either:
// * a `metadata.json` file next to the typings entry-point
// * a custom config for this entry-point
const metadataPath = resolve(entryPointPath, typings.replace(/\.d\.ts$/, '') + '.metadata.json');
const metadataPath =
fs.resolve(entryPointPath, typings.replace(/\.d\.ts$/, '') + '.metadata.json');
const compiledByAngular = entryPointConfig !== undefined || fs.exists(metadataPath);
const entryPointInfo: EntryPoint = {
@ -185,7 +184,7 @@ export function getEntryPointInfo(
packageName,
packagePath,
packageJson: entryPointPackageJson,
typings: resolve(entryPointPath, typings),
typings: fs.resolve(entryPointPath, typings),
compiledByAngular,
ignoreMissingDependencies:
entryPointConfig !== undefined ? !!entryPointConfig.ignoreMissingDependencies : false,
@ -208,8 +207,8 @@ export function isEntryPoint(result: GetEntryPointResult): result is EntryPoint
* @returns An entry-point format or `undefined` if none match the given property.
*/
export function getEntryPointFormat(
fs: FileSystem, entryPoint: EntryPoint, property: EntryPointJsonProperty): EntryPointFormat|
undefined {
fs: ReadonlyFileSystem, entryPoint: EntryPoint,
property: EntryPointJsonProperty): EntryPointFormat|undefined {
switch (property) {
case 'fesm2015':
return 'esm2015';
@ -226,13 +225,13 @@ export function getEntryPointFormat(
if (typeof browserFile !== 'string') {
return undefined;
}
return sniffModuleFormat(fs, join(entryPoint.path, browserFile));
return sniffModuleFormat(fs, fs.join(entryPoint.path, browserFile));
case 'main':
const mainFile = entryPoint.packageJson['main'];
if (mainFile === undefined) {
return undefined;
}
return sniffModuleFormat(fs, join(entryPoint.path, mainFile));
return sniffModuleFormat(fs, fs.join(entryPoint.path, mainFile));
case 'module':
const moduleFilePath = entryPoint.packageJson['module'];
// As of version 10, the `module` property in `package.json` should point to
@ -254,8 +253,8 @@ export function getEntryPointFormat(
* @param packageJsonPath the absolute path to the `package.json` file.
* @returns JSON from the `package.json` file if it is valid, `null` otherwise.
*/
function loadPackageJson(fs: FileSystem, packageJsonPath: AbsoluteFsPath): EntryPointPackageJson|
null {
function loadPackageJson(
fs: ReadonlyFileSystem, packageJsonPath: AbsoluteFsPath): EntryPointPackageJson|null {
try {
return JSON.parse(fs.readFile(packageJsonPath));
} catch {
@ -263,8 +262,8 @@ function loadPackageJson(fs: FileSystem, packageJsonPath: AbsoluteFsPath): Entry
}
}
function sniffModuleFormat(fs: FileSystem, sourceFilePath: AbsoluteFsPath): EntryPointFormat|
undefined {
function sniffModuleFormat(
fs: ReadonlyFileSystem, sourceFilePath: AbsoluteFsPath): EntryPointFormat|undefined {
const resolvedPath = resolveFileWithPostfixes(fs, sourceFilePath, ['', '.js', '/index.js']);
if (resolvedPath === null) {
return undefined;
@ -285,18 +284,19 @@ function sniffModuleFormat(fs: FileSystem, sourceFilePath: AbsoluteFsPath): Entr
}
function mergeConfigAndPackageJson(
entryPointPackageJson: EntryPointPackageJson|null, entryPointConfig: NgccEntryPointConfig,
packagePath: AbsoluteFsPath, entryPointPath: AbsoluteFsPath): EntryPointPackageJson {
fs: PathManipulation, entryPointPackageJson: EntryPointPackageJson|null,
entryPointConfig: NgccEntryPointConfig, packagePath: AbsoluteFsPath,
entryPointPath: AbsoluteFsPath): EntryPointPackageJson {
if (entryPointPackageJson !== null) {
return {...entryPointPackageJson, ...entryPointConfig.override};
} else {
const name = `${basename(packagePath)}/${relative(packagePath, entryPointPath)}`;
const name = `${fs.basename(packagePath)}/${fs.relative(packagePath, entryPointPath)}`;
return {name, ...entryPointConfig.override};
}
}
function guessTypingsFromPackageJson(
fs: FileSystem, entryPointPath: AbsoluteFsPath,
fs: ReadonlyFileSystem, entryPointPath: AbsoluteFsPath,
entryPointPackageJson: EntryPointPackageJson): AbsoluteFsPath|null {
for (const prop of SUPPORTED_FORMAT_PROPERTIES) {
const field = entryPointPackageJson[prop];
@ -305,7 +305,7 @@ function guessTypingsFromPackageJson(
continue;
}
const relativeTypingsPath = field.replace(/\.js$/, '.d.ts');
const typingsPath = resolve(entryPointPath, relativeTypingsPath);
const typingsPath = fs.resolve(entryPointPath, relativeTypingsPath);
if (fs.exists(typingsPath)) {
return typingsPath;
}
@ -321,14 +321,15 @@ function guessTypingsFromPackageJson(
* - The version is read off of the `version` property of the package's `package.json` file (if
* available).
*
* @param fs The `FileSystem` instance to use for parsing `packagePath` (if needed).
* @param fs The file-system to use for processing `packagePath`.
* @param packagePath the absolute path to the package.
* @param packagePackageJson the parsed `package.json` of the package (if available).
* @param entryPointPackageJson the parsed `package.json` of an entry-point (if available).
* @returns the computed name and version of the package.
*/
function getPackageNameAndVersion(
fs: FileSystem, packagePath: AbsoluteFsPath, packagePackageJson: EntryPointPackageJson|null,
fs: PathManipulation, packagePath: AbsoluteFsPath,
packagePackageJson: EntryPointPackageJson|null,
entryPointPackageJson: EntryPointPackageJson|
null): {packageName: string, packageVersion: string|null} {
let packageName: string;

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, FileSystem, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {PathMappings} from '../path_mappings';
import {BundleProgram, makeBundleProgram} from './bundle_program';
import {EntryPoint, EntryPointFormat} from './entry_point';
@ -86,7 +86,7 @@ export function makeEntryPointBundle(
}
function computePotentialDtsFilesFromJsFiles(
fs: FileSystem, srcProgram: ts.Program, formatPath: AbsoluteFsPath,
fs: ReadonlyFileSystem, srcProgram: ts.Program, formatPath: AbsoluteFsPath,
typingsPath: AbsoluteFsPath) {
const formatRoot = fs.dirname(formatPath);
const typingsRoot = fs.dirname(typingsPath);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
/**
* A cache that holds on to source files that can be shared for processing all entry-points in a
@ -29,7 +29,7 @@ import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
export class SharedFileCache {
private sfCache = new Map<AbsoluteFsPath, ts.SourceFile>();
constructor(private fs: FileSystem) {}
constructor(private fs: ReadonlyFileSystem) {}
/**
* Loads a `ts.SourceFile` if the provided `fileName` is deemed appropriate to be cached. To
@ -95,7 +95,7 @@ const DEFAULT_LIB_PATTERN = ['node_modules', 'typescript', 'lib', /^lib\..+\.d\.
* @param absPath The path for which to determine if it corresponds with a default library file.
* @param fs The filesystem to use for inspecting the path.
*/
export function isDefaultLibrary(absPath: AbsoluteFsPath, fs: FileSystem): boolean {
export function isDefaultLibrary(absPath: AbsoluteFsPath, fs: ReadonlyFileSystem): boolean {
return isFile(absPath, DEFAULT_LIB_PATTERN, fs);
}
@ -109,7 +109,7 @@ const ANGULAR_DTS_PATTERN = ['node_modules', '@angular', /./, /\.d\.ts$/];
* @param absPath The path for which to determine if it corresponds with an @angular .d.ts file.
* @param fs The filesystem to use for inspecting the path.
*/
export function isAngularDts(absPath: AbsoluteFsPath, fs: FileSystem): boolean {
export function isAngularDts(absPath: AbsoluteFsPath, fs: ReadonlyFileSystem): boolean {
return isFile(absPath, ANGULAR_DTS_PATTERN, fs);
}
@ -122,7 +122,7 @@ export function isAngularDts(absPath: AbsoluteFsPath, fs: FileSystem): boolean {
* @param fs The filesystem to use for inspecting the path.
*/
function isFile(
path: AbsoluteFsPath, segments: ReadonlyArray<string|RegExp>, fs: FileSystem): boolean {
path: AbsoluteFsPath, segments: ReadonlyArray<string|RegExp>, fs: ReadonlyFileSystem): boolean {
for (let i = segments.length - 1; i >= 0; i--) {
const pattern = segments[i];
const segment = fs.basename(path);
@ -147,7 +147,7 @@ function isFile(
export class EntryPointFileCache {
private readonly sfCache = new Map<AbsoluteFsPath, ts.SourceFile>();
constructor(private fs: FileSystem, private sharedFileCache: SharedFileCache) {}
constructor(private fs: ReadonlyFileSystem, private sharedFileCache: SharedFileCache) {}
/**
* Returns and caches a parsed `ts.SourceFile` for the provided `fileName`. If the `fileName` is
@ -178,7 +178,7 @@ export class EntryPointFileCache {
}
}
function readFile(absPath: AbsoluteFsPath, fs: FileSystem): string|undefined {
function readFile(absPath: AbsoluteFsPath, fs: ReadonlyFileSystem): string|undefined {
if (!fs.exists(absPath) || !fs.stat(absPath).isFile()) {
return undefined;
}
@ -190,7 +190,7 @@ function readFile(absPath: AbsoluteFsPath, fs: FileSystem): string|undefined {
*
* @param fs The filesystem to use for path operations.
*/
export function createModuleResolutionCache(fs: FileSystem): ts.ModuleResolutionCache {
export function createModuleResolutionCache(fs: ReadonlyFileSystem): ts.ModuleResolutionCache {
return ts.createModuleResolutionCache(fs.pwd(), fileName => {
return fs.isCaseSensitive() ? fileName : fileName.toLowerCase();
});

View File

@ -8,7 +8,7 @@
import * as ts from 'typescript';
import {ParsedConfiguration} from '../../..';
import {FileSystem} from '../../../src/ngtsc/file_system';
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {TypeScriptReflectionHost} from '../../../src/ngtsc/reflection';
import {DecorationAnalyzer} from '../analysis/decoration_analyzer';
@ -64,7 +64,7 @@ export type TransformResult = {
*/
export class Transformer {
constructor(
private fs: FileSystem, private logger: Logger,
private fs: ReadonlyFileSystem, private logger: Logger,
private tsConfig: ParsedConfiguration|null = null) {}
/**
@ -100,7 +100,7 @@ export class Transformer {
decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses);
if (bundle.dts) {
const dtsFormatter = new EsmRenderingFormatter(reflectionHost, bundle.isCore);
const dtsFormatter = new EsmRenderingFormatter(this.fs, reflectionHost, bundle.isCore);
const dtsRenderer =
new DtsRenderer(dtsFormatter, this.fs, this.logger, reflectionHost, bundle);
const renderedDtsFiles = dtsRenderer.renderProgram(
@ -129,16 +129,16 @@ export class Transformer {
getRenderingFormatter(host: NgccReflectionHost, bundle: EntryPointBundle): RenderingFormatter {
switch (bundle.format) {
case 'esm2015':
return new EsmRenderingFormatter(host, bundle.isCore);
return new EsmRenderingFormatter(this.fs, host, bundle.isCore);
case 'esm5':
return new Esm5RenderingFormatter(host, bundle.isCore);
return new Esm5RenderingFormatter(this.fs, host, bundle.isCore);
case 'umd':
if (!(host instanceof UmdReflectionHost)) {
throw new Error('UmdRenderer requires a UmdReflectionHost');
}
return new UmdRenderingFormatter(host, bundle.isCore);
return new UmdRenderingFormatter(this.fs, host, bundle.isCore);
case 'commonjs':
return new CommonJsRenderingFormatter(host, bundle.isCore);
return new CommonJsRenderingFormatter(this.fs, host, bundle.isCore);
default:
throw new Error(`Renderer for "${bundle.format}" not yet implemented.`);
}

View File

@ -5,10 +5,9 @@
* 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 {AbsoluteFsPath, resolve} from '../../src/ngtsc/file_system';
import {AbsoluteFsPath, PathManipulation} from '../../src/ngtsc/file_system';
import {ParsedConfiguration} from '../../src/perform_compile';
export type PathMappings = {
baseUrl: string,
paths: {[key: string]: string[]}
@ -18,11 +17,12 @@ export type PathMappings = {
* If `pathMappings` is not provided directly, then try getting it from `tsConfig`, if available.
*/
export function getPathMappingsFromTsConfig(
tsConfig: ParsedConfiguration|null, projectPath: AbsoluteFsPath): PathMappings|undefined {
fs: PathManipulation, tsConfig: ParsedConfiguration|null,
projectPath: AbsoluteFsPath): PathMappings|undefined {
if (tsConfig !== null && tsConfig.options.baseUrl !== undefined &&
tsConfig.options.paths !== undefined) {
return {
baseUrl: resolve(projectPath, tsConfig.options.baseUrl),
baseUrl: fs.resolve(projectPath, tsConfig.options.baseUrl),
paths: tsConfig.options.paths,
};
}

View File

@ -5,7 +5,7 @@
* 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 {dirname, relative} from 'canonical-path';
import {PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
import MagicString from 'magic-string';
import * as ts from 'typescript';
@ -24,8 +24,8 @@ import {stripExtension} from './utils';
* wrapper function for AMD, CommonJS and global module formats.
*/
export class CommonJsRenderingFormatter extends Esm5RenderingFormatter {
constructor(protected commonJsHost: NgccReflectionHost, isCore: boolean) {
super(commonJsHost, isCore);
constructor(fs: PathManipulation, protected commonJsHost: NgccReflectionHost, isCore: boolean) {
super(fs, commonJsHost, isCore);
}
/**
@ -51,7 +51,7 @@ export class CommonJsRenderingFormatter extends Esm5RenderingFormatter {
importManager: ImportManager, file: ts.SourceFile): void {
exports.forEach(e => {
const basePath = stripExtension(e.from);
const relativePath = './' + relative(dirname(entryPointBasePath), basePath);
const relativePath = './' + this.fs.relative(this.fs.dirname(entryPointBasePath), basePath);
const namedImport = entryPointBasePath !== basePath ?
importManager.generateNamedImport(relativePath, e.identifier) :
{symbol: e.identifier, moduleImport: null};

View File

@ -8,7 +8,7 @@
import MagicString from 'magic-string';
import * as ts from 'typescript';
import {FileSystem} from '../../../src/ngtsc/file_system';
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Reexport} from '../../../src/ngtsc/imports';
import {Logger} from '../../../src/ngtsc/logging';
import {CompileResult} from '../../../src/ngtsc/transform';
@ -56,8 +56,8 @@ export interface DtsClassInfo {
*/
export class DtsRenderer {
constructor(
private dtsFormatter: RenderingFormatter, private fs: FileSystem, private logger: Logger,
private host: NgccReflectionHost, private bundle: EntryPointBundle) {}
private dtsFormatter: RenderingFormatter, private fs: ReadonlyFileSystem,
private logger: Logger, private host: NgccReflectionHost, private bundle: EntryPointBundle) {}
renderProgram(
decorationAnalyses: DecorationAnalyses,

View File

@ -9,7 +9,7 @@ import {Statement} from '@angular/compiler';
import MagicString from 'magic-string';
import * as ts from 'typescript';
import {absoluteFromSourceFile, AbsoluteFsPath, dirname, relative, toRelativeImport} from '../../../src/ngtsc/file_system';
import {absoluteFromSourceFile, AbsoluteFsPath, PathManipulation, toRelativeImport} from '../../../src/ngtsc/file_system';
import {Reexport} from '../../../src/ngtsc/imports';
import {Import, ImportManager, translateStatement} from '../../../src/ngtsc/translator';
import {isDtsPath} from '../../../src/ngtsc/util/src/typescript';
@ -28,7 +28,9 @@ import {stripExtension} from './utils';
export class EsmRenderingFormatter implements RenderingFormatter {
protected printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed});
constructor(protected host: NgccReflectionHost, protected isCore: boolean) {}
constructor(
protected fs: PathManipulation, protected host: NgccReflectionHost,
protected isCore: boolean) {}
/**
* Add the imports at the top of the file, after any imports that are already there.
@ -57,7 +59,7 @@ export class EsmRenderingFormatter implements RenderingFormatter {
if (from) {
const basePath = stripExtension(from);
const relativePath = relative(dirname(entryPointBasePath), basePath);
const relativePath = this.fs.relative(this.fs.dirname(entryPointBasePath), basePath);
const relativeImport = toRelativeImport(relativePath);
exportFrom = entryPointBasePath !== basePath ? ` from '${relativeImport}'` : '';
}
@ -198,7 +200,7 @@ export class EsmRenderingFormatter implements RenderingFormatter {
const ngModuleName = info.ngModule.node.name.text;
const declarationFile = absoluteFromSourceFile(info.declaration.getSourceFile());
const ngModuleFile = absoluteFromSourceFile(info.ngModule.node.getSourceFile());
const relativePath = relative(dirname(declarationFile), ngModuleFile);
const relativePath = this.fs.relative(this.fs.dirname(declarationFile), ngModuleFile);
const relativeImport = toRelativeImport(relativePath);
const importPath = info.ngModule.ownedByModuleGuess ||
(declarationFile !== ngModuleFile ? stripExtension(relativeImport) : null);

View File

@ -9,7 +9,7 @@ import {ConstantPool, Expression, jsDocComment, LeadingComment, Statement, Wrapp
import MagicString from 'magic-string';
import * as ts from 'typescript';
import {FileSystem} from '../../../src/ngtsc/file_system';
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {ImportManager} from '../../../src/ngtsc/translator';
import {ParsedConfiguration} from '../../../src/perform_compile';
@ -33,7 +33,7 @@ import {FileToWrite, getImportRewriter, stripExtension} from './utils';
export class Renderer {
constructor(
private host: NgccReflectionHost, private srcFormatter: RenderingFormatter,
private fs: FileSystem, private logger: Logger, private bundle: EntryPointBundle,
private fs: ReadonlyFileSystem, private logger: Logger, private bundle: EntryPointBundle,
private tsConfig: ParsedConfiguration|null = null) {}
renderProgram(

View File

@ -9,7 +9,7 @@ import {fromObject, generateMapFileComment, SourceMapConverter} from 'convert-so
import MagicString from 'magic-string';
import * as ts from 'typescript';
import {absoluteFrom, absoluteFromSourceFile, basename, FileSystem} from '../../../src/ngtsc/file_system';
import {absoluteFrom, absoluteFromSourceFile, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {RawSourceMap, SourceFileLoader} from '../../../src/ngtsc/sourcemaps';
@ -26,7 +26,7 @@ export interface SourceMapInfo {
* with an appropriate source-map comment pointing to the merged source-map.
*/
export function renderSourceAndMap(
logger: Logger, fs: FileSystem, sourceFile: ts.SourceFile,
logger: Logger, fs: ReadonlyFileSystem, sourceFile: ts.SourceFile,
generatedMagicString: MagicString): FileToWrite[] {
const generatedPath = absoluteFromSourceFile(sourceFile);
const generatedMapPath = absoluteFrom(`${generatedPath}.map`);
@ -55,7 +55,7 @@ export function renderSourceAndMap(
{path: generatedPath, contents: `${generatedFile.contents}\n${mergedMap.toComment()}`}
];
} else {
const sourceMapComment = generateMapFileComment(`${basename(generatedPath)}.map`);
const sourceMapComment = generateMapFileComment(`${fs.basename(generatedPath)}.map`);
return [
{path: generatedPath, contents: `${generatedFile.contents}\n${sourceMapComment}`},
{path: generatedMapPath, contents: mergedMap.toJSON()}

View File

@ -5,10 +5,10 @@
* 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 {dirname, relative} from 'canonical-path';
import MagicString from 'magic-string';
import * as ts from 'typescript';
import {PathManipulation} from '../../../src/ngtsc/file_system';
import {Reexport} from '../../../src/ngtsc/imports';
import {Import, ImportManager} from '../../../src/ngtsc/translator';
import {ExportInfo} from '../analysis/private_declarations_analyzer';
@ -26,8 +26,8 @@ type AmdConditional = ts.ConditionalExpression&{whenTrue: ts.CallExpression};
* wrapper function for AMD, CommonJS and global module formats.
*/
export class UmdRenderingFormatter extends Esm5RenderingFormatter {
constructor(protected umdHost: UmdReflectionHost, isCore: boolean) {
super(umdHost, isCore);
constructor(fs: PathManipulation, protected umdHost: UmdReflectionHost, isCore: boolean) {
super(fs, umdHost, isCore);
}
/**
@ -87,7 +87,7 @@ export class UmdRenderingFormatter extends Esm5RenderingFormatter {
lastStatement ? lastStatement.getEnd() : factoryFunction.body.getEnd() - 1;
exports.forEach(e => {
const basePath = stripExtension(e.from);
const relativePath = './' + relative(dirname(entryPointBasePath), basePath);
const relativePath = './' + this.fs.relative(this.fs.dirname(entryPointBasePath), basePath);
const namedImport = entryPointBasePath !== basePath ?
importManager.generateNamedImport(relativePath, e.identifier) :
{symbol: e.identifier, moduleImport: null};

View File

@ -7,7 +7,7 @@
*/
import * as ts from 'typescript';
import {absoluteFrom, AbsoluteFsPath, FileSystem, isRooted} from '../../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, isRooted, ReadonlyFileSystem} from '../../src/ngtsc/file_system';
import {DeclarationNode, KnownDeclaration} from '../../src/ngtsc/reflection';
/**
@ -122,7 +122,7 @@ export class FactoryMap<K, V> {
* @returns An absolute path to the first matching existing file, or `null` if none exist.
*/
export function resolveFileWithPostfixes(
fs: FileSystem, path: AbsoluteFsPath, postFixes: string[]): AbsoluteFsPath|null {
fs: ReadonlyFileSystem, path: AbsoluteFsPath, postFixes: string[]): AbsoluteFsPath|null {
for (const postFix of postFixes) {
const testPath = absoluteFrom(path + postFix);
if (fs.exists(testPath) && fs.stat(testPath).isFile()) {

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem} from '../../../../src/ngtsc/file_system';
import {AbsoluteFsPath, FileSystem, ReadonlyFileSystem} from '../../../../src/ngtsc/file_system';
import {needsCleaning} from '../../packages/build_marker';
import {EntryPoint} from '../../packages/entry_point';
@ -16,7 +16,7 @@ import {isLocalDirectory} from './utils';
* A class that can clean ngcc artifacts from a directory.
*/
export class PackageCleaner {
constructor(private fs: FileSystem, private cleaners: CleaningStrategy[]) {}
constructor(private fs: ReadonlyFileSystem, private cleaners: CleaningStrategy[]) {}
/**
* Recurse through the file-system cleaning files and directories as determined by the configured

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem} from '../../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../../src/ngtsc/file_system';
/**
* Returns true if the given `path` is a directory (not a symlink) and actually exists.
@ -13,7 +13,7 @@ import {AbsoluteFsPath, FileSystem} from '../../../../src/ngtsc/file_system';
* @param fs the current filesystem
* @param path the path to check
*/
export function isLocalDirectory(fs: FileSystem, path: AbsoluteFsPath): boolean {
export function isLocalDirectory(fs: ReadonlyFileSystem, path: AbsoluteFsPath): boolean {
if (fs.exists(path)) {
const stat = fs.lstat(path);
return stat.isDirectory();

View File

@ -6,7 +6,7 @@
* 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 {absoluteFromSourceFile, AbsoluteFsPath, dirname, FileSystem, isLocalRelativePath, join, relative, resolve} from '../../../src/ngtsc/file_system';
import {absoluteFromSourceFile, AbsoluteFsPath, FileSystem, isLocalRelativePath} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging';
import {isDtsPath} from '../../../src/ngtsc/util/src/typescript';
import {EntryPoint, EntryPointJsonProperty} from '../packages/entry_point';
@ -39,7 +39,7 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
formatProperties: EntryPointJsonProperty[]) {
// The new folder is at the root of the overall package
const entryPoint = bundle.entryPoint;
const ngccFolder = join(entryPoint.packagePath, NGCC_DIRECTORY);
const ngccFolder = this.fs.join(entryPoint.packagePath, NGCC_DIRECTORY);
this.copyBundle(bundle, entryPoint.packagePath, ngccFolder);
transformedFiles.forEach(file => this.writeFile(file, entryPoint.packagePath, ngccFolder));
this.updatePackageJson(entryPoint, formatProperties, ngccFolder);
@ -69,11 +69,11 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
protected copyBundle(
bundle: EntryPointBundle, packagePath: AbsoluteFsPath, ngccFolder: AbsoluteFsPath) {
bundle.src.program.getSourceFiles().forEach(sourceFile => {
const relativePath = relative(packagePath, absoluteFromSourceFile(sourceFile));
const relativePath = this.fs.relative(packagePath, absoluteFromSourceFile(sourceFile));
const isInsidePackage = isLocalRelativePath(relativePath);
if (!sourceFile.isDeclarationFile && isInsidePackage) {
const newFilePath = resolve(ngccFolder, relativePath);
this.fs.ensureDir(dirname(newFilePath));
const newFilePath = this.fs.resolve(ngccFolder, relativePath);
this.fs.ensureDir(this.fs.dirname(newFilePath));
this.fs.copyFile(absoluteFromSourceFile(sourceFile), newFilePath);
}
});
@ -85,9 +85,9 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
// This is either `.d.ts` or `.d.ts.map` file
super.writeFileAndBackup(file);
} else {
const relativePath = relative(packagePath, file.path);
const newFilePath = resolve(ngccFolder, relativePath);
this.fs.ensureDir(dirname(newFilePath));
const relativePath = this.fs.relative(packagePath, file.path);
const newFilePath = this.fs.resolve(ngccFolder, relativePath);
this.fs.ensureDir(this.fs.dirname(newFilePath));
this.fs.writeFile(newFilePath, file.contents);
}
}
@ -97,8 +97,8 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
// This is either `.d.ts` or `.d.ts.map` file
super.revertFileAndBackup(filePath);
} else if (this.fs.exists(filePath)) {
const relativePath = relative(packagePath, filePath);
const newFilePath = resolve(packagePath, NGCC_DIRECTORY, relativePath);
const relativePath = this.fs.relative(packagePath, filePath);
const newFilePath = this.fs.resolve(packagePath, NGCC_DIRECTORY, relativePath);
this.fs.removeFile(newFilePath);
}
}
@ -112,15 +112,15 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
}
const packageJson = entryPoint.packageJson;
const packageJsonPath = join(entryPoint.path, 'package.json');
const packageJsonPath = this.fs.join(entryPoint.path, 'package.json');
// All format properties point to the same format-path.
const oldFormatProp = formatProperties[0]!;
const oldFormatPath = packageJson[oldFormatProp]!;
const oldAbsFormatPath = resolve(entryPoint.path, oldFormatPath);
const oldAbsFormatPath = this.fs.resolve(entryPoint.path, oldFormatPath);
const newAbsFormatPath =
resolve(ngccFolder, relative(entryPoint.packagePath, oldAbsFormatPath));
const newFormatPath = relative(entryPoint.path, newAbsFormatPath);
this.fs.resolve(ngccFolder, this.fs.relative(entryPoint.packagePath, oldAbsFormatPath));
const newFormatPath = this.fs.relative(entryPoint.path, newAbsFormatPath);
// Update all properties in `package.json` (both in memory and on disk).
const update = this.pkgJsonUpdater.createUpdate();
@ -146,7 +146,7 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
}
const packageJson = entryPoint.packageJson;
const packageJsonPath = join(entryPoint.path, 'package.json');
const packageJsonPath = this.fs.join(entryPoint.path, 'package.json');
// Revert all properties in `package.json` (both in memory and on disk).
// Since `updatePackageJson()` only adds properties, it is safe to just remove them (if they

View File

@ -5,7 +5,7 @@
* 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 {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, relative} from '../../../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '../../../src/ngtsc/file_system';
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -114,7 +114,7 @@ runInEachFileSystem(() => {
loadTestFiles(createPackage(basePath, 'some-package'));
spyOn(config, 'getPackageConfig')
.and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), {
new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: {
'.': {ignore: true},
},
@ -137,7 +137,7 @@ runInEachFileSystem(() => {
]);
spyOn(config, 'getPackageConfig')
.and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), {
new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: {
'./sub-entry-point-1': {ignore: true},
},
@ -457,7 +457,7 @@ runInEachFileSystem(() => {
function dumpEntryPointPaths(
basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] {
return entryPoints.map(
x => [relative(basePath, x.packagePath), relative(basePath, x.path)]);
x => [fs.relative(basePath, x.packagePath), fs.relative(basePath, x.path)]);
}
});
});

View File

@ -5,7 +5,7 @@
* 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 {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, relative} from '../../../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '../../../src/ngtsc/file_system';
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -231,7 +231,7 @@ runInEachFileSystem(() => {
function dumpEntryPointPaths(
basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] {
return entryPoints.map(
x => [relative(basePath, x.packagePath), relative(basePath, x.path)]);
x => [fs.relative(basePath, x.packagePath), fs.relative(basePath, x.path)]);
}
});
});

View File

@ -5,7 +5,7 @@
* 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 {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, relative} from '../../../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '../../../src/ngtsc/file_system';
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -118,7 +118,7 @@ runInEachFileSystem(() => {
loadTestFiles(createPackage(basePath, 'some-package'));
spyOn(config, 'getPackageConfig')
.and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), {
new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: {
'.': {ignore: true},
},
@ -383,7 +383,7 @@ runInEachFileSystem(() => {
function dumpEntryPointPaths(
basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] {
return entryPoints.map(
x => [relative(basePath, x.packagePath), relative(basePath, x.path)]);
x => [fs.relative(basePath, x.packagePath), fs.relative(basePath, x.path)]);
}
});
@ -419,7 +419,7 @@ runInEachFileSystem(() => {
loadTestFiles(createPackage(basePath, 'some-package'));
spyOn(config, 'getPackageConfig')
.and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), {
new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: {
'.': {ignore: true},
},

View File

@ -5,7 +5,7 @@
* 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 {FileSystem} from '../../../src/ngtsc/file_system';
import {PathManipulation} from '../../../src/ngtsc/file_system';
import {LockFile} from '../../src/locking/lock_file';
/**
@ -13,7 +13,7 @@ import {LockFile} from '../../src/locking/lock_file';
*/
export class MockLockFile implements LockFile {
constructor(
fs: FileSystem, private log: string[] = [], public path = fs.resolve('/lockfile'),
fs: PathManipulation, private log: string[] = [], public path = fs.resolve('/lockfile'),
private pid = '1234') {}
write() {
this.log.push('write()');

View File

@ -10,7 +10,7 @@
import {readFileSync} from 'fs';
import * as os from 'os';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, join} from '../../../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '../../../src/ngtsc/file_system';
import {Folder, MockFileSystem, runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadStandardTestFiles, loadTestFiles} from '../../../src/ngtsc/testing';
@ -1017,7 +1017,7 @@ runInEachFileSystem(() => {
function markPropertiesAsProcessed(packagePath: string, properties: EntryPointJsonProperty[]) {
const basePath = _('/node_modules');
const targetPackageJsonPath = join(basePath, packagePath, 'package.json');
const targetPackageJsonPath = fs.join(basePath, packagePath, 'package.json');
const targetPackage = loadPackage(packagePath);
markAsProcessed(
pkgJsonUpdater, targetPackage, targetPackageJsonPath, ['typings', ...properties]);

View File

@ -7,7 +7,7 @@
*/
import {createHash} from 'crypto';
import {absoluteFrom, FileSystem, getFileSystem} from '../../../src/ngtsc/file_system';
import {absoluteFrom, getFileSystem, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing';
import {DEFAULT_NGCC_CONFIG, NgccConfiguration, ProcessLockingConfiguration} from '../../src/packages/configuration';
@ -15,7 +15,7 @@ import {DEFAULT_NGCC_CONFIG, NgccConfiguration, ProcessLockingConfiguration} fro
runInEachFileSystem(() => {
let _Abs: typeof absoluteFrom;
let fs: FileSystem;
let fs: ReadonlyFileSystem;
beforeEach(() => {
_Abs = absoluteFrom;

View File

@ -225,7 +225,7 @@ runInEachFileSystem(() => {
spyOn(config, 'getPackageConfig')
.and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some_package'), {
new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some_package'), {
entryPoints: {
'./ignored_entry_point': {ignore: true},
},

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, join, relative} from '../../../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, getFileSystem, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -17,7 +17,7 @@ runInEachFileSystem(() => {
describe('getEntryPointInfo()', () => {
let SOME_PACKAGE: AbsoluteFsPath;
let _: typeof absoluteFrom;
let fs: FileSystem;
let fs: ReadonlyFileSystem;
beforeEach(() => {
_ = absoluteFrom;
@ -71,7 +71,7 @@ runInEachFileSystem(() => {
const config = new NgccConfiguration(fs, _('/project'));
spyOn(config, 'getPackageConfig')
.and.returnValue(new ProcessedNgccPackageConfig(
_('/project/node_modules/some_package'),
fs, _('/project/node_modules/some_package'),
{entryPoints: {'./valid_entry_point': {ignore: true}}}));
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
@ -80,7 +80,7 @@ runInEachFileSystem(() => {
});
it('should retrieve the entry-point\'s version from the package\'s `package.json`', () => {
const entryPointPath = join(SOME_PACKAGE, 'valid_entry_point');
const entryPointPath = fs.join(SOME_PACKAGE, 'valid_entry_point');
loadTestFiles([
{
@ -102,15 +102,15 @@ runInEachFileSystem(() => {
`,
},
{
name: join(SOME_PACKAGE, 'package.json'),
name: fs.join(SOME_PACKAGE, 'package.json'),
contents: createPackageJson('', {version: '1.0.0'}),
},
{
name: join(entryPointPath, 'package.json'),
name: fs.join(entryPointPath, 'package.json'),
contents: createPackageJson('valid_entry_point', {version: '2.0.0'}),
},
{
name: join(entryPointPath, 'valid_entry_point.metadata.json'),
name: fs.join(entryPointPath, 'valid_entry_point.metadata.json'),
contents: 'some meta data',
},
]);
@ -123,7 +123,7 @@ runInEachFileSystem(() => {
});
it('should use `null` for version if it cannot be retrieved from a `package.json`', () => {
const entryPointPath = join(SOME_PACKAGE, 'valid_entry_point');
const entryPointPath = fs.join(SOME_PACKAGE, 'valid_entry_point');
loadTestFiles([
{
@ -145,15 +145,15 @@ runInEachFileSystem(() => {
`,
},
{
name: join(SOME_PACKAGE, 'package.json'),
name: fs.join(SOME_PACKAGE, 'package.json'),
contents: createPackageJson(''),
},
{
name: join(entryPointPath, 'package.json'),
name: fs.join(entryPointPath, 'package.json'),
contents: createPackageJson('valid_entry_point'),
},
{
name: join(entryPointPath, 'valid_entry_point.metadata.json'),
name: fs.join(entryPointPath, 'valid_entry_point.metadata.json'),
contents: 'some meta data',
},
]);
@ -184,7 +184,7 @@ runInEachFileSystem(() => {
};
spyOn(config, 'getPackageConfig')
.and.returnValue(new ProcessedNgccPackageConfig(
_('/project/node_modules/some_package'),
fs, _('/project/node_modules/some_package'),
{entryPoints: {'./valid_entry_point': {override}}}));
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
@ -236,7 +236,7 @@ runInEachFileSystem(() => {
JSON.parse(createPackageJson('missing_package_json', {excludes: ['name']}));
spyOn(config, 'getPackageConfig')
.and.returnValue(new ProcessedNgccPackageConfig(
_('/project/node_modules/some_package/'),
fs, _('/project/node_modules/some_package/'),
{entryPoints: {'./missing_package_json': {override}}}));
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
@ -273,7 +273,7 @@ runInEachFileSystem(() => {
// Ensure a `package.json` exists for the entry-point (containing `entryPointName`).
loadTestFiles([
{
name: join(entryPointPath, 'package.json'),
name: fs.join(entryPointPath, 'package.json'),
contents: JSON.stringify({name: entryPointName, typings: './index.d.ts'}),
},
]);
@ -284,11 +284,11 @@ runInEachFileSystem(() => {
// avoid returning `INCOMPATIBLE_ENTRY_POINT` (since there is no `package.json`).
loadTestFiles([
{
name: join(packagePath, 'ngcc.config.js'),
name: fs.join(packagePath, 'ngcc.config.js'),
contents: `
module.exports = {
entryPoints: {
'${relative(packagePath, entryPointPath)}': {
'${fs.relative(packagePath, entryPointPath)}': {
override: {typings: './index.d.ts'},
},
},
@ -321,7 +321,7 @@ runInEachFileSystem(() => {
it('for a secondary entry-point with a `package.json`', () => {
const packagePath = _(`/project/node_modules/${nameWithScope('on-disk-package-name')}`);
const entryPointPath = join(packagePath, 'some-entry-point');
const entryPointPath = fs.join(packagePath, 'some-entry-point');
const expectedPackageName = nameWithScope('package-json-package-name');
setUpPackageWithEntryPointPackageJson(
@ -332,7 +332,7 @@ runInEachFileSystem(() => {
it('for a secondary entry-point without a `package.json`', () => {
const packagePath = _(`/project/node_modules/${nameWithScope('on-disk-package-name')}`);
const entryPointPath = join(packagePath, 'some-entry-point');
const entryPointPath = fs.join(packagePath, 'some-entry-point');
const expectedPackageName = nameWithScope('on-disk-package-name');
setUpPackageWithoutEntryPointPackageJson(packagePath, entryPointPath);
@ -354,7 +354,7 @@ runInEachFileSystem(() => {
it('for a secondary entry-point without a `package.json` in nested `node_modules/`', () => {
const packagePath = _(`/project/node_modules/other-package/node_modules/${
nameWithScope('on-disk-package-name')}`);
const entryPointPath = join(packagePath, 'some-entry-point');
const entryPointPath = fs.join(packagePath, 'some-entry-point');
const expectedPackageName = nameWithScope('on-disk-package-name');
setUpPackageWithoutEntryPointPackageJson(packagePath, entryPointPath);
@ -384,7 +384,7 @@ runInEachFileSystem(() => {
it('for a secondary entry-point with a `package.json` outside `node_modules/`', () => {
const packagePath = _(`/project/libs/${nameWithScope('on-disk-package-name')}`);
const entryPointPath = join(packagePath, 'some-entry-point');
const entryPointPath = fs.join(packagePath, 'some-entry-point');
const expectedPackageName = nameWithScope('package-json-package-name');
setUpPackageWithEntryPointPackageJson(expectedPackageName, entryPointPath);
@ -394,7 +394,7 @@ runInEachFileSystem(() => {
it('for a secondary entry-point without a `package.json` outside `node_modules/`', () => {
const packagePath = _(`/project/libs/${nameWithScope('on-disk-package-name')}`);
const entryPointPath = join(packagePath, 'some-entry-point');
const entryPointPath = fs.join(packagePath, 'some-entry-point');
const expectedPackageName = nameWithScope('on-disk-package-name');
setUpPackageWithoutEntryPointPackageJson(packagePath, entryPointPath);
@ -522,7 +522,7 @@ runInEachFileSystem(() => {
const config = new NgccConfiguration(fs, _('/project'));
spyOn(config, 'getPackageConfig')
.and.returnValue(new ProcessedNgccPackageConfig(
_('/project/node_modules/some_package'),
fs, _('/project/node_modules/some_package'),
{entryPoints: {'./missing_metadata': {}}}));
const entryPoint = getEntryPointInfo(
fs, config, new MockLogger(), SOME_PACKAGE,
@ -626,7 +626,7 @@ runInEachFileSystem(() => {
describe('getEntryPointFormat()', () => {
let SOME_PACKAGE: AbsoluteFsPath;
let _: typeof absoluteFrom;
let fs: FileSystem;
let fs: ReadonlyFileSystem;
let entryPoint: EntryPoint;
beforeEach(() => {
@ -781,6 +781,6 @@ export function createPackageJson(
return JSON.stringify(packageJson);
}
export function loadPackageJson(fs: FileSystem, packagePath: string) {
export function loadPackageJson(fs: ReadonlyFileSystem, packagePath: string) {
return JSON.parse(fs.readFile(fs.resolve(packagePath + '/package.json')));
}

View File

@ -157,7 +157,7 @@ exports.D = D;
new DecorationAnalyzer(fs, bundle, host, referencesRegistry).analyzeProgram();
const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host, bundle.entryPoint.packagePath)
.analyzeProgram(bundle.src.program);
const renderer = new CommonJsRenderingFormatter(host, false);
const renderer = new CommonJsRenderingFormatter(fs, host, false);
const importManager = new ImportManager(new NoopImportRewriter(), 'i');
return {
host,

View File

@ -34,7 +34,7 @@ function setup(file: {name: AbsoluteFsPath, contents: string}) {
new DecorationAnalyzer(fs, bundle, host, referencesRegistry).analyzeProgram();
const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host, bundle.entryPoint.packagePath)
.analyzeProgram(bundle.src.program);
const renderer = new Esm5RenderingFormatter(host, false);
const renderer = new Esm5RenderingFormatter(fs, host, false);
const importManager = new ImportManager(new NoopImportRewriter(), IMPORT_PREFIX);
return {
host,

View File

@ -40,7 +40,7 @@ function setup(files: TestFile[], dtsFiles?: TestFile[]) {
new DecorationAnalyzer(fs, bundle, host, referencesRegistry).analyzeProgram();
const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host, bundle.entryPoint.packagePath)
.analyzeProgram(bundle.src.program);
const renderer = new EsmRenderingFormatter(host, false);
const renderer = new EsmRenderingFormatter(fs, host, false);
const importManager = new ImportManager(new NoopImportRewriter(), IMPORT_PREFIX);
return {
host,

View File

@ -34,7 +34,7 @@ function setup(file: TestFile) {
new DecorationAnalyzer(fs, bundle, host, referencesRegistry).analyzeProgram();
const switchMarkerAnalyses =
new SwitchMarkerAnalyzer(host, bundle.entryPoint.packagePath).analyzeProgram(src.program);
const renderer = new UmdRenderingFormatter(host, false);
const renderer = new UmdRenderingFormatter(fs, host, false);
const importManager = new ImportManager(new NoopImportRewriter(), 'i');
return {
decorationAnalyses,

View File

@ -5,7 +5,7 @@
* 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 {absoluteFrom, FileSystem, getFileSystem, join} from '../../../src/ngtsc/file_system';
import {absoluteFrom, FileSystem, getFileSystem} from '../../../src/ngtsc/file_system';
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -578,7 +578,7 @@ runInEachFileSystem(() => {
it('should revert changes to `package.json`', () => {
const entryPoint = esm5bundle.entryPoint;
const packageJsonPath = join(entryPoint.packagePath, 'package.json');
const packageJsonPath = fs.join(entryPoint.packagePath, 'package.json');
fileWriter.writeBundle(
esm5bundle,

View File

@ -10,8 +10,8 @@ import {compileComponentFromMetadata, compileDeclareComponentFromMetadata, Const
import * as ts from 'typescript';
import {CycleAnalyzer} from '../../cycles';
import {ErrorCode, FatalDiagnosticError, ngErrorCode} from '../../diagnostics';
import {absoluteFrom, relative, resolve} from '../../file_system';
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
import {absoluteFrom, relative} from '../../file_system';
import {DefaultImportRecorder, ModuleResolver, Reference, ReferenceEmitter} from '../../imports';
import {DependencyTracker} from '../../incremental/api';
import {IndexingContext} from '../../indexer';
@ -21,7 +21,6 @@ import {ClassDeclaration, DeclarationNode, Decorator, ReflectionHost, reflectObj
import {ComponentScopeReader, LocalModuleScopeRegistry, TypeCheckScopeRegistry} from '../../scope';
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerFlags, HandlerPrecedence, ResolveResult} from '../../transform';
import {TemplateSourceMapping, TypeCheckContext} from '../../typecheck/api';
import {getTemplateId, makeTemplateDiagnostic} from '../../typecheck/diagnostics';
import {tsSourceMapBug29300Fixed} from '../../util/src/ts_source_map_bug_29300';
import {SubsetOfKeys} from '../../util/src/typescript';

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {FileSystem} from '../../file_system';
import {PathManipulation} from '../../file_system';
import {TestFile} from '../../file_system/testing';
import {makeProgram} from '../../testing';
@ -31,7 +31,7 @@ import {makeProgram} from '../../testing';
*
* represents a program where a.ts exports from b.ts and imports from c.ts.
*/
export function makeProgramFromGraph(fs: FileSystem, graph: string): {
export function makeProgramFromGraph(fs: PathManipulation, graph: string): {
program: ts.Program,
host: ts.CompilerHost,
options: ts.CompilerOptions,

View File

@ -8,7 +8,7 @@
import {removeComments, removeMapFileComments} from 'convert-source-map';
import {decode, encode, SourceMapMappings, SourceMapSegment} from 'sourcemap-codec';
import {AbsoluteFsPath, FileSystem} from '../../file_system';
import {AbsoluteFsPath, PathManipulation} from '../../file_system';
import {RawSourceMap} from './raw_source_map';
import {compareSegments, offsetSegment, SegmentMarker} from './segment_marker';
@ -39,7 +39,7 @@ export class SourceFile {
readonly inline: boolean,
/** Any source files referenced by the raw source map associated with this source file. */
readonly sources: (SourceFile|null)[],
private fs: FileSystem,
private fs: PathManipulation,
) {
this.contents = removeSourceMapComments(contents);
this.startOfLinePositions = computeStartOfLinePositions(this.contents);

View File

@ -7,7 +7,7 @@
*/
import {commentRegex, fromComment, mapFileCommentRegex} from 'convert-source-map';
import {AbsoluteFsPath, FileSystem} from '../../file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../file_system';
import {Logger} from '../../logging';
import {RawSourceMap} from './raw_source_map';
@ -28,7 +28,7 @@ export class SourceFileLoader {
private currentPaths: AbsoluteFsPath[] = [];
constructor(
private fs: FileSystem, private logger: Logger,
private fs: ReadonlyFileSystem, private logger: Logger,
/** A map of URL schemes to base paths. The scheme name should be lowercase. */
private schemeMap: Record<string, AbsoluteFsPath>) {}

View File

@ -7,7 +7,7 @@
*/
import {encode} from 'sourcemap-codec';
import {absoluteFrom, FileSystem, getFileSystem} from '../../file_system';
import {absoluteFrom, getFileSystem, PathManipulation} from '../../file_system';
import {runInEachFileSystem} from '../../file_system/testing';
import {RawSourceMap} from '../src/raw_source_map';
import {SegmentMarker} from '../src/segment_marker';
@ -15,7 +15,7 @@ import {computeStartOfLinePositions, ensureOriginalSegmentLinks, extractOriginal
runInEachFileSystem(() => {
describe('SourceFile and utilities', () => {
let fs: FileSystem;
let fs: PathManipulation;
let _: typeof absoluteFrom;
beforeEach(() => {

View File

@ -109,6 +109,11 @@ function loadAngularFolder(): Folder {
/**
* Load real files from the real file-system into a mock file-system.
*
* Note that this function contains a mix of `FileSystem` calls and NodeJS `fs` calls.
* This is because the function is a bridge between the "real" file-system (via `fs`) and the "mock"
* file-system (via `FileSystem`).
*
* @param fs the file-system where the directory is to be loaded.
* @param directoryPath the path to the directory we want to load.
* @param mockPath the path within the mock file-system where the directory is to be loaded.

View File

@ -9,7 +9,7 @@
import {isSyntaxError, Position} from '@angular/compiler';
import * as ts from 'typescript';
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, relative, resolve} from '../src/ngtsc/file_system';
import {absoluteFrom, AbsoluteFsPath, getFileSystem, ReadonlyFileSystem, relative, resolve} from '../src/ngtsc/file_system';
import {replaceTsWithNgInErrors} from './ngtsc/diagnostics';
import * as api from './transformers/api';
@ -109,10 +109,8 @@ export function formatDiagnostics(
}
/** Used to read configuration files. */
// TODO(ayazhafiz): split FileSystem into a ReadonlyFileSystem and make this a
// subset of that.
export type ConfigurationHost =
Pick<FileSystem, 'readFile'|'exists'|'lstat'|'resolve'|'join'|'dirname'|'extname'|'pwd'>;
export type ConfigurationHost = Pick<
ReadonlyFileSystem, 'readFile'|'exists'|'lstat'|'resolve'|'join'|'dirname'|'extname'|'pwd'>;
export interface ParsedConfiguration {
project: string;

View File

@ -5,7 +5,7 @@
* 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 {FileSystem} from '../../../src/ngtsc/file_system';
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {getBuildOutputDirectory, getRootDirectory} from './compile_test';
import {verifyUniqueFactory} from './di_checks';
@ -33,7 +33,7 @@ const EXTRA_CHECK_FUNCTIONS: Record<string, ExtraCheckFunction> = {
* @param expectedFiles The list of expected-generated pairs to compare.
*/
export function checkExpectations(
fs: FileSystem, testPath: string, failureMessage: string, expectedFiles: ExpectedFile[],
fs: ReadonlyFileSystem, testPath: string, failureMessage: string, expectedFiles: ExpectedFile[],
extraChecks: ExtraCheck[]): void {
const builtDirectory = getBuildOutputDirectory(fs);
for (const expectedFile of expectedFiles) {

View File

@ -7,7 +7,7 @@
*/
import * as ts from 'typescript';
import {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, FileSystem, PathManipulation, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {initMockFileSystem} from '../../../src/ngtsc/file_system/testing';
import {loadStandardTestFiles, loadTestDirectory, NgtscTestCompilerHost} from '../../../src/ngtsc/testing';
import {Diagnostics, performCompilation} from '../../../src/perform_compile';
@ -65,7 +65,7 @@ export function compileTest(
*
* @param fs the mock file-system where the compilation is happening.
*/
export function getRootDirectory(fs: FileSystem): AbsoluteFsPath {
export function getRootDirectory(fs: PathManipulation): AbsoluteFsPath {
return fs.resolve('/');
}
@ -75,7 +75,7 @@ export function getRootDirectory(fs: FileSystem): AbsoluteFsPath {
*
* @param fs the mock file-system where the compilation is happening.
*/
export function getBuildOutputDirectory(fs: FileSystem): AbsoluteFsPath {
export function getBuildOutputDirectory(fs: PathManipulation): AbsoluteFsPath {
return fs.resolve('/built');
}
@ -129,7 +129,7 @@ function getOptions(
* This allows us to simulate, more reliably, files that have `\r\n` line-endings.
* (See `test_cases/r3_view_compiler_i18n/line_ending_normalization/template.html`.)
*/
function monkeyPatchReadFile(fs: FileSystem): void {
function monkeyPatchReadFile(fs: ReadonlyFileSystem): void {
const originalReadFile = fs.readFile;
fs.readFile = (path: AbsoluteFsPath): string => {
const file = originalReadFile.call(fs, path);

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem, NodeJSFileSystem, PathSegment} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, NodeJSFileSystem, PathSegment, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
const fs = new NodeJSFileSystem();
const basePath = fs.resolve(__dirname, '../test_cases');
@ -55,7 +55,7 @@ export function* getComplianceTests(testConfigPath: string): Generator<Complianc
}
function loadTestCasesFile(
fs: FileSystem, testCasesPath: AbsoluteFsPath, basePath: AbsoluteFsPath): any {
fs: ReadonlyFileSystem, testCasesPath: AbsoluteFsPath, basePath: AbsoluteFsPath): any {
try {
return JSON.parse(fs.readFile(testCasesPath));
} catch (e) {

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, FileSystem} from '../../../src/ngtsc/file_system';
import {AbsoluteFsPath, ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {ConsoleLogger, LogLevel} from '../../../src/ngtsc/logging';
import {SourceFileLoader} from '../../../src/ngtsc/sourcemaps';
@ -33,8 +33,8 @@ import {SourceFileLoader} from '../../../src/ngtsc/sourcemaps';
* @returns The content of the expected source file, stripped of the mapping information.
*/
export function checkMappings(
fs: FileSystem, generated: string, generatedPath: AbsoluteFsPath, expectedSource: string,
expectedPath: AbsoluteFsPath): string {
fs: ReadonlyFileSystem, generated: string, generatedPath: AbsoluteFsPath,
expectedSource: string, expectedPath: AbsoluteFsPath): string {
const actualMappings = getMappedSegments(fs, generatedPath, generated);
const {expected, mappings} = extractMappings(fs, expectedSource);
@ -77,7 +77,7 @@ interface SegmentMapping {
* @param expected The content of the expected file containing source-map information.
*/
function extractMappings(
fs: FileSystem, expected: string): {expected: string, mappings: SegmentMapping[]} {
fs: ReadonlyFileSystem, expected: string): {expected: string, mappings: SegmentMapping[]} {
const mappings: SegmentMapping[] = [];
// capture and remove source mapping info
expected = expected.replace(
@ -113,7 +113,8 @@ function unescape(str: string): string {
* empty array is returned if there is no source-map file found.
*/
function getMappedSegments(
fs: FileSystem, generatedPath: AbsoluteFsPath, generatedContents: string): SegmentMapping[] {
fs: ReadonlyFileSystem, generatedPath: AbsoluteFsPath,
generatedContents: string): SegmentMapping[] {
const logger = new ConsoleLogger(LogLevel.debug);
const loader = new SourceFileLoader(fs, logger, {});
const generatedFile = loader.loadSourceFile(generatedPath, generatedContents);

View File

@ -5,7 +5,7 @@
* 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 {AbsoluteFsPath, resolve} from '@angular/compiler-cli/src/ngtsc/file_system';
import {AbsoluteFsPath, getFileSystem, PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
import {AbsoluteSourceSpan, IdentifierKind, IndexedComponent, TopLevelIdentifier} from '@angular/compiler-cli/src/ngtsc/indexer';
import {ParseSourceFile} from '@angular/compiler/src/compiler';
@ -14,6 +14,7 @@ import {NgtscTestEnvironment} from './env';
runInEachFileSystem(() => {
describe('ngtsc component indexing', () => {
let fs: PathManipulation;
let env!: NgtscTestEnvironment;
let testSourceFile: AbsoluteFsPath;
let testTemplateFile: AbsoluteFsPath;
@ -21,8 +22,9 @@ runInEachFileSystem(() => {
beforeEach(() => {
env = NgtscTestEnvironment.setup();
env.tsconfig();
testSourceFile = resolve(env.basePath, 'test.ts');
testTemplateFile = resolve(env.basePath, 'test.html');
fs = getFileSystem();
testSourceFile = fs.resolve(env.basePath, 'test.ts');
testTemplateFile = fs.resolve(env.basePath, 'test.html');
});
describe('indexing metadata', () => {