diff --git a/packages/compiler-cli/src/ngcc/src/packages/transformer.ts b/packages/compiler-cli/src/ngcc/src/packages/transformer.ts index ac03b344fc..a7955f68a4 100644 --- a/packages/compiler-cli/src/ngcc/src/packages/transformer.ts +++ b/packages/compiler-cli/src/ngcc/src/packages/transformer.ts @@ -16,9 +16,7 @@ import {DtsMapper} from '../host/dts_mapper'; import {Esm2015ReflectionHost} from '../host/esm2015_host'; import {Esm5ReflectionHost} from '../host/esm5_host'; import {NgccReflectionHost} from '../host/ngcc_host'; -import {Esm2015Renderer} from '../rendering/esm2015_renderer'; -import {Esm5Renderer} from '../rendering/esm5_renderer'; -import {Fesm2015Renderer} from '../rendering/fesm2015_renderer'; +import {EsmRenderer} from '../rendering/esm_renderer'; import {FileInfo, Renderer} from '../rendering/renderer'; import {checkMarkerFile, writeMarkerFile} from './build_marker'; @@ -122,18 +120,13 @@ export class Transformer { getRenderer( format: string, program: ts.Program, host: NgccReflectionHost, isCore: boolean, - rewriteCoreImportsTo: ts.SourceFile|null, dtsMapper: DtsMapper): Renderer { + rewriteCoreImportsTo: ts.SourceFile|null, dtsMapper: DtsMapper|null): Renderer { switch (format) { case 'esm2015': - return new Esm2015Renderer( - host, isCore, rewriteCoreImportsTo, this.sourcePath, this.targetPath, dtsMapper); - case 'fesm2015': - return new Fesm2015Renderer( - host, isCore, rewriteCoreImportsTo, this.sourcePath, this.targetPath); case 'esm5': + case 'fesm2015': case 'fesm5': - return new Esm5Renderer( - host, isCore, rewriteCoreImportsTo, this.sourcePath, this.targetPath); + return new EsmRenderer(host, isCore, rewriteCoreImportsTo, this.sourcePath, this.targetPath, dtsMapper); default: throw new Error(`Renderer for "${format}" not yet implemented.`); } diff --git a/packages/compiler-cli/src/ngcc/src/rendering/esm2015_renderer.ts b/packages/compiler-cli/src/ngcc/src/rendering/esm2015_renderer.ts deleted file mode 100644 index bc2b3991aa..0000000000 --- a/packages/compiler-cli/src/ngcc/src/rendering/esm2015_renderer.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @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 {relative, resolve} from 'canonical-path'; -import {readFileSync} from 'fs'; -import * as ts from 'typescript'; - -import {DtsFileTransformer} from '../../../ngtsc/transform'; -import {DecorationAnalysis} from '../analysis/decoration_analyzer'; -import {SwitchMarkerAnalysis} from '../analysis/switch_marker_analyzer'; -import {IMPORT_PREFIX} from '../constants'; -import {DtsMapper} from '../host/dts_mapper'; -import {NgccReflectionHost} from '../host/ngcc_host'; - -import {Fesm2015Renderer} from './fesm2015_renderer'; -import {FileInfo} from './renderer'; - -export class Esm2015Renderer extends Fesm2015Renderer { - constructor( - protected host: NgccReflectionHost, protected isCore: boolean, - protected rewriteCoreImportsTo: ts.SourceFile|null, protected sourcePath: string, - protected targetPath: string, protected dtsMapper: DtsMapper) { - super(host, isCore, rewriteCoreImportsTo, sourcePath, targetPath); - } - - renderFile( - sourceFile: ts.SourceFile, decorationAnalysis: DecorationAnalysis|undefined, - switchMarkerAnalysis: SwitchMarkerAnalysis|undefined, targetPath: string): FileInfo[] { - const renderedFiles = - super.renderFile(sourceFile, decorationAnalysis, switchMarkerAnalysis, targetPath); - - // Transform the `.d.ts` files. - // TODO(gkalpak): What about `.d.ts` source maps? (See - // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#new---declarationmap.) - if (decorationAnalysis) { - // Create a `DtsFileTransformer` for the source file and record the generated fields, which - // will allow the corresponding `.d.ts` file to be transformed later. - const dtsTransformer = new DtsFileTransformer(this.rewriteCoreImportsTo, IMPORT_PREFIX); - decorationAnalysis.analyzedClasses.forEach( - analyzedClass => - dtsTransformer.recordStaticField(analyzedClass.name, analyzedClass.compilation)); - - // Find the corresponding `.d.ts` file. - const sourceFileName = sourceFile.fileName; - const originalDtsFileName = this.dtsMapper.getDtsFileNameFor(sourceFileName); - const originalDtsContents = readFileSync(originalDtsFileName, 'utf8'); - - // Transform the `.d.ts` file based on the recorded source file changes. - const transformedDtsFileName = - resolve(this.targetPath, relative(this.sourcePath, originalDtsFileName)); - const transformedDtsContents = dtsTransformer.transform(originalDtsContents, sourceFileName); - - // Add the transformed `.d.ts` file to the list of output files. - renderedFiles.push({path: transformedDtsFileName, contents: transformedDtsContents}); - } - - return renderedFiles; - } -} diff --git a/packages/compiler-cli/src/ngcc/src/rendering/esm5_renderer.ts b/packages/compiler-cli/src/ngcc/src/rendering/esm5_renderer.ts deleted file mode 100644 index 9581029e34..0000000000 --- a/packages/compiler-cli/src/ngcc/src/rendering/esm5_renderer.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * @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 {Fesm2015Renderer} from './fesm2015_renderer'; - -export class Esm5Renderer extends Fesm2015Renderer {} diff --git a/packages/compiler-cli/src/ngcc/src/rendering/fesm2015_renderer.ts b/packages/compiler-cli/src/ngcc/src/rendering/esm_renderer.ts similarity index 95% rename from packages/compiler-cli/src/ngcc/src/rendering/fesm2015_renderer.ts rename to packages/compiler-cli/src/ngcc/src/rendering/esm_renderer.ts index fe45f08a66..087e4de324 100644 --- a/packages/compiler-cli/src/ngcc/src/rendering/fesm2015_renderer.ts +++ b/packages/compiler-cli/src/ngcc/src/rendering/esm_renderer.ts @@ -7,16 +7,17 @@ */ import * as ts from 'typescript'; import MagicString from 'magic-string'; +import {DtsMapper} from '../host/dts_mapper'; import {NgccReflectionHost, POST_R3_MARKER, PRE_R3_MARKER, SwitchableVariableDeclaration} from '../host/ngcc_host'; import {AnalyzedClass} from '../analysis/decoration_analyzer'; import {Renderer} from './renderer'; -export class Fesm2015Renderer extends Renderer { +export class EsmRenderer extends Renderer { constructor( protected host: NgccReflectionHost, protected isCore: boolean, protected rewriteCoreImportsTo: ts.SourceFile|null, protected sourcePath: string, - protected targetPath: string) { - super(host, isCore, rewriteCoreImportsTo, sourcePath, targetPath); + protected targetPath: string, dtsMapper: DtsMapper|null) { + super(host, isCore, rewriteCoreImportsTo, sourcePath, targetPath, dtsMapper); } /** diff --git a/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts b/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts index 76676eef1f..9a05bf143e 100644 --- a/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts +++ b/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts @@ -14,11 +14,13 @@ import {SourceMapConsumer, SourceMapGenerator, RawSourceMap} from 'source-map'; import * as ts from 'typescript'; import {Decorator} from '../../../ngtsc/host'; +import {DtsFileTransformer} from '../../../ngtsc/transform'; import {translateStatement} from '../../../ngtsc/translator'; import {NgccImportManager} from './ngcc_import_manager'; import {AnalyzedClass, DecorationAnalysis, DecorationAnalyses} from '../analysis/decoration_analyzer'; import {SwitchMarkerAnalyses, SwitchMarkerAnalysis} from '../analysis/switch_marker_analyzer'; import {IMPORT_PREFIX} from '../constants'; +import {DtsMapper} from '../host/dts_mapper'; import {NgccReflectionHost, SwitchableVariableDeclaration} from '../host/ngcc_host'; interface SourceMapInfo { @@ -65,23 +67,27 @@ export abstract class Renderer { constructor( protected host: NgccReflectionHost, protected isCore: boolean, protected rewriteCoreImportsTo: ts.SourceFile|null, protected sourcePath: string, - protected targetPath: string) {} + protected targetPath: string, protected dtsMapper: DtsMapper|null) {} renderProgram( program: ts.Program, decorationAnalyses: DecorationAnalyses, switchMarkerAnalyses: SwitchMarkerAnalyses): FileInfo[] { const renderedFiles: FileInfo[] = []; - // Transform the source files and source maps. + + // Transform the source files, source maps and typings files. program.getSourceFiles().map(sourceFile => { const decorationAnalysis = decorationAnalyses.get(sourceFile); const switchMarkerAnalysis = switchMarkerAnalyses.get(sourceFile); - // Transform the source files and source maps. if (decorationAnalysis || switchMarkerAnalysis) { const targetPath = resolve(this.targetPath, relative(this.sourcePath, sourceFile.fileName)); renderedFiles.push( ...this.renderFile(sourceFile, decorationAnalysis, switchMarkerAnalysis, targetPath)); } + + if (decorationAnalyses) { + renderedFiles.push(...this.renderTypings(decorationAnalyses)); + } }); return renderedFiles; } @@ -244,6 +250,27 @@ export abstract class Renderer { }; } } + + // TODO(gkalpak): What about `.d.ts` source maps? (See + // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#new---declarationmap.) + renderTypings(decorationAnalyses: DecorationAnalyses): FileInfo[] { + const renderedFiles: FileInfo[] = []; + if (this.dtsMapper) { + const dtsTransformer = new DtsFileTransformer(this.rewriteCoreImportsTo, IMPORT_PREFIX); + decorationAnalyses.forEach((analysis, sourceFile) => { + const sourceFileName = sourceFile.fileName; + const dtsFileName = this.dtsMapper !.getDtsFileNameFor(sourceFileName); + const dtsContents = readFileSync(dtsFileName, 'utf8'); + analysis.analyzedClasses.forEach(analyzedClass => dtsTransformer.recordStaticField(analyzedClass.name, analyzedClass.compilation)); + const newDtsFileName = resolve(this.targetPath, relative(this.sourcePath, dtsFileName)); + const newDtsContents = dtsTransformer.transform(dtsContents, sourceFileName); + renderedFiles.push({path: newDtsFileName, contents: newDtsContents}); + }); + } + return renderedFiles; + + // } + } } /** diff --git a/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts b/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts index 7e8252764e..05e310e056 100644 --- a/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts @@ -1208,8 +1208,7 @@ describe('Fesm2015ReflectionHost', () => { it('should return a collection of all the switchable variable declarations in the given module', () => { const program = makeProgram(MARKER_FILE); - const dtsMapper = new DtsMapper('/src', '/typings'); - const host = new Esm2015ReflectionHost(false, program.getTypeChecker(), dtsMapper); + const host = new Esm2015ReflectionHost(false, program.getTypeChecker()); const file = program.getSourceFile(MARKER_FILE.name) !; const declarations = host.getSwitchableDeclarations(file); expect(declarations.map(d => [d.name.getText(), d.initializer !.getText()])).toEqual([ @@ -1222,8 +1221,7 @@ describe('Fesm2015ReflectionHost', () => { it('should return an array of objects for each file that has exported and decorated classes', () => { const program = makeProgram(...DECORATED_FILES); - const dtsMapper = new DtsMapper('/src', '/typings'); - const host = new Esm2015ReflectionHost(false, program.getTypeChecker(), dtsMapper); + const host = new Esm2015ReflectionHost(false, program.getTypeChecker()); const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; const decoratedFiles = host.findDecoratedFiles(primaryFile); diff --git a/packages/compiler-cli/src/ngcc/test/rendering/esm2015_renderer_spec.ts b/packages/compiler-cli/src/ngcc/test/rendering/esm2015_renderer_spec.ts index a7c533a969..bfdb94ce89 100644 --- a/packages/compiler-cli/src/ngcc/test/rendering/esm2015_renderer_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/rendering/esm2015_renderer_spec.ts @@ -14,18 +14,17 @@ import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer'; import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer'; import {DtsMapper} from '../../src/host/dts_mapper'; import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; -import {Esm2015Renderer} from '../../src/rendering/esm2015_renderer'; +import {EsmRenderer} from '../../src/rendering/esm_renderer'; function setup(file: {name: string, contents: string}, transformDts: boolean = false) { const dir = dirname(file.name); - const dtsMapper = new DtsMapper(dir, dir); const program = makeProgram(file); const sourceFile = program.getSourceFile(file.name) !; const host = new Esm2015ReflectionHost(false, program.getTypeChecker()); const decorationAnalyses = new DecorationAnalyzer(program.getTypeChecker(), host, [''], false).analyzeProgram(program); const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).analyzeProgram(program); - const renderer = new Esm2015Renderer(host, false, null, dir, dir, dtsMapper); + const renderer = new EsmRenderer(host, false, null, dir, dir, null); return {host, program, sourceFile, renderer, decorationAnalyses, switchMarkerAnalyses}; } diff --git a/packages/compiler-cli/src/ngcc/test/rendering/esm5_renderer_spec.ts b/packages/compiler-cli/src/ngcc/test/rendering/esm5_renderer_spec.ts index e6baed1531..8cc31708b0 100644 --- a/packages/compiler-cli/src/ngcc/test/rendering/esm5_renderer_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/rendering/esm5_renderer_spec.ts @@ -11,7 +11,7 @@ import {makeProgram} from '../helpers/utils'; import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer'; import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer'; import {Esm5ReflectionHost} from '../../src/host/esm5_host'; -import {Esm5Renderer} from '../../src/rendering/esm5_renderer'; +import {EsmRenderer} from '../../src/rendering/esm_renderer'; function setup(file: {name: string, contents: string}) { const program = makeProgram(file); @@ -20,7 +20,7 @@ function setup(file: {name: string, contents: string}) { const decorationAnalyses = new DecorationAnalyzer(program.getTypeChecker(), host, [''], false).analyzeProgram(program); const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).analyzeProgram(program); - const renderer = new Esm5Renderer(host, false, null, '', ''); + const renderer = new EsmRenderer(host, false, null, '', '', null); return {host, program, sourceFile, renderer, decorationAnalyses, switchMarkerAnalyses}; } diff --git a/packages/compiler-cli/src/ngcc/test/rendering/renderer_spec.ts b/packages/compiler-cli/src/ngcc/test/rendering/renderer_spec.ts index 283e46eedb..54f69e0d8f 100644 --- a/packages/compiler-cli/src/ngcc/test/rendering/renderer_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/rendering/renderer_spec.ts @@ -17,7 +17,7 @@ import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; import {Renderer} from '../../src/rendering/renderer'; class TestRenderer extends Renderer { - constructor(host: Esm2015ReflectionHost) { super(host, false, null, '/src', '/dist'); } + constructor(host: Esm2015ReflectionHost) { super(host, false, null, '/src', '/dist', null); } addImports(output: MagicString, imports: {name: string, as: string}[]) { output.prepend('\n// ADD IMPORTS\n'); }