@@ -21,6 +21,7 @@ export interface NamedSourceText {
2121export interface ProgramWithSourceTexts extends ts . Program {
2222 sourceTexts ?: readonly NamedSourceText [ ] ;
2323 host : TestCompilerHost ;
24+ version : number ;
2425}
2526
2627export interface TestCompilerHost extends ts . CompilerHost {
@@ -102,7 +103,7 @@ function createSourceFileWithText(fileName: string, sourceText: SourceText, targ
102103 return file ;
103104}
104105
105- export function createTestCompilerHost ( texts : readonly NamedSourceText [ ] , target : ts . ScriptTarget , oldProgram ?: ProgramWithSourceTexts , useGetSourceFileByPath ?: boolean ) {
106+ export function createTestCompilerHost ( texts : readonly NamedSourceText [ ] , target : ts . ScriptTarget , oldProgram ?: ProgramWithSourceTexts , useGetSourceFileByPath ?: boolean , useCaseSensitiveFileNames ?: boolean ) {
106107 const files = ts . arrayToMap ( texts , t => t . name , t => {
107108 if ( oldProgram ) {
108109 let oldFile = oldProgram . getSourceFile ( t . name ) as SourceFileWithText ;
@@ -115,52 +116,64 @@ export function createTestCompilerHost(texts: readonly NamedSourceText[], target
115116 }
116117 return createSourceFileWithText ( t . name , t . text , target ) ;
117118 } ) ;
118- const useCaseSensitiveFileNames = ts . sys && ts . sys . useCaseSensitiveFileNames ;
119+ if ( useCaseSensitiveFileNames === undefined ) useCaseSensitiveFileNames = ts . sys && ts . sys . useCaseSensitiveFileNames ;
119120 const getCanonicalFileName = ts . createGetCanonicalFileName ( useCaseSensitiveFileNames ) ;
121+ const filesByPath = ts . mapEntries ( files , ( fileName , file ) => [ ts . toPath ( fileName , "" , getCanonicalFileName ) , file ] ) ;
120122 const trace : string [ ] = [ ] ;
121123 const result : TestCompilerHost = {
122124 trace : s => trace . push ( s ) ,
123125 getTrace : ( ) => trace ,
124126 clearTrace : ( ) => trace . length = 0 ,
125- getSourceFile : fileName => files . get ( fileName ) ,
127+ getSourceFile : fileName => filesByPath . get ( ts . toPath ( fileName , "" , getCanonicalFileName ) ) ,
126128 getDefaultLibFileName : ( ) => "lib.d.ts" ,
127129 writeFile : ts . notImplemented ,
128130 getCurrentDirectory : ( ) => "" ,
129131 getDirectories : ( ) => [ ] ,
130132 getCanonicalFileName,
131133 useCaseSensitiveFileNames : ( ) => useCaseSensitiveFileNames ,
132134 getNewLine : ( ) => ts . sys ? ts . sys . newLine : newLine ,
133- fileExists : fileName => files . has ( fileName ) ,
135+ fileExists : fileName => filesByPath . has ( ts . toPath ( fileName , "" , getCanonicalFileName ) ) ,
134136 readFile : fileName => {
135- const file = files . get ( fileName ) ;
137+ const file = filesByPath . get ( ts . toPath ( fileName , "" , getCanonicalFileName ) ) ;
136138 return file && file . text ;
137139 } ,
138140 } ;
139141 if ( useGetSourceFileByPath ) {
140- const filesByPath = ts . mapEntries ( files , ( fileName , file ) => [ ts . toPath ( fileName , "" , getCanonicalFileName ) , file ] ) ;
141142 result . getSourceFileByPath = ( _fileName , path ) => filesByPath . get ( path ) ;
142143 }
143144 return result ;
144145}
145146
146- export function newProgram ( texts : NamedSourceText [ ] , rootNames : string [ ] , options : ts . CompilerOptions , useGetSourceFileByPath ?: boolean ) : ProgramWithSourceTexts {
147- const host = createTestCompilerHost ( texts , options . target ! , /*oldProgram*/ undefined , useGetSourceFileByPath ) ;
148- const program = ts . createProgram ( rootNames , options , host ) as ProgramWithSourceTexts ;
149- program . sourceTexts = texts ;
150- program . host = host ;
151- return program ;
147+ export function newProgram ( texts : NamedSourceText [ ] , rootNames : string [ ] , options : ts . CompilerOptions , useGetSourceFileByPath ?: boolean , useCaseSensitiveFileNames ?: boolean ) : ProgramWithSourceTexts {
148+ const host = createTestCompilerHost ( texts , options . target ! , /*oldProgram*/ undefined , useGetSourceFileByPath , useCaseSensitiveFileNames ) ;
149+ return programToProgramWithSourceTexts (
150+ ts . createProgram ( rootNames , options , host ) ,
151+ texts ,
152+ host ,
153+ 1 ,
154+ ) ;
152155}
153156
154- export function updateProgram ( oldProgram : ProgramWithSourceTexts , rootNames : readonly string [ ] , options : ts . CompilerOptions , updater : ( files : NamedSourceText [ ] ) => void , newTexts ?: NamedSourceText [ ] , useGetSourceFileByPath ?: boolean ) {
157+ function programToProgramWithSourceTexts ( program : ts . Program , texts : NamedSourceText [ ] , host : TestCompilerHost , version : number ) : ProgramWithSourceTexts {
158+ const result = program as ProgramWithSourceTexts ;
159+ result . sourceTexts = texts ;
160+ result . host = host ;
161+ result . version = version ;
162+ return result ;
163+ }
164+
165+ export function updateProgram ( oldProgram : ProgramWithSourceTexts , rootNames : readonly string [ ] , options : ts . CompilerOptions , updater : ( files : NamedSourceText [ ] ) => void , newTexts ?: NamedSourceText [ ] , useGetSourceFileByPath ?: boolean , useCaseSensitiveFileNames ?: boolean ) {
155166 if ( ! newTexts ) {
156167 newTexts = oldProgram . sourceTexts ! . slice ( 0 ) ;
157168 }
158169 updater ( newTexts ) ;
159- const host = createTestCompilerHost ( newTexts , options . target ! , oldProgram , useGetSourceFileByPath ) ;
160- const program = ts . createProgram ( rootNames , options , host , oldProgram ) as ProgramWithSourceTexts ;
161- program . sourceTexts = newTexts ;
162- program . host = host ;
163- return program ;
170+ const host = createTestCompilerHost ( newTexts , options . target ! , oldProgram , useGetSourceFileByPath , useCaseSensitiveFileNames ) ;
171+ return programToProgramWithSourceTexts (
172+ ts . createProgram ( rootNames , options , host , oldProgram ) ,
173+ newTexts ,
174+ host ,
175+ oldProgram . version + 1 ,
176+ ) ;
164177}
165178
166179export function updateProgramText ( files : readonly NamedSourceText [ ] , fileName : string , newProgramText : string ) {
0 commit comments