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 * found in the LICENSE file at https://angular.io/license
*/ */
import {LinkerOptions} from '../..'; import {LinkerOptions} from '../..';
import {FileSystem} from '../../../src/ngtsc/file_system'; import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging'; import {Logger} from '../../../src/ngtsc/logging';
export interface LinkerPluginOptions extends Partial<LinkerOptions> { export interface LinkerPluginOptions extends Partial<LinkerOptions> {
/** /**
* File-system, used to load up the input source-map and content. * File-system, used to load up the input source-map and content.
*/ */
fileSystem: FileSystem; fileSystem: ReadonlyFileSystem;
/** /**
* Logger used by the linker. * 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 * 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 * 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 {Logger} from '../../../src/ngtsc/logging';
import {SourceFileLoader} from '../../../src/ngtsc/sourcemaps'; import {SourceFileLoader} from '../../../src/ngtsc/sourcemaps';
import {AstFactory} from '../../../src/ngtsc/translator'; 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; this.options.sourceMapping ? new SourceFileLoader(this.fileSystem, this.logger, {}) : null;
private constructor( private constructor(
readonly fileSystem: FileSystem, readonly logger: Logger, readonly host: AstHost<TExpression>, readonly fileSystem: ReadonlyFileSystem, readonly logger: Logger,
readonly factory: AstFactory<TStatement, TExpression>, readonly options: LinkerOptions) {} readonly host: AstHost<TExpression>, readonly factory: AstFactory<TStatement, TExpression>,
readonly options: LinkerOptions) {}
static create<TStatement, TExpression>( static create<TStatement, TExpression>(
fileSystem: FileSystem, logger: Logger, host: AstHost<TExpression>, fileSystem: ReadonlyFileSystem, logger: Logger, host: AstHost<TExpression>,
factory: AstFactory<TStatement, TExpression>, factory: AstFactory<TStatement, TExpression>,
options: Partial<LinkerOptions>): LinkerEnvironment<TStatement, TExpression> { options: Partial<LinkerOptions>): LinkerEnvironment<TStatement, TExpression> {
return new LinkerEnvironment(fileSystem, logger, host, factory, { 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 {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, PipeDecoratorHandler, ReferencesRegistry, ResourceLoader} from '../../../src/ngtsc/annotations';
import {CycleAnalyzer, ImportGraph} from '../../../src/ngtsc/cycles'; import {CycleAnalyzer, ImportGraph} from '../../../src/ngtsc/cycles';
import {isFatalDiagnosticError} from '../../../src/ngtsc/diagnostics'; 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 {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 {CompoundMetadataReader, CompoundMetadataRegistry, DtsMetadataReader, InjectableClassRegistry, LocalMetadataRegistry, ResourceRegistry} from '../../../src/ngtsc/metadata';
import {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator'; 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. * Simple class that resolves and loads files directly from the filesystem.
*/ */
class NgccResourceLoader implements ResourceLoader { class NgccResourceLoader implements ResourceLoader {
constructor(private fs: FileSystem) {} constructor(private fs: ReadonlyFileSystem) {}
canPreload = false; canPreload = false;
preload(): undefined|Promise<void> { preload(): undefined|Promise<void> {
throw new Error('Not implemented.'); throw new Error('Not implemented.');
} }
load(url: string): string { load(url: string): string {
return this.fs.readFile(resolve(url)); return this.fs.readFile(this.fs.resolve(url));
} }
resolve(url: string, containingFile: string): string { 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( constructor(
private fs: FileSystem, private bundle: EntryPointBundle, private fs: ReadonlyFileSystem, private bundle: EntryPointBundle,
private reflectionHost: NgccReflectionHost, private referencesRegistry: ReferencesRegistry, private reflectionHost: NgccReflectionHost, private referencesRegistry: ReferencesRegistry,
private diagnosticHandler: (error: ts.Diagnostic) => void = () => {}, private diagnosticHandler: (error: ts.Diagnostic) => void = () => {},
private tsConfig: ParsedConfiguration|null = null) {} private tsConfig: ParsedConfiguration|null = null) {}

View File

@ -8,7 +8,7 @@
*/ */
import * as yargs from 'yargs'; 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 {ConsoleLogger, LogLevel} from '../../src/ngtsc/logging';
import {NgccOptions} from './ngcc_options'; import {NgccOptions} from './ngcc_options';
@ -115,9 +115,10 @@ export function parseCommandLineOptions(args: string[]): NgccOptions {
process.exit(1); 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 propertiesToConsider = options.p;
const targetEntryPointPath = options.t; const targetEntryPointPath = options.t;
const compileAllFormats = !options['first-only']; 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 * 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 * 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 {EntryPoint} from '../packages/entry_point';
import {resolveFileWithPostfixes} from '../utils'; import {resolveFileWithPostfixes} from '../utils';
@ -32,7 +32,7 @@ export function createDependencyInfo(): DependencyInfo {
} }
export abstract class DependencyHostBase implements DependencyHost { 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. * Find all the dependencies for the entry-point at the given path.

View File

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

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {PathMappings} from '../path_mappings';
import {EsmDependencyHost} from './esm_dependency_host'; import {EsmDependencyHost} from './esm_dependency_host';
import {ModuleResolver} from './module_resolver'; import {ModuleResolver} from './module_resolver';
@ -14,7 +14,7 @@ import {ModuleResolver} from './module_resolver';
* Helper functions for computing dependencies via typings files. * Helper functions for computing dependencies via typings files.
*/ */
export class DtsDependencyHost extends EsmDependencyHost { export class DtsDependencyHost extends EsmDependencyHost {
constructor(fs: FileSystem, pathMappings?: PathMappings) { constructor(fs: ReadonlyFileSystem, pathMappings?: PathMappings) {
super( super(
fs, new ModuleResolver(fs, pathMappings, ['', '.d.ts', '/index.d.ts', '.js', '/index.js']), fs, new ModuleResolver(fs, pathMappings, ['', '.d.ts', '/index.d.ts', '.js', '/index.js']),
false); false);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import * as ts from 'typescript'; 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 {DependencyHostBase} from './dependency_host';
import {ModuleResolver} from './module_resolver'; import {ModuleResolver} from './module_resolver';
@ -15,7 +15,8 @@ import {ModuleResolver} from './module_resolver';
*/ */
export class EsmDependencyHost extends DependencyHostBase { export class EsmDependencyHost extends DependencyHostBase {
constructor( constructor(
fs: FileSystem, moduleResolver: ModuleResolver, private scanImportExpressions = true) { fs: ReadonlyFileSystem, moduleResolver: ModuleResolver,
private scanImportExpressions = true) {
super(fs, moduleResolver); super(fs, moduleResolver);
} }
// By skipping trivia here we don't have to account for it in the processing below // 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 * 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 * 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 {PathMappings} from '../path_mappings';
import {isRelativePath, resolveFileWithPostfixes} from '../utils'; import {isRelativePath, resolveFileWithPostfixes} from '../utils';
@ -25,9 +25,9 @@ import {isRelativePath, resolveFileWithPostfixes} from '../utils';
export class ModuleResolver { export class ModuleResolver {
private pathMappings: ProcessedPathMapping[]; private pathMappings: ProcessedPathMapping[];
constructor(private fs: FileSystem, pathMappings?: PathMappings, readonly relativeExtensions = [ constructor(
'', '.js', '/index.js' private fs: ReadonlyFileSystem, pathMappings?: PathMappings,
]) { readonly relativeExtensions = ['', '.js', '/index.js']) {
this.pathMappings = pathMappings ? this.processPathMappings(pathMappings) : []; this.pathMappings = pathMappings ? this.processPathMappings(pathMappings) : [];
} }
@ -54,7 +54,7 @@ export class ModuleResolver {
* Convert the `pathMappings` into a collection of `PathMapper` functions. * Convert the `pathMappings` into a collection of `PathMapper` functions.
*/ */
private processPathMappings(pathMappings: PathMappings): ProcessedPathMapping[] { private processPathMappings(pathMappings: PathMappings): ProcessedPathMapping[] {
const baseUrl = absoluteFrom(pathMappings.baseUrl); const baseUrl = this.fs.resolve(pathMappings.baseUrl);
return Object.keys(pathMappings.paths).map(pathPattern => { return Object.keys(pathMappings.paths).map(pathPattern => {
const matcher = splitOnStar(pathPattern); const matcher = splitOnStar(pathPattern);
const templates = pathMappings.paths[pathPattern].map(splitOnStar); const templates = pathMappings.paths[pathPattern].map(splitOnStar);
@ -71,7 +71,7 @@ export class ModuleResolver {
*/ */
private resolveAsRelativePath(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null { private resolveAsRelativePath(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null {
const resolvedPath = resolveFileWithPostfixes( 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); return resolvedPath && new ResolvedRelativeModule(resolvedPath);
} }
@ -115,13 +115,13 @@ export class ModuleResolver {
*/ */
private resolveAsEntryPoint(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null { private resolveAsEntryPoint(moduleName: string, fromPath: AbsoluteFsPath): ResolvedModule|null {
let folder = fromPath; let folder = fromPath;
while (!isRoot(folder)) { while (!this.fs.isRoot(folder)) {
folder = dirname(folder); folder = this.fs.dirname(folder);
if (folder.endsWith('node_modules')) { if (folder.endsWith('node_modules')) {
// Skip up if the folder already ends in 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)) { if (this.isEntryPoint(modulePath)) {
return new ResolvedExternalModule(modulePath); return new ResolvedExternalModule(modulePath);
} else if (this.resolveAsRelativePath(modulePath, fromPath)) { } 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`. * This is achieved by checking for the existence of `${modulePath}/package.json`.
*/ */
private isEntryPoint(modulePath: AbsoluteFsPath): boolean { 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) { private computeMappedTemplates(mapping: ProcessedPathMapping, match: string) {
return mapping.templates.map( 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 { private findPackagePath(path: AbsoluteFsPath): AbsoluteFsPath|null {
let folder = path; let folder = path;
while (!isRoot(folder)) { while (!this.fs.isRoot(folder)) {
folder = dirname(folder); folder = this.fs.dirname(folder);
if (this.fs.exists(join(folder, 'package.json'))) { if (this.fs.exists(this.fs.join(folder, 'package.json'))) {
return folder; return folder;
} }
} }

View File

@ -5,9 +5,8 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {Logger} from '../../../src/ngtsc/logging';
import {EntryPointWithDependencies} from '../dependencies/dependency_host'; import {EntryPointWithDependencies} from '../dependencies/dependency_host';
import {DependencyResolver} from '../dependencies/dependency_resolver'; import {DependencyResolver} from '../dependencies/dependency_resolver';
import {NgccConfiguration} from '../packages/configuration'; import {NgccConfiguration} from '../packages/configuration';
@ -20,7 +19,7 @@ import {NGCC_DIRECTORY} from '../writing/new_entry_point_file_writer';
*/ */
export class EntryPointCollector { export class EntryPointCollector {
constructor( constructor(
private fs: FileSystem, private config: NgccConfiguration, private logger: Logger, private fs: ReadonlyFileSystem, private config: NgccConfiguration, private logger: Logger,
private resolver: DependencyResolver) {} private resolver: DependencyResolver) {}
/** /**

View File

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

View File

@ -5,9 +5,8 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {Logger} from '../../../src/ngtsc/logging';
import {EntryPointWithDependencies} from '../dependencies/dependency_host'; import {EntryPointWithDependencies} from '../dependencies/dependency_host';
import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver'; import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/dependency_resolver';
import {NgccConfiguration} from '../packages/configuration'; import {NgccConfiguration} from '../packages/configuration';
@ -36,9 +35,9 @@ export abstract class TracingEntryPointFinder implements EntryPointFinder {
private basePaths: AbsoluteFsPath[]|null = null; private basePaths: AbsoluteFsPath[]|null = null;
constructor( constructor(
protected fs: FileSystem, protected config: NgccConfiguration, protected logger: Logger, protected fs: ReadonlyFileSystem, protected config: NgccConfiguration,
protected resolver: DependencyResolver, protected basePath: AbsoluteFsPath, protected logger: Logger, protected resolver: DependencyResolver,
protected pathMappings: PathMappings|undefined) {} protected basePath: AbsoluteFsPath, protected pathMappings: PathMappings|undefined) {}
/** /**
* Search for Angular package entry-points. * 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 * 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 * 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 {Logger} from '../../../src/ngtsc/logging';
import {PathMappings} from '../path_mappings'; import {PathMappings} from '../path_mappings';
@ -34,7 +34,7 @@ export function getBasePaths(
const fs = getFileSystem(); const fs = getFileSystem();
const basePaths = [sourceDirectory]; const basePaths = [sourceDirectory];
if (pathMappings) { if (pathMappings) {
const baseUrl = resolve(pathMappings.baseUrl); const baseUrl = fs.resolve(pathMappings.baseUrl);
if (fs.isRoot(baseUrl)) { if (fs.isRoot(baseUrl)) {
logger.warn( logger.warn(
`The provided pathMappings baseUrl is the root path ${baseUrl}.\n` + `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. // 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. // 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 * (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.) * one of the base paths.)
*/ */
export function dedupePaths(paths: AbsoluteFsPath[]): AbsoluteFsPath[] { function dedupePaths(fs: PathManipulation, paths: AbsoluteFsPath[]): AbsoluteFsPath[] {
const root: Node = {children: new Map()}; const root: Node = {children: new Map()};
for (const path of paths) { for (const path of paths) {
addPath(root, path); addPath(fs, root, path);
} }
return flattenTree(root); 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. * 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; let node = root;
if (!isRoot(path)) { if (!fs.isRoot(path)) {
const segments = path.split('/'); const segments = path.split('/');
for (let index = 0; index < segments.length; index++) { for (let index = 0; index < segments.length; index++) {
if (isLeaf(node)) { if (isLeaf(node)) {

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {Logger} from '../../../../src/ngtsc/logging';
import {AsyncLocker} from '../../locking/async_locker'; import {AsyncLocker} from '../../locking/async_locker';
import {FileWriter} from '../../writing/file_writer'; import {FileWriter} from '../../writing/file_writer';
@ -21,7 +21,7 @@ import {ClusterMaster} from './master';
*/ */
export class ClusterExecutor implements Executor { export class ClusterExecutor implements Executor {
constructor( 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 fileWriter: FileWriter, private pkgJsonUpdater: PackageJsonUpdater,
private lockFile: AsyncLocker, private lockFile: AsyncLocker,
private createTaskCompletedCallback: CreateTaskCompletedCallback) {} private createTaskCompletedCallback: CreateTaskCompletedCallback) {}

View File

@ -10,7 +10,7 @@
import * as cluster from 'cluster'; 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 {Logger} from '../../../../src/ngtsc/logging';
import {FileWriter} from '../../writing/file_writer'; import {FileWriter} from '../../writing/file_writer';
import {PackageJsonUpdater} from '../../writing/package_json_updater'; import {PackageJsonUpdater} from '../../writing/package_json_updater';
@ -35,7 +35,7 @@ export class ClusterMaster {
private remainingRespawnAttempts = 3; private remainingRespawnAttempts = 3;
constructor( 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, private fileWriter: FileWriter, private pkgJsonUpdater: PackageJsonUpdater,
analyzeEntryPoints: AnalyzeEntryPointsFn, analyzeEntryPoints: AnalyzeEntryPointsFn,
createTaskCompletedCallback: CreateTaskCompletedCallback) { createTaskCompletedCallback: CreateTaskCompletedCallback) {

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@ import {createHash} from 'crypto';
import {satisfies} from 'semver'; import {satisfies} from 'semver';
import * as vm from 'vm'; 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'; import {PackageJsonFormatPropertiesMap} from './entry_point';
@ -186,13 +186,14 @@ export class ProcessedNgccPackageConfig implements Omit<RawNgccPackageConfig, 'e
*/ */
ignorableDeepImportMatchers: RegExp[]; ignorableDeepImportMatchers: RegExp[];
constructor(packagePath: AbsoluteFsPath, { constructor(fs: PathManipulation, packagePath: AbsoluteFsPath, {
entryPoints = {}, entryPoints = {},
ignorableDeepImportMatchers = [], ignorableDeepImportMatchers = [],
}: RawNgccPackageConfig) { }: RawNgccPackageConfig) {
const absolutePathEntries: [AbsoluteFsPath, NgccEntryPointConfig][] = const absolutePathEntries: [AbsoluteFsPath, NgccEntryPointConfig][] =
Object.entries(entryPoints).map(([relativePath, Object.entries(entryPoints).map(([
config]) => [resolve(packagePath, relativePath), config]); relativePath, config
]) => [fs.resolve(packagePath, relativePath), config]);
this.packagePath = packagePath; this.packagePath = packagePath;
this.entryPoints = new Map(absolutePathEntries); this.entryPoints = new Map(absolutePathEntries);
@ -230,7 +231,7 @@ export class NgccConfiguration {
private cache = new Map<string, VersionedPackageConfig>(); private cache = new Map<string, VersionedPackageConfig>();
readonly hash: string; readonly hash: string;
constructor(private fs: FileSystem, baseDir: AbsoluteFsPath) { constructor(private fs: ReadonlyFileSystem, baseDir: AbsoluteFsPath) {
this.defaultConfig = this.processProjectConfig(DEFAULT_NGCC_CONFIG); this.defaultConfig = this.processProjectConfig(DEFAULT_NGCC_CONFIG);
this.projectConfig = this.processProjectConfig(this.loadProjectConfig(baseDir)); this.projectConfig = this.processProjectConfig(this.loadProjectConfig(baseDir));
this.hash = this.computeHash(); this.hash = this.computeHash();
@ -261,7 +262,7 @@ export class NgccConfiguration {
getPackageConfig(packageName: string, packagePath: AbsoluteFsPath, version: string|null): getPackageConfig(packageName: string, packagePath: AbsoluteFsPath, version: string|null):
ProcessedNgccPackageConfig { ProcessedNgccPackageConfig {
const rawPackageConfig = this.getRawPackageConfig(packageName, packagePath, version); const rawPackageConfig = this.getRawPackageConfig(packageName, packagePath, version);
return new ProcessedNgccPackageConfig(packagePath, rawPackageConfig); return new ProcessedNgccPackageConfig(this.fs, packagePath, rawPackageConfig);
} }
private getRawPackageConfig( private getRawPackageConfig(
@ -320,7 +321,7 @@ export class NgccConfiguration {
} }
private loadProjectConfig(baseDir: AbsoluteFsPath): NgccProjectConfig { 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)) { if (this.fs.exists(configFilePath)) {
try { try {
return this.evalSrcFile(configFilePath); return this.evalSrcFile(configFilePath);
@ -334,7 +335,7 @@ export class NgccConfiguration {
private loadPackageConfig(packagePath: AbsoluteFsPath, version: string|null): private loadPackageConfig(packagePath: AbsoluteFsPath, version: string|null):
VersionedPackageConfig|null { VersionedPackageConfig|null {
const configFilePath = join(packagePath, NGCC_CONFIG_FILENAME); const configFilePath = this.fs.join(packagePath, NGCC_CONFIG_FILENAME);
if (this.fs.exists(configFilePath)) { if (this.fs.exists(configFilePath)) {
try { try {
const packageConfig = this.evalSrcFile(configFilePath); const packageConfig = this.evalSrcFile(configFilePath);
@ -357,7 +358,7 @@ export class NgccConfiguration {
module: {exports: theExports}, module: {exports: theExports},
exports: theExports, exports: theExports,
require, require,
__dirname: dirname(srcPath), __dirname: this.fs.dirname(srcPath),
__filename: srcPath __filename: srcPath
}; };
vm.runInNewContext(src, sandbox, {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 * 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 * 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 * 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 {Logger} from '../../../src/ngtsc/logging';
import {parseStatementForUmdModule} from '../host/umd_host'; import {parseStatementForUmdModule} from '../host/umd_host';
import {resolveFileWithPostfixes} from '../utils'; import {resolveFileWithPostfixes} from '../utils';
@ -130,10 +128,10 @@ export type GetEntryPointResult =
* entry-point. * entry-point.
*/ */
export function getEntryPointInfo( export function getEntryPointInfo(
fs: FileSystem, config: NgccConfiguration, logger: Logger, packagePath: AbsoluteFsPath, fs: ReadonlyFileSystem, config: NgccConfiguration, logger: Logger, packagePath: AbsoluteFsPath,
entryPointPath: AbsoluteFsPath): GetEntryPointResult { entryPointPath: AbsoluteFsPath): GetEntryPointResult {
const packagePackageJsonPath = resolve(packagePath, 'package.json'); const packagePackageJsonPath = fs.resolve(packagePath, 'package.json');
const entryPointPackageJsonPath = resolve(entryPointPath, 'package.json'); const entryPointPackageJsonPath = fs.resolve(entryPointPath, 'package.json');
const loadedPackagePackageJson = loadPackageJson(fs, packagePackageJsonPath); const loadedPackagePackageJson = loadPackageJson(fs, packagePackageJsonPath);
const loadedEntryPointPackageJson = (packagePackageJsonPath === entryPointPackageJsonPath) ? const loadedEntryPointPackageJson = (packagePackageJsonPath === entryPointPackageJsonPath) ?
loadedPackagePackageJson : loadedPackagePackageJson :
@ -163,7 +161,7 @@ export function getEntryPointInfo(
return IGNORED_ENTRY_POINT; return IGNORED_ENTRY_POINT;
} else { } else {
entryPointPackageJson = mergeConfigAndPackageJson( entryPointPackageJson = mergeConfigAndPackageJson(
loadedEntryPointPackageJson, entryPointConfig, packagePath, entryPointPath); fs, loadedEntryPointPackageJson, entryPointConfig, packagePath, entryPointPath);
} }
const typings = entryPointPackageJson.typings || entryPointPackageJson.types || 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: // 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 `metadata.json` file next to the typings entry-point
// * a custom config for this 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 compiledByAngular = entryPointConfig !== undefined || fs.exists(metadataPath);
const entryPointInfo: EntryPoint = { const entryPointInfo: EntryPoint = {
@ -185,7 +184,7 @@ export function getEntryPointInfo(
packageName, packageName,
packagePath, packagePath,
packageJson: entryPointPackageJson, packageJson: entryPointPackageJson,
typings: resolve(entryPointPath, typings), typings: fs.resolve(entryPointPath, typings),
compiledByAngular, compiledByAngular,
ignoreMissingDependencies: ignoreMissingDependencies:
entryPointConfig !== undefined ? !!entryPointConfig.ignoreMissingDependencies : false, 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. * @returns An entry-point format or `undefined` if none match the given property.
*/ */
export function getEntryPointFormat( export function getEntryPointFormat(
fs: FileSystem, entryPoint: EntryPoint, property: EntryPointJsonProperty): EntryPointFormat| fs: ReadonlyFileSystem, entryPoint: EntryPoint,
undefined { property: EntryPointJsonProperty): EntryPointFormat|undefined {
switch (property) { switch (property) {
case 'fesm2015': case 'fesm2015':
return 'esm2015'; return 'esm2015';
@ -226,13 +225,13 @@ export function getEntryPointFormat(
if (typeof browserFile !== 'string') { if (typeof browserFile !== 'string') {
return undefined; return undefined;
} }
return sniffModuleFormat(fs, join(entryPoint.path, browserFile)); return sniffModuleFormat(fs, fs.join(entryPoint.path, browserFile));
case 'main': case 'main':
const mainFile = entryPoint.packageJson['main']; const mainFile = entryPoint.packageJson['main'];
if (mainFile === undefined) { if (mainFile === undefined) {
return undefined; return undefined;
} }
return sniffModuleFormat(fs, join(entryPoint.path, mainFile)); return sniffModuleFormat(fs, fs.join(entryPoint.path, mainFile));
case 'module': case 'module':
const moduleFilePath = entryPoint.packageJson['module']; const moduleFilePath = entryPoint.packageJson['module'];
// As of version 10, the `module` property in `package.json` should point to // 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. * @param packageJsonPath the absolute path to the `package.json` file.
* @returns JSON from the `package.json` file if it is valid, `null` otherwise. * @returns JSON from the `package.json` file if it is valid, `null` otherwise.
*/ */
function loadPackageJson(fs: FileSystem, packageJsonPath: AbsoluteFsPath): EntryPointPackageJson| function loadPackageJson(
null { fs: ReadonlyFileSystem, packageJsonPath: AbsoluteFsPath): EntryPointPackageJson|null {
try { try {
return JSON.parse(fs.readFile(packageJsonPath)); return JSON.parse(fs.readFile(packageJsonPath));
} catch { } catch {
@ -263,8 +262,8 @@ function loadPackageJson(fs: FileSystem, packageJsonPath: AbsoluteFsPath): Entry
} }
} }
function sniffModuleFormat(fs: FileSystem, sourceFilePath: AbsoluteFsPath): EntryPointFormat| function sniffModuleFormat(
undefined { fs: ReadonlyFileSystem, sourceFilePath: AbsoluteFsPath): EntryPointFormat|undefined {
const resolvedPath = resolveFileWithPostfixes(fs, sourceFilePath, ['', '.js', '/index.js']); const resolvedPath = resolveFileWithPostfixes(fs, sourceFilePath, ['', '.js', '/index.js']);
if (resolvedPath === null) { if (resolvedPath === null) {
return undefined; return undefined;
@ -285,18 +284,19 @@ function sniffModuleFormat(fs: FileSystem, sourceFilePath: AbsoluteFsPath): Entr
} }
function mergeConfigAndPackageJson( function mergeConfigAndPackageJson(
entryPointPackageJson: EntryPointPackageJson|null, entryPointConfig: NgccEntryPointConfig, fs: PathManipulation, entryPointPackageJson: EntryPointPackageJson|null,
packagePath: AbsoluteFsPath, entryPointPath: AbsoluteFsPath): EntryPointPackageJson { entryPointConfig: NgccEntryPointConfig, packagePath: AbsoluteFsPath,
entryPointPath: AbsoluteFsPath): EntryPointPackageJson {
if (entryPointPackageJson !== null) { if (entryPointPackageJson !== null) {
return {...entryPointPackageJson, ...entryPointConfig.override}; return {...entryPointPackageJson, ...entryPointConfig.override};
} else { } else {
const name = `${basename(packagePath)}/${relative(packagePath, entryPointPath)}`; const name = `${fs.basename(packagePath)}/${fs.relative(packagePath, entryPointPath)}`;
return {name, ...entryPointConfig.override}; return {name, ...entryPointConfig.override};
} }
} }
function guessTypingsFromPackageJson( function guessTypingsFromPackageJson(
fs: FileSystem, entryPointPath: AbsoluteFsPath, fs: ReadonlyFileSystem, entryPointPath: AbsoluteFsPath,
entryPointPackageJson: EntryPointPackageJson): AbsoluteFsPath|null { entryPointPackageJson: EntryPointPackageJson): AbsoluteFsPath|null {
for (const prop of SUPPORTED_FORMAT_PROPERTIES) { for (const prop of SUPPORTED_FORMAT_PROPERTIES) {
const field = entryPointPackageJson[prop]; const field = entryPointPackageJson[prop];
@ -305,7 +305,7 @@ function guessTypingsFromPackageJson(
continue; continue;
} }
const relativeTypingsPath = field.replace(/\.js$/, '.d.ts'); const relativeTypingsPath = field.replace(/\.js$/, '.d.ts');
const typingsPath = resolve(entryPointPath, relativeTypingsPath); const typingsPath = fs.resolve(entryPointPath, relativeTypingsPath);
if (fs.exists(typingsPath)) { if (fs.exists(typingsPath)) {
return 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 * - The version is read off of the `version` property of the package's `package.json` file (if
* available). * 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 packagePath the absolute path to the package.
* @param packagePackageJson the parsed `package.json` of the package (if available). * @param packagePackageJson the parsed `package.json` of the package (if available).
* @param entryPointPackageJson the parsed `package.json` of an entry-point (if available). * @param entryPointPackageJson the parsed `package.json` of an entry-point (if available).
* @returns the computed name and version of the package. * @returns the computed name and version of the package.
*/ */
function getPackageNameAndVersion( function getPackageNameAndVersion(
fs: FileSystem, packagePath: AbsoluteFsPath, packagePackageJson: EntryPointPackageJson|null, fs: PathManipulation, packagePath: AbsoluteFsPath,
packagePackageJson: EntryPointPackageJson|null,
entryPointPackageJson: EntryPointPackageJson| entryPointPackageJson: EntryPointPackageJson|
null): {packageName: string, packageVersion: string|null} { null): {packageName: string, packageVersion: string|null} {
let packageName: string; let packageName: string;

View File

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

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import * as ts from 'typescript'; 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 * 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 { export class SharedFileCache {
private sfCache = new Map<AbsoluteFsPath, ts.SourceFile>(); 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 * 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 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. * @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); 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 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. * @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); 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. * @param fs The filesystem to use for inspecting the path.
*/ */
function isFile( 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--) { for (let i = segments.length - 1; i >= 0; i--) {
const pattern = segments[i]; const pattern = segments[i];
const segment = fs.basename(path); const segment = fs.basename(path);
@ -147,7 +147,7 @@ function isFile(
export class EntryPointFileCache { export class EntryPointFileCache {
private readonly sfCache = new Map<AbsoluteFsPath, ts.SourceFile>(); 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 * 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()) { if (!fs.exists(absPath) || !fs.stat(absPath).isFile()) {
return undefined; return undefined;
} }
@ -190,7 +190,7 @@ function readFile(absPath: AbsoluteFsPath, fs: FileSystem): string|undefined {
* *
* @param fs The filesystem to use for path operations. * @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 ts.createModuleResolutionCache(fs.pwd(), fileName => {
return fs.isCaseSensitive() ? fileName : fileName.toLowerCase(); return fs.isCaseSensitive() ? fileName : fileName.toLowerCase();
}); });

View File

@ -8,7 +8,7 @@
import * as ts from 'typescript'; import * as ts from 'typescript';
import {ParsedConfiguration} from '../../..'; import {ParsedConfiguration} from '../../..';
import {FileSystem} from '../../../src/ngtsc/file_system'; import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
import {Logger} from '../../../src/ngtsc/logging'; import {Logger} from '../../../src/ngtsc/logging';
import {TypeScriptReflectionHost} from '../../../src/ngtsc/reflection'; import {TypeScriptReflectionHost} from '../../../src/ngtsc/reflection';
import {DecorationAnalyzer} from '../analysis/decoration_analyzer'; import {DecorationAnalyzer} from '../analysis/decoration_analyzer';
@ -64,7 +64,7 @@ export type TransformResult = {
*/ */
export class Transformer { export class Transformer {
constructor( constructor(
private fs: FileSystem, private logger: Logger, private fs: ReadonlyFileSystem, private logger: Logger,
private tsConfig: ParsedConfiguration|null = null) {} private tsConfig: ParsedConfiguration|null = null) {}
/** /**
@ -100,7 +100,7 @@ export class Transformer {
decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses); decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses);
if (bundle.dts) { if (bundle.dts) {
const dtsFormatter = new EsmRenderingFormatter(reflectionHost, bundle.isCore); const dtsFormatter = new EsmRenderingFormatter(this.fs, reflectionHost, bundle.isCore);
const dtsRenderer = const dtsRenderer =
new DtsRenderer(dtsFormatter, this.fs, this.logger, reflectionHost, bundle); new DtsRenderer(dtsFormatter, this.fs, this.logger, reflectionHost, bundle);
const renderedDtsFiles = dtsRenderer.renderProgram( const renderedDtsFiles = dtsRenderer.renderProgram(
@ -129,16 +129,16 @@ export class Transformer {
getRenderingFormatter(host: NgccReflectionHost, bundle: EntryPointBundle): RenderingFormatter { getRenderingFormatter(host: NgccReflectionHost, bundle: EntryPointBundle): RenderingFormatter {
switch (bundle.format) { switch (bundle.format) {
case 'esm2015': case 'esm2015':
return new EsmRenderingFormatter(host, bundle.isCore); return new EsmRenderingFormatter(this.fs, host, bundle.isCore);
case 'esm5': case 'esm5':
return new Esm5RenderingFormatter(host, bundle.isCore); return new Esm5RenderingFormatter(this.fs, host, bundle.isCore);
case 'umd': case 'umd':
if (!(host instanceof UmdReflectionHost)) { if (!(host instanceof UmdReflectionHost)) {
throw new Error('UmdRenderer requires a UmdReflectionHost'); throw new Error('UmdRenderer requires a UmdReflectionHost');
} }
return new UmdRenderingFormatter(host, bundle.isCore); return new UmdRenderingFormatter(this.fs, host, bundle.isCore);
case 'commonjs': case 'commonjs':
return new CommonJsRenderingFormatter(host, bundle.isCore); return new CommonJsRenderingFormatter(this.fs, host, bundle.isCore);
default: default:
throw new Error(`Renderer for "${bundle.format}" not yet implemented.`); 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 * 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 * 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'; import {ParsedConfiguration} from '../../src/perform_compile';
export type PathMappings = { export type PathMappings = {
baseUrl: string, baseUrl: string,
paths: {[key: string]: 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. * If `pathMappings` is not provided directly, then try getting it from `tsConfig`, if available.
*/ */
export function getPathMappingsFromTsConfig( 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 && if (tsConfig !== null && tsConfig.options.baseUrl !== undefined &&
tsConfig.options.paths !== undefined) { tsConfig.options.paths !== undefined) {
return { return {
baseUrl: resolve(projectPath, tsConfig.options.baseUrl), baseUrl: fs.resolve(projectPath, tsConfig.options.baseUrl),
paths: tsConfig.options.paths, 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 * 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 * 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 MagicString from 'magic-string';
import * as ts from 'typescript'; import * as ts from 'typescript';
@ -24,8 +24,8 @@ import {stripExtension} from './utils';
* wrapper function for AMD, CommonJS and global module formats. * wrapper function for AMD, CommonJS and global module formats.
*/ */
export class CommonJsRenderingFormatter extends Esm5RenderingFormatter { export class CommonJsRenderingFormatter extends Esm5RenderingFormatter {
constructor(protected commonJsHost: NgccReflectionHost, isCore: boolean) { constructor(fs: PathManipulation, protected commonJsHost: NgccReflectionHost, isCore: boolean) {
super(commonJsHost, isCore); super(fs, commonJsHost, isCore);
} }
/** /**
@ -51,7 +51,7 @@ export class CommonJsRenderingFormatter extends Esm5RenderingFormatter {
importManager: ImportManager, file: ts.SourceFile): void { importManager: ImportManager, file: ts.SourceFile): void {
exports.forEach(e => { exports.forEach(e => {
const basePath = stripExtension(e.from); 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 ? const namedImport = entryPointBasePath !== basePath ?
importManager.generateNamedImport(relativePath, e.identifier) : importManager.generateNamedImport(relativePath, e.identifier) :
{symbol: e.identifier, moduleImport: null}; {symbol: e.identifier, moduleImport: null};

View File

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

View File

@ -9,7 +9,7 @@ import {Statement} from '@angular/compiler';
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import * as ts from 'typescript'; 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 {Reexport} from '../../../src/ngtsc/imports';
import {Import, ImportManager, translateStatement} from '../../../src/ngtsc/translator'; import {Import, ImportManager, translateStatement} from '../../../src/ngtsc/translator';
import {isDtsPath} from '../../../src/ngtsc/util/src/typescript'; import {isDtsPath} from '../../../src/ngtsc/util/src/typescript';
@ -28,7 +28,9 @@ import {stripExtension} from './utils';
export class EsmRenderingFormatter implements RenderingFormatter { export class EsmRenderingFormatter implements RenderingFormatter {
protected printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed}); 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. * 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) { if (from) {
const basePath = stripExtension(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); const relativeImport = toRelativeImport(relativePath);
exportFrom = entryPointBasePath !== basePath ? ` from '${relativeImport}'` : ''; exportFrom = entryPointBasePath !== basePath ? ` from '${relativeImport}'` : '';
} }
@ -198,7 +200,7 @@ export class EsmRenderingFormatter implements RenderingFormatter {
const ngModuleName = info.ngModule.node.name.text; const ngModuleName = info.ngModule.node.name.text;
const declarationFile = absoluteFromSourceFile(info.declaration.getSourceFile()); const declarationFile = absoluteFromSourceFile(info.declaration.getSourceFile());
const ngModuleFile = absoluteFromSourceFile(info.ngModule.node.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 relativeImport = toRelativeImport(relativePath);
const importPath = info.ngModule.ownedByModuleGuess || const importPath = info.ngModule.ownedByModuleGuess ||
(declarationFile !== ngModuleFile ? stripExtension(relativeImport) : null); (declarationFile !== ngModuleFile ? stripExtension(relativeImport) : null);

View File

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

View File

@ -9,7 +9,7 @@ import {fromObject, generateMapFileComment, SourceMapConverter} from 'convert-so
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import * as ts from 'typescript'; 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 {Logger} from '../../../src/ngtsc/logging';
import {RawSourceMap, SourceFileLoader} from '../../../src/ngtsc/sourcemaps'; 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. * with an appropriate source-map comment pointing to the merged source-map.
*/ */
export function renderSourceAndMap( export function renderSourceAndMap(
logger: Logger, fs: FileSystem, sourceFile: ts.SourceFile, logger: Logger, fs: ReadonlyFileSystem, sourceFile: ts.SourceFile,
generatedMagicString: MagicString): FileToWrite[] { generatedMagicString: MagicString): FileToWrite[] {
const generatedPath = absoluteFromSourceFile(sourceFile); const generatedPath = absoluteFromSourceFile(sourceFile);
const generatedMapPath = absoluteFrom(`${generatedPath}.map`); const generatedMapPath = absoluteFrom(`${generatedPath}.map`);
@ -55,7 +55,7 @@ export function renderSourceAndMap(
{path: generatedPath, contents: `${generatedFile.contents}\n${mergedMap.toComment()}`} {path: generatedPath, contents: `${generatedFile.contents}\n${mergedMap.toComment()}`}
]; ];
} else { } else {
const sourceMapComment = generateMapFileComment(`${basename(generatedPath)}.map`); const sourceMapComment = generateMapFileComment(`${fs.basename(generatedPath)}.map`);
return [ return [
{path: generatedPath, contents: `${generatedFile.contents}\n${sourceMapComment}`}, {path: generatedPath, contents: `${generatedFile.contents}\n${sourceMapComment}`},
{path: generatedMapPath, contents: mergedMap.toJSON()} {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 * 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 * found in the LICENSE file at https://angular.io/license
*/ */
import {dirname, relative} from 'canonical-path';
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import * as ts from 'typescript'; import * as ts from 'typescript';
import {PathManipulation} from '../../../src/ngtsc/file_system';
import {Reexport} from '../../../src/ngtsc/imports'; import {Reexport} from '../../../src/ngtsc/imports';
import {Import, ImportManager} from '../../../src/ngtsc/translator'; import {Import, ImportManager} from '../../../src/ngtsc/translator';
import {ExportInfo} from '../analysis/private_declarations_analyzer'; 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. * wrapper function for AMD, CommonJS and global module formats.
*/ */
export class UmdRenderingFormatter extends Esm5RenderingFormatter { export class UmdRenderingFormatter extends Esm5RenderingFormatter {
constructor(protected umdHost: UmdReflectionHost, isCore: boolean) { constructor(fs: PathManipulation, protected umdHost: UmdReflectionHost, isCore: boolean) {
super(umdHost, isCore); super(fs, umdHost, isCore);
} }
/** /**
@ -87,7 +87,7 @@ export class UmdRenderingFormatter extends Esm5RenderingFormatter {
lastStatement ? lastStatement.getEnd() : factoryFunction.body.getEnd() - 1; lastStatement ? lastStatement.getEnd() : factoryFunction.body.getEnd() - 1;
exports.forEach(e => { exports.forEach(e => {
const basePath = stripExtension(e.from); 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 ? const namedImport = entryPointBasePath !== basePath ?
importManager.generateNamedImport(relativePath, e.identifier) : importManager.generateNamedImport(relativePath, e.identifier) :
{symbol: e.identifier, moduleImport: null}; {symbol: e.identifier, moduleImport: null};

View File

@ -7,7 +7,7 @@
*/ */
import * as ts from 'typescript'; 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'; 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. * @returns An absolute path to the first matching existing file, or `null` if none exist.
*/ */
export function resolveFileWithPostfixes( export function resolveFileWithPostfixes(
fs: FileSystem, path: AbsoluteFsPath, postFixes: string[]): AbsoluteFsPath|null { fs: ReadonlyFileSystem, path: AbsoluteFsPath, postFixes: string[]): AbsoluteFsPath|null {
for (const postFix of postFixes) { for (const postFix of postFixes) {
const testPath = absoluteFrom(path + postFix); const testPath = absoluteFrom(path + postFix);
if (fs.exists(testPath) && fs.stat(testPath).isFile()) { 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 * 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 * 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 {needsCleaning} from '../../packages/build_marker';
import {EntryPoint} from '../../packages/entry_point'; import {EntryPoint} from '../../packages/entry_point';
@ -16,7 +16,7 @@ import {isLocalDirectory} from './utils';
* A class that can clean ngcc artifacts from a directory. * A class that can clean ngcc artifacts from a directory.
*/ */
export class PackageCleaner { 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 * 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 * 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 * 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. * 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 fs the current filesystem
* @param path the path to check * @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)) { if (fs.exists(path)) {
const stat = fs.lstat(path); const stat = fs.lstat(path);
return stat.isDirectory(); return stat.isDirectory();

View File

@ -6,7 +6,7 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {Logger} from '../../../src/ngtsc/logging';
import {isDtsPath} from '../../../src/ngtsc/util/src/typescript'; import {isDtsPath} from '../../../src/ngtsc/util/src/typescript';
import {EntryPoint, EntryPointJsonProperty} from '../packages/entry_point'; import {EntryPoint, EntryPointJsonProperty} from '../packages/entry_point';
@ -39,7 +39,7 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
formatProperties: EntryPointJsonProperty[]) { formatProperties: EntryPointJsonProperty[]) {
// The new folder is at the root of the overall package // The new folder is at the root of the overall package
const entryPoint = bundle.entryPoint; 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); this.copyBundle(bundle, entryPoint.packagePath, ngccFolder);
transformedFiles.forEach(file => this.writeFile(file, entryPoint.packagePath, ngccFolder)); transformedFiles.forEach(file => this.writeFile(file, entryPoint.packagePath, ngccFolder));
this.updatePackageJson(entryPoint, formatProperties, ngccFolder); this.updatePackageJson(entryPoint, formatProperties, ngccFolder);
@ -69,11 +69,11 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
protected copyBundle( protected copyBundle(
bundle: EntryPointBundle, packagePath: AbsoluteFsPath, ngccFolder: AbsoluteFsPath) { bundle: EntryPointBundle, packagePath: AbsoluteFsPath, ngccFolder: AbsoluteFsPath) {
bundle.src.program.getSourceFiles().forEach(sourceFile => { bundle.src.program.getSourceFiles().forEach(sourceFile => {
const relativePath = relative(packagePath, absoluteFromSourceFile(sourceFile)); const relativePath = this.fs.relative(packagePath, absoluteFromSourceFile(sourceFile));
const isInsidePackage = isLocalRelativePath(relativePath); const isInsidePackage = isLocalRelativePath(relativePath);
if (!sourceFile.isDeclarationFile && isInsidePackage) { if (!sourceFile.isDeclarationFile && isInsidePackage) {
const newFilePath = resolve(ngccFolder, relativePath); const newFilePath = this.fs.resolve(ngccFolder, relativePath);
this.fs.ensureDir(dirname(newFilePath)); this.fs.ensureDir(this.fs.dirname(newFilePath));
this.fs.copyFile(absoluteFromSourceFile(sourceFile), 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 // This is either `.d.ts` or `.d.ts.map` file
super.writeFileAndBackup(file); super.writeFileAndBackup(file);
} else { } else {
const relativePath = relative(packagePath, file.path); const relativePath = this.fs.relative(packagePath, file.path);
const newFilePath = resolve(ngccFolder, relativePath); const newFilePath = this.fs.resolve(ngccFolder, relativePath);
this.fs.ensureDir(dirname(newFilePath)); this.fs.ensureDir(this.fs.dirname(newFilePath));
this.fs.writeFile(newFilePath, file.contents); 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 // This is either `.d.ts` or `.d.ts.map` file
super.revertFileAndBackup(filePath); super.revertFileAndBackup(filePath);
} else if (this.fs.exists(filePath)) { } else if (this.fs.exists(filePath)) {
const relativePath = relative(packagePath, filePath); const relativePath = this.fs.relative(packagePath, filePath);
const newFilePath = resolve(packagePath, NGCC_DIRECTORY, relativePath); const newFilePath = this.fs.resolve(packagePath, NGCC_DIRECTORY, relativePath);
this.fs.removeFile(newFilePath); this.fs.removeFile(newFilePath);
} }
} }
@ -112,15 +112,15 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
} }
const packageJson = entryPoint.packageJson; 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. // All format properties point to the same format-path.
const oldFormatProp = formatProperties[0]!; const oldFormatProp = formatProperties[0]!;
const oldFormatPath = packageJson[oldFormatProp]!; const oldFormatPath = packageJson[oldFormatProp]!;
const oldAbsFormatPath = resolve(entryPoint.path, oldFormatPath); const oldAbsFormatPath = this.fs.resolve(entryPoint.path, oldFormatPath);
const newAbsFormatPath = const newAbsFormatPath =
resolve(ngccFolder, relative(entryPoint.packagePath, oldAbsFormatPath)); this.fs.resolve(ngccFolder, this.fs.relative(entryPoint.packagePath, oldAbsFormatPath));
const newFormatPath = relative(entryPoint.path, newAbsFormatPath); const newFormatPath = this.fs.relative(entryPoint.path, newAbsFormatPath);
// Update all properties in `package.json` (both in memory and on disk). // Update all properties in `package.json` (both in memory and on disk).
const update = this.pkgJsonUpdater.createUpdate(); const update = this.pkgJsonUpdater.createUpdate();
@ -146,7 +146,7 @@ export class NewEntryPointFileWriter extends InPlaceFileWriter {
} }
const packageJson = entryPoint.packageJson; 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). // 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 // 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 * 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 * 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 {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing'; import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing'; import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -114,7 +114,7 @@ runInEachFileSystem(() => {
loadTestFiles(createPackage(basePath, 'some-package')); loadTestFiles(createPackage(basePath, 'some-package'));
spyOn(config, 'getPackageConfig') spyOn(config, 'getPackageConfig')
.and.returnValue( .and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), { new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: { entryPoints: {
'.': {ignore: true}, '.': {ignore: true},
}, },
@ -137,7 +137,7 @@ runInEachFileSystem(() => {
]); ]);
spyOn(config, 'getPackageConfig') spyOn(config, 'getPackageConfig')
.and.returnValue( .and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), { new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: { entryPoints: {
'./sub-entry-point-1': {ignore: true}, './sub-entry-point-1': {ignore: true},
}, },
@ -457,7 +457,7 @@ runInEachFileSystem(() => {
function dumpEntryPointPaths( function dumpEntryPointPaths(
basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] { basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] {
return entryPoints.map( 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 * 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 * 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 {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing'; import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing'; import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -231,7 +231,7 @@ runInEachFileSystem(() => {
function dumpEntryPointPaths( function dumpEntryPointPaths(
basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] { basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] {
return entryPoints.map( 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 * 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 * 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 {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing'; import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing'; import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -118,7 +118,7 @@ runInEachFileSystem(() => {
loadTestFiles(createPackage(basePath, 'some-package')); loadTestFiles(createPackage(basePath, 'some-package'));
spyOn(config, 'getPackageConfig') spyOn(config, 'getPackageConfig')
.and.returnValue( .and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), { new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: { entryPoints: {
'.': {ignore: true}, '.': {ignore: true},
}, },
@ -383,7 +383,7 @@ runInEachFileSystem(() => {
function dumpEntryPointPaths( function dumpEntryPointPaths(
basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] { basePath: AbsoluteFsPath, entryPoints: EntryPoint[]): [string, string][] {
return entryPoints.map( 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')); loadTestFiles(createPackage(basePath, 'some-package'));
spyOn(config, 'getPackageConfig') spyOn(config, 'getPackageConfig')
.and.returnValue( .and.returnValue(
new ProcessedNgccPackageConfig(_Abs('/project/node_modules/some-package'), { new ProcessedNgccPackageConfig(fs, _Abs('/project/node_modules/some-package'), {
entryPoints: { entryPoints: {
'.': {ignore: true}, '.': {ignore: true},
}, },

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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'; import {LockFile} from '../../src/locking/lock_file';
/** /**
@ -13,7 +13,7 @@ import {LockFile} from '../../src/locking/lock_file';
*/ */
export class MockLockFile implements LockFile { export class MockLockFile implements LockFile {
constructor( constructor(
fs: FileSystem, private log: string[] = [], public path = fs.resolve('/lockfile'), fs: PathManipulation, private log: string[] = [], public path = fs.resolve('/lockfile'),
private pid = '1234') {} private pid = '1234') {}
write() { write() {
this.log.push('write()'); this.log.push('write()');

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing'; import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {loadTestFiles} from '../../../src/ngtsc/testing'; import {loadTestFiles} from '../../../src/ngtsc/testing';
@ -578,7 +578,7 @@ runInEachFileSystem(() => {
it('should revert changes to `package.json`', () => { it('should revert changes to `package.json`', () => {
const entryPoint = esm5bundle.entryPoint; const entryPoint = esm5bundle.entryPoint;
const packageJsonPath = join(entryPoint.packagePath, 'package.json'); const packageJsonPath = fs.join(entryPoint.packagePath, 'package.json');
fileWriter.writeBundle( fileWriter.writeBundle(
esm5bundle, esm5bundle,

View File

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

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import * as ts from 'typescript'; import * as ts from 'typescript';
import {FileSystem} from '../../file_system'; import {PathManipulation} from '../../file_system';
import {TestFile} from '../../file_system/testing'; import {TestFile} from '../../file_system/testing';
import {makeProgram} from '../../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. * 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, program: ts.Program,
host: ts.CompilerHost, host: ts.CompilerHost,
options: ts.CompilerOptions, options: ts.CompilerOptions,

View File

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

View File

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

View File

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

View File

@ -109,6 +109,11 @@ function loadAngularFolder(): Folder {
/** /**
* Load real files from the real file-system into a mock file-system. * 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 fs the file-system where the directory is to be loaded.
* @param directoryPath the path to the directory we want to load. * @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. * @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 {isSyntaxError, Position} from '@angular/compiler';
import * as ts from 'typescript'; 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 {replaceTsWithNgInErrors} from './ngtsc/diagnostics';
import * as api from './transformers/api'; import * as api from './transformers/api';
@ -109,10 +109,8 @@ export function formatDiagnostics(
} }
/** Used to read configuration files. */ /** Used to read configuration files. */
// TODO(ayazhafiz): split FileSystem into a ReadonlyFileSystem and make this a export type ConfigurationHost = Pick<
// subset of that. ReadonlyFileSystem, 'readFile'|'exists'|'lstat'|'resolve'|'join'|'dirname'|'extname'|'pwd'>;
export type ConfigurationHost =
Pick<FileSystem, 'readFile'|'exists'|'lstat'|'resolve'|'join'|'dirname'|'extname'|'pwd'>;
export interface ParsedConfiguration { export interface ParsedConfiguration {
project: string; project: string;

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {getBuildOutputDirectory, getRootDirectory} from './compile_test';
import {verifyUniqueFactory} from './di_checks'; 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. * @param expectedFiles The list of expected-generated pairs to compare.
*/ */
export function checkExpectations( export function checkExpectations(
fs: FileSystem, testPath: string, failureMessage: string, expectedFiles: ExpectedFile[], fs: ReadonlyFileSystem, testPath: string, failureMessage: string, expectedFiles: ExpectedFile[],
extraChecks: ExtraCheck[]): void { extraChecks: ExtraCheck[]): void {
const builtDirectory = getBuildOutputDirectory(fs); const builtDirectory = getBuildOutputDirectory(fs);
for (const expectedFile of expectedFiles) { for (const expectedFile of expectedFiles) {

View File

@ -7,7 +7,7 @@
*/ */
import * as ts from 'typescript'; 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 {initMockFileSystem} from '../../../src/ngtsc/file_system/testing';
import {loadStandardTestFiles, loadTestDirectory, NgtscTestCompilerHost} from '../../../src/ngtsc/testing'; import {loadStandardTestFiles, loadTestDirectory, NgtscTestCompilerHost} from '../../../src/ngtsc/testing';
import {Diagnostics, performCompilation} from '../../../src/perform_compile'; 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. * @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('/'); return fs.resolve('/');
} }
@ -75,7 +75,7 @@ export function getRootDirectory(fs: FileSystem): AbsoluteFsPath {
* *
* @param fs the mock file-system where the compilation is happening. * @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'); return fs.resolve('/built');
} }
@ -129,7 +129,7 @@ function getOptions(
* This allows us to simulate, more reliably, files that have `\r\n` line-endings. * 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`.) * (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; const originalReadFile = fs.readFile;
fs.readFile = (path: AbsoluteFsPath): string => { fs.readFile = (path: AbsoluteFsPath): string => {
const file = originalReadFile.call(fs, path); 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 * 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 * 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 fs = new NodeJSFileSystem();
const basePath = fs.resolve(__dirname, '../test_cases'); const basePath = fs.resolve(__dirname, '../test_cases');
@ -55,7 +55,7 @@ export function* getComplianceTests(testConfigPath: string): Generator<Complianc
} }
function loadTestCasesFile( function loadTestCasesFile(
fs: FileSystem, testCasesPath: AbsoluteFsPath, basePath: AbsoluteFsPath): any { fs: ReadonlyFileSystem, testCasesPath: AbsoluteFsPath, basePath: AbsoluteFsPath): any {
try { try {
return JSON.parse(fs.readFile(testCasesPath)); return JSON.parse(fs.readFile(testCasesPath));
} catch (e) { } catch (e) {

View File

@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * 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 {ConsoleLogger, LogLevel} from '../../../src/ngtsc/logging';
import {SourceFileLoader} from '../../../src/ngtsc/sourcemaps'; 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. * @returns The content of the expected source file, stripped of the mapping information.
*/ */
export function checkMappings( export function checkMappings(
fs: FileSystem, generated: string, generatedPath: AbsoluteFsPath, expectedSource: string, fs: ReadonlyFileSystem, generated: string, generatedPath: AbsoluteFsPath,
expectedPath: AbsoluteFsPath): string { expectedSource: string, expectedPath: AbsoluteFsPath): string {
const actualMappings = getMappedSegments(fs, generatedPath, generated); const actualMappings = getMappedSegments(fs, generatedPath, generated);
const {expected, mappings} = extractMappings(fs, expectedSource); const {expected, mappings} = extractMappings(fs, expectedSource);
@ -77,7 +77,7 @@ interface SegmentMapping {
* @param expected The content of the expected file containing source-map information. * @param expected The content of the expected file containing source-map information.
*/ */
function extractMappings( function extractMappings(
fs: FileSystem, expected: string): {expected: string, mappings: SegmentMapping[]} { fs: ReadonlyFileSystem, expected: string): {expected: string, mappings: SegmentMapping[]} {
const mappings: SegmentMapping[] = []; const mappings: SegmentMapping[] = [];
// capture and remove source mapping info // capture and remove source mapping info
expected = expected.replace( expected = expected.replace(
@ -113,7 +113,8 @@ function unescape(str: string): string {
* empty array is returned if there is no source-map file found. * empty array is returned if there is no source-map file found.
*/ */
function getMappedSegments( function getMappedSegments(
fs: FileSystem, generatedPath: AbsoluteFsPath, generatedContents: string): SegmentMapping[] { fs: ReadonlyFileSystem, generatedPath: AbsoluteFsPath,
generatedContents: string): SegmentMapping[] {
const logger = new ConsoleLogger(LogLevel.debug); const logger = new ConsoleLogger(LogLevel.debug);
const loader = new SourceFileLoader(fs, logger, {}); const loader = new SourceFileLoader(fs, logger, {});
const generatedFile = loader.loadSourceFile(generatedPath, generatedContents); 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 * 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 * 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 {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
import {AbsoluteSourceSpan, IdentifierKind, IndexedComponent, TopLevelIdentifier} from '@angular/compiler-cli/src/ngtsc/indexer'; import {AbsoluteSourceSpan, IdentifierKind, IndexedComponent, TopLevelIdentifier} from '@angular/compiler-cli/src/ngtsc/indexer';
import {ParseSourceFile} from '@angular/compiler/src/compiler'; import {ParseSourceFile} from '@angular/compiler/src/compiler';
@ -14,6 +14,7 @@ import {NgtscTestEnvironment} from './env';
runInEachFileSystem(() => { runInEachFileSystem(() => {
describe('ngtsc component indexing', () => { describe('ngtsc component indexing', () => {
let fs: PathManipulation;
let env!: NgtscTestEnvironment; let env!: NgtscTestEnvironment;
let testSourceFile: AbsoluteFsPath; let testSourceFile: AbsoluteFsPath;
let testTemplateFile: AbsoluteFsPath; let testTemplateFile: AbsoluteFsPath;
@ -21,8 +22,9 @@ runInEachFileSystem(() => {
beforeEach(() => { beforeEach(() => {
env = NgtscTestEnvironment.setup(); env = NgtscTestEnvironment.setup();
env.tsconfig(); env.tsconfig();
testSourceFile = resolve(env.basePath, 'test.ts'); fs = getFileSystem();
testTemplateFile = resolve(env.basePath, 'test.html'); testSourceFile = fs.resolve(env.basePath, 'test.ts');
testTemplateFile = fs.resolve(env.basePath, 'test.html');
}); });
describe('indexing metadata', () => { describe('indexing metadata', () => {