import { StandardizedFilePath , TransactionalFileSystem } from "../fileSystem" ; import { ScriptKind , ScriptTarget , ts } from "../typescript" ; import { deepClone } from "../utils" ; import { createCompilerSourceFile } from "./createCompilerSourceFile" ; remarks internal export interface DocumentCache { __documentCacheBrand : undefined ; internal _getCacheForFileSystem ( fileSystem ) : FileSystemSpecificDocumentCache ; } internal export interface DocumentCacheItem { /**
     * This may be a relative path (ex. `./node_modules/package/file.js`). The path
     * will be resolved for each project based on its file system's current
     * working directory.
     */ fileName : string ; /**
     * The text of the file.
     */ text : string ; } param files internal export function createDocumentCache ( files ) { const cache = new InternalDocumentCache ( ) ; cache . _addFiles ( files ) ; return cache ; } internal export interface FileSystemSpecificDocumentCache { getDocumentIfMatch ( filePath , scriptSnapshot , scriptTarget , scriptKind ) : ts . SourceFile | undefined ; } type DocumentKey = string & { _documentKeyBrand : undefined ; } ; class FileSystemDocumentCache implements FileSystemSpecificDocumentCache { private readonly absoluteToOriginalPath = new Map < StandardizedFilePath , string > ( ) ; constructor ( fileSystem , private readonly documentCache ) { for ( const filePath of documentCache . _getFilePaths ( ) ) this . absoluteToOriginalPath . set ( fileSystem . getStandardizedAbsolutePath ( filePath ) , filePath ) ; } getDocumentIfMatch ( filePath , scriptSnapshot , scriptTarget , scriptKind ) { const originalFilePath = this . absoluteToOriginalPath . get ( filePath ) ; if ( originalFilePath == null ) return ; return this . documentCache . _getDocumentIfMatch ( originalFilePath , filePath , scriptSnapshot , scriptTarget , scriptKind ) ; } } class InternalDocumentCache implements DocumentCache { __documentCacheBrand : undefined ; private readonly _fileTexts = new Map < string , string > ( ) ; private readonly _documents = new Map < DocumentKey , ts . SourceFile > ( ) ; _addFiles ( files ) { for ( const file of files ) this . _fileTexts . set ( file . fileName , file . text ) ; } _getFilePaths ( ) { return this . _fileTexts . keys ( ) ; } _getCacheForFileSystem ( fileSystem ) { return new FileSystemDocumentCache ( fileSystem , this ) ; } _getDocumentIfMatch ( filePath , absoluteFilePath , scriptSnapshot , scriptTarget , scriptKind ) { const fileText = this . _fileTexts . get ( filePath ) ; if ( fileText == null ) return undefined ; if ( fileText !== scriptSnapshot . getText ( 0 , scriptSnapshot . getLength ( ) ) ) return undefined ; return this . _getDocument ( filePath , absoluteFilePath , scriptSnapshot , scriptTarget , scriptKind ) ; } private _getDocument ( filePath , absoluteFilePath , scriptSnapshot , scriptTarget , scriptKind ) { const documentKey = this . _getKey ( filePath , scriptTarget , scriptKind ) ; let document = this . _documents . get ( documentKey ) ; if ( document == null ) { document = createCompilerSourceFile ( absoluteFilePath , scriptSnapshot , scriptTarget , "-1" , false , scriptKind ) ; this . _documents . set ( documentKey , document ) ; } document = deepClone ( document ) ; document . fileName = absoluteFilePath ; return document ; } internal private _getKey ( filePath , scriptTarget , scriptKind ) { return ( filePath + ( scriptTarget ?. toString ( ) ?? "-1" ) + ( scriptKind ?. toString ( ) ?? "-1" ) ) as DocumentKey ; } }