1import debug from 'debug'; 2import path from 'path'; 3import * as ts from 'typescript'; 4import { Extra } from '../parser-options'; 5import { 6 ASTAndProgram, 7 getTsconfigPath, 8 createDefaultCompilerOptionsFromExtra, 9} from './shared'; 10 11const log = debug('typescript-eslint:typescript-estree:createDefaultProgram'); 12 13/** 14 * @param code The code of the file being linted 15 * @param extra The config object 16 * @param extra.tsconfigRootDir The root directory for relative tsconfig paths 17 * @param extra.projects Provided tsconfig paths 18 * @returns If found, returns the source file corresponding to the code and the containing program 19 */ 20function createDefaultProgram( 21 code: string, 22 extra: Extra, 23): ASTAndProgram | undefined { 24 log('Getting default program for: %s', extra.filePath || 'unnamed file'); 25 26 if (!extra.projects || extra.projects.length !== 1) { 27 return undefined; 28 } 29 30 const tsconfigPath = getTsconfigPath(extra.projects[0], extra); 31 32 const commandLine = ts.getParsedCommandLineOfConfigFile( 33 tsconfigPath, 34 createDefaultCompilerOptionsFromExtra(extra), 35 { ...ts.sys, onUnRecoverableConfigFileDiagnostic: () => {} }, 36 ); 37 38 if (!commandLine) { 39 return undefined; 40 } 41 42 const compilerHost = ts.createCompilerHost( 43 commandLine.options, 44 /* setParentNodes */ true, 45 ); 46 const oldReadFile = compilerHost.readFile; 47 compilerHost.readFile = (fileName: string): string | undefined => 48 path.normalize(fileName) === path.normalize(extra.filePath) 49 ? code 50 : oldReadFile(fileName); 51 52 const program = ts.createProgram( 53 [extra.filePath], 54 commandLine.options, 55 compilerHost, 56 ); 57 const ast = program.getSourceFile(extra.filePath); 58 59 return ast && { ast, program }; 60} 61 62export { createDefaultProgram }; 63