55/// <reference path="./vfs.ts" />
66/// <reference path="./vfsutils.ts" />
77/// <reference path="./utils.ts" />
8+ /// <reference path="./fakes.ts" />
89
910// NOTE: The contents of this file are all exported from the namespace 'compiler'. This is to
1011// support the eventual conversion of harness into a modular system.
1112
1213namespace compiler {
13- /**
14- * A `ts.CompilerHost` that leverages a virtual file system.
15- */
16- export class CompilerHost implements ts . CompilerHost {
17- public readonly vfs : vfs . FileSystem ;
18- public readonly defaultLibLocation : string ;
19- public readonly outputs : documents . TextDocument [ ] = [ ] ;
20- public readonly traces : string [ ] = [ ] ;
21- public readonly shouldAssertInvariants = ! Harness . lightMode ;
22-
23- private _setParentNodes : boolean ;
24- private _sourceFiles : core . SortedMap < string , ts . SourceFile > ;
25- private _newLine : string ;
26- private _parseConfigHost : ParseConfigHost ;
27-
28- constructor ( vfs : vfs . FileSystem , options : ts . CompilerOptions , setParentNodes = false ) {
29- this . vfs = vfs ;
30- this . defaultLibLocation = vfs . meta . get ( "defaultLibLocation" ) || "" ;
31- this . _sourceFiles = new core . SortedMap < string , ts . SourceFile > ( { comparer : this . vfs . stringComparer , sort : "insertion" } ) ;
32- this . _newLine = options . newLine === ts . NewLineKind . LineFeed ? "\n" : "\r\n" ;
33- this . _setParentNodes = setParentNodes ;
34- }
35-
36- public get parseConfigHost ( ) {
37- return this . _parseConfigHost || ( this . _parseConfigHost = new ParseConfigHost ( this . vfs ) ) ;
38- }
39-
40- public getCurrentDirectory ( ) : string {
41- return this . vfs . cwd ( ) ;
42- }
43-
44- public useCaseSensitiveFileNames ( ) : boolean {
45- return ! this . vfs . ignoreCase ;
46- }
47-
48- public getNewLine ( ) : string {
49- return this . _newLine ;
50- }
51-
52- public getCanonicalFileName ( fileName : string ) : string {
53- return this . vfs . ignoreCase ? fileName . toLowerCase ( ) : fileName ;
54- }
55-
56- public fileExists ( fileName : string ) : boolean {
57- return vfsutils . fileExists ( this . vfs , fileName ) ;
58- }
59-
60- public directoryExists ( directoryName : string ) : boolean {
61- return vfsutils . directoryExists ( this . vfs , directoryName ) ;
62- }
63-
64- public getDirectories ( path : string ) : string [ ] {
65- return vfsutils . getDirectories ( this . vfs , path ) ;
66- }
67-
68- public readFile ( path : string ) : string | undefined {
69- if ( path . endsWith ( "lib.d.ts" ) ) debugger ;
70- return vfsutils . readFile ( this . vfs , path ) ;
71- }
72-
73- public writeFile ( fileName : string , content : string , writeByteOrderMark : boolean ) {
74- if ( writeByteOrderMark ) content = core . addUTF8ByteOrderMark ( content ) ;
75- vfsutils . writeFile ( this . vfs , fileName , content ) ;
76- const document = new documents . TextDocument ( fileName , content ) ;
77- document . meta . set ( "fileName" , fileName ) ;
78- this . vfs . filemeta ( fileName ) . set ( "document" , document ) ;
79- const index = this . outputs . findIndex ( output => this . vfs . stringComparer ( document . file , output . file ) === 0 ) ;
80- if ( index < 0 ) {
81- this . outputs . push ( document ) ;
82- }
83- else {
84- this . outputs [ index ] = document ;
85- }
86- }
87-
88- public trace ( s : string ) : void {
89- this . traces . push ( s ) ;
90- }
91-
92- public realpath ( path : string ) : string {
93- return this . vfs . realpathSync ( path ) ;
94- }
95-
96- public getDefaultLibLocation ( ) : string {
97- return vpath . resolve ( this . vfs . cwd ( ) , this . defaultLibLocation ) ;
98- }
99-
100- public getDefaultLibFileName ( options : ts . CompilerOptions ) : string {
101- // return vpath.resolve(this.getDefaultLibLocation(), ts.getDefaultLibFileName(options));
102-
103- // TODO(rbuckton): This patches the baseline to replace lib.es5.d.ts with lib.d.ts.
104- // This is only to make the PR for this change easier to read. A follow-up PR will
105- // revert this change and accept the new baselines.
106- // See https://github.com/Microsoft/TypeScript/pull/20763#issuecomment-352553264
107- return vpath . resolve ( this . getDefaultLibLocation ( ) , getDefaultLibFileName ( options ) ) ;
108- function getDefaultLibFileName ( options : ts . CompilerOptions ) {
109- switch ( options . target ) {
110- case ts . ScriptTarget . ESNext :
111- case ts . ScriptTarget . ES2017 :
112- return "lib.es2017.d.ts" ;
113- case ts . ScriptTarget . ES2016 :
114- return "lib.es2016.d.ts" ;
115- case ts . ScriptTarget . ES2015 :
116- return "lib.es2015.d.ts" ;
117-
118- default :
119- return "lib.d.ts" ;
120- }
121- }
122- }
123-
124- public getSourceFile ( fileName : string , languageVersion : number ) : ts . SourceFile | undefined {
125- const canonicalFileName = this . getCanonicalFileName ( vpath . resolve ( this . vfs . cwd ( ) , fileName ) ) ;
126- const existing = this . _sourceFiles . get ( canonicalFileName ) ;
127- if ( existing ) return existing ;
128-
129- const content = this . readFile ( canonicalFileName ) ;
130- if ( content === undefined ) return undefined ;
131-
132- // A virtual file system may shadow another existing virtual file system. This
133- // allows us to reuse a common virtual file system structure across multiple
134- // tests. If a virtual file is a shadow, it is likely that the file will be
135- // reused across multiple tests. In that case, we cache the SourceFile we parse
136- // so that it can be reused across multiple tests to avoid the cost of
137- // repeatedly parsing the same file over and over (such as lib.d.ts).
138- const cacheKey = this . vfs . shadowRoot && `SourceFile[languageVersion=${ languageVersion } ,setParentNodes=${ this . _setParentNodes } ]` ;
139- if ( cacheKey ) {
140- const meta = this . vfs . filemeta ( canonicalFileName ) ;
141- const sourceFileFromMetadata = meta . get ( cacheKey ) as ts . SourceFile | undefined ;
142- if ( sourceFileFromMetadata ) {
143- this . _sourceFiles . set ( canonicalFileName , sourceFileFromMetadata ) ;
144- return sourceFileFromMetadata ;
145- }
146- }
147-
148- const parsed = ts . createSourceFile ( fileName , content , languageVersion , this . _setParentNodes || this . shouldAssertInvariants ) ;
149- if ( this . shouldAssertInvariants ) {
150- Utils . assertInvariants ( parsed , /*parent*/ undefined ) ;
151- }
152-
153- this . _sourceFiles . set ( canonicalFileName , parsed ) ;
154-
155- if ( cacheKey ) {
156- // store the cached source file on the unshadowed file with the same version.
157- const stats = this . vfs . statSync ( canonicalFileName ) ;
158-
159- let fs = this . vfs ;
160- while ( fs . shadowRoot ) {
161- try {
162- const shadowRootStats = fs . shadowRoot . statSync ( canonicalFileName ) ;
163- if ( shadowRootStats . dev !== stats . dev ||
164- shadowRootStats . ino !== stats . ino ||
165- shadowRootStats . mtimeMs !== stats . mtimeMs ) {
166- break ;
167- }
168-
169- fs = fs . shadowRoot ;
170- }
171- catch {
172- break ;
173- }
174- }
175-
176- if ( fs !== this . vfs ) {
177- fs . filemeta ( canonicalFileName ) . set ( cacheKey , parsed ) ;
178- }
179- }
180-
181- return parsed ;
182- }
183- }
184-
185- /**
186- * A `ts.ParseConfigHost` that leverages a virtual file system.
187- */
188- export class ParseConfigHost implements ts . ParseConfigHost {
189- public readonly vfs : vfs . FileSystem ;
190-
191- constructor ( vfs : vfs . FileSystem ) {
192- this . vfs = vfs ;
193- }
194-
195- public get useCaseSensitiveFileNames ( ) {
196- return ! this . vfs . ignoreCase ;
197- }
198-
199- public fileExists ( fileName : string ) : boolean {
200- return vfsutils . fileExists ( this . vfs , fileName ) ;
201- }
202-
203- public directoryExists ( directoryName : string ) : boolean {
204- return vfsutils . directoryExists ( this . vfs , directoryName ) ;
205- }
206-
207- public readFile ( path : string ) : string | undefined {
208- return vfsutils . readFile ( this . vfs , path ) ;
209- }
210-
211- public readDirectory ( path : string , extensions : string [ ] , excludes : string [ ] , includes : string [ ] , depth : number ) : string [ ] {
212- return ts . matchFiles (
213- path ,
214- extensions ,
215- excludes ,
216- includes ,
217- ! this . vfs . ignoreCase ,
218- this . vfs . cwd ( ) ,
219- depth ,
220- path => vfsutils . getAccessibleFileSystemEntries ( this . vfs , path ) ) ;
221- }
222- }
223-
22414 export interface Project {
22515 file : string ;
22616 config ?: ts . ParsedCommandLine ;
22717 errors ?: ts . Diagnostic [ ] ;
22818 }
22919
230- export function readProject ( host : ParseConfigHost , project : string | undefined , existingOptions ?: ts . CompilerOptions ) : Project | undefined {
20+ export function readProject ( host : fakes . ParseConfigHost , project : string | undefined , existingOptions ?: ts . CompilerOptions ) : Project | undefined {
23121 if ( project ) {
23222 project = host . vfs . stringComparer ( vpath . basename ( project ) , "tsconfig.json" ) === 0 ? project :
23323 vpath . combine ( project , "tsconfig.json" ) ;
@@ -265,7 +55,7 @@ namespace compiler {
26555 }
26656
26757 export class CompilationResult {
268- public readonly host : CompilerHost ;
58+ public readonly host : fakes . CompilerHost ;
26959 public readonly program : ts . Program | undefined ;
27060 public readonly result : ts . EmitResult | undefined ;
27161 public readonly options : ts . CompilerOptions ;
@@ -277,7 +67,7 @@ namespace compiler {
27767 private _inputs : documents . TextDocument [ ] = [ ] ;
27868 private _inputsAndOutputs : core . SortedMap < string , CompilationOutput > ;
27969
280- constructor ( host : CompilerHost , options : ts . CompilerOptions , program : ts . Program | undefined , result : ts . EmitResult | undefined , diagnostics : ts . Diagnostic [ ] ) {
70+ constructor ( host : fakes . CompilerHost , options : ts . CompilerOptions , program : ts . Program | undefined , result : ts . EmitResult | undefined , diagnostics : ts . Diagnostic [ ] ) {
28171 this . host = host ;
28272 this . program = program ;
28373 this . result = result ;
@@ -438,7 +228,7 @@ namespace compiler {
438228 }
439229 }
440230
441- export function compileFiles ( host : CompilerHost , rootFiles : string [ ] | undefined , compilerOptions : ts . CompilerOptions ) : CompilationResult {
231+ export function compileFiles ( host : fakes . CompilerHost , rootFiles : string [ ] | undefined , compilerOptions : ts . CompilerOptions ) : CompilationResult {
442232 if ( compilerOptions . project || ! rootFiles || rootFiles . length === 0 ) {
443233 const project = readProject ( host . parseConfigHost , compilerOptions . project , compilerOptions ) ;
444234 if ( project ) {
0 commit comments