feat(compiler-cli): ngcc - make logging more configurable (#29591)
This allows CLI usage to filter excessive log messages and integrations like webpack plugins to provide their own logger. // FW-1198 PR Close #29591
This commit is contained in:

committed by
Jason Aden

parent
39345b6fae
commit
8d3d75e454
@ -9,6 +9,7 @@
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, ClassSymbol, CtorParameter, Decorator, Import, TypeScriptReflectionHost, reflectObjectLiteral} from '../../../src/ngtsc/reflection';
|
||||
import {Logger} from '../logging/logger';
|
||||
import {BundleProgram} from '../packages/bundle_program';
|
||||
import {findAll, getNameText, hasNameIdentifier, isDefined} from '../utils';
|
||||
|
||||
@ -49,7 +50,9 @@ export const CONSTRUCTOR_PARAMS = 'ctorParameters' as ts.__String;
|
||||
*/
|
||||
export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements NgccReflectionHost {
|
||||
protected dtsDeclarationMap: Map<string, ts.Declaration>|null;
|
||||
constructor(protected isCore: boolean, checker: ts.TypeChecker, dts?: BundleProgram|null) {
|
||||
constructor(
|
||||
protected logger: Logger, protected isCore: boolean, checker: ts.TypeChecker,
|
||||
dts?: BundleProgram|null) {
|
||||
super(checker);
|
||||
this.dtsDeclarationMap = dts && this.computeDtsDeclarationMap(dts.path, dts.program) || null;
|
||||
}
|
||||
@ -848,7 +851,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
}
|
||||
|
||||
if (kind === null) {
|
||||
console.warn(`Unknown member type: "${node.getText()}`);
|
||||
this.logger.warn(`Unknown member type: "${node.getText()}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
46
packages/compiler-cli/ngcc/src/logging/console_logger.ts
Normal file
46
packages/compiler-cli/ngcc/src/logging/console_logger.ts
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {Logger} from './logger';
|
||||
|
||||
const RESET = '\x1b[0m';
|
||||
const RED = '\x1b[31m';
|
||||
const YELLOW = '\x1b[33m';
|
||||
const BLUE = '\x1b[36m';
|
||||
|
||||
export const DEBUG = `${BLUE}Debug:${RESET}`;
|
||||
export const WARN = `${YELLOW}Warning:${RESET}`;
|
||||
export const ERROR = `${RED}Error:${RESET}`;
|
||||
|
||||
export enum LogLevel {
|
||||
debug,
|
||||
info,
|
||||
warn,
|
||||
error,
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple logger that outputs directly to the Console.
|
||||
*
|
||||
* The log messages can be filtered based on severity via the `logLevel`
|
||||
* constructor parameter.
|
||||
*/
|
||||
export class ConsoleLogger implements Logger {
|
||||
constructor(private logLevel: LogLevel) {}
|
||||
debug(...args: string[]) {
|
||||
if (this.logLevel <= LogLevel.debug) console.debug(DEBUG, ...args);
|
||||
}
|
||||
info(...args: string[]) {
|
||||
if (this.logLevel <= LogLevel.info) console.info(...args);
|
||||
}
|
||||
warn(...args: string[]) {
|
||||
if (this.logLevel <= LogLevel.warn) console.warn(WARN, ...args);
|
||||
}
|
||||
error(...args: string[]) {
|
||||
if (this.logLevel <= LogLevel.error) console.error(ERROR, ...args);
|
||||
}
|
||||
}
|
18
packages/compiler-cli/ngcc/src/logging/logger.ts
Normal file
18
packages/compiler-cli/ngcc/src/logging/logger.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implement this interface if you want to provide different logging
|
||||
* output from the standard ConsoleLogger.
|
||||
*/
|
||||
export interface Logger {
|
||||
debug(...args: string[]): void;
|
||||
info(...args: string[]): void;
|
||||
warn(...args: string[]): void;
|
||||
error(...args: string[]): void;
|
||||
}
|
@ -11,6 +11,8 @@ import {readFileSync} from 'fs';
|
||||
|
||||
import {AbsoluteFsPath} from '../../src/ngtsc/path';
|
||||
|
||||
import {ConsoleLogger, LogLevel} from './logging/console_logger';
|
||||
import {Logger} from './logging/logger';
|
||||
import {hasBeenProcessed, markAsProcessed} from './packages/build_marker';
|
||||
import {DependencyHost} from './packages/dependency_host';
|
||||
import {DependencyResolver} from './packages/dependency_resolver';
|
||||
@ -23,6 +25,7 @@ import {InPlaceFileWriter} from './writing/in_place_file_writer';
|
||||
import {NewEntryPointFileWriter} from './writing/new_entry_point_file_writer';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The options to configure the ngcc compiler.
|
||||
*/
|
||||
@ -50,6 +53,10 @@ export interface NgccOptions {
|
||||
* Whether to create new entry-points bundles rather than overwriting the original files.
|
||||
*/
|
||||
createNewEntryPointFormats?: boolean;
|
||||
/**
|
||||
* Provide a logger that will be called with log messages.
|
||||
*/
|
||||
logger?: Logger;
|
||||
}
|
||||
|
||||
const SUPPORTED_FORMATS: EntryPointFormat[] = ['esm5', 'esm2015'];
|
||||
@ -62,13 +69,14 @@ const SUPPORTED_FORMATS: EntryPointFormat[] = ['esm5', 'esm2015'];
|
||||
*
|
||||
* @param options The options telling ngcc what to compile and how.
|
||||
*/
|
||||
export function mainNgcc(
|
||||
{basePath, targetEntryPointPath, propertiesToConsider = SUPPORTED_FORMAT_PROPERTIES,
|
||||
compileAllFormats = true, createNewEntryPointFormats = false}: NgccOptions): void {
|
||||
const transformer = new Transformer(basePath);
|
||||
export function mainNgcc({basePath, targetEntryPointPath,
|
||||
propertiesToConsider = SUPPORTED_FORMAT_PROPERTIES,
|
||||
compileAllFormats = true, createNewEntryPointFormats = false,
|
||||
logger = new ConsoleLogger(LogLevel.info)}: NgccOptions): void {
|
||||
const transformer = new Transformer(logger, basePath);
|
||||
const host = new DependencyHost();
|
||||
const resolver = new DependencyResolver(host);
|
||||
const finder = new EntryPointFinder(resolver);
|
||||
const resolver = new DependencyResolver(logger, host);
|
||||
const finder = new EntryPointFinder(logger, resolver);
|
||||
const fileWriter = getFileWriter(createNewEntryPointFormats);
|
||||
|
||||
const absoluteTargetEntryPointPath = targetEntryPointPath ?
|
||||
@ -112,7 +120,7 @@ export function mainNgcc(
|
||||
|
||||
if (hasBeenProcessed(entryPointPackageJson, property)) {
|
||||
compiledFormats.add(formatPath);
|
||||
console.warn(`Skipping ${entryPoint.name} : ${property} (already compiled).`);
|
||||
logger.info(`Skipping ${entryPoint.name} : ${property} (already compiled).`);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -123,16 +131,16 @@ export function mainNgcc(
|
||||
entryPoint.path, formatPath, entryPoint.typings, isCore, property, format,
|
||||
compiledFormats.size === 0);
|
||||
if (bundle) {
|
||||
console.warn(`Compiling ${entryPoint.name} : ${property} as ${format}`);
|
||||
logger.info(`Compiling ${entryPoint.name} : ${property} as ${format}`);
|
||||
const transformedFiles = transformer.transform(bundle);
|
||||
fileWriter.writeBundle(entryPoint, bundle, transformedFiles);
|
||||
compiledFormats.add(formatPath);
|
||||
} else {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
`Skipping ${entryPoint.name} : ${format} (no valid entry point file for this format).`);
|
||||
}
|
||||
} else if (!compileAllFormats) {
|
||||
console.warn(`Skipping ${entryPoint.name} : ${property} (already compiled).`);
|
||||
logger.info(`Skipping ${entryPoint.name} : ${property} (already compiled).`);
|
||||
}
|
||||
|
||||
// Either this format was just compiled or its underlying format was compiled because of a
|
||||
|
@ -10,6 +10,8 @@ import {resolve} from 'canonical-path';
|
||||
import {DepGraph} from 'dependency-graph';
|
||||
|
||||
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
||||
import {Logger} from '../logging/logger';
|
||||
|
||||
import {DependencyHost} from './dependency_host';
|
||||
import {EntryPoint, EntryPointJsonProperty, getEntryPointFormat} from './entry_point';
|
||||
|
||||
@ -65,7 +67,7 @@ export interface SortedEntryPointsInfo {
|
||||
* A class that resolves dependencies between entry-points.
|
||||
*/
|
||||
export class DependencyResolver {
|
||||
constructor(private host: DependencyHost) {}
|
||||
constructor(private logger: Logger, private host: DependencyHost) {}
|
||||
/**
|
||||
* Sort the array of entry points so that the dependant entry points always come later than
|
||||
* their dependencies in the array.
|
||||
@ -134,7 +136,7 @@ export class DependencyResolver {
|
||||
|
||||
if (deepImports.size) {
|
||||
const imports = Array.from(deepImports).map(i => `'${i}'`).join(', ');
|
||||
console.warn(
|
||||
this.logger.warn(
|
||||
`Entry point '${entryPoint.name}' contains deep imports into ${imports}. ` +
|
||||
`This is probably not a problem, but may cause the compilation of entry points to be out of order.`);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import * as path from 'canonical-path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
||||
import {Logger} from '../logging/logger';
|
||||
|
||||
|
||||
/**
|
||||
@ -67,13 +68,13 @@ export const SUPPORTED_FORMAT_PROPERTIES: EntryPointJsonProperty[] =
|
||||
* @returns An entry-point if it is valid, `null` otherwise.
|
||||
*/
|
||||
export function getEntryPointInfo(
|
||||
packagePath: AbsoluteFsPath, entryPointPath: AbsoluteFsPath): EntryPoint|null {
|
||||
logger: Logger, packagePath: AbsoluteFsPath, entryPointPath: AbsoluteFsPath): EntryPoint|null {
|
||||
const packageJsonPath = path.resolve(entryPointPath, 'package.json');
|
||||
if (!fs.existsSync(packageJsonPath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const entryPointPackageJson = loadEntryPointPackage(packageJsonPath);
|
||||
const entryPointPackageJson = loadEntryPointPackage(logger, packageJsonPath);
|
||||
if (!entryPointPackageJson) {
|
||||
return null;
|
||||
}
|
||||
@ -135,12 +136,13 @@ export function getEntryPointFormat(property: string): EntryPointFormat|undefine
|
||||
* @param packageJsonPath the absolute path to the package.json file.
|
||||
* @returns JSON from the package.json file if it is valid, `null` otherwise.
|
||||
*/
|
||||
function loadEntryPointPackage(packageJsonPath: string): EntryPointPackageJson|null {
|
||||
function loadEntryPointPackage(logger: Logger, packageJsonPath: string): EntryPointPackageJson|
|
||||
null {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
} catch (e) {
|
||||
// We may have run into a package.json with unexpected symbols
|
||||
console.warn(`Failed to read entry point info from ${packageJsonPath} with error ${e}.`);
|
||||
logger.warn(`Failed to read entry point info from ${packageJsonPath} with error ${e}.`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -9,109 +9,111 @@ import * as path from 'canonical-path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
||||
import {Logger} from '../logging/logger';
|
||||
|
||||
import {DependencyResolver, SortedEntryPointsInfo} from './dependency_resolver';
|
||||
import {EntryPoint, getEntryPointInfo} from './entry_point';
|
||||
|
||||
|
||||
export class EntryPointFinder {
|
||||
constructor(private resolver: DependencyResolver) {}
|
||||
constructor(private logger: Logger, private resolver: DependencyResolver) {}
|
||||
/**
|
||||
* Search the given directory, and sub-directories, for Angular package entry points.
|
||||
* @param sourceDirectory An absolute path to the directory to search for entry points.
|
||||
*/
|
||||
findEntryPoints(sourceDirectory: AbsoluteFsPath, targetEntryPointPath?: AbsoluteFsPath):
|
||||
SortedEntryPointsInfo {
|
||||
const unsortedEntryPoints = walkDirectoryForEntryPoints(sourceDirectory);
|
||||
const unsortedEntryPoints = this.walkDirectoryForEntryPoints(sourceDirectory);
|
||||
const targetEntryPoint = targetEntryPointPath ?
|
||||
unsortedEntryPoints.find(entryPoint => entryPoint.path === targetEntryPointPath) :
|
||||
undefined;
|
||||
return this.resolver.sortEntryPointsByDependency(unsortedEntryPoints, targetEntryPoint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for entry points that need to be compiled, starting at the source directory.
|
||||
* The function will recurse into directories that start with `@...`, e.g. `@angular/...`.
|
||||
* @param sourceDirectory An absolute path to the root directory where searching begins.
|
||||
*/
|
||||
function walkDirectoryForEntryPoints(sourceDirectory: AbsoluteFsPath): EntryPoint[] {
|
||||
const entryPoints: EntryPoint[] = [];
|
||||
fs.readdirSync(sourceDirectory)
|
||||
// Not interested in hidden files
|
||||
.filter(p => !p.startsWith('.'))
|
||||
// Ignore node_modules
|
||||
.filter(p => p !== 'node_modules')
|
||||
// Only interested in directories (and only those that are not symlinks)
|
||||
.filter(p => {
|
||||
const stat = fs.lstatSync(path.resolve(sourceDirectory, p));
|
||||
return stat.isDirectory() && !stat.isSymbolicLink();
|
||||
})
|
||||
.forEach(p => {
|
||||
// Either the directory is a potential package or a namespace containing packages (e.g
|
||||
// `@angular`).
|
||||
const packagePath = AbsoluteFsPath.from(path.join(sourceDirectory, p));
|
||||
if (p.startsWith('@')) {
|
||||
entryPoints.push(...walkDirectoryForEntryPoints(packagePath));
|
||||
} else {
|
||||
entryPoints.push(...getEntryPointsForPackage(packagePath));
|
||||
/**
|
||||
* Look for entry points that need to be compiled, starting at the source directory.
|
||||
* The function will recurse into directories that start with `@...`, e.g. `@angular/...`.
|
||||
* @param sourceDirectory An absolute path to the root directory where searching begins.
|
||||
*/
|
||||
private walkDirectoryForEntryPoints(sourceDirectory: AbsoluteFsPath): EntryPoint[] {
|
||||
const entryPoints: EntryPoint[] = [];
|
||||
fs.readdirSync(sourceDirectory)
|
||||
// Not interested in hidden files
|
||||
.filter(p => !p.startsWith('.'))
|
||||
// Ignore node_modules
|
||||
.filter(p => p !== 'node_modules')
|
||||
// Only interested in directories (and only those that are not symlinks)
|
||||
.filter(p => {
|
||||
const stat = fs.lstatSync(path.resolve(sourceDirectory, p));
|
||||
return stat.isDirectory() && !stat.isSymbolicLink();
|
||||
})
|
||||
.forEach(p => {
|
||||
// Either the directory is a potential package or a namespace containing packages (e.g
|
||||
// `@angular`).
|
||||
const packagePath = AbsoluteFsPath.from(path.join(sourceDirectory, p));
|
||||
if (p.startsWith('@')) {
|
||||
entryPoints.push(...this.walkDirectoryForEntryPoints(packagePath));
|
||||
} else {
|
||||
entryPoints.push(...this.getEntryPointsForPackage(packagePath));
|
||||
|
||||
// Also check for any nested node_modules in this package
|
||||
const nestedNodeModulesPath =
|
||||
AbsoluteFsPath.from(path.resolve(packagePath, 'node_modules'));
|
||||
if (fs.existsSync(nestedNodeModulesPath)) {
|
||||
entryPoints.push(...walkDirectoryForEntryPoints(nestedNodeModulesPath));
|
||||
// Also check for any nested node_modules in this package
|
||||
const nestedNodeModulesPath =
|
||||
AbsoluteFsPath.from(path.resolve(packagePath, 'node_modules'));
|
||||
if (fs.existsSync(nestedNodeModulesPath)) {
|
||||
entryPoints.push(...this.walkDirectoryForEntryPoints(nestedNodeModulesPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return entryPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recurse the folder structure looking for all the entry points
|
||||
* @param packagePath The absolute path to an npm package that may contain entry points
|
||||
* @returns An array of entry points that were discovered.
|
||||
*/
|
||||
function getEntryPointsForPackage(packagePath: AbsoluteFsPath): EntryPoint[] {
|
||||
const entryPoints: EntryPoint[] = [];
|
||||
|
||||
// Try to get an entry point from the top level package directory
|
||||
const topLevelEntryPoint = getEntryPointInfo(packagePath, packagePath);
|
||||
if (topLevelEntryPoint !== null) {
|
||||
entryPoints.push(topLevelEntryPoint);
|
||||
});
|
||||
return entryPoints;
|
||||
}
|
||||
|
||||
// Now search all the directories of this package for possible entry points
|
||||
walkDirectory(packagePath, subdir => {
|
||||
const subEntryPoint = getEntryPointInfo(packagePath, subdir);
|
||||
if (subEntryPoint !== null) {
|
||||
entryPoints.push(subEntryPoint);
|
||||
/**
|
||||
* Recurse the folder structure looking for all the entry points
|
||||
* @param packagePath The absolute path to an npm package that may contain entry points
|
||||
* @returns An array of entry points that were discovered.
|
||||
*/
|
||||
private getEntryPointsForPackage(packagePath: AbsoluteFsPath): EntryPoint[] {
|
||||
const entryPoints: EntryPoint[] = [];
|
||||
|
||||
// Try to get an entry point from the top level package directory
|
||||
const topLevelEntryPoint = getEntryPointInfo(this.logger, packagePath, packagePath);
|
||||
if (topLevelEntryPoint !== null) {
|
||||
entryPoints.push(topLevelEntryPoint);
|
||||
}
|
||||
});
|
||||
|
||||
return entryPoints;
|
||||
}
|
||||
// Now search all the directories of this package for possible entry points
|
||||
this.walkDirectory(packagePath, subdir => {
|
||||
const subEntryPoint = getEntryPointInfo(this.logger, packagePath, subdir);
|
||||
if (subEntryPoint !== null) {
|
||||
entryPoints.push(subEntryPoint);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Recursively walk a directory and its sub-directories, applying a given
|
||||
* function to each directory.
|
||||
* @param dir the directory to recursively walk.
|
||||
* @param fn the function to apply to each directory.
|
||||
*/
|
||||
function walkDirectory(dir: AbsoluteFsPath, fn: (dir: AbsoluteFsPath) => void) {
|
||||
return fs
|
||||
.readdirSync(dir)
|
||||
// Not interested in hidden files
|
||||
.filter(p => !p.startsWith('.'))
|
||||
// Ignore node_modules
|
||||
.filter(p => p !== 'node_modules')
|
||||
// Only interested in directories (and only those that are not symlinks)
|
||||
.filter(p => {
|
||||
const stat = fs.lstatSync(path.resolve(dir, p));
|
||||
return stat.isDirectory() && !stat.isSymbolicLink();
|
||||
})
|
||||
.forEach(subDir => {
|
||||
const resolvedSubDir = AbsoluteFsPath.from(path.resolve(dir, subDir));
|
||||
fn(resolvedSubDir);
|
||||
walkDirectory(resolvedSubDir, fn);
|
||||
});
|
||||
return entryPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively walk a directory and its sub-directories, applying a given
|
||||
* function to each directory.
|
||||
* @param dir the directory to recursively walk.
|
||||
* @param fn the function to apply to each directory.
|
||||
*/
|
||||
private walkDirectory(dir: AbsoluteFsPath, fn: (dir: AbsoluteFsPath) => void) {
|
||||
return fs
|
||||
.readdirSync(dir)
|
||||
// Not interested in hidden files
|
||||
.filter(p => !p.startsWith('.'))
|
||||
// Ignore node_modules
|
||||
.filter(p => p !== 'node_modules')
|
||||
// Only interested in directories (and only those that are not symlinks)
|
||||
.filter(p => {
|
||||
const stat = fs.lstatSync(path.resolve(dir, p));
|
||||
return stat.isDirectory() && !stat.isSymbolicLink();
|
||||
})
|
||||
.forEach(subDir => {
|
||||
const resolvedSubDir = AbsoluteFsPath.from(path.resolve(dir, subDir));
|
||||
fn(resolvedSubDir);
|
||||
this.walkDirectory(resolvedSubDir, fn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import {SwitchMarkerAnalyses, SwitchMarkerAnalyzer} from '../analysis/switch_mar
|
||||
import {Esm2015ReflectionHost} from '../host/esm2015_host';
|
||||
import {Esm5ReflectionHost} from '../host/esm5_host';
|
||||
import {NgccReflectionHost} from '../host/ngcc_host';
|
||||
import {Logger} from '../logging/logger';
|
||||
import {Esm5Renderer} from '../rendering/esm5_renderer';
|
||||
import {EsmRenderer} from '../rendering/esm_renderer';
|
||||
import {FileInfo, Renderer} from '../rendering/renderer';
|
||||
@ -45,7 +46,7 @@ import {EntryPointBundle} from './entry_point_bundle';
|
||||
* - Some formats may contain multiple "modules" in a single file.
|
||||
*/
|
||||
export class Transformer {
|
||||
constructor(private sourcePath: string) {}
|
||||
constructor(private logger: Logger, private sourcePath: string) {}
|
||||
|
||||
/**
|
||||
* Transform the source (and typings) files of a bundle.
|
||||
@ -73,9 +74,9 @@ export class Transformer {
|
||||
const typeChecker = bundle.src.program.getTypeChecker();
|
||||
switch (bundle.format) {
|
||||
case 'esm2015':
|
||||
return new Esm2015ReflectionHost(isCore, typeChecker, bundle.dts);
|
||||
return new Esm2015ReflectionHost(this.logger, isCore, typeChecker, bundle.dts);
|
||||
case 'esm5':
|
||||
return new Esm5ReflectionHost(isCore, typeChecker, bundle.dts);
|
||||
return new Esm5ReflectionHost(this.logger, isCore, typeChecker, bundle.dts);
|
||||
default:
|
||||
throw new Error(`Reflection host for "${bundle.format}" not yet implemented.`);
|
||||
}
|
||||
@ -84,9 +85,9 @@ export class Transformer {
|
||||
getRenderer(host: NgccReflectionHost, isCore: boolean, bundle: EntryPointBundle): Renderer {
|
||||
switch (bundle.format) {
|
||||
case 'esm2015':
|
||||
return new EsmRenderer(host, isCore, bundle, this.sourcePath);
|
||||
return new EsmRenderer(this.logger, host, isCore, bundle, this.sourcePath);
|
||||
case 'esm5':
|
||||
return new Esm5Renderer(host, isCore, bundle, this.sourcePath);
|
||||
return new Esm5Renderer(this.logger, host, isCore, bundle, this.sourcePath);
|
||||
default:
|
||||
throw new Error(`Renderer for "${bundle.format}" not yet implemented.`);
|
||||
}
|
||||
|
@ -12,11 +12,13 @@ import {NgccReflectionHost} from '../host/ngcc_host';
|
||||
import {CompiledClass} from '../analysis/decoration_analyzer';
|
||||
import {EsmRenderer} from './esm_renderer';
|
||||
import {EntryPointBundle} from '../packages/entry_point_bundle';
|
||||
import {Logger} from '../logging/logger';
|
||||
|
||||
export class Esm5Renderer extends EsmRenderer {
|
||||
constructor(
|
||||
host: NgccReflectionHost, isCore: boolean, bundle: EntryPointBundle, sourcePath: string) {
|
||||
super(host, isCore, bundle, sourcePath);
|
||||
logger: Logger, host: NgccReflectionHost, isCore: boolean, bundle: EntryPointBundle,
|
||||
sourcePath: string) {
|
||||
super(logger, host, isCore, bundle, sourcePath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,11 +14,13 @@ import {RedundantDecoratorMap, Renderer, stripExtension} from './renderer';
|
||||
import {EntryPointBundle} from '../packages/entry_point_bundle';
|
||||
import {ExportInfo} from '../analysis/private_declarations_analyzer';
|
||||
import {isDtsPath} from '../../../src/ngtsc/util/src/typescript';
|
||||
import {Logger} from '../logging/logger';
|
||||
|
||||
export class EsmRenderer extends Renderer {
|
||||
constructor(
|
||||
host: NgccReflectionHost, isCore: boolean, bundle: EntryPointBundle, sourcePath: string) {
|
||||
super(host, isCore, bundle, sourcePath);
|
||||
logger: Logger, host: NgccReflectionHost, isCore: boolean, bundle: EntryPointBundle,
|
||||
sourcePath: string) {
|
||||
super(logger, host, isCore, bundle, sourcePath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,7 @@ import {SwitchMarkerAnalyses, SwitchMarkerAnalysis} from '../analysis/switch_mar
|
||||
import {IMPORT_PREFIX} from '../constants';
|
||||
import {NgccReflectionHost, SwitchableVariableDeclaration} from '../host/ngcc_host';
|
||||
import {EntryPointBundle} from '../packages/entry_point_bundle';
|
||||
import {Logger} from '../logging/logger';
|
||||
|
||||
interface SourceMapInfo {
|
||||
source: string;
|
||||
@ -80,7 +81,7 @@ export const RedundantDecoratorMap = Map;
|
||||
*/
|
||||
export abstract class Renderer {
|
||||
constructor(
|
||||
protected host: NgccReflectionHost, protected isCore: boolean,
|
||||
protected logger: Logger, protected host: NgccReflectionHost, protected isCore: boolean,
|
||||
protected bundle: EntryPointBundle, protected sourcePath: string) {}
|
||||
|
||||
renderProgram(
|
||||
@ -299,16 +300,16 @@ export abstract class Renderer {
|
||||
externalSourceMap = fromMapFileSource(file.text, dirname(file.fileName));
|
||||
} catch (e) {
|
||||
if (e.code === 'ENOENT') {
|
||||
console.warn(
|
||||
this.logger.warn(
|
||||
`The external map file specified in the source code comment "${e.path}" was not found on the file system.`);
|
||||
const mapPath = file.fileName + '.map';
|
||||
if (basename(e.path) !== basename(mapPath) && statSync(mapPath).isFile()) {
|
||||
console.warn(
|
||||
this.logger.warn(
|
||||
`Guessing the map file name from the source file name: "${basename(mapPath)}"`);
|
||||
try {
|
||||
externalSourceMap = fromObject(JSON.parse(readFileSync(mapPath, 'utf8')));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
this.logger.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user