refactor(ivy): implement ngcc `SwitchMarkerAnalyzer` (#26082)

PR Close #26082
This commit is contained in:
Pete Bacon Darwin 2018-10-03 22:08:12 +01:00 committed by Miško Hevery
parent 880c0add56
commit 9562324ea4
2 changed files with 119 additions and 0 deletions

View File

@ -0,0 +1,43 @@
/**
* @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 * as ts from 'typescript';
import {NgccReflectionHost, SwitchableVariableDeclaration} from '../host/ngcc_host';
export interface SwitchMarkerAnalysis {
sourceFile: ts.SourceFile;
declarations: SwitchableVariableDeclaration[];
}
export type SwitchMarkerAnalyses = Map<ts.SourceFile, SwitchMarkerAnalysis>;
export const SwitchMarkerAnalyses = Map;
/**
* This Analyzer will analyse the files that have an NGCC switch marker in them
* that will be replaced.
*/
export class SwitchMarkerAnalyzer {
constructor(private host: NgccReflectionHost) {}
/**
* Analyze the files in the program to identify declarations that contain NGCC
* switch markers.
* @param program The program to analyze.
* @return A map of source files to analysis objects. The map will contain only the
* source files that had switch markers, and the analysis will contain an array of
* the declarations in that source file that contain the marker.
*/
analyzeProgram(program: ts.Program): SwitchMarkerAnalyses {
const analyzedFiles = new SwitchMarkerAnalyses();
program.getSourceFiles().forEach(sourceFile => {
const declarations = this.host.getSwitchableDeclarations(sourceFile);
if (declarations.length) {
analyzedFiles.set(sourceFile, {sourceFile, declarations});
}
});
return analyzedFiles;
}
}

View File

@ -0,0 +1,76 @@
/**
* @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 * as ts from 'typescript';
import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
import {Fesm2015ReflectionHost} from '../../src/host/fesm2015_host';
import {makeProgram} from '../helpers/utils';
const TEST_PROGRAM = [
{
name: 'entrypoint.js',
contents: `
import {a} from './a';
import {b} from './b';
`
},
{
name: 'a.js',
contents: `
import {c} from './c';
export const a = 1;
`
},
{
name: 'b.js',
contents: `
export const b = 42;
var factoryB = factory__PRE_NGCC__;
`
},
{
name: 'c.js',
contents: `
export const c = 'So long, and thanks for all the fish!';
var factoryC = factory__PRE_NGCC__;
var factoryD = factory__PRE_NGCC__;
`
},
];
describe('SwitchMarkerAnalyzer', () => {
describe('analyzeProgram()', () => {
it('should check for switchable markers in all the files of the program', () => {
const program = makeProgram(...TEST_PROGRAM);
const host = new Fesm2015ReflectionHost(program.getTypeChecker());
const analyzer = new SwitchMarkerAnalyzer(host);
const analysis = analyzer.analyzeProgram(program);
const entrypoint = program.getSourceFile('entrypoint.js') !;
const a = program.getSourceFile('a.js') !;
const b = program.getSourceFile('b.js') !;
const c = program.getSourceFile('c.js') !;
expect(analysis.size).toEqual(2);
expect(analysis.has(entrypoint)).toBe(false);
expect(analysis.has(a)).toBe(false);
expect(analysis.has(b)).toBe(true);
expect(analysis.get(b) !.sourceFile).toBe(b);
expect(analysis.get(b) !.declarations.map(decl => decl.getText())).toEqual([
'factoryB = factory__PRE_NGCC__'
]);
expect(analysis.has(c)).toBe(true);
expect(analysis.get(c) !.sourceFile).toBe(c);
expect(analysis.get(c) !.declarations.map(decl => decl.getText())).toEqual([
'factoryC = factory__PRE_NGCC__',
'factoryD = factory__PRE_NGCC__',
]);
});
});
});