diff --git a/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts b/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts index 656a3400e9..c24f698fc9 100644 --- a/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts +++ b/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts @@ -59,34 +59,38 @@ export class FileResourceLoader implements ResourceLoader { */ export class DecorationAnalyzer { resourceLoader = new FileResourceLoader(); - scopeRegistry = new SelectorScopeRegistry(this.typeChecker, this.host); - evaluator = new PartialEvaluator(this.host, this.typeChecker); + scopeRegistry = new SelectorScopeRegistry(this.typeChecker, this.reflectionHost); + evaluator = new PartialEvaluator(this.reflectionHost, this.typeChecker); handlers: DecoratorHandler[] = [ - new BaseDefDecoratorHandler(this.host, this.evaluator), + new BaseDefDecoratorHandler(this.reflectionHost, this.evaluator), new ComponentDecoratorHandler( - this.host, this.evaluator, this.scopeRegistry, this.isCore, this.resourceLoader, + this.reflectionHost, this.evaluator, this.scopeRegistry, this.isCore, this.resourceLoader, this.rootDirs, /* defaultPreserveWhitespaces */ false, /* i18nUseExternalIds */ true), - new DirectiveDecoratorHandler(this.host, this.evaluator, this.scopeRegistry, this.isCore), - new InjectableDecoratorHandler(this.host, this.isCore), + new DirectiveDecoratorHandler( + this.reflectionHost, this.evaluator, this.scopeRegistry, this.isCore), + new InjectableDecoratorHandler(this.reflectionHost, this.isCore), new NgModuleDecoratorHandler( - this.host, this.evaluator, this.scopeRegistry, this.referencesRegistry, this.isCore), - new PipeDecoratorHandler(this.host, this.evaluator, this.scopeRegistry, this.isCore), + this.reflectionHost, this.evaluator, this.scopeRegistry, this.referencesRegistry, + this.isCore), + new PipeDecoratorHandler(this.reflectionHost, this.evaluator, this.scopeRegistry, this.isCore), ]; constructor( - private typeChecker: ts.TypeChecker, private host: NgccReflectionHost, - private referencesRegistry: ReferencesRegistry, private rootDirs: string[], - private isCore: boolean) {} + private program: ts.Program, private options: ts.CompilerOptions, + private host: ts.CompilerHost, private typeChecker: ts.TypeChecker, + private reflectionHost: NgccReflectionHost, private referencesRegistry: ReferencesRegistry, + private rootDirs: string[], private isCore: boolean) {} /** * Analyze a program to find all the decorated files should be transformed. - * @param program The program whose files should be analysed. + * * @returns a map of the source files to the analysis for those files. */ - analyzeProgram(program: ts.Program): DecorationAnalyses { + analyzeProgram(): DecorationAnalyses { const decorationAnalyses = new DecorationAnalyses(); - const analysedFiles = - program.getSourceFiles().map(sourceFile => this.analyzeFile(sourceFile)).filter(isDefined); + const analysedFiles = this.program.getSourceFiles() + .map(sourceFile => this.analyzeFile(sourceFile)) + .filter(isDefined); const compiledFiles = analysedFiles.map(analysedFile => this.compileFile(analysedFile)); compiledFiles.forEach( compiledFile => decorationAnalyses.set(compiledFile.sourceFile, compiledFile)); @@ -94,7 +98,7 @@ export class DecorationAnalyzer { } protected analyzeFile(sourceFile: ts.SourceFile): AnalyzedFile|undefined { - const decoratedClasses = this.host.findDecoratedClasses(sourceFile); + const decoratedClasses = this.reflectionHost.findDecoratedClasses(sourceFile); return decoratedClasses.length ? { sourceFile, analyzedClasses: decoratedClasses.map(clazz => this.analyzeClass(clazz)).filter(isDefined) diff --git a/packages/compiler-cli/src/ngcc/src/packages/bundle_program.ts b/packages/compiler-cli/src/ngcc/src/packages/bundle_program.ts index 9bbcd8abb8..5c8ba5eeb3 100644 --- a/packages/compiler-cli/src/ngcc/src/packages/bundle_program.ts +++ b/packages/compiler-cli/src/ngcc/src/packages/bundle_program.ts @@ -19,6 +19,8 @@ import * as ts from 'typescript'; */ export interface BundleProgram { program: ts.Program; + options: ts.CompilerOptions; + host: ts.CompilerHost; path: string; file: ts.SourceFile; r3SymbolsPath: string|null; @@ -37,7 +39,7 @@ export function makeBundleProgram( const file = program.getSourceFile(path) !; const r3SymbolsFile = r3SymbolsPath && program.getSourceFile(r3SymbolsPath) || null; - return {program, path, file, r3SymbolsPath, r3SymbolsFile}; + return {program, options, host, path, file, r3SymbolsPath, r3SymbolsFile}; } /** diff --git a/packages/compiler-cli/src/ngcc/src/packages/transformer.ts b/packages/compiler-cli/src/ngcc/src/packages/transformer.ts index e2bf4a57a8..fb1ff94ebc 100644 --- a/packages/compiler-cli/src/ngcc/src/packages/transformer.ts +++ b/packages/compiler-cli/src/ngcc/src/packages/transformer.ts @@ -110,8 +110,9 @@ export class Transformer { const switchMarkerAnalyses = switchMarkerAnalyzer.analyzeProgram(bundle.src.program); const decorationAnalyzer = new DecorationAnalyzer( - typeChecker, reflectionHost, referencesRegistry, bundle.rootDirs, isCore); - const decorationAnalyses = decorationAnalyzer.analyzeProgram(bundle.src.program); + bundle.src.program, bundle.src.options, bundle.src.host, typeChecker, reflectionHost, + referencesRegistry, bundle.rootDirs, isCore); + const decorationAnalyses = decorationAnalyzer.analyzeProgram(); const moduleWithProvidersAnalyzer = bundle.dts && new ModuleWithProvidersAnalyzer(reflectionHost, referencesRegistry); diff --git a/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts b/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts index 56ec22c88c..e4a145825f 100644 --- a/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts @@ -12,8 +12,7 @@ import {DecoratorHandler} from '../../../ngtsc/transform'; import {DecorationAnalyses, DecorationAnalyzer} from '../../src/analysis/decoration_analyzer'; import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry'; import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; - -import {makeTestProgram} from '../helpers/utils'; +import {makeTestBundleProgram} from '../helpers/utils'; const TEST_PROGRAM = { name: 'test.js', @@ -84,14 +83,17 @@ describe('DecorationAnalyzer', () => { let result: DecorationAnalyses; beforeEach(() => { - program = makeTestProgram(TEST_PROGRAM); - const host = new Esm2015ReflectionHost(false, program.getTypeChecker()); - const referencesRegistry = new NgccReferencesRegistry(host); - const analyzer = - new DecorationAnalyzer(program.getTypeChecker(), host, referencesRegistry, [''], false); + const {options, host, ...bundle} = makeTestBundleProgram([TEST_PROGRAM]); + program = bundle.program; + + const reflectionHost = new Esm2015ReflectionHost(false, program.getTypeChecker()); + const referencesRegistry = new NgccReferencesRegistry(reflectionHost); + const analyzer = new DecorationAnalyzer( + program, options, host, program.getTypeChecker(), reflectionHost, referencesRegistry, + [''], false); testHandler = createTestHandler(); analyzer.handlers = [testHandler]; - result = analyzer.analyzeProgram(program); + result = analyzer.analyzeProgram(); }); it('should return an object containing a reference to the original source file', () => { @@ -127,14 +129,15 @@ describe('DecorationAnalyzer', () => { // is not yet solved. it('should analyze an internally imported component, which is not publicly exported from the entry-point', () => { - const program = makeTestProgram(...INTERNAL_COMPONENT_PROGRAM); - const host = new Esm2015ReflectionHost(false, program.getTypeChecker()); - const referencesRegistry = new NgccReferencesRegistry(host); + const {program, options, host} = makeTestBundleProgram(INTERNAL_COMPONENT_PROGRAM); + const reflectionHost = new Esm2015ReflectionHost(false, program.getTypeChecker()); + const referencesRegistry = new NgccReferencesRegistry(reflectionHost); const analyzer = new DecorationAnalyzer( - program.getTypeChecker(), host, referencesRegistry, [''], false); + program, options, host, program.getTypeChecker(), reflectionHost, referencesRegistry, + [''], false); const testHandler = createTestHandler(); analyzer.handlers = [testHandler]; - const result = analyzer.analyzeProgram(program); + const result = analyzer.analyzeProgram(); const file = program.getSourceFile('component.js') !; const analysis = result.get(file) !; expect(analysis).toBeDefined(); @@ -144,14 +147,15 @@ describe('DecorationAnalyzer', () => { }); it('should analyze an internally defined component, which is not exported at all', () => { - const program = makeTestProgram(...INTERNAL_COMPONENT_PROGRAM); - const host = new Esm2015ReflectionHost(false, program.getTypeChecker()); - const referencesRegistry = new NgccReferencesRegistry(host); - const analyzer = - new DecorationAnalyzer(program.getTypeChecker(), host, referencesRegistry, [''], false); + const {program, options, host} = makeTestBundleProgram(INTERNAL_COMPONENT_PROGRAM); + const reflectionHost = new Esm2015ReflectionHost(false, program.getTypeChecker()); + const referencesRegistry = new NgccReferencesRegistry(reflectionHost); + const analyzer = new DecorationAnalyzer( + program, options, host, program.getTypeChecker(), reflectionHost, referencesRegistry, + [''], false); const testHandler = createTestHandler(); analyzer.handlers = [testHandler]; - const result = analyzer.analyzeProgram(program); + const result = analyzer.analyzeProgram(); const file = program.getSourceFile('entrypoint.js') !; const analysis = result.get(file) !; expect(analysis).toBeDefined(); diff --git a/packages/compiler-cli/src/ngcc/test/helpers/utils.ts b/packages/compiler-cli/src/ngcc/test/helpers/utils.ts index 3b5656ffab..68e3f5c9b0 100644 --- a/packages/compiler-cli/src/ngcc/test/helpers/utils.ts +++ b/packages/compiler-cli/src/ngcc/test/helpers/utils.ts @@ -35,20 +35,27 @@ export function makeTestEntryPointBundle( * @param files The source files of the bundle program. */ export function makeTestBundleProgram(files: {name: string, contents: string}[]): BundleProgram { - const program = makeTestProgram(...files); + const {program, options, host} = makeTestProgramInternal(...files); const path = files[0].name; const file = program.getSourceFile(path) !; const r3SymbolsInfo = files.find(file => file.name.indexOf('r3_symbols') !== -1) || null; const r3SymbolsPath = r3SymbolsInfo && r3SymbolsInfo.name; const r3SymbolsFile = r3SymbolsPath && program.getSourceFile(r3SymbolsPath) || null; - return {program, path, file, r3SymbolsPath, r3SymbolsFile}; + return {program, options, host, path, file, r3SymbolsPath, r3SymbolsFile}; } +function makeTestProgramInternal( + ...files: {name: string, contents: string, isRoot?: boolean | undefined}[]): { + program: ts.Program, + host: ts.CompilerHost, + options: ts.CompilerOptions, +} { + return makeProgram([getFakeCore(), getFakeTslib(), ...files], {allowJs: true, checkJs: false}); +} export function makeTestProgram( ...files: {name: string, contents: string, isRoot?: boolean | undefined}[]): ts.Program { - return makeProgram([getFakeCore(), getFakeTslib(), ...files], {allowJs: true, checkJs: false}) - .program; + return makeTestProgramInternal(...files).program; } // TODO: unify this with the //packages/compiler-cli/test/ngtsc/fake_core package 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 8e91618073..bce94403d7 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 @@ -21,9 +21,10 @@ function setup(file: {name: string, contents: string}) { const typeChecker = bundle.src.program.getTypeChecker(); const host = new Esm2015ReflectionHost(false, typeChecker); const referencesRegistry = new NgccReferencesRegistry(host); - const decorationAnalyses = - new DecorationAnalyzer(typeChecker, host, referencesRegistry, [''], false) - .analyzeProgram(bundle.src.program); + const decorationAnalyses = new DecorationAnalyzer( + bundle.src.program, bundle.src.options, bundle.src.host, + typeChecker, host, referencesRegistry, [''], false) + .analyzeProgram(); const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).analyzeProgram(bundle.src.program); const renderer = new EsmRenderer(host, false, bundle, dir, dir); return { 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 2642653f62..ccc4299f3d 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 @@ -21,9 +21,10 @@ function setup(file: {name: string, contents: string}) { const typeChecker = bundle.src.program.getTypeChecker(); const host = new Esm5ReflectionHost(false, typeChecker); const referencesRegistry = new NgccReferencesRegistry(host); - const decorationAnalyses = - new DecorationAnalyzer(typeChecker, host, referencesRegistry, [''], false) - .analyzeProgram(bundle.src.program); + const decorationAnalyses = new DecorationAnalyzer( + bundle.src.program, bundle.src.options, bundle.src.host, + typeChecker, host, referencesRegistry, [''], false) + .analyzeProgram(); const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).analyzeProgram(bundle.src.program); const renderer = new Esm5Renderer(host, false, bundle, dir, dir); return { 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 ca4151e524..0c582c52f1 100644 --- a/packages/compiler-cli/src/ngcc/test/rendering/renderer_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/rendering/renderer_spec.ts @@ -54,9 +54,10 @@ function createTestRenderer( const typeChecker = bundle.src.program.getTypeChecker(); const host = new Esm2015ReflectionHost(isCore, typeChecker, bundle.dts); const referencesRegistry = new NgccReferencesRegistry(host); - const decorationAnalyses = - new DecorationAnalyzer(typeChecker, host, referencesRegistry, bundle.rootDirs, isCore) - .analyzeProgram(bundle.src.program); + const decorationAnalyses = new DecorationAnalyzer( + bundle.src.program, bundle.src.options, bundle.src.host, + typeChecker, host, referencesRegistry, bundle.rootDirs, isCore) + .analyzeProgram(); const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).analyzeProgram(bundle.src.program); const moduleWithProvidersAnalyses = new ModuleWithProvidersAnalyzer(host, referencesRegistry).analyzeProgram(bundle.src.program); diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts index 6f6f82cf2f..0e380e8cef 100644 --- a/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts @@ -20,47 +20,50 @@ function makeSimpleProgram(contents: string): ts.Program { } function makeExpression( - code: string, expr: string): {expression: ts.Expression, checker: ts.TypeChecker} { - const {program} = - makeProgram([{name: 'entry.ts', contents: `${code}; const target$ = ${expr};`}]); + code: string, expr: string, supportingFiles: {name: string, contents: string}[] = []): { + expression: ts.Expression, + host: ts.CompilerHost, + checker: ts.TypeChecker, + program: ts.Program, + options: ts.CompilerOptions +} { + const {program, options, host} = makeProgram( + [{name: 'entry.ts', contents: `${code}; const target$ = ${expr};`}, ...supportingFiles]); const checker = program.getTypeChecker(); const decl = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); return { expression: decl.initializer !, + host, + options, checker, + program, }; } -function evaluate(code: string, expr: string): T { - const {expression, checker} = makeExpression(code, expr); - const host = new TypeScriptReflectionHost(checker); - const evaluator = new PartialEvaluator(host, checker); +function evaluate( + code: string, expr: string, supportingFiles: {name: string, contents: string}[] = []): T { + const {expression, checker} = makeExpression(code, expr, supportingFiles); + const reflectionHost = new TypeScriptReflectionHost(checker); + const evaluator = new PartialEvaluator(reflectionHost, checker); return evaluator.evaluate(expression) as T; } describe('ngtsc metadata', () => { it('reads a file correctly', () => { - const {program} = makeProgram([ - { - name: 'entry.ts', - contents: ` - import {Y} from './other'; - const A = Y; - export const X = A; - ` - }, - { - name: 'other.ts', - contents: ` + const value = evaluate( + ` + import {Y} from './other'; + const A = Y; + `, + 'A', [ + { + name: 'other.ts', + contents: ` export const Y = 'test'; ` - } - ]); - const decl = getDeclaration(program, 'entry.ts', 'X', ts.isVariableDeclaration); - const host = new TypeScriptReflectionHost(program.getTypeChecker()); - const evaluator = new PartialEvaluator(host, program.getTypeChecker()); + }, + ]); - const value = evaluator.evaluate(decl.initializer !); expect(value).toEqual('test'); }); @@ -143,10 +146,10 @@ describe('ngtsc metadata', () => { }, ]); const checker = program.getTypeChecker(); - const host = new TypeScriptReflectionHost(checker); + const reflectionHost = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); const expr = result.initializer !; - const evaluator = new PartialEvaluator(host, checker); + const evaluator = new PartialEvaluator(reflectionHost, checker); const resolved = evaluator.evaluate(expr); if (!(resolved instanceof Reference)) { return fail('Expected expression to resolve to a reference'); @@ -175,10 +178,10 @@ describe('ngtsc metadata', () => { }, ]); const checker = program.getTypeChecker(); - const host = new TypeScriptReflectionHost(checker); + const reflectionHost = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); const expr = result.initializer !; - const evaluator = new PartialEvaluator(host, checker); + const evaluator = new PartialEvaluator(reflectionHost, checker); const resolved = evaluator.evaluate(expr); if (!(resolved instanceof AbsoluteReference)) { return fail('Expected expression to resolve to an absolute reference'); @@ -197,60 +200,31 @@ describe('ngtsc metadata', () => { }); it('reads values from default exports', () => { - const {program} = makeProgram([ - {name: 'second.ts', contents: 'export default {property: "test"}'}, - { - name: 'entry.ts', - contents: ` - import mod from './second'; - const target$ = mod.property; - ` - }, - ]); - const checker = program.getTypeChecker(); - const host = new TypeScriptReflectionHost(checker); - const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); - const expr = result.initializer !; - const evaluator = new PartialEvaluator(host, checker); - expect(evaluator.evaluate(expr)).toEqual('test'); + const value = evaluate( + ` + import mod from './second'; + `, + 'mod.property', [ + {name: 'second.ts', contents: 'export default {property: "test"}'}, + ]); + expect(value).toEqual('test'); }); it('reads values from named exports', () => { - const {program} = makeProgram([ + const value = evaluate(`import * as mod from './second';`, 'mod.a.property', [ {name: 'second.ts', contents: 'export const a = {property: "test"};'}, - { - name: 'entry.ts', - contents: ` - import * as mod from './second'; - const target$ = mod.a.property; - ` - }, ]); - const checker = program.getTypeChecker(); - const host = new TypeScriptReflectionHost(checker); - const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); - const expr = result.initializer !; - const evaluator = new PartialEvaluator(host, checker); - expect(evaluator.evaluate(expr)).toEqual('test'); + expect(value).toEqual('test'); }); it('chain of re-exports works', () => { - const {program} = makeProgram([ + const value = evaluate(`import * as mod from './direct-reexport';`, 'mod.value.property', [ {name: 'const.ts', contents: 'export const value = {property: "test"};'}, {name: 'def.ts', contents: `import {value} from './const'; export default value;`}, {name: 'indirect-reexport.ts', contents: `import value from './def'; export {value};`}, {name: 'direct-reexport.ts', contents: `export {value} from './indirect-reexport';`}, - { - name: 'entry.ts', - contents: `import * as mod from './direct-reexport'; const target$ = mod.value.property;` - }, ]); - const checker = program.getTypeChecker(); - const host = new TypeScriptReflectionHost(checker); - const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); - const expr = result.initializer !; - const evaluator = new PartialEvaluator(host, checker); - expect(evaluator.evaluate(expr)).toEqual('test'); + expect(value).toEqual('test'); }); it('map spread works', () => { @@ -299,15 +273,9 @@ describe('ngtsc metadata', () => { }); it('variable declaration resolution works', () => { - const {program} = makeProgram([ + const value = evaluate(`import {value} from './decl';`, 'value', [ {name: 'decl.d.ts', contents: 'export declare let value: number;'}, - {name: 'entry.ts', contents: `import {value} from './decl'; const target$ = value;`}, ]); - const checker = program.getTypeChecker(); - const host = new TypeScriptReflectionHost(checker); - const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); - const evaluator = new PartialEvaluator(host, checker); - const res = evaluator.evaluate(result.initializer !); - expect(res instanceof Reference).toBe(true); + expect(value instanceof Reference).toBe(true); }); }); diff --git a/packages/compiler-cli/src/ngtsc/testing/in_memory_typescript.ts b/packages/compiler-cli/src/ngtsc/testing/in_memory_typescript.ts index 36a5b90b0d..9bbdf1f2c2 100644 --- a/packages/compiler-cli/src/ngtsc/testing/in_memory_typescript.ts +++ b/packages/compiler-cli/src/ngtsc/testing/in_memory_typescript.ts @@ -13,19 +13,18 @@ import * as ts from 'typescript'; export function makeProgram( files: {name: string, contents: string, isRoot?: boolean}[], options?: ts.CompilerOptions, - host: ts.CompilerHost = new InMemoryHost(), - checkForErrors: boolean = true): {program: ts.Program, host: ts.CompilerHost} { + host: ts.CompilerHost = new InMemoryHost(), checkForErrors: boolean = true): + {program: ts.Program, host: ts.CompilerHost, options: ts.CompilerOptions} { files.forEach(file => host.writeFile(file.name, file.contents, false, undefined, [])); const rootNames = files.filter(file => file.isRoot !== false).map(file => host.getCanonicalFileName(file.name)); - const program = ts.createProgram( - rootNames, { - noLib: true, - experimentalDecorators: true, - moduleResolution: ts.ModuleResolutionKind.NodeJs, ...options - }, - host); + const compilerOptions = { + noLib: true, + experimentalDecorators: true, + moduleResolution: ts.ModuleResolutionKind.NodeJs, ...options + }; + const program = ts.createProgram(rootNames, compilerOptions, host); if (checkForErrors) { const diags = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics()]; if (diags.length > 0) { @@ -41,7 +40,7 @@ export function makeProgram( throw new Error(`Typescript diagnostics failed! ${errors.join(', ')}`); } } - return {program, host}; + return {program, host, options: compilerOptions}; } export class InMemoryHost implements ts.CompilerHost {