refactor(ivy): ngcc - move typings rendering to Renderer
(#26403)
The rendering of typings is not specific to the package format, so it doesn't make sense to put it in a specific renderer. As a result there is no real difference between esm5 and esm2015 renderers, so there is no point in having separate classes. PR Close #26403
This commit is contained in:
parent
e804143183
commit
dff10085e8
@ -16,9 +16,7 @@ import {DtsMapper} from '../host/dts_mapper';
|
|||||||
import {Esm2015ReflectionHost} from '../host/esm2015_host';
|
import {Esm2015ReflectionHost} from '../host/esm2015_host';
|
||||||
import {Esm5ReflectionHost} from '../host/esm5_host';
|
import {Esm5ReflectionHost} from '../host/esm5_host';
|
||||||
import {NgccReflectionHost} from '../host/ngcc_host';
|
import {NgccReflectionHost} from '../host/ngcc_host';
|
||||||
import {Esm2015Renderer} from '../rendering/esm2015_renderer';
|
import {EsmRenderer} from '../rendering/esm_renderer';
|
||||||
import {Esm5Renderer} from '../rendering/esm5_renderer';
|
|
||||||
import {Fesm2015Renderer} from '../rendering/fesm2015_renderer';
|
|
||||||
import {FileInfo, Renderer} from '../rendering/renderer';
|
import {FileInfo, Renderer} from '../rendering/renderer';
|
||||||
|
|
||||||
import {checkMarkerFile, writeMarkerFile} from './build_marker';
|
import {checkMarkerFile, writeMarkerFile} from './build_marker';
|
||||||
@ -122,18 +120,13 @@ export class Transformer {
|
|||||||
|
|
||||||
getRenderer(
|
getRenderer(
|
||||||
format: string, program: ts.Program, host: NgccReflectionHost, isCore: boolean,
|
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) {
|
switch (format) {
|
||||||
case 'esm2015':
|
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 'esm5':
|
||||||
|
case 'fesm2015':
|
||||||
case 'fesm5':
|
case 'fesm5':
|
||||||
return new Esm5Renderer(
|
return new EsmRenderer(host, isCore, rewriteCoreImportsTo, this.sourcePath, this.targetPath, dtsMapper);
|
||||||
host, isCore, rewriteCoreImportsTo, this.sourcePath, this.targetPath);
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Renderer for "${format}" not yet implemented.`);
|
throw new Error(`Renderer for "${format}" not yet implemented.`);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 {}
|
|
@ -7,16 +7,17 @@
|
|||||||
*/
|
*/
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
import MagicString from 'magic-string';
|
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 {NgccReflectionHost, POST_R3_MARKER, PRE_R3_MARKER, SwitchableVariableDeclaration} from '../host/ngcc_host';
|
||||||
import {AnalyzedClass} from '../analysis/decoration_analyzer';
|
import {AnalyzedClass} from '../analysis/decoration_analyzer';
|
||||||
import {Renderer} from './renderer';
|
import {Renderer} from './renderer';
|
||||||
|
|
||||||
export class Fesm2015Renderer extends Renderer {
|
export class EsmRenderer extends Renderer {
|
||||||
constructor(
|
constructor(
|
||||||
protected host: NgccReflectionHost, protected isCore: boolean,
|
protected host: NgccReflectionHost, protected isCore: boolean,
|
||||||
protected rewriteCoreImportsTo: ts.SourceFile|null, protected sourcePath: string,
|
protected rewriteCoreImportsTo: ts.SourceFile|null, protected sourcePath: string,
|
||||||
protected targetPath: string) {
|
protected targetPath: string, dtsMapper: DtsMapper|null) {
|
||||||
super(host, isCore, rewriteCoreImportsTo, sourcePath, targetPath);
|
super(host, isCore, rewriteCoreImportsTo, sourcePath, targetPath, dtsMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -14,11 +14,13 @@ import {SourceMapConsumer, SourceMapGenerator, RawSourceMap} from 'source-map';
|
|||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {Decorator} from '../../../ngtsc/host';
|
import {Decorator} from '../../../ngtsc/host';
|
||||||
|
import {DtsFileTransformer} from '../../../ngtsc/transform';
|
||||||
import {translateStatement} from '../../../ngtsc/translator';
|
import {translateStatement} from '../../../ngtsc/translator';
|
||||||
import {NgccImportManager} from './ngcc_import_manager';
|
import {NgccImportManager} from './ngcc_import_manager';
|
||||||
import {AnalyzedClass, DecorationAnalysis, DecorationAnalyses} from '../analysis/decoration_analyzer';
|
import {AnalyzedClass, DecorationAnalysis, DecorationAnalyses} from '../analysis/decoration_analyzer';
|
||||||
import {SwitchMarkerAnalyses, SwitchMarkerAnalysis} from '../analysis/switch_marker_analyzer';
|
import {SwitchMarkerAnalyses, SwitchMarkerAnalysis} from '../analysis/switch_marker_analyzer';
|
||||||
import {IMPORT_PREFIX} from '../constants';
|
import {IMPORT_PREFIX} from '../constants';
|
||||||
|
import {DtsMapper} from '../host/dts_mapper';
|
||||||
import {NgccReflectionHost, SwitchableVariableDeclaration} from '../host/ngcc_host';
|
import {NgccReflectionHost, SwitchableVariableDeclaration} from '../host/ngcc_host';
|
||||||
|
|
||||||
interface SourceMapInfo {
|
interface SourceMapInfo {
|
||||||
@ -65,23 +67,27 @@ export abstract class Renderer {
|
|||||||
constructor(
|
constructor(
|
||||||
protected host: NgccReflectionHost, protected isCore: boolean,
|
protected host: NgccReflectionHost, protected isCore: boolean,
|
||||||
protected rewriteCoreImportsTo: ts.SourceFile|null, protected sourcePath: string,
|
protected rewriteCoreImportsTo: ts.SourceFile|null, protected sourcePath: string,
|
||||||
protected targetPath: string) {}
|
protected targetPath: string, protected dtsMapper: DtsMapper|null) {}
|
||||||
|
|
||||||
renderProgram(
|
renderProgram(
|
||||||
program: ts.Program, decorationAnalyses: DecorationAnalyses,
|
program: ts.Program, decorationAnalyses: DecorationAnalyses,
|
||||||
switchMarkerAnalyses: SwitchMarkerAnalyses): FileInfo[] {
|
switchMarkerAnalyses: SwitchMarkerAnalyses): FileInfo[] {
|
||||||
const renderedFiles: FileInfo[] = [];
|
const renderedFiles: FileInfo[] = [];
|
||||||
// Transform the source files and source maps.
|
|
||||||
|
// Transform the source files, source maps and typings files.
|
||||||
program.getSourceFiles().map(sourceFile => {
|
program.getSourceFiles().map(sourceFile => {
|
||||||
const decorationAnalysis = decorationAnalyses.get(sourceFile);
|
const decorationAnalysis = decorationAnalyses.get(sourceFile);
|
||||||
const switchMarkerAnalysis = switchMarkerAnalyses.get(sourceFile);
|
const switchMarkerAnalysis = switchMarkerAnalyses.get(sourceFile);
|
||||||
|
|
||||||
// Transform the source files and source maps.
|
|
||||||
if (decorationAnalysis || switchMarkerAnalysis) {
|
if (decorationAnalysis || switchMarkerAnalysis) {
|
||||||
const targetPath = resolve(this.targetPath, relative(this.sourcePath, sourceFile.fileName));
|
const targetPath = resolve(this.targetPath, relative(this.sourcePath, sourceFile.fileName));
|
||||||
renderedFiles.push(
|
renderedFiles.push(
|
||||||
...this.renderFile(sourceFile, decorationAnalysis, switchMarkerAnalysis, targetPath));
|
...this.renderFile(sourceFile, decorationAnalysis, switchMarkerAnalysis, targetPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (decorationAnalyses) {
|
||||||
|
renderedFiles.push(...this.renderTypings(decorationAnalyses));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return renderedFiles;
|
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;
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1208,8 +1208,7 @@ describe('Fesm2015ReflectionHost', () => {
|
|||||||
it('should return a collection of all the switchable variable declarations in the given module',
|
it('should return a collection of all the switchable variable declarations in the given module',
|
||||||
() => {
|
() => {
|
||||||
const program = makeProgram(MARKER_FILE);
|
const program = makeProgram(MARKER_FILE);
|
||||||
const dtsMapper = new DtsMapper('/src', '/typings');
|
const host = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||||
const host = new Esm2015ReflectionHost(false, program.getTypeChecker(), dtsMapper);
|
|
||||||
const file = program.getSourceFile(MARKER_FILE.name) !;
|
const file = program.getSourceFile(MARKER_FILE.name) !;
|
||||||
const declarations = host.getSwitchableDeclarations(file);
|
const declarations = host.getSwitchableDeclarations(file);
|
||||||
expect(declarations.map(d => [d.name.getText(), d.initializer !.getText()])).toEqual([
|
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',
|
it('should return an array of objects for each file that has exported and decorated classes',
|
||||||
() => {
|
() => {
|
||||||
const program = makeProgram(...DECORATED_FILES);
|
const program = makeProgram(...DECORATED_FILES);
|
||||||
const dtsMapper = new DtsMapper('/src', '/typings');
|
const host = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||||
const host = new Esm2015ReflectionHost(false, program.getTypeChecker(), dtsMapper);
|
|
||||||
const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !;
|
const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !;
|
||||||
const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !;
|
const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !;
|
||||||
const decoratedFiles = host.findDecoratedFiles(primaryFile);
|
const decoratedFiles = host.findDecoratedFiles(primaryFile);
|
||||||
|
@ -14,18 +14,17 @@ import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
|||||||
import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
|
import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
|
||||||
import {DtsMapper} from '../../src/host/dts_mapper';
|
import {DtsMapper} from '../../src/host/dts_mapper';
|
||||||
import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
|
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) {
|
function setup(file: {name: string, contents: string}, transformDts: boolean = false) {
|
||||||
const dir = dirname(file.name);
|
const dir = dirname(file.name);
|
||||||
const dtsMapper = new DtsMapper(dir, dir);
|
|
||||||
const program = makeProgram(file);
|
const program = makeProgram(file);
|
||||||
const sourceFile = program.getSourceFile(file.name) !;
|
const sourceFile = program.getSourceFile(file.name) !;
|
||||||
const host = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
const host = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||||
const decorationAnalyses =
|
const decorationAnalyses =
|
||||||
new DecorationAnalyzer(program.getTypeChecker(), host, [''], false).analyzeProgram(program);
|
new DecorationAnalyzer(program.getTypeChecker(), host, [''], false).analyzeProgram(program);
|
||||||
const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).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};
|
return {host, program, sourceFile, renderer, decorationAnalyses, switchMarkerAnalyses};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import {makeProgram} from '../helpers/utils';
|
|||||||
import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
||||||
import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
|
import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
|
||||||
import {Esm5ReflectionHost} from '../../src/host/esm5_host';
|
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}) {
|
function setup(file: {name: string, contents: string}) {
|
||||||
const program = makeProgram(file);
|
const program = makeProgram(file);
|
||||||
@ -20,7 +20,7 @@ function setup(file: {name: string, contents: string}) {
|
|||||||
const decorationAnalyses =
|
const decorationAnalyses =
|
||||||
new DecorationAnalyzer(program.getTypeChecker(), host, [''], false).analyzeProgram(program);
|
new DecorationAnalyzer(program.getTypeChecker(), host, [''], false).analyzeProgram(program);
|
||||||
const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).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};
|
return {host, program, sourceFile, renderer, decorationAnalyses, switchMarkerAnalyses};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
|
|||||||
import {Renderer} from '../../src/rendering/renderer';
|
import {Renderer} from '../../src/rendering/renderer';
|
||||||
|
|
||||||
class TestRenderer extends 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}[]) {
|
addImports(output: MagicString, imports: {name: string, as: string}[]) {
|
||||||
output.prepend('\n// ADD IMPORTS\n');
|
output.prepend('\n// ADD IMPORTS\n');
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user