Skip to content

Commit 725841a

Browse files
Adds VFS deleteFile method (#3173)
Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
1 parent 441338c commit 725841a

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

.changeset/tame-garlics-shop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@typescript/vfs": minor
3+
---
4+
5+
Adds `deleteFile` to the vfs api to which allows file to be removed from the file system.

packages/typescript-vfs/src/index.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export interface VirtualTypeScriptEnvironment {
3232
getSourceFile: (fileName: string) => import("typescript").SourceFile | undefined
3333
createFile: (fileName: string, content: string) => void
3434
updateFile: (fileName: string, content: string, replaceTextSpan?: import("typescript").TextSpan) => void
35+
deleteFile: (fileName: string) => void
3536
}
3637

3738
/**
@@ -54,7 +55,7 @@ export function createVirtualTypeScriptEnvironment(
5455
): VirtualTypeScriptEnvironment {
5556
const mergedCompilerOpts = { ...defaultCompilerOptions(ts), ...compilerOptions }
5657

57-
const { languageServiceHost, updateFile } = createVirtualLanguageServiceHost(
58+
const { languageServiceHost, updateFile, deleteFile } = createVirtualLanguageServiceHost(
5859
sys,
5960
rootFiles,
6061
mergedCompilerOpts,
@@ -99,6 +100,12 @@ export function createVirtualTypeScriptEnvironment(
99100

100101
updateFile(newSourceFile)
101102
},
103+
deleteFile(fileName) {
104+
const sourceFile = languageService.getProgram()!.getSourceFile(fileName)
105+
if (sourceFile) {
106+
deleteFile(sourceFile)
107+
}
108+
}
102109
}
103110
}
104111

@@ -466,6 +473,9 @@ export function createSystem(files: Map<string, string>): System {
466473
writeFile: (fileName, contents) => {
467474
files.set(fileName, contents)
468475
},
476+
deleteFile: (fileName) => {
477+
files.delete(fileName)
478+
},
469479
}
470480
}
471481

@@ -545,6 +555,9 @@ export function createFSBackedSystem(
545555
writeFile: (fileName, contents) => {
546556
files.set(fileName, contents)
547557
},
558+
deleteFile: (fileName) => {
559+
files.delete(fileName)
560+
},
548561
realpath: nodeSys.realpath,
549562
}
550563
}
@@ -564,6 +577,7 @@ export function createVirtualCompilerHost(sys: System, compilerOptions: Compiler
564577
type Return = {
565578
compilerHost: CompilerHost
566579
updateFile: (sourceFile: SourceFile) => boolean
580+
deleteFile: (sourceFile: SourceFile) => boolean
567581
}
568582

569583
const vHost: Return = {
@@ -594,6 +608,12 @@ export function createVirtualCompilerHost(sys: System, compilerOptions: Compiler
594608
sourceFiles.set(sourceFile.fileName, sourceFile)
595609
return alreadyExists
596610
},
611+
deleteFile: sourceFile => {
612+
const alreadyExists = sourceFiles.has(sourceFile.fileName)
613+
sourceFiles.delete(sourceFile.fileName)
614+
sys.deleteFile!(sourceFile.fileName)
615+
return alreadyExists
616+
}
597617
}
598618
return vHost
599619
}
@@ -609,7 +629,7 @@ export function createVirtualLanguageServiceHost(
609629
customTransformers?: CustomTransformers
610630
) {
611631
const fileNames = [...rootFiles]
612-
const { compilerHost, updateFile } = createVirtualCompilerHost(sys, compilerOptions, ts)
632+
const { compilerHost, updateFile, deleteFile } = createVirtualCompilerHost(sys, compilerOptions, ts)
613633
const fileVersions = new Map<string, string>()
614634
let projectVersion = 0
615635
const languageServiceHost: LanguageServiceHost = {
@@ -642,6 +662,7 @@ export function createVirtualLanguageServiceHost(
642662
type Return = {
643663
languageServiceHost: LanguageServiceHost
644664
updateFile: (sourceFile: import("typescript").SourceFile) => void
665+
deleteFile: (sourceFile: import("typescript").SourceFile) => void
645666
}
646667

647668
const lsHost: Return = {
@@ -654,6 +675,15 @@ export function createVirtualLanguageServiceHost(
654675
}
655676
updateFile(sourceFile)
656677
},
678+
deleteFile: sourceFile => {
679+
projectVersion++
680+
fileVersions.set(sourceFile.fileName, projectVersion.toString())
681+
const index = fileNames.indexOf(sourceFile.fileName)
682+
if (index !== -1) {
683+
fileNames.splice(index, 1)
684+
}
685+
deleteFile(sourceFile)
686+
}
657687
}
658688
return lsHost
659689
}

packages/typescript-vfs/test/fsbacked.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,27 @@ it("searches node_modules/@types", () => {
7272
const semDiags = env.languageService.getSemanticDiagnostics("index.ts")
7373
expect(semDiags.length).toBe(0)
7474
})
75+
76+
it("can delete files in the virtual fs", () => {
77+
const compilerOpts: ts.CompilerOptions = { target: ts.ScriptTarget.ES2016, esModuleInterop: true }
78+
const fsMap = new Map<string, string>()
79+
80+
const monorepoRoot = path.join(__dirname, "..", "..", "..")
81+
const fakeFolder = path.join(monorepoRoot, "fake")
82+
const exporter = path.join(fakeFolder, "file-with-export.ts")
83+
const index = path.join(fakeFolder, "index.ts")
84+
85+
// TODO: the VFS should really be normalizing paths when looking into fsMap instead.
86+
fsMap.set(exporter.replace(/\\/g, "/"), `export const helloWorld = "Example string";`)
87+
fsMap.set(index.replace(/\\/g, "/"), `import {helloWorld} from "./file-with-export"; console.log(helloWorld)`)
88+
89+
const system = createFSBackedSystem(fsMap, monorepoRoot, ts)
90+
const env = createVirtualTypeScriptEnvironment(system, [index, exporter], ts, compilerOpts)
91+
92+
expect(env.getSourceFile(index)).toBeTruthy()
93+
94+
env.deleteFile(index);
95+
96+
expect(env.getSourceFile(index)).toBeFalsy()
97+
98+
})

0 commit comments

Comments
 (0)