@@ -21,6 +21,7 @@ export interface NamedSourceText {
21
21
export interface ProgramWithSourceTexts extends ts . Program {
22
22
sourceTexts ?: readonly NamedSourceText [ ] ;
23
23
host : TestCompilerHost ;
24
+ version : number ;
24
25
}
25
26
26
27
export interface TestCompilerHost extends ts . CompilerHost {
@@ -102,7 +103,7 @@ function createSourceFileWithText(fileName: string, sourceText: SourceText, targ
102
103
return file ;
103
104
}
104
105
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 ) {
106
107
const files = ts . arrayToMap ( texts , t => t . name , t => {
107
108
if ( oldProgram ) {
108
109
let oldFile = oldProgram . getSourceFile ( t . name ) as SourceFileWithText ;
@@ -115,52 +116,64 @@ export function createTestCompilerHost(texts: readonly NamedSourceText[], target
115
116
}
116
117
return createSourceFileWithText ( t . name , t . text , target ) ;
117
118
} ) ;
118
- const useCaseSensitiveFileNames = ts . sys && ts . sys . useCaseSensitiveFileNames ;
119
+ if ( useCaseSensitiveFileNames === undefined ) useCaseSensitiveFileNames = ts . sys && ts . sys . useCaseSensitiveFileNames ;
119
120
const getCanonicalFileName = ts . createGetCanonicalFileName ( useCaseSensitiveFileNames ) ;
121
+ const filesByPath = ts . mapEntries ( files , ( fileName , file ) => [ ts . toPath ( fileName , "" , getCanonicalFileName ) , file ] ) ;
120
122
const trace : string [ ] = [ ] ;
121
123
const result : TestCompilerHost = {
122
124
trace : s => trace . push ( s ) ,
123
125
getTrace : ( ) => trace ,
124
126
clearTrace : ( ) => trace . length = 0 ,
125
- getSourceFile : fileName => files . get ( fileName ) ,
127
+ getSourceFile : fileName => filesByPath . get ( ts . toPath ( fileName , "" , getCanonicalFileName ) ) ,
126
128
getDefaultLibFileName : ( ) => "lib.d.ts" ,
127
129
writeFile : ts . notImplemented ,
128
130
getCurrentDirectory : ( ) => "" ,
129
131
getDirectories : ( ) => [ ] ,
130
132
getCanonicalFileName,
131
133
useCaseSensitiveFileNames : ( ) => useCaseSensitiveFileNames ,
132
134
getNewLine : ( ) => ts . sys ? ts . sys . newLine : newLine ,
133
- fileExists : fileName => files . has ( fileName ) ,
135
+ fileExists : fileName => filesByPath . has ( ts . toPath ( fileName , "" , getCanonicalFileName ) ) ,
134
136
readFile : fileName => {
135
- const file = files . get ( fileName ) ;
137
+ const file = filesByPath . get ( ts . toPath ( fileName , "" , getCanonicalFileName ) ) ;
136
138
return file && file . text ;
137
139
} ,
138
140
} ;
139
141
if ( useGetSourceFileByPath ) {
140
- const filesByPath = ts . mapEntries ( files , ( fileName , file ) => [ ts . toPath ( fileName , "" , getCanonicalFileName ) , file ] ) ;
141
142
result . getSourceFileByPath = ( _fileName , path ) => filesByPath . get ( path ) ;
142
143
}
143
144
return result ;
144
145
}
145
146
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
+ ) ;
152
155
}
153
156
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 ) {
155
166
if ( ! newTexts ) {
156
167
newTexts = oldProgram . sourceTexts ! . slice ( 0 ) ;
157
168
}
158
169
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
+ ) ;
164
177
}
165
178
166
179
export function updateProgramText ( files : readonly NamedSourceText [ ] , fileName : string , newProgramText : string ) {
0 commit comments