diff --git a/packages/compiler-cli/src/ngcc/src/analysis/switch_marker_analyzer.ts b/packages/compiler-cli/src/ngcc/src/analysis/switch_marker_analyzer.ts new file mode 100644 index 0000000000..22962e593d --- /dev/null +++ b/packages/compiler-cli/src/ngcc/src/analysis/switch_marker_analyzer.ts @@ -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; +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; + } +} diff --git a/packages/compiler-cli/src/ngcc/test/analysis/switch_marker_analyzer_spec.ts b/packages/compiler-cli/src/ngcc/test/analysis/switch_marker_analyzer_spec.ts new file mode 100644 index 0000000000..e3e21aaccd --- /dev/null +++ b/packages/compiler-cli/src/ngcc/test/analysis/switch_marker_analyzer_spec.ts @@ -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__', + ]); + }); + }); +});