import { Tree } from '@angular-devkit/schematics' ; import * as pathFs from 'path' ; import * as ts from 'typescript/lib/tsserverlibrary' ; import { CUSTOM_TS_PLUGIN_NAME , CUSTOM_TS_PLUGIN_PATH } from './tsUtils' ; /**
 * Langauge server host is responsible for **most** of the FS operations / checks
 * Angular's Ivy LS sometimes bypasses these, calling path methods instead of tsLsHost operations
 */ export class ServerHost implements ts . server . ServerHost { public readonly args : string [ ] ; public readonly newLine : string ; public readonly useCaseSensitiveFileNames : boolean ; constructor ( private host ) { this . args = ts . sys . args ; this . newLine = ts . sys . newLine ; this . useCaseSensitiveFileNames = ts . sys . useCaseSensitiveFileNames ; } /**
     * Read a file's content from the Virtual Tree
     * If file does not exist in virtual tree, check in physical FS
     */ public readFile ( path , encoding ? ) { let content ; path = pathFs . relative ( this . getCurrentDirectory ( ) , path ) ; try { content = this . host . read ( path ) . toString ( encoding ) ; } finally { return content || ts . sys . readFile ( path , encoding ) ; } } public getFileSize ( path ) { return ts . sys . getFileSize ( path ) ; } public watchFile ( path , callback , pollingInterval ? ) { return ts . sys . watchFile ( path , callback , pollingInterval ) ; } public watchDirectory ( path , callback , recursive ? ) { return ts . sys . watchDirectory ( path , callback , recursive ) ; } public resolvePath ( path ) { return ts . sys . resolvePath ( path ) ; } /**
     * Checks for file in Virtual Tree w/ relative path
     * If file does not exist in virtual tree, check in physical FS
     */ public fileExists ( path ) { path = pathFs . relative ( this . getCurrentDirectory ( ) , path ) ; let flag = false ; try { flag = this . host . exists ( path ) ; } finally { return flag || ts . sys . fileExists ( path ) ; } } public directoryExists ( path ) { let exists ; path = pathFs . relative ( this . getCurrentDirectory ( ) , path ) ; try { exists = this . host . getDir ( path ) !== void 0 ; } finally { return exists || ts . sys . directoryExists ( path ) ; } } public getExecutingFilePath ( ) { return ts . sys . getExecutingFilePath ( ) ; } public getCurrentDirectory ( ) { return process . cwd ( ) ; } /**
     * Get all subdirs of a directory from the Tree mapped to absolute paths
     */ public getDirectories ( path ) { path = pathFs . relative ( this . getCurrentDirectory ( ) , path ) ; return this . host . getDir ( path ) . subdirs . map ( e => pathFs . resolve ( e ) ) ; } /**
     * Get all files of a directory from the Tree mapped to absolute paths
     */ public readDirectory ( path ) { path = pathFs . relative ( this . getCurrentDirectory ( ) , path ) ; return this . host . getDir ( path ) . subfiles . map ( e => pathFs . resolve ( e ) ) ; } public require ( initialPath , moduleName ) { try { const paths = [ initialPath ] ; if ( moduleName === CUSTOM_TS_PLUGIN_NAME ) { moduleName = CUSTOM_TS_PLUGIN_PATH ; paths . push ( __dirname ) ; } const modulePath = require . resolve ( moduleName , { paths } ) ; return { module : require ( modulePath ) , error : undefined , } ; } catch ( e ) { return { module : undefined , error : e as Error , } ; } } public getModifiedTime ( path ) { return ts . sys . getModifiedTime ( path ) ; } public realpath ( path ) { return ts . sys . realpath ( path ) ; } public createSHA256Hash ( data ) { return ts . sys . createSHA256Hash ( data ) ; } public write ( _data ) { throw new Error ( 'Method "write" not implemented.' ) ; } public writeOutputIsTTY ( ) { throw new Error ( 'Method "writeOutputIsTTY" not implemented.' ) ; } public writeFile ( _path , _data , _writeByteOrderMark ? ) { throw new Error ( 'Method "writeFile" not implemented.' ) ; } public createDirectory ( _path ) { throw new Error ( 'Method "createDirectory" not implemented.' ) ; } public setModifiedTime ( _path , _time ) { throw new Error ( 'Method "setModifiedTime" not implemented.' ) ; } public deleteFile ( _path ) { throw new Error ( 'Method "deleteFile" not implemented.' ) ; } public createHash ( _data ) { throw new Error ( 'Method "createHash" not implemented.' ) ; } public getMemoryUsage ( ) { throw new Error ( 'Method "getMemoryUsage" not implemented.' ) ; } public exit ( _exitCode ? ) { throw new Error ( 'Method "exit" not implemented.' ) ; } public setTimeout ( _callback , _ms , ... _args ) { throw new Error ( 'Method "setTimeout" not implemented.' ) ; } public clearTimeout ( _timeoutId ) { throw new Error ( 'Method "clearTimeout" not implemented.' ) ; } public clearScreen ( ) { throw new Error ( 'Method "clearScreen" not implemented.' ) ; } public base64decode ( _input ) { throw new Error ( 'Method "base64decode" not implemented.' ) ; } public base64encode ( _input ) { throw new Error ( 'Method "base64encode" not implemented.' ) ; } public setImmediate ( _callback , ... _args ) { throw new Error ( 'Method "setImmediate" not implemented.' ) ; } public clearImmediate ( _timeoutId ) { throw new Error ( 'Method "clearImmediate" not implemented.' ) ; } }