From 5ecfa782fcc012d0a86b186604e7cc2811036110 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 3 May 2018 10:52:24 -0700 Subject: [PATCH] Few renames to distinguish between fs File and File in the test case to load in the VFS with watch --- src/harness/unittests/compileOnSave.ts | 38 +- src/harness/unittests/organizeImports.ts | 8 +- .../unittests/reuseProgramStructure.ts | 38 +- src/harness/unittests/telemetry.ts | 2 +- src/harness/unittests/tscWatchMode.ts | 155 +++---- .../unittests/tsserverProjectSystem.ts | 402 +++++++++--------- src/harness/unittests/typingsInstaller.ts | 22 +- src/harness/virtualFileSystemWithWatch.ts | 171 ++++---- 8 files changed, 428 insertions(+), 408 deletions(-) diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 0efd8662cf1..df73c575b15 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -11,7 +11,7 @@ namespace ts.projectSystem { } describe("CompileOnSave affected list", () => { - function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) { + function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: File[] }[]) { const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[]; const actualResult = response.sort((list1, list2) => compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); expectedFileList = expectedFileList.sort((list1, list2) => compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); @@ -47,12 +47,12 @@ namespace ts.projectSystem { } describe("for configured projects", () => { - let moduleFile1: FileOrFolder; - let file1Consumer1: FileOrFolder; - let file1Consumer2: FileOrFolder; - let moduleFile2: FileOrFolder; - let globalFile3: FileOrFolder; - let configFile: FileOrFolder; + let moduleFile1: File; + let file1Consumer1: File; + let file1Consumer2: File; + let moduleFile2: File; + let globalFile3: File; + let configFile: File; let changeModuleFile1ShapeRequest1: server.protocol.Request; let changeModuleFile1InternalRequest1: server.protocol.Request; // A compile on save affected file request using file1 @@ -225,7 +225,7 @@ namespace ts.projectSystem { openFilesForSession([moduleFile1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); - const file1Consumer3: FileOrFolder = { + const file1Consumer3: File = { path: "/a/b/file1Consumer3.ts", content: `import {Foo} from "./moduleFile1"; let y = Foo();` }; @@ -330,7 +330,7 @@ namespace ts.projectSystem { }` }; - const configFile2: FileOrFolder = { + const configFile2: File = { path: "/a/tsconfig.json", content: `{ "compileOnSave": true @@ -403,7 +403,7 @@ namespace ts.projectSystem { }); it("should return cascaded affected file list", () => { - const file1Consumer1Consumer1: FileOrFolder = { + const file1Consumer1Consumer1: File = { path: "/a/b/file1Consumer1Consumer1.ts", content: `import {y} from "./file1Consumer1";` }; @@ -428,13 +428,13 @@ namespace ts.projectSystem { }); it("should work fine for files with circular references", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: ` /// export var t1 = 10;` }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/file2.ts", content: ` /// @@ -450,11 +450,11 @@ namespace ts.projectSystem { }); it("should return results for all projects if not specifying projectFileName", () => { - const file1: FileOrFolder = { path: "/a/b/file1.ts", content: "export var t = 10;" }; - const file2: FileOrFolder = { path: "/a/b/file2.ts", content: `import {t} from "./file1"; var t2 = 11;` }; - const file3: FileOrFolder = { path: "/a/c/file2.ts", content: `import {t} from "../b/file1"; var t3 = 11;` }; - const configFile1: FileOrFolder = { path: "/a/b/tsconfig.json", content: `{ "compileOnSave": true }` }; - const configFile2: FileOrFolder = { path: "/a/c/tsconfig.json", content: `{ "compileOnSave": true }` }; + const file1: File = { path: "/a/b/file1.ts", content: "export var t = 10;" }; + const file2: File = { path: "/a/b/file2.ts", content: `import {t} from "./file1"; var t2 = 11;` }; + const file3: File = { path: "/a/c/file2.ts", content: `import {t} from "../b/file1"; var t3 = 11;` }; + const configFile1: File = { path: "/a/b/tsconfig.json", content: `{ "compileOnSave": true }` }; + const configFile2: File = { path: "/a/c/tsconfig.json", content: `{ "compileOnSave": true }` }; const host = createServerHost([file1, file2, file3, configFile1, configFile2]); const session = createSession(host); @@ -469,7 +469,7 @@ namespace ts.projectSystem { }); it("should detect removed code file", () => { - const referenceFile1: FileOrFolder = { + const referenceFile1: File = { path: "/a/b/referenceFile1.ts", content: ` /// @@ -490,7 +490,7 @@ namespace ts.projectSystem { }); it("should detect non-existing code file", () => { - const referenceFile1: FileOrFolder = { + const referenceFile1: File = { path: "/a/b/referenceFile1.ts", content: ` /// diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index 4471600b1c1..ebd5a7925a2 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -446,11 +446,11 @@ import { React, Other } from "react"; }, reactLibFile); - function testOrganizeImports(testName: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) { + function testOrganizeImports(testName: string, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) { it(testName, () => runBaseline(`organizeImports/${testName}.ts`, testFile, ...otherFiles)); } - function runBaseline(baselinePath: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) { + function runBaseline(baselinePath: string, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) { const { path: testPath, content: testContent } = testFile; const languageService = makeLanguageService(testFile, ...otherFiles); const changes = languageService.organizeImports({ type: "file", fileName: testPath }, testFormatOptions, defaultPreferences); @@ -468,7 +468,7 @@ import { React, Other } from "react"; }); } - function makeLanguageService(...files: TestFSWithWatch.FileOrFolder[]) { + function makeLanguageService(...files: TestFSWithWatch.File[]) { const host = projectSystem.createServerHost(files); const projectService = projectSystem.createProjectService(host, { useSingleInferredProject: true }); projectService.setCompilerOptionsForInferredProjects({ jsx: files.some(f => f.path.endsWith("x")) ? JsxEmit.React : JsxEmit.None }); @@ -555,4 +555,4 @@ import { React, Other } from "react"; } } }); -} \ No newline at end of file +} diff --git a/src/harness/unittests/reuseProgramStructure.ts b/src/harness/unittests/reuseProgramStructure.ts index 0ba9e6f6351..74037d79418 100644 --- a/src/harness/unittests/reuseProgramStructure.ts +++ b/src/harness/unittests/reuseProgramStructure.ts @@ -884,7 +884,7 @@ namespace ts { }); }); - type FileOrFolder = TestFSWithWatch.FileOrFolder; + type File = TestFSWithWatch.File; import createTestSystem = TestFSWithWatch.createWatchedSystem; import libFile = TestFSWithWatch.libFile; @@ -920,22 +920,22 @@ namespace ts { verifyProgramIsUptoDate(program, fileNames, options); } - function verifyProgram(files: FileOrFolder[], rootFiles: string[], options: CompilerOptions, configFile: string) { + function verifyProgram(files: File[], rootFiles: string[], options: CompilerOptions, configFile: string) { const system = createTestSystem(files); verifyProgramWithoutConfigFile(system, rootFiles, options); verifyProgramWithConfigFile(system, configFile); } it("has empty options", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: "let x = 1" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/file2.ts", content: "let y = 1" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: "{}" }; @@ -944,19 +944,19 @@ namespace ts { it("has lib specified in the options", () => { const compilerOptions: CompilerOptions = { lib: ["es5", "es2015.promise"] }; - const app: FileOrFolder = { + const app: File = { path: "/src/app.ts", content: "var x: Promise;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/src/tsconfig.json", content: JSON.stringify({ compilerOptions }) }; - const es5Lib: FileOrFolder = { + const es5Lib: File = { path: "/compiler/lib.es5.d.ts", content: "declare const eval: any" }; - const es2015Promise: FileOrFolder = { + const es2015Promise: File = { path: "/compiler/lib.es2015.promise.d.ts", content: "declare class Promise {}" }; @@ -975,26 +975,26 @@ namespace ts { ] } }; - const app: FileOrFolder = { + const app: File = { path: "/src/packages/framework/app.ts", content: 'import classc from "module1/lib/file1";\ import classD from "module3/file3";\ let x = new classc();\ let y = new classD();' }; - const module1: FileOrFolder = { + const module1: File = { path: "/src/packages/mail/data/module1/lib/file1.ts", content: 'import classc from "module2/file2";export default classc;', }; - const module2: FileOrFolder = { + const module2: File = { path: "/src/packages/mail/data/module1/lib/module2/file2.ts", content: 'class classc { method2() { return "hello"; } }\nexport default classc', }; - const module3: FileOrFolder = { + const module3: File = { path: "/src/packages/styles/module3/file3.ts", content: "class classD { method() { return 10; } }\nexport default classD;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/src/tsconfig.json", content: JSON.stringify({ compilerOptions }) }; @@ -1013,26 +1013,26 @@ namespace ts { ] } }; - const app: FileOrFolder = { + const app: File = { path: "/src/packages/framework/app.ts", content: 'import classc from "module1/lib/file1";\ import classD from "module3/file3";\ let x = new classc();\ let y = new classD();' }; - const module1: FileOrFolder = { + const module1: File = { path: "/src/packages/mail/data/module1/lib/file1.ts", content: 'import classc from "module2/file2";export default classc;', }; - const module2: FileOrFolder = { + const module2: File = { path: "/src/packages/mail/data/module1/lib/module2/file2.ts", content: 'class classc { method2() { return "hello"; } }\nexport default classc', }; - const module3: FileOrFolder = { + const module3: File = { path: "/src/packages/styles/module3/file3.ts", content: "class classD { method() { return 10; } }\nexport default classD;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/src/tsconfig.json", content: JSON.stringify({ compilerOptions, include: ["packages/**/*.ts"] }) }; diff --git a/src/harness/unittests/telemetry.ts b/src/harness/unittests/telemetry.ts index 27512ba1e8c..2e3e299ac3b 100644 --- a/src/harness/unittests/telemetry.ts +++ b/src/harness/unittests/telemetry.ts @@ -236,7 +236,7 @@ namespace ts.projectSystem { }); }); - function makeFile(path: string, content: {} = ""): FileOrFolder { + function makeFile(path: string, content: {} = ""): File { return { path, content: isString(content) ? "" : JSON.stringify(content) }; } } diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index b64b02e301a..f3194d68dcd 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -4,7 +4,8 @@ namespace ts.tscWatch { import WatchedSystem = TestFSWithWatch.TestServerHost; - type FileOrFolder = TestFSWithWatch.FileOrFolder; + type File = TestFSWithWatch.File; + type SymLink = TestFSWithWatch.SymLink; import createWatchedSystem = TestFSWithWatch.createWatchedSystem; import checkArray = TestFSWithWatch.checkArray; import libFile = TestFSWithWatch.libFile; @@ -33,7 +34,7 @@ namespace ts.tscWatch { return () => watch.getCurrentProgram().getProgram(); } - function getEmittedLineForMultiFileOutput(file: FileOrFolder, host: WatchedSystem) { + function getEmittedLineForMultiFileOutput(file: File, host: WatchedSystem) { return `TSFILE: ${file.path.replace(".ts", ".js")}${host.newLine}`; } @@ -41,11 +42,11 @@ namespace ts.tscWatch { return `TSFILE: ${filename}${host.newLine}`; } - interface FileOrFolderEmit extends FileOrFolder { + interface FileOrFolderEmit extends File { output?: string; } - function getFileOrFolderEmit(file: FileOrFolder, getOutput?: (file: FileOrFolder) => string): FileOrFolderEmit { + function getFileOrFolderEmit(file: File, getOutput?: (file: File) => string): FileOrFolderEmit { const result = file as FileOrFolderEmit; if (getOutput) { result.output = getOutput(file); @@ -202,7 +203,7 @@ namespace ts.tscWatch { return getDiagnosticOfFileFrom(file, text, start, length, message); } - function getUnknownCompilerOption(program: Program, configFile: FileOrFolder, option: string) { + function getUnknownCompilerOption(program: Program, configFile: File, option: string) { const quotedOption = `"${option}"`; return getDiagnosticOfFile(program.getCompilerOptions().configFile, configFile.content.indexOf(quotedOption), quotedOption.length, Diagnostics.Unknown_compiler_option_0, option); } @@ -218,23 +219,23 @@ namespace ts.tscWatch { text, start, length, message); } - function getDiagnosticModuleNotFoundOfFile(program: Program, file: FileOrFolder, moduleName: string) { + function getDiagnosticModuleNotFoundOfFile(program: Program, file: File, moduleName: string) { const quotedModuleName = `"${moduleName}"`; return getDiagnosticOfFileFromProgram(program, file.path, file.content.indexOf(quotedModuleName), quotedModuleName.length, Diagnostics.Cannot_find_module_0, moduleName); } describe("tsc-watch program updates", () => { - const commonFile1: FileOrFolder = { + const commonFile1: File = { path: "/a/b/commonFile1.ts", content: "let x = 1" }; - const commonFile2: FileOrFolder = { + const commonFile2: File = { path: "/a/b/commonFile2.ts", content: "let y = 1" }; it("create watch without config file", () => { - const appFile: FileOrFolder = { + const appFile: File = { path: "/a/b/c/app.ts", content: ` import {f} from "./module" @@ -242,7 +243,7 @@ namespace ts.tscWatch { ` }; - const moduleFile: FileOrFolder = { + const moduleFile: File = { path: "/a/b/c/module.d.ts", content: `export let x: number` }; @@ -277,7 +278,7 @@ namespace ts.tscWatch { }); it("create configured project without file list", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: ` { @@ -287,15 +288,15 @@ namespace ts.tscWatch { ] }` }; - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/c/f1.ts", content: "let x = 1" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/d/f2.ts", content: "let y = 1" }; - const file3: FileOrFolder = { + const file3: File = { path: "/a/b/e/f3.ts", content: "let z = 1" }; @@ -315,7 +316,7 @@ namespace ts.tscWatch { // }); it("add new files to a configured program without file list", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{}` }; @@ -333,7 +334,7 @@ namespace ts.tscWatch { }); it("should ignore non-existing files specified in the config file", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, @@ -352,7 +353,7 @@ namespace ts.tscWatch { }); it("handle recreated files correctly", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{}` }; @@ -373,7 +374,7 @@ namespace ts.tscWatch { it("handles the missing files - that were added to program because they were added with /// { const commonFile2Name = "commonFile2.ts"; - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/commonFile1.ts", content: `/// let x = y` @@ -396,7 +397,7 @@ namespace ts.tscWatch { }); it("should reflect change in config file", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, @@ -419,7 +420,7 @@ namespace ts.tscWatch { }); it("works correctly when config file is changed but its content havent", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, @@ -441,14 +442,14 @@ namespace ts.tscWatch { }); it("files explicitly excluded in config file", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, "exclude": ["/a/c"] }` }; - const excludedFile1: FileOrFolder = { + const excludedFile1: File = { path: "/a/c/excluedFile1.ts", content: `let t = 1;` }; @@ -459,19 +460,19 @@ namespace ts.tscWatch { }); it("should properly handle module resolution changes in config file", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: `import { T } from "module1";` }; - const nodeModuleFile: FileOrFolder = { + const nodeModuleFile: File = { path: "/a/b/node_modules/module1.ts", content: `export interface T {}` }; - const classicModuleFile: FileOrFolder = { + const classicModuleFile: File = { path: "/a/module1.ts", content: `export interface T {}` }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -499,7 +500,7 @@ namespace ts.tscWatch { }); it("should tolerate config file errors and still try to build a project", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -1117,15 +1118,15 @@ namespace ts.tscWatch { it("should not trigger recompilation because of program emit", () => { const proj = "/user/username/projects/myproject"; - const file1: FileOrFolder = { + const file1: File = { path: `${proj}/file1.ts`, content: "export const c = 30;" }; - const file2: FileOrFolder = { + const file2: File = { path: `${proj}/src/file2.ts`, content: `import {c} from "file1"; export const d = 30;` }; - const tsconfig: FileOrFolder = { + const tsconfig: File = { path: `${proj}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -1153,7 +1154,7 @@ namespace ts.tscWatch { one(); } }`; - const file: FileOrFolder = { + const file: File = { path: "/a/b/file.ts", content: getFileContent(/*asModule*/ false) }; @@ -1174,11 +1175,11 @@ namespace ts.tscWatch { it("watched files when file is deleted and new file is added as part of change", () => { const projectLocation = "/home/username/project"; - const file: FileOrFolder = { + const file: File = { path: `${projectLocation}/src/file1.ts`, content: "var a = 10;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: `${projectLocation}/tsconfig.json`, content: "{}" }; @@ -1211,7 +1212,7 @@ namespace ts.tscWatch { }) }; - let getOutput: (file: FileOrFolder) => string; + let getOutput: (file: File) => string; if (out) { config.content = JSON.stringify({ compilerOptions: { listEmittedFiles: true, out } @@ -1266,23 +1267,23 @@ namespace ts.tscWatch { }); function verifyFilesEmittedOnce(useOutFile: boolean) { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/output/AnotherDependency/file1.d.ts", content: "declare namespace Common.SomeComponent.DynamicMenu { enum Z { Full = 0, Min = 1, Average = 2, } }" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/dependencies/file2.d.ts", content: "declare namespace Dependencies.SomeComponent { export class SomeClass { version: string; } }" }; - const file3: FileOrFolder = { + const file3: File = { path: "/a/b/project/src/main.ts", content: "namespace Main { export function fooBar() {} }" }; - const file4: FileOrFolder = { + const file4: File = { path: "/a/b/project/src/main2.ts", content: "namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/project/tsconfig.json", content: JSON.stringify({ compilerOptions: useOutFile ? @@ -1334,16 +1335,16 @@ namespace ts.tscWatch { /** list of the files that will be emitted for first compilation */ firstCompilationEmitFiles?: string[]; /** get the emit file for file - default is multi file emit line */ - getEmitLine?(file: FileOrFolder, host: WatchedSystem): string; + getEmitLine?(file: File, host: WatchedSystem): string; /** Additional files and folders to add */ - getAdditionalFileOrFolder?(): FileOrFolder[]; + getAdditionalFileOrFolder?(): File[]; /** initial list of files to emit if not the default list */ firstReloadFileList?: string[]; } function getInitialState({ configObj = {}, firstCompilationEmitFiles, getEmitLine, getAdditionalFileOrFolder, firstReloadFileList }: InitialStateParams = {}) { const host = createWatchedSystem([]); - const getOutputName = getEmitLine ? (file: FileOrFolder) => getEmitLine(file, host) : - (file: FileOrFolder) => getEmittedLineForMultiFileOutput(file, host); + const getOutputName = getEmitLine ? (file: File) => getEmitLine(file, host) : + (file: File) => getEmittedLineForMultiFileOutput(file, host); const moduleFile1 = getFileOrFolderEmit({ path: moduleFile1Path, @@ -1555,7 +1556,7 @@ namespace ts.tscWatch { }); it("should return cascaded affected file list", () => { - const file1Consumer1Consumer1: FileOrFolder = { + const file1Consumer1Consumer1: File = { path: "/a/b/file1Consumer1Consumer1.ts", content: `import {y} from "./file1Consumer1";` }; @@ -1582,13 +1583,13 @@ namespace ts.tscWatch { it("should work fine for files with circular references", () => { // TODO: do not exit on such errors? Just continue to watch the files for update in watch mode - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: ` /// export var t1 = 10;` }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/file2.ts", content: ` /// @@ -1611,7 +1612,7 @@ namespace ts.tscWatch { }); it("should detect removed code file", () => { - const referenceFile1: FileOrFolder = { + const referenceFile1: File = { path: "/a/b/referenceFile1.ts", content: ` /// @@ -1632,7 +1633,7 @@ namespace ts.tscWatch { }); it("should detect non-existing code file", () => { - const referenceFile1: FileOrFolder = { + const referenceFile1: File = { path: "/a/b/referenceFile1.ts", content: ` /// @@ -1659,7 +1660,7 @@ namespace ts.tscWatch { }); describe("tsc-watch emit file content", () => { - interface EmittedFile extends FileOrFolder { + interface EmittedFile extends File { shouldBeWritten: boolean; } function getEmittedFiles(files: FileOrFolderEmit[], contents: string[]): EmittedFile[] { @@ -1684,8 +1685,8 @@ namespace ts.tscWatch { } } - function verifyEmittedFileContents(newLine: string, inputFiles: FileOrFolder[], initialEmittedFileContents: string[], - modifyFiles: (files: FileOrFolderEmit[], emitedFiles: EmittedFile[]) => FileOrFolderEmit[], configFile?: FileOrFolder) { + function verifyEmittedFileContents(newLine: string, inputFiles: File[], initialEmittedFileContents: string[], + modifyFiles: (files: FileOrFolderEmit[], emitedFiles: EmittedFile[]) => FileOrFolderEmit[], configFile?: File) { const host = createWatchedSystem([], { newLine }); const files = concatenate( map(inputFiles, file => getFileOrFolderEmit(file, fileToConvert => getEmittedLineForMultiFileOutput(fileToConvert, host))), @@ -1778,15 +1779,15 @@ namespace ts.tscWatch { it("Elides const enums correctly in incremental compilation", () => { const currentDirectory = "/user/someone/projects/myproject"; - const file1: FileOrFolder = { + const file1: File = { path: `${currentDirectory}/file1.ts`, content: "export const enum E1 { V = 1 }" }; - const file2: FileOrFolder = { + const file2: File = { path: `${currentDirectory}/file2.ts`, content: `import { E1 } from "./file1"; export const enum E2 { V = E1.V }` }; - const file3: FileOrFolder = { + const file3: File = { path: `${currentDirectory}/file3.ts`, content: `import { E2 } from "./file2"; const v: E2 = E2.V;` }; @@ -1808,12 +1809,12 @@ namespace ts.tscWatch { it("file is deleted and created as part of change", () => { const projectLocation = "/home/username/project"; - const file: FileOrFolder = { + const file: File = { path: `${projectLocation}/app/file.ts`, content: "var a = 10;" }; const fileJs = `${projectLocation}/app/file.js`; - const configFile: FileOrFolder = { + const configFile: File = { path: `${projectLocation}/tsconfig.json`, content: JSON.stringify({ include: [ @@ -2101,19 +2102,19 @@ declare module "fs" { it("works when reusing program with files from external library", () => { interface ExpectedFile { path: string; isExpectedToEmit?: boolean; content?: string; } const configDir = "/a/b/projects/myProject/src/"; - const file1: FileOrFolder = { + const file1: File = { path: configDir + "file1.ts", content: 'import module1 = require("module1");\nmodule1("hello");' }; - const file2: FileOrFolder = { + const file2: File = { path: configDir + "file2.ts", content: 'import module11 = require("module1");\nmodule11("hello");' }; - const module1: FileOrFolder = { + const module1: File = { path: "/a/b/projects/myProject/node_modules/module1/index.js", content: "module.exports = options => { return options.toString(); }" }; - const configFile: FileOrFolder = { + const configFile: File = { path: configDir + "tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -2169,7 +2170,7 @@ declare module "fs" { }; } - function createExpectedEmittedFile(file: FileOrFolder): ExpectedFile { + function createExpectedEmittedFile(file: File): ExpectedFile { return { path: removeFileExtension(file.path.replace(configDir, outDirFolder)) + Extension.Js, isExpectedToEmit: true, @@ -2180,11 +2181,11 @@ declare module "fs" { it("works when renaming node_modules folder that already contains @types folder", () => { const currentDirectory = "/user/username/projects/myproject"; - const file: FileOrFolder = { + const file: File = { path: `${currentDirectory}/a.ts`, content: `import * as q from "qqq";` }; - const module: FileOrFolder = { + const module: File = { path: `${currentDirectory}/node_modules2/@types/qqq/index.d.ts`, content: "export {}" }; @@ -2203,7 +2204,7 @@ declare module "fs" { describe("tsc-watch with when module emit is specified as node", () => { it("when instead of filechanged recursive directory watcher is invoked", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/rootFolder/project/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -2217,11 +2218,11 @@ declare module "fs" { }) }; const outputFolder = "/a/rootFolder/project/Static/scripts/"; - const file1: FileOrFolder = { + const file1: File = { path: "/a/rootFolder/project/Scripts/TypeScript.ts", content: "var z = 10;" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/rootFolder/project/Scripts/Javascript.js", content: "var zz = 10;" }; @@ -2299,7 +2300,7 @@ declare module "fs" { describe("tsc-watch with different polling/non polling options", () => { it("watchFile using dynamic priority polling", () => { const projectFolder = "/a/username/project"; - const file1: FileOrFolder = { + const file1: File = { path: `${projectFolder}/typescript.ts`, content: "var z = 10;" }; @@ -2362,11 +2363,11 @@ declare module "fs" { function verifyRenamingFileInSubFolder(tscWatchDirectory: TestFSWithWatch.Tsc_WatchDirectory) { const projectFolder = "/a/username/project"; const projectSrcFolder = `${projectFolder}/src`; - const configFile: FileOrFolder = { + const configFile: File = { path: `${projectFolder}/tsconfig.json`, content: "{}" }; - const file: FileOrFolder = { + const file: File = { path: `${projectSrcFolder}/file1.ts`, content: "" }; @@ -2428,35 +2429,35 @@ declare module "fs" { it("when there are symlinks to folders in recursive folders", () => { const cwd = "/home/user/projects/myproject"; - const file1: FileOrFolder = { + const file1: File = { path: `${cwd}/src/file.ts`, content: `import * as a from "a"` }; - const tsconfig: FileOrFolder = { + const tsconfig: File = { path: `${cwd}/tsconfig.json`, content: `{ "compilerOptions": { "extendedDiagnostics": true, "traceResolution": true }}` }; - const realA: FileOrFolder = { + const realA: File = { path: `${cwd}/node_modules/reala/index.d.ts`, content: `export {}` }; - const realB: FileOrFolder = { + const realB: File = { path: `${cwd}/node_modules/realb/index.d.ts`, content: `export {}` }; - const symLinkA: FileOrFolder = { + const symLinkA: SymLink = { path: `${cwd}/node_modules/a`, symLink: `${cwd}/node_modules/reala` }; - const symLinkB: FileOrFolder = { + const symLinkB: SymLink = { path: `${cwd}/node_modules/b`, symLink: `${cwd}/node_modules/realb` }; - const symLinkBInA: FileOrFolder = { + const symLinkBInA: SymLink = { path: `${cwd}/node_modules/reala/node_modules/b`, symLink: `${cwd}/node_modules/b` }; - const symLinkAInB: FileOrFolder = { + const symLinkAInB: SymLink = { path: `${cwd}/node_modules/realb/node_modules/a`, symLink: `${cwd}/node_modules/a` }; diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 5f04b643a35..bed1940ee88 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -8,7 +8,9 @@ namespace ts.projectSystem { import CommandNames = server.CommandNames; export import TestServerHost = TestFSWithWatch.TestServerHost; - export type FileOrFolder = TestFSWithWatch.FileOrFolder; + export type File = TestFSWithWatch.File; + export type SymLink = TestFSWithWatch.SymLink; + export type Folder = TestFSWithWatch.Folder; export import createServerHost = TestFSWithWatch.createServerHost; export import checkArray = TestFSWithWatch.checkArray; export import libFile = TestFSWithWatch.libFile; @@ -170,7 +172,7 @@ namespace ts.projectSystem { readonly session: TestSession; readonly service: server.ProjectService; readonly host: TestServerHost; - constructor(files: FileOrFolder[], suppressDiagnosticEvents?: boolean) { + constructor(files: File[], suppressDiagnosticEvents?: boolean) { this.host = createServerHost(files); this.session = createSession(this.host, { canUseEvents: true, @@ -394,7 +396,7 @@ namespace ts.projectSystem { return countWhere(recursiveWatchedDirs, dir => file.length > dir.length && startsWith(file, dir) && file[dir.length] === directorySeparator); } - function checkOpenFiles(projectService: server.ProjectService, expectedFiles: FileOrFolder[]) { + function checkOpenFiles(projectService: server.ProjectService, expectedFiles: File[]) { checkArray("Open files", arrayFrom(projectService.openFiles.keys(), path => projectService.getScriptInfoForPath(path as Path).fileName), expectedFiles.map(file => file.path)); } @@ -451,7 +453,7 @@ namespace ts.projectSystem { return newRequest; } - export function openFilesForSession(files: FileOrFolder[], session: server.Session) { + export function openFilesForSession(files: File[], session: server.Session) { for (const file of files) { const request = makeSessionRequest(CommandNames.Open, { file: file.path }); session.executeCommand(request); @@ -512,17 +514,17 @@ namespace ts.projectSystem { } describe("tsserverProjectSystem general functionality", () => { - const commonFile1: FileOrFolder = { + const commonFile1: File = { path: "/a/b/commonFile1.ts", content: "let x = 1" }; - const commonFile2: FileOrFolder = { + const commonFile2: File = { path: "/a/b/commonFile2.ts", content: "let y = 1" }; it("create inferred project", () => { - const appFile: FileOrFolder = { + const appFile: File = { path: "/a/b/c/app.ts", content: ` import {f} from "./module" @@ -530,7 +532,7 @@ namespace ts.projectSystem { ` }; - const moduleFile: FileOrFolder = { + const moduleFile: File = { path: "/a/b/c/module.d.ts", content: `export let x: number` }; @@ -583,7 +585,7 @@ namespace ts.projectSystem { }); it("create configured project without file list", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: ` { @@ -593,15 +595,15 @@ namespace ts.projectSystem { ] }` }; - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/c/f1.ts", content: "let x = 1" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/d/f2.ts", content: "let y = 1" }; - const file3: FileOrFolder = { + const file3: File = { path: "/a/b/e/f3.ts", content: "let z = 1" }; @@ -625,7 +627,7 @@ namespace ts.projectSystem { }); it("create configured project with the file list", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: ` { @@ -633,15 +635,15 @@ namespace ts.projectSystem { "include": ["*.ts"] }` }; - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/f1.ts", content: "let x = 1" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/f2.ts", content: "let y = 1" }; - const file3: FileOrFolder = { + const file3: File = { path: "/a/b/c/f3.ts", content: "let z = 1" }; @@ -664,7 +666,7 @@ namespace ts.projectSystem { }); it("add and then remove a config file in a folder with loose files", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "files": ["commonFile1.ts"] @@ -713,7 +715,7 @@ namespace ts.projectSystem { }); it("add new files to a configured project without file list", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{}` }; @@ -735,7 +737,7 @@ namespace ts.projectSystem { }); it("should ignore non-existing files specified in the config file", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, @@ -769,7 +771,7 @@ namespace ts.projectSystem { path: "/c/app.ts", content: "let x = 1" }; - const makeProject = (f: FileOrFolder) => ({ projectFileName: f.path + ".csproj", rootFiles: [toExternalFile(f.path)], options: {} }); + const makeProject = (f: File) => ({ projectFileName: f.path + ".csproj", rootFiles: [toExternalFile(f.path)], options: {} }); const p1 = makeProject(f1); const p2 = makeProject(f2); const p3 = makeProject(f3); @@ -817,7 +819,7 @@ namespace ts.projectSystem { }); it("handle recreated files correctly", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{}` }; @@ -841,7 +843,7 @@ namespace ts.projectSystem { }); it("handles the missing files - that were added to program because they were added with /// { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/commonFile1.ts", content: `/// let x = y` @@ -878,7 +880,7 @@ namespace ts.projectSystem { }); it("should create new inferred projects for files excluded from a configured project", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, @@ -909,14 +911,14 @@ namespace ts.projectSystem { }); it("files explicitly excluded in config file", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, "exclude": ["/a/c"] }` }; - const excludedFile1: FileOrFolder = { + const excludedFile1: File = { path: "/a/c/excluedFile1.ts", content: `let t = 1;` }; @@ -933,23 +935,23 @@ namespace ts.projectSystem { }); it("should properly handle module resolution changes in config file", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: `import { T } from "module1";` }; - const nodeModuleFile: FileOrFolder = { + const nodeModuleFile: File = { path: "/a/b/node_modules/module1.ts", content: `export interface T {}` }; - const classicModuleFile: FileOrFolder = { + const classicModuleFile: File = { path: "/a/module1.ts", content: `export interface T {}` }; - const randomFile: FileOrFolder = { + const randomFile: File = { path: "/a/file1.ts", content: `export interface T {}` }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -998,15 +1000,15 @@ namespace ts.projectSystem { }); it("should keep the configured project when the opened file is referenced by the project but not its root", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/main.ts", content: "import { objA } from './obj-a';" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/obj-a.ts", content: `export const objA = Object.assign({foo: "bar"}, {bar: "baz"});` }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -1025,15 +1027,15 @@ namespace ts.projectSystem { }); it("should keep the configured project when the opened file is referenced by the project but not its root", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/main.ts", content: "import { objA } from './obj-a';" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/obj-a.ts", content: `export const objA = Object.assign({foo: "bar"}, {bar: "baz"});` }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -1051,7 +1053,7 @@ namespace ts.projectSystem { checkNumberOfInferredProjects(projectService, 0); }); it("should tolerate config file errors and still try to build a project", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -1108,7 +1110,7 @@ namespace ts.projectSystem { path: "/a/b/main.ts", content: "let x =1;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -1154,7 +1156,7 @@ namespace ts.projectSystem { path: "/a/b/main2.ts", content: "let y =1;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -1188,7 +1190,7 @@ namespace ts.projectSystem { path: "/a/b/main.ts", content: "let x =1;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -2449,19 +2451,19 @@ namespace ts.projectSystem { }); it("Open ref of configured project when open file gets added to the project as part of configured file update", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/src/file1.ts", content: "let x = 1;" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/src/file2.ts", content: "let y = 1;" }; - const file3: FileOrFolder = { + const file3: File = { path: "/a/b/file3.ts", content: "let z = 1;" }; - const file4: FileOrFolder = { + const file4: File = { path: "/a/file4.ts", content: "let z = 1;" }; @@ -2527,7 +2529,7 @@ namespace ts.projectSystem { checkProjectActualFiles(inferredProject4, [file4.path]); assert.strictEqual(inferredProject5, inferredProject4); - const file5: FileOrFolder = { + const file5: File = { path: "/file5.ts", content: "let zz = 1;" }; @@ -2545,7 +2547,7 @@ namespace ts.projectSystem { infos.forEach(info => assert.strictEqual(projectService.getScriptInfoForPath(info.path), info)); } - function verifyScriptInfosAreUndefined(files: FileOrFolder[]) { + function verifyScriptInfosAreUndefined(files: File[]) { for (const file of files) { assert.isUndefined(projectService.getScriptInfoForPath(file.path as Path)); } @@ -2561,19 +2563,19 @@ namespace ts.projectSystem { }); it("Open ref of configured project when open file gets added to the project as part of configured file update buts its open file references are all closed when the update happens", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/src/file1.ts", content: "let x = 1;" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/src/file2.ts", content: "let y = 1;" }; - const file3: FileOrFolder = { + const file3: File = { path: "/a/b/file3.ts", content: "let z = 1;" }; - const file4: FileOrFolder = { + const file4: File = { path: "/a/file4.ts", content: "let z = 1;" }; @@ -2943,19 +2945,19 @@ namespace ts.projectSystem { }); it("Changed module resolution reflected when specifying files list", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: 'import classc from "file2"' }; - const file2a: FileOrFolder = { + const file2a: File = { path: "/a/file2.ts", content: "export classc { method2a() { return 10; } }" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/file2.ts", content: "export classc { method2() { return 10; } }" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ files: [file1.path], compilerOptions: { module: "amd" } }) }; @@ -2997,24 +2999,24 @@ namespace ts.projectSystem { it("Failed lookup locations uses parent most node_modules directory", () => { const root = "/user/username/rootfolder"; - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/src/file1.ts", content: 'import { classc } from "module1"' }; - const module1: FileOrFolder = { + const module1: File = { path: "/a/b/node_modules/module1/index.d.ts", content: `import { class2 } from "module2"; export classc { method2a(): class2; }` }; - const module2: FileOrFolder = { + const module2: File = { path: "/a/b/node_modules/module2/index.d.ts", content: "export class2 { method2() { return 10; } }" }; - const module3: FileOrFolder = { + const module3: File = { path: "/a/b/node_modules/module/node_modules/module3/index.d.ts", content: "export class3 { method2() { return 10; } }" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/src/tsconfig.json", content: JSON.stringify({ files: ["file1.ts"] }) }; @@ -3036,7 +3038,7 @@ namespace ts.projectSystem { }); it("Properly handle Windows-style outDir", () => { - const configFile: FileOrFolder = { + const configFile: File = { path: "C:\\a\\tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -3045,7 +3047,7 @@ namespace ts.projectSystem { include: ["*.ts"] }) }; - const file1: FileOrFolder = { + const file1: File = { path: "C:\\a\\f1.ts", content: "let x = 1;" }; @@ -3062,7 +3064,7 @@ namespace ts.projectSystem { }); it("dynamic file without external project", () => { - const file: FileOrFolder = { + const file: File = { path: "^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js", content: "var x = 10;" }; @@ -3101,19 +3103,19 @@ namespace ts.projectSystem { }); it("files opened, closed affecting multiple projects", () => { - const file: FileOrFolder = { + const file: File = { path: "/a/b/projects/config/file.ts", content: `import {a} from "../files/file1"; export let b = a;` }; - const config: FileOrFolder = { + const config: File = { path: "/a/b/projects/config/tsconfig.json", content: "" }; - const filesFile1: FileOrFolder = { + const filesFile1: File = { path: "/a/b/projects/files/file1.ts", content: "export let a = 10;" }; - const filesFile2: FileOrFolder = { + const filesFile2: File = { path: "/a/b/projects/files/file2.ts", content: "export let aa = 10;" }; @@ -3179,15 +3181,15 @@ namespace ts.projectSystem { it("requests are done on file on pendingReload but has svc for previous version", () => { const projectLocation = "/user/username/projects/project"; - const file1: FileOrFolder = { + const file1: File = { path: `${projectLocation}/src/file1.ts`, content: `import { y } from "./file2"; let x = 10;` }; - const file2: FileOrFolder = { + const file2: File = { path: `${projectLocation}/src/file2.ts`, content: "export let y = 10;" }; - const config: FileOrFolder = { + const config: File = { path: `${projectLocation}/tsconfig.json`, content: "{}" }; @@ -3262,18 +3264,18 @@ namespace ts.projectSystem { it("Orphan source files are handled correctly on watch trigger", () => { const projectLocation = "/user/username/projects/project"; - const file1: FileOrFolder = { + const file1: File = { path: `${projectLocation}/src/file1.ts`, content: `export let x = 10;` }; - const file2: FileOrFolder = { + const file2: File = { path: `${projectLocation}/src/file2.ts`, content: "export let y = 10;" }; const configContent1 = JSON.stringify({ files: ["src/file1.ts", "src/file2.ts"] }); - const config: FileOrFolder = { + const config: File = { path: `${projectLocation}/tsconfig.json`, content: configContent1 }; @@ -3424,15 +3426,15 @@ namespace ts.projectSystem { it("folder rename updates project structure and reports no errors", () => { const projectDir = "/a/b/projects/myproject"; - const app: FileOrFolder = { + const app: File = { path: `${projectDir}/bar/app.ts`, content: "class Bar implements foo.Foo { getFoo() { return ''; } get2() { return 1; } }" }; - const foo: FileOrFolder = { + const foo: File = { path: `${projectDir}/foo/foo.ts`, content: "declare namespace foo { interface Foo { get2(): number; getFoo(): string; } }" }; - const configFile: FileOrFolder = { + const configFile: File = { path: `${projectDir}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", targer: "es5" }, exclude: ["node_modules"] }) }; @@ -3479,7 +3481,7 @@ namespace ts.projectSystem { }); it("Getting errors before opening file", () => { - const file: FileOrFolder = { + const file: File = { path: "/a/b/project/file.ts", content: "let x: number = false;" }; @@ -3505,15 +3507,15 @@ namespace ts.projectSystem { it("Reports errors correctly when file referenced by inferred project root, is opened right after closing the root file", () => { const projectRoot = "/user/username/projects/myproject"; - const app: FileOrFolder = { + const app: File = { path: `${projectRoot}/src/client/app.js`, content: "" }; - const serverUtilities: FileOrFolder = { + const serverUtilities: File = { path: `${projectRoot}/src/server/utilities.js`, content: `function getHostName() { return "hello"; } export { getHostName };` }; - const backendTest: FileOrFolder = { + const backendTest: File = { path: `${projectRoot}/test/backend/index.js`, content: `import { getHostName } from '../../src/server/utilities';export default getHostName;` }; @@ -3657,11 +3659,11 @@ namespace ts.projectSystem { } it("should not include type symbols", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.js", content: "function foo() {}" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/jsconfig.json", content: "{}" }; @@ -4050,19 +4052,19 @@ namespace ts.projectSystem { } function verifyOpenFileWorks(useCaseSensitiveFileNames: boolean) { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/src/app.ts", content: "let x = 10;" }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/B/lib/module2.ts", content: "let z = 10;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: "" }; - const configFile2: FileOrFolder = { + const configFile2: File = { path: "/a/tsconfig.json", content: "" }; @@ -4081,7 +4083,7 @@ namespace ts.projectSystem { verifyConfigFileName(file2, "/a/b", useCaseSensitiveFileNames ? configFile2 : configFile); verifyConfigFileName(file2, "/a/B", useCaseSensitiveFileNames ? undefined : configFile); - function verifyConfigFileName(file: FileOrFolder, projectRoot: string, expectedConfigFile: FileOrFolder | undefined) { + function verifyConfigFileName(file: File, projectRoot: string, expectedConfigFile: File | undefined) { const { configFileName } = service.openClientFile(file.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectRoot); assert.equal(configFileName, expectedConfigFile && expectedConfigFile.path); service.closeClientFile(file.path); @@ -4097,11 +4099,11 @@ namespace ts.projectSystem { it("uses existing project even if project refresh is pending", () => { const projectFolder = "/user/someuser/projects/myproject"; - const aFile: FileOrFolder = { + const aFile: File = { path: `${projectFolder}/src/a.ts`, content: "export const x = 0;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: `${projectFolder}/tsconfig.json`, content: "{}" }; @@ -4111,7 +4113,7 @@ namespace ts.projectSystem { service.openClientFile(aFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder); verifyProject(); - const bFile: FileOrFolder = { + const bFile: File = { path: `${projectFolder}/src/b.ts`, content: `export {}; declare module "./a" { export const y: number; }` }; @@ -4320,7 +4322,7 @@ namespace ts.projectSystem { it("npm install @types works", () => { const folderPath = "/a/b/projects/temp"; - const file1: FileOrFolder = { + const file1: File = { path: `${folderPath}/a.ts`, content: 'import f = require("pad"); f;' }; @@ -4367,7 +4369,7 @@ namespace ts.projectSystem { checkCompleteEvent(session, 2, expectedSequenceId); session.clearMessages(); - const padIndex: FileOrFolder = { + const padIndex: File = { path: `${folderPath}/node_modules/@types/pad/index.d.ts`, content: "export = pad;declare function pad(length: number, text: string, char ?: string): string;" }; @@ -4386,7 +4388,7 @@ namespace ts.projectSystem { }); it("suggestion diagnostics", () => { - const file: FileOrFolder = { + const file: File = { path: "/a.js", content: "function f(p) {}", }; @@ -4439,7 +4441,7 @@ namespace ts.projectSystem { }); it("disable suggestion diagnostics", () => { - const file: FileOrFolder = { + const file: File = { path: "/a.js", content: 'require("b")', }; @@ -4490,7 +4492,7 @@ namespace ts.projectSystem { }); it("suppressed diagnostic events", () => { - const file: FileOrFolder = { + const file: File = { path: "/a.ts", content: "1 = 2;", }; @@ -5261,13 +5263,13 @@ namespace ts.projectSystem { assert.equal(projectService.inferredProjects[2].getCompilationSettings().target, ScriptTarget.ES2015); }); - function checkInferredProject(inferredProject: server.InferredProject, actualFiles: FileOrFolder[], target: ScriptTarget) { + function checkInferredProject(inferredProject: server.InferredProject, actualFiles: File[], target: ScriptTarget) { checkProjectActualFiles(inferredProject, actualFiles.map(f => f.path)); assert.equal(inferredProject.getCompilationSettings().target, target); } function verifyProjectRootWithCaseSensitivity(useCaseSensitiveFileNames: boolean) { - const files: [FileOrFolder, FileOrFolder, FileOrFolder, FileOrFolder] = [ + const files: [File, File, File, File] = [ { path: "/a/file1.ts", content: "let x = 1;" }, { path: "/A/file2.ts", content: "let y = 2;" }, { path: "/b/file2.ts", content: "let x = 3;" }, @@ -5351,7 +5353,7 @@ namespace ts.projectSystem { files.forEach(file => projectService.closeClientFile(file.path)); } - function verifyInferredProjectsState(expected: [FileOrFolder[], ScriptTarget][]) { + function verifyInferredProjectsState(expected: [File[], ScriptTarget][]) { checkNumberOfProjects(projectService, { inferredProjects: expected.length }); projectService.inferredProjects.forEach((p, index) => { const [actualFiles, target] = expected[index]; @@ -5610,11 +5612,11 @@ namespace ts.projectSystem { describe("when the opened file is not from project root", () => { const projectRoot = "/a/b/projects/project"; - const file: FileOrFolder = { + const file: File = { path: `${projectRoot}/src/index.ts`, content: "let y = 10" }; - const tsconfig: FileOrFolder = { + const tsconfig: File = { path: `${projectRoot}/tsconfig.json`, content: "{}" }; @@ -5622,7 +5624,7 @@ namespace ts.projectSystem { const filesWithConfig = files.concat(tsconfig); const dirOfFile = getDirectoryPath(file.path); - function openClientFile(files: FileOrFolder[]) { + function openClientFile(files: File[]) { const host = createServerHost(files); const projectService = createProjectService(host); @@ -5963,7 +5965,7 @@ namespace ts.projectSystem { describe("tsserverProjectSystem occurence highlight on string", () => { it("should be marked if only on string values", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: `let t1 = "div";\nlet t2 = "div";\nlet t3 = { "div": 123 };\nlet t4 = t3["div"];` }; @@ -6009,11 +6011,11 @@ namespace ts.projectSystem { describe("tsserverProjectSystem maxNodeModuleJsDepth for inferred projects", () => { it("should be set to 2 if the project has js root files", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.js", content: `var t = require("test"); t.` }; - const moduleFile: FileOrFolder = { + const moduleFile: File = { path: "/a/b/node_modules/test/index.js", content: `var v = 10; module.exports = v;` }; @@ -6278,12 +6280,12 @@ namespace ts.projectSystem { it("works using legacy resolution logic", () => { let rootContent = `import {x} from "f1"`; - const root: FileOrFolder = { + const root: File = { path: "/c/d/f0.ts", content: rootContent }; - const imported: FileOrFolder = { + const imported: File = { path: "/c/f1.ts", content: `foo()` }; @@ -6394,12 +6396,12 @@ namespace ts.projectSystem { }); it("loads missing files from disk", () => { - const root: FileOrFolder = { + const root: File = { path: "/c/foo.ts", content: `import {y} from "bar"` }; - const imported: FileOrFolder = { + const imported: File = { path: "/c/bar.d.ts", content: `export var y = 1` }; @@ -6431,25 +6433,25 @@ namespace ts.projectSystem { }); it("when calling goto definition of module", () => { - const clientFile: FileOrFolder = { + const clientFile: File = { path: "/a/b/controllers/vessels/client.ts", content: ` import { Vessel } from '~/models/vessel'; const v = new Vessel(); ` }; - const anotherModuleFile: FileOrFolder = { + const anotherModuleFile: File = { path: "/a/b/utils/db.ts", content: "export class Bookshelf { }" }; - const moduleFile: FileOrFolder = { + const moduleFile: File = { path: "/a/b/models/vessel.ts", content: ` import { Bookshelf } from '~/utils/db'; export class Vessel extends Bookshelf {} ` }; - const tsconfigFile: FileOrFolder = { + const tsconfigFile: File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -6510,25 +6512,25 @@ namespace ts.projectSystem { const frontendDir = "/Users/someuser/work/applications/frontend"; const toCanonical: (s: string) => Path = useCaseSensitiveFileNames ? s => s as Path : s => s.toLowerCase() as Path; const canonicalFrontendDir = toCanonical(frontendDir); - const file1: FileOrFolder = { + const file1: File = { path: `${frontendDir}/src/app/utils/Analytic.ts`, content: "export class SomeClass { };" }; - const file2: FileOrFolder = { + const file2: File = { path: `${frontendDir}/src/app/redux/configureStore.ts`, content: "export class configureStore { }" }; - const file3: FileOrFolder = { + const file3: File = { path: `${frontendDir}/src/app/utils/Cookie.ts`, content: "export class Cookie { }" }; - const es2016LibFile: FileOrFolder = { + const es2016LibFile: File = { path: "/a/lib/lib.es2016.full.d.ts", content: libFile.content }; const typeRoots = ["types", "node_modules/@types"]; const types = ["node", "jest"]; - const tsconfigFile: FileOrFolder = { + const tsconfigFile: File = { path: `${frontendDir}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -6602,7 +6604,7 @@ namespace ts.projectSystem { verifyProjectAndWatchedDirectories(); callsTrackingHost.verifyNoHostCalls(); - function getFilePathIfNotOpen(f: FileOrFolder) { + function getFilePathIfNotOpen(f: File) { const path = toCanonical(f.path); const info = projectService.getScriptInfoForPath(toCanonical(f.path)); return info && info.isScriptOpen() ? undefined : path; @@ -6628,15 +6630,15 @@ namespace ts.projectSystem { describe("Subfolder invalidations correctly include parent folder failed lookup locations", () => { function runFailedLookupTest(resolution: "Node" | "Classic") { const projectLocation = "/proj"; - const file1: FileOrFolder = { + const file1: File = { path: `${projectLocation}/foo/boo/app.ts`, content: `import * as debug from "debug"` }; - const file2: FileOrFolder = { + const file2: File = { path: `${projectLocation}/foo/boo/moo/app.ts`, content: `import * as debug from "debug"` }; - const tsconfig: FileOrFolder = { + const tsconfig: File = { path: `${projectLocation}/tsconfig.json`, content: JSON.stringify({ files: ["foo/boo/app.ts", "foo/boo/moo/app.ts"], @@ -6654,7 +6656,7 @@ namespace ts.projectSystem { assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]); - const debugTypesFile: FileOrFolder = { + const debugTypesFile: File = { path: `${projectLocation}/node_modules/debug/index.d.ts`, content: "export {}" }; @@ -6677,19 +6679,19 @@ namespace ts.projectSystem { describe("Verify npm install in directory with tsconfig file works when", () => { function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) { const root = "/user/username/rootfolder/otherfolder"; - const getRootedFileOrFolder = (fileOrFolder: FileOrFolder) => { + const getRootedFileOrFolder = (fileOrFolder: File) => { fileOrFolder.path = root + fileOrFolder.path; return fileOrFolder; }; - const app: FileOrFolder = getRootedFileOrFolder({ + const app: File = getRootedFileOrFolder({ path: "/a/b/app.ts", content: "import _ from 'lodash';" }); - const tsconfigJson: FileOrFolder = getRootedFileOrFolder({ + const tsconfigJson: File = getRootedFileOrFolder({ path: "/a/b/tsconfig.json", content: '{ "compilerOptions": { } }' }); - const packageJson: FileOrFolder = getRootedFileOrFolder({ + const packageJson: File = getRootedFileOrFolder({ path: "/a/b/package.json", content: ` { @@ -6728,7 +6730,7 @@ namespace ts.projectSystem { let timeoutAfterReloadFs = timeoutDuringPartialInstallation; // Simulate npm install - const filesAndFoldersToAdd: FileOrFolder[] = [ + const filesAndFoldersToAdd: File[] = [ { path: "/a/b/node_modules" }, { path: "/a/b/node_modules/.staging/@types" }, { path: "/a/b/node_modules/.staging/lodash-b0733faa" }, @@ -6843,11 +6845,11 @@ namespace ts.projectSystem { it("when node_modules dont receive event for the @types file addition", () => { const projectLocation = "/user/username/folder/myproject"; - const app: FileOrFolder = { + const app: File = { path: `${projectLocation}/app.ts`, content: `import * as debug from "debug"` }; - const tsconfig: FileOrFolder = { + const tsconfig: File = { path: `${projectLocation}/tsconfig.json`, content: "" }; @@ -6861,7 +6863,7 @@ namespace ts.projectSystem { checkProjectActualFiles(project, files.map(f => f.path)); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(app.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]); - const debugTypesFile: FileOrFolder = { + const debugTypesFile: File = { path: `${projectLocation}/node_modules/@types/debug/index.d.ts`, content: "export {}" }; @@ -6892,7 +6894,7 @@ namespace ts.projectSystem { } function createVerifyInitialOpen(session: TestSession, verifyProjectsUpdatedInBackgroundEventHandler: (events: server.ProjectsUpdatedInBackgroundEvent[]) => void) { - return (file: FileOrFolder) => { + return (file: File) => { session.executeCommandSeq({ command: server.CommandNames.Open, arguments: { @@ -6906,24 +6908,24 @@ namespace ts.projectSystem { interface ProjectsUpdatedInBackgroundEventVerifier { session: TestSession; verifyProjectsUpdatedInBackgroundEventHandler(events: server.ProjectsUpdatedInBackgroundEvent[]): void; - verifyInitialOpen(file: FileOrFolder): void; + verifyInitialOpen(file: File): void; } function verifyProjectsUpdatedInBackgroundEvent(createSession: (host: TestServerHost) => ProjectsUpdatedInBackgroundEventVerifier) { it("when adding new file", () => { - const commonFile1: FileOrFolder = { + const commonFile1: File = { path: "/a/b/file1.ts", content: "export var x = 10;" }; - const commonFile2: FileOrFolder = { + const commonFile2: File = { path: "/a/b/file2.ts", content: "export var y = 10;" }; - const commonFile3: FileOrFolder = { + const commonFile3: File = { path: "/a/b/file3.ts", content: "export var z = 10;" }; - const configFile: FileOrFolder = { + const configFile: File = { path: "/a/b/tsconfig.json", content: `{}` }; @@ -6953,18 +6955,18 @@ namespace ts.projectSystem { describe("with --out or --outFile setting", () => { function verifyEventWithOutSettings(compilerOptions: CompilerOptions = {}) { - const config: FileOrFolder = { + const config: File = { path: "/a/tsconfig.json", content: JSON.stringify({ compilerOptions }) }; - const f1: FileOrFolder = { + const f1: File = { path: "/a/a.ts", content: "export let x = 1" }; - const f2: FileOrFolder = { + const f2: File = { path: "/a/b.ts", content: "export let y = 1" }; @@ -7020,32 +7022,32 @@ namespace ts.projectSystem { /** custom config file options */ configObj?: any; /** Additional files and folders to add */ - getAdditionalFileOrFolder?(): FileOrFolder[]; + getAdditionalFileOrFolder?(): File[]; /** initial list of files to reload in fs and first file in this list being the file to open */ firstReloadFileList?: string[]; } function getInitialState({ configObj = {}, getAdditionalFileOrFolder, firstReloadFileList }: InitialStateParams = {}) { - const moduleFile1: FileOrFolder = { + const moduleFile1: File = { path: moduleFile1Path, content: "export function Foo() { };", }; - const file1Consumer1: FileOrFolder = { + const file1Consumer1: File = { path: file1Consumer1Path, content: `import {Foo} from "./moduleFile1"; export var y = 10;`, }; - const file1Consumer2: FileOrFolder = { + const file1Consumer2: File = { path: "/a/b/file1Consumer2.ts", content: `import {Foo} from "./moduleFile1"; let z = 10;`, }; - const moduleFile2: FileOrFolder = { + const moduleFile2: File = { path: "/a/b/moduleFile2.ts", content: `export var Foo4 = 10;`, }; - const globalFile3: FileOrFolder = { + const globalFile3: File = { path: "/a/b/globalFile3.ts", content: `interface GlobalFoo { age: number }` }; @@ -7085,13 +7087,13 @@ namespace ts.projectSystem { return find(files, file => file.path === fileName); } - function verifyNoProjectsUpdatedInBackgroundEvent(filesToReload?: FileOrFolder[]) { + function verifyNoProjectsUpdatedInBackgroundEvent(filesToReload?: File[]) { host.reloadFS(filesToReload || files); host.runQueuedTimeoutCallbacks(); verifyProjectsUpdatedInBackgroundEventHandler([]); } - function verifyProjectsUpdatedInBackgroundEvent(filesToReload?: FileOrFolder[]) { + function verifyProjectsUpdatedInBackgroundEvent(filesToReload?: File[]) { host.reloadFS(filesToReload || files); host.runQueuedTimeoutCallbacks(); verifyProjectsUpdatedInBackgroundEventHandler([{ @@ -7102,7 +7104,7 @@ namespace ts.projectSystem { }]); } - function updateContentOfOpenFile(file: FileOrFolder, newContent: string) { + function updateContentOfOpenFile(file: File, newContent: string) { session.executeCommandSeq({ command: server.CommandNames.Change, arguments: { @@ -7172,7 +7174,7 @@ namespace ts.projectSystem { it("should be up-to-date with newly created files", () => { const { moduleFile1, files, verifyProjectsUpdatedInBackgroundEvent, } = getInitialState(); - const file1Consumer3: FileOrFolder = { + const file1Consumer3: File = { path: "/a/b/file1Consumer3.ts", content: `import {Foo} from "./moduleFile1"; let y = Foo();` }; @@ -7220,7 +7222,7 @@ namespace ts.projectSystem { }); it("should return cascaded affected file list", () => { - const file1Consumer1Consumer1: FileOrFolder = { + const file1Consumer1Consumer1: File = { path: "/a/b/file1Consumer1Consumer1.ts", content: `import {y} from "./file1Consumer1";` }; @@ -7242,13 +7244,13 @@ namespace ts.projectSystem { }); it("should work fine for files with circular references", () => { - const file1: FileOrFolder = { + const file1: File = { path: "/a/b/file1.ts", content: ` /// export var t1 = 10;` }; - const file2: FileOrFolder = { + const file2: File = { path: "/a/b/file2.ts", content: ` /// @@ -7264,7 +7266,7 @@ namespace ts.projectSystem { }); it("should detect removed code file", () => { - const referenceFile1: FileOrFolder = { + const referenceFile1: File = { path: "/a/b/referenceFile1.ts", content: ` /// @@ -7279,7 +7281,7 @@ namespace ts.projectSystem { }); it("should detect non-existing code file", () => { - const referenceFile1: FileOrFolder = { + const referenceFile1: File = { path: "/a/b/referenceFile1.ts", content: ` /// @@ -7301,19 +7303,19 @@ namespace ts.projectSystem { describe("resolution when resolution cache size", () => { function verifyWithMaxCacheLimit(limitHit: boolean, useSlashRootAsSomeNotRootFolderInUserDirectory: boolean) { const rootFolder = useSlashRootAsSomeNotRootFolderInUserDirectory ? "/user/username/rootfolder/otherfolder/" : "/"; - const file1: FileOrFolder = { + const file1: File = { path: rootFolder + "a/b/project/file1.ts", content: 'import a from "file2"' }; - const file2: FileOrFolder = { + const file2: File = { path: rootFolder + "a/b/node_modules/file2.d.ts", content: "export class a { }" }; - const file3: FileOrFolder = { + const file3: File = { path: rootFolder + "a/b/project/file3.ts", content: "export class c { }" }; - const configFile: FileOrFolder = { + const configFile: File = { path: rootFolder + "a/b/project/tsconfig.json", content: JSON.stringify({ compilerOptions: { typeRoots: [] } }) }; @@ -7479,15 +7481,15 @@ namespace ts.projectSystem { describe("tsserverProjectSystem Watched recursive directories with windows style file system", () => { function verifyWatchedDirectories(useProjectAtRoot: boolean) { const root = useProjectAtRoot ? "c:/" : "c:/myfolder/allproject/"; - const configFile: FileOrFolder = { + const configFile: File = { path: root + "project/tsconfig.json", content: "{}" }; - const file1: FileOrFolder = { + const file1: File = { path: root + "project/file1.ts", content: "let x = 10;" }; - const file2: FileOrFolder = { + const file2: File = { path: root + "project/file2.ts", content: "let y = 10;" }; @@ -7520,13 +7522,13 @@ namespace ts.projectSystem { it("when projectRootPath is provided", () => { const projects = "/users/username/projects"; const projectRootPath = `${projects}/san2`; - const file: FileOrFolder = { + const file: File = { path: `${projectRootPath}/x.js`, content: "const aaaaaaav = 1;" }; const currentDirectory = `${projects}/anotherProject`; - const packageJsonInCurrentDirectory: FileOrFolder = { + const packageJsonInCurrentDirectory: File = { path: `${currentDirectory}/package.json`, content: JSON.stringify({ devDependencies: { @@ -7534,7 +7536,7 @@ namespace ts.projectSystem { }, }) }; - const packageJsonOfPkgcurrentdirectory: FileOrFolder = { + const packageJsonOfPkgcurrentdirectory: File = { path: `${currentDirectory}/node_modules/pkgcurrentdirectory/package.json`, content: JSON.stringify({ name: "pkgcurrentdirectory", @@ -7542,20 +7544,20 @@ namespace ts.projectSystem { typings: "index.d.ts" }) }; - const indexOfPkgcurrentdirectory: FileOrFolder = { + const indexOfPkgcurrentdirectory: File = { path: `${currentDirectory}/node_modules/pkgcurrentdirectory/index.d.ts`, content: "export function foo() { }" }; const typingsCache = `/users/username/Library/Caches/typescript/2.7`; - const typingsCachePackageJson: FileOrFolder = { + const typingsCachePackageJson: File = { path: `${typingsCache}/package.json`, content: JSON.stringify({ devDependencies: { }, }) }; - const typingsCachePackageLockJson: FileOrFolder = { + const typingsCachePackageLockJson: File = { path: `${typingsCache}/package-lock.json`, content: JSON.stringify({ dependencies: { @@ -7598,37 +7600,37 @@ namespace ts.projectSystem { it("rename in common file renames all project", () => { const projects = "/users/username/projects"; const folderA = `${projects}/a`; - const aFile: FileOrFolder = { + const aFile: File = { path: `${folderA}/a.ts`, content: `import {C} from "./c/fc"; console.log(C)` }; - const aTsconfig: FileOrFolder = { + const aTsconfig: File = { path: `${folderA}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "commonjs" } }) }; - const aC: FileOrFolder = { + const aC: SymLink = { path: `${folderA}/c`, symLink: "../c" }; const aFc = `${folderA}/c/fc.ts`; const folderB = `${projects}/b`; - const bFile: FileOrFolder = { + const bFile: File = { path: `${folderB}/b.ts`, content: `import {C} from "./c/fc"; console.log(C)` }; - const bTsconfig: FileOrFolder = { + const bTsconfig: File = { path: `${folderB}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "commonjs" } }) }; - const bC: FileOrFolder = { + const bC: SymLink = { path: `${folderB}/c`, symLink: "../c" }; const bFc = `${folderB}/c/fc.ts`; const folderC = `${projects}/c`; - const cFile: FileOrFolder = { + const cFile: File = { path: `${folderC}/fc.ts`, content: `export const C = 8` }; @@ -7709,19 +7711,19 @@ namespace ts.projectSystem { describe("tsserverProjectSystem forceConsistentCasingInFileNames", () => { it("works when extends is specified with a case insensitive file system", () => { const rootPath = "/Users/username/dev/project"; - const file1: FileOrFolder = { + const file1: File = { path: `${rootPath}/index.ts`, content: 'import {x} from "file2";', }; - const file2: FileOrFolder = { + const file2: File = { path: `${rootPath}/file2.js`, content: "", }; - const file2Dts: FileOrFolder = { + const file2Dts: File = { path: `${rootPath}/types/file2/index.d.ts`, content: "export declare const x: string;", }; - const tsconfigAll: FileOrFolder = { + const tsconfigAll: File = { path: `${rootPath}/tsconfig.all.json`, content: JSON.stringify({ compilerOptions: { @@ -7732,7 +7734,7 @@ namespace ts.projectSystem { }, }), }; - const tsconfig: FileOrFolder = { + const tsconfig: File = { path: `${rootPath}/tsconfig.json`, content: JSON.stringify({ extends: "./tsconfig.all.json" }), }; @@ -7752,17 +7754,17 @@ namespace ts.projectSystem { describe("tsserverProjectSystem module resolution caching", () => { const projectLocation = "/user/username/projects/myproject"; - const configFile: FileOrFolder = { + const configFile: File = { path: `${projectLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { traceResolution: true } }) }; function getModules(module1Path: string, module2Path: string) { - const module1: FileOrFolder = { + const module1: File = { path: module1Path, content: `export function module1() {}` }; - const module2: FileOrFolder = { + const module2: File = { path: module2Path, content: `export function module2() {}` }; @@ -7774,7 +7776,7 @@ namespace ts.projectSystem { resolutionTrace.length = 0; } - function getExpectedFileDoesNotExistResolutionTrace(host: TestServerHost, expectedTrace: string[], foundModule: boolean, module: FileOrFolder, directory: string, file: string, ignoreIfParentMissing?: boolean) { + function getExpectedFileDoesNotExistResolutionTrace(host: TestServerHost, expectedTrace: string[], foundModule: boolean, module: File, directory: string, file: string, ignoreIfParentMissing?: boolean) { if (!foundModule) { const path = combinePaths(directory, file); if (!ignoreIfParentMissing || host.directoryExists(getDirectoryPath(path))) { @@ -7789,7 +7791,7 @@ namespace ts.projectSystem { return foundModule; } - function getExpectedMissedLocationResolutionTrace(host: TestServerHost, expectedTrace: string[], dirPath: string, module: FileOrFolder, moduleName: string, useNodeModules: boolean, cacheLocation?: string) { + function getExpectedMissedLocationResolutionTrace(host: TestServerHost, expectedTrace: string[], dirPath: string, module: File, moduleName: string, useNodeModules: boolean, cacheLocation?: string) { let foundModule = false; forEachAncestorDirectory(dirPath, dirPath => { if (dirPath === cacheLocation) { @@ -7813,14 +7815,14 @@ namespace ts.projectSystem { }); } - function getExpectedResolutionTraceHeader(expectedTrace: string[], file: FileOrFolder, moduleName: string) { + function getExpectedResolutionTraceHeader(expectedTrace: string[], file: File, moduleName: string) { expectedTrace.push( `======== Resolving module '${moduleName}' from '${file.path}'. ========`, `Module resolution kind is not specified, using 'NodeJs'.` ); } - function getExpectedResolutionTraceFooter(expectedTrace: string[], module: FileOrFolder, moduleName: string, addRealPathTrace: boolean, ignoreModuleFileFound?: boolean) { + function getExpectedResolutionTraceFooter(expectedTrace: string[], module: File, moduleName: string, addRealPathTrace: boolean, ignoreModuleFileFound?: boolean) { if (!ignoreModuleFileFound) { expectedTrace.push(`File '${module.path}' exist - use it as a name resolution result.`); } @@ -7830,7 +7832,7 @@ namespace ts.projectSystem { expectedTrace.push(`======== Module name '${moduleName}' was successfully resolved to '${module.path}'. ========`); } - function getExpectedRelativeModuleResolutionTrace(host: TestServerHost, file: FileOrFolder, module: FileOrFolder, moduleName: string, expectedTrace: string[] = []) { + function getExpectedRelativeModuleResolutionTrace(host: TestServerHost, file: File, module: File, moduleName: string, expectedTrace: string[] = []) { getExpectedResolutionTraceHeader(expectedTrace, file, moduleName); expectedTrace.push(`Loading module as file / folder, candidate module location '${removeFileExtension(module.path)}', target file type 'TypeScript'.`); getExpectedMissedLocationResolutionTrace(host, expectedTrace, getDirectoryPath(normalizePath(combinePaths(getDirectoryPath(file.path), moduleName))), module, moduleName.substring(moduleName.lastIndexOf("/") + 1), /*useNodeModules*/ false); @@ -7838,7 +7840,7 @@ namespace ts.projectSystem { return expectedTrace; } - function getExpectedNonRelativeModuleResolutionTrace(host: TestServerHost, file: FileOrFolder, module: FileOrFolder, moduleName: string, expectedTrace: string[] = []) { + function getExpectedNonRelativeModuleResolutionTrace(host: TestServerHost, file: File, module: File, moduleName: string, expectedTrace: string[] = []) { getExpectedResolutionTraceHeader(expectedTrace, file, moduleName); expectedTrace.push(`Loading module '${moduleName}' from 'node_modules' folder, target file type 'TypeScript'.`); getExpectedMissedLocationResolutionTrace(host, expectedTrace, getDirectoryPath(file.path), module, moduleName, /*useNodeModules*/ true); @@ -7846,7 +7848,7 @@ namespace ts.projectSystem { return expectedTrace; } - function getExpectedNonRelativeModuleResolutionFromCacheTrace(host: TestServerHost, file: FileOrFolder, module: FileOrFolder, moduleName: string, cacheLocation: string, expectedTrace: string[] = []) { + function getExpectedNonRelativeModuleResolutionFromCacheTrace(host: TestServerHost, file: File, module: File, moduleName: string, cacheLocation: string, expectedTrace: string[] = []) { getExpectedResolutionTraceHeader(expectedTrace, file, moduleName); expectedTrace.push(`Loading module '${moduleName}' from 'node_modules' folder, target file type 'TypeScript'.`); getExpectedMissedLocationResolutionTrace(host, expectedTrace, getDirectoryPath(file.path), module, moduleName, /*useNodeModules*/ true, cacheLocation); @@ -7855,11 +7857,11 @@ namespace ts.projectSystem { return expectedTrace; } - function getExpectedReusingResolutionFromOldProgram(file: FileOrFolder, moduleName: string) { + function getExpectedReusingResolutionFromOldProgram(file: File, moduleName: string) { return `Reusing resolution of module '${moduleName}' to file '${file.path}' from old program.`; } - function verifyWatchesWithConfigFile(host: TestServerHost, files: FileOrFolder[], openFile: FileOrFolder) { + function verifyWatchesWithConfigFile(host: TestServerHost, files: File[], openFile: File) { checkWatchedFiles(host, mapDefined(files, f => f === openFile ? undefined : f.path)); checkWatchedDirectories(host, [], /*recursive*/ false); const configDirectory = getDirectoryPath(configFile.path); @@ -7868,11 +7870,11 @@ namespace ts.projectSystem { describe("from files in same folder", () => { function getFiles(fileContent: string) { - const file1: FileOrFolder = { + const file1: File = { path: `${projectLocation}/src/file1.ts`, content: fileContent }; - const file2: FileOrFolder = { + const file2: File = { path: `${projectLocation}/src/file2.ts`, content: fileContent }; @@ -7936,19 +7938,19 @@ namespace ts.projectSystem { describe("from files in different folders", () => { function getFiles(fileContent1: string, fileContent2 = fileContent1, fileContent3 = fileContent1, fileContent4 = fileContent1) { - const file1: FileOrFolder = { + const file1: File = { path: `${projectLocation}/product/src/file1.ts`, content: fileContent1 }; - const file2: FileOrFolder = { + const file2: File = { path: `${projectLocation}/product/src/feature/file2.ts`, content: fileContent2 }; - const file3: FileOrFolder = { + const file3: File = { path: `${projectLocation}/product/test/src/file3.ts`, content: fileContent3 }; - const file4: FileOrFolder = { + const file4: File = { path: `${projectLocation}/product/test/file4.ts`, content: fileContent4 }; @@ -8103,15 +8105,15 @@ namespace ts.projectSystem { function verifyCompletionListWithNewFileInSubFolder(tscWatchDirectory: TestFSWithWatch.Tsc_WatchDirectory) { const projectFolder = "/a/username/project"; const projectSrcFolder = `${projectFolder}/src`; - const configFile: FileOrFolder = { + const configFile: File = { path: `${projectFolder}/tsconfig.json`, content: "{}" }; - const index: FileOrFolder = { + const index: File = { path: `${projectSrcFolder}/index.ts`, content: `import {} from "./"` }; - const file1: FileOrFolder = { + const file1: File = { path: `${projectSrcFolder}/file1.ts`, content: "" }; @@ -8145,7 +8147,7 @@ namespace ts.projectSystem { verifyProjectAndCompletions(); // Add file2 - const file2: FileOrFolder = { + const file2: File = { path: `${projectSrcFolder}/file2.ts`, content: "" }; diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index a8c7d4895d1..2f83fe90c8a 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -30,7 +30,7 @@ namespace ts.projectSystem { } } - function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[] | string, typingFiles: FileOrFolder[], cb: TI.RequestCompletedAction): void { + function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[] | string, typingFiles: File[], cb: TI.RequestCompletedAction): void { self.addPostExecAction(installedTypings, success => { for (const file of typingFiles) { host.ensureFileOrFolder(file); @@ -417,7 +417,7 @@ namespace ts.projectSystem { } installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { const installedTypings: string[] = []; - const typingFiles: FileOrFolder[] = []; + const typingFiles: File[] = []; executeCommand(this, host, installedTypings, typingFiles, cb); } })(); @@ -460,7 +460,7 @@ namespace ts.projectSystem { } installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { const installedTypings: string[] = []; - const typingFiles: FileOrFolder[] = []; + const typingFiles: File[] = []; executeCommand(this, host, installedTypings, typingFiles, cb); } })(); @@ -697,7 +697,7 @@ namespace ts.projectSystem { super(host, { throttleLimit: 1, typesRegistry: createTypesRegistry("commander", "jquery", "lodash", "cordova", "gulp", "grunt") }); } installWorker(_requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { - let typingFiles: (FileOrFolder & { typings: string })[] = []; + let typingFiles: (File & { typings: string })[] = []; if (args.indexOf(typingsName("commander")) >= 0) { typingFiles = [commander, jquery, lodash, cordova]; } @@ -1193,7 +1193,7 @@ namespace ts.projectSystem { } installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) { const installedTypings: string[] = []; - const typingFiles: FileOrFolder[] = []; + const typingFiles: File[] = []; executeCommand(this, host, installedTypings, typingFiles, cb); } })(); @@ -1656,12 +1656,12 @@ namespace ts.projectSystem { return foooResolution; } - function verifyUnresolvedImportResolutions(appContents: string, typingNames: string[], typingFiles: FileOrFolder[]) { - const app: FileOrFolder = { + function verifyUnresolvedImportResolutions(appContents: string, typingNames: string[], typingFiles: File[]) { + const app: File = { path: appPath, content: `${appContents}import * as x from "fooo";` }; - const fooo: FileOrFolder = { + const fooo: File = { path: foooPath, content: `export var x: string;` }; @@ -1697,15 +1697,15 @@ namespace ts.projectSystem { }); it("correctly invalidate the resolutions with typing names that are trimmed", () => { - const fooAA: FileOrFolder = { + const fooAA: File = { path: `${globalTypingsCacheLocation}/node_modules/foo/a/a.d.ts`, content: "export function a (): void;" }; - const fooAB: FileOrFolder = { + const fooAB: File = { path: `${globalTypingsCacheLocation}/node_modules/foo/a/b.d.ts`, content: "export function b (): void;" }; - const fooAC: FileOrFolder = { + const fooAC: File = { path: `${globalTypingsCacheLocation}/node_modules/foo/a/c.d.ts`, content: "export function c (): void;" }; diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 323a51c25ae..1ff6e4dbdf6 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -1,7 +1,7 @@ /// namespace ts.TestFSWithWatch { - export const libFile: FileOrFolder = { + export const libFile: File = { path: "/a/lib/lib.d.ts", content: `/// interface Boolean {} @@ -39,7 +39,7 @@ interface Array {}` environmentVariables?: Map; } - export function createWatchedSystem(fileOrFolderList: ReadonlyArray, params?: TestServerHostCreationParameters): TestServerHost { + export function createWatchedSystem(fileOrFolderList: ReadonlyArray, params?: TestServerHostCreationParameters): TestServerHost { if (!params) { params = {}; } @@ -54,7 +54,7 @@ interface Array {}` return host; } - export function createServerHost(fileOrFolderList: ReadonlyArray, params?: TestServerHostCreationParameters): TestServerHost { + export function createServerHost(fileOrFolderList: ReadonlyArray, params?: TestServerHostCreationParameters): TestServerHost { if (!params) { params = {}; } @@ -69,11 +69,28 @@ interface Array {}` return host; } - export interface FileOrFolder { + export interface File { path: string; - content?: string; + content: string; fileSize?: number; - symLink?: string; + } + + export interface Folder { + path: string; + } + + export interface SymLink { + path: string; + symLink: string; + } + + export type FileOrFolderOrSymLink = File | Folder | SymLink; + function isFile(fileOrFolderOrSymLink: FileOrFolderOrSymLink): fileOrFolderOrSymLink is File { + return isString((fileOrFolderOrSymLink).content); + } + + function isSymLink(fileOrFolderOrSymLink: FileOrFolderOrSymLink): fileOrFolderOrSymLink is SymLink { + return isString((fileOrFolderOrSymLink).symLink); } interface FSEntry { @@ -82,29 +99,29 @@ interface Array {}` modifiedTime: Date; } - interface File extends FSEntry { + interface FsFile extends FSEntry { content: string; fileSize?: number; } - interface Folder extends FSEntry { + interface FsFolder extends FSEntry { entries: SortedArray; } - interface SymLink extends FSEntry { + interface FsSymLink extends FSEntry { symLink: string; } - function isFolder(s: FSEntry): s is Folder { - return s && isArray((s).entries); + function isFsFolder(s: FSEntry): s is FsFolder { + return s && isArray((s).entries); } - function isFile(s: FSEntry): s is File { - return s && isString((s).content); + function isFsFile(s: FSEntry): s is FsFile { + return s && isString((s).content); } - function isSymLink(s: FSEntry): s is SymLink { - return s && isString((s).symLink); + function isFsSymLink(s: FSEntry): s is FsSymLink { + return s && isString((s).symLink); } function invokeWatcherCallbacks(callbacks: T[], invokeCallback: (cb: T) => void): void { @@ -306,12 +323,12 @@ interface Array {}` private readonly dynamicPriorityWatchFile: HostWatchFile; private readonly customRecursiveWatchDirectory: HostWatchDirectory | undefined; - constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderList: ReadonlyArray, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map) { + constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderorSymLinkList: ReadonlyArray, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map) { this.getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); this.toPath = s => toPath(s, currentDirectory, this.getCanonicalFileName); this.executingFilePath = this.getHostSpecificPath(executingFilePath); this.currentDirectory = this.getHostSpecificPath(currentDirectory); - this.reloadFS(fileOrFolderList); + this.reloadFS(fileOrFolderorSymLinkList); this.dynamicPriorityWatchFile = this.environmentVariables && this.environmentVariables.get("TSC_WATCHFILE") === "DynamicPriorityPolling" ? createDynamicPriorityPollingWatchFile(this) : undefined; @@ -373,12 +390,12 @@ interface Array {}` return new Date(this.time); } - reloadFS(fileOrFolderList: ReadonlyArray, options?: Partial) { + reloadFS(fileOrFolderOrSymLinkList: ReadonlyArray, options?: Partial) { const mapNewLeaves = createMap(); const isNewFs = this.fs.size === 0; - fileOrFolderList = fileOrFolderList.concat(this.withSafeList ? safeList : []); - const filesOrFoldersToLoad: ReadonlyArray = !this.useWindowsStylePath ? fileOrFolderList : - fileOrFolderList.map(f => { + fileOrFolderOrSymLinkList = fileOrFolderOrSymLinkList.concat(this.withSafeList ? safeList : []); + const filesOrFoldersToLoad: ReadonlyArray = !this.useWindowsStylePath ? fileOrFolderOrSymLinkList : + fileOrFolderOrSymLinkList.map(f => { const result = clone(f); result.path = this.getHostSpecificPath(f.path); return result; @@ -389,8 +406,8 @@ interface Array {}` // If its a change const currentEntry = this.fs.get(path); if (currentEntry) { - if (isFile(currentEntry)) { - if (isString(fileOrDirectory.content)) { + if (isFsFile(currentEntry)) { + if (isFile(fileOrDirectory)) { // Update file if (currentEntry.content !== fileOrDirectory.content) { this.modifyFile(fileOrDirectory.path, fileOrDirectory.content, options); @@ -400,12 +417,12 @@ interface Array {}` // TODO: Changing from file => folder/Symlink } } - else if (isSymLink(currentEntry)) { + else if (isFsSymLink(currentEntry)) { // TODO: update symlinks } else { // Folder - if (isString(fileOrDirectory.content)) { + if (isFile(fileOrDirectory)) { // TODO: Changing from folder => file } else { @@ -424,7 +441,7 @@ interface Array {}` // If this entry is not from the new file or folder if (!mapNewLeaves.get(path)) { // Leaf entries that arent in new list => remove these - if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory) || isFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) { + if (isFsFile(fileOrDirectory) || isFsSymLink(fileOrDirectory) || isFsFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) { this.removeFileOrFolder(fileOrDirectory, folder => !mapNewLeaves.get(folder.path)); } } @@ -435,7 +452,7 @@ interface Array {}` modifyFile(filePath: string, content: string, options?: Partial) { const path = this.toFullPath(filePath); const currentEntry = this.fs.get(path); - if (!currentEntry || !isFile(currentEntry)) { + if (!currentEntry || !isFsFile(currentEntry)) { throw new Error(`file not present: ${filePath}`); } @@ -459,7 +476,7 @@ interface Array {}` renameFolder(folderName: string, newFolderName: string) { const fullPath = getNormalizedAbsolutePath(folderName, this.currentDirectory); const path = this.toPath(fullPath); - const folder = this.fs.get(path) as Folder; + const folder = this.fs.get(path) as FsFolder; Debug.assert(!!folder); // Only remove the folder @@ -467,19 +484,19 @@ interface Array {}` // Add updated folder with new folder name const newFullPath = getNormalizedAbsolutePath(newFolderName, this.currentDirectory); - const newFolder = this.toFolder(newFullPath); + const newFolder = this.toFsFolder(newFullPath); const newPath = newFolder.path; const basePath = getDirectoryPath(path); Debug.assert(basePath !== path); Debug.assert(basePath === getDirectoryPath(newPath)); - const baseFolder = this.fs.get(basePath) as Folder; + const baseFolder = this.fs.get(basePath) as FsFolder; this.addFileOrFolderInFolder(baseFolder, newFolder); // Invoke watches for files in the folder as deleted (from old path) this.renameFolderEntries(folder, newFolder); } - private renameFolderEntries(oldFolder: Folder, newFolder: Folder) { + private renameFolderEntries(oldFolder: FsFolder, newFolder: FsFolder) { for (const entry of oldFolder.entries) { this.fs.delete(entry.path); this.invokeFileWatcher(entry.fullPath, FileWatcherEventKind.Deleted); @@ -491,38 +508,38 @@ interface Array {}` } this.fs.set(entry.path, entry); this.invokeFileWatcher(entry.fullPath, FileWatcherEventKind.Created); - if (isFolder(entry)) { + if (isFsFolder(entry)) { this.renameFolderEntries(entry, entry); } } } - ensureFileOrFolder(fileOrDirectory: FileOrFolder, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) { - if (isString(fileOrDirectory.content)) { - const file = this.toFile(fileOrDirectory); + ensureFileOrFolder(fileOrDirectoryOrSymLink: FileOrFolderOrSymLink, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) { + if (isFile(fileOrDirectoryOrSymLink)) { + const file = this.toFsFile(fileOrDirectoryOrSymLink); // file may already exist when updating existing type declaration file if (!this.fs.get(file.path)) { const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath)); this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate); } } - else if (isString(fileOrDirectory.symLink)) { - const symLink = this.toSymLink(fileOrDirectory); + else if (isSymLink(fileOrDirectoryOrSymLink)) { + const symLink = this.toFsSymLink(fileOrDirectoryOrSymLink); Debug.assert(!this.fs.get(symLink.path)); const baseFolder = this.ensureFolder(getDirectoryPath(symLink.fullPath)); this.addFileOrFolderInFolder(baseFolder, symLink, ignoreWatchInvokedWithTriggerAsFileCreate); } else { - const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory); + const fullPath = getNormalizedAbsolutePath(fileOrDirectoryOrSymLink.path, this.currentDirectory); this.ensureFolder(fullPath); } } - private ensureFolder(fullPath: string): Folder { + private ensureFolder(fullPath: string): FsFolder { const path = this.toPath(fullPath); - let folder = this.fs.get(path) as Folder; + let folder = this.fs.get(path) as FsFolder; if (!folder) { - folder = this.toFolder(fullPath); + folder = this.toFsFolder(fullPath); const baseFullPath = getDirectoryPath(fullPath); if (fullPath !== baseFullPath) { // Add folder in the base folder @@ -535,11 +552,11 @@ interface Array {}` this.fs.set(path, folder); } } - Debug.assert(isFolder(folder)); + Debug.assert(isFsFolder(folder)); return folder; } - private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder | SymLink, ignoreWatch?: boolean) { + private addFileOrFolderInFolder(folder: FsFolder, fileOrDirectory: FsFile | FsFolder | FsSymLink, ignoreWatch?: boolean) { insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path))); folder.modifiedTime = this.now(); this.fs.set(fileOrDirectory.path, fileOrDirectory); @@ -551,9 +568,9 @@ interface Array {}` this.invokeDirectoryWatcher(folder.fullPath, fileOrDirectory.fullPath); } - private removeFileOrFolder(fileOrDirectory: File | Folder | SymLink, isRemovableLeafFolder: (folder: Folder) => boolean, isRenaming?: boolean) { + private removeFileOrFolder(fileOrDirectory: FsFile | FsFolder | FsSymLink, isRemovableLeafFolder: (folder: FsFolder) => boolean, isRenaming?: boolean) { const basePath = getDirectoryPath(fileOrDirectory.path); - const baseFolder = this.fs.get(basePath) as Folder; + const baseFolder = this.fs.get(basePath) as FsFolder; if (basePath !== fileOrDirectory.path) { Debug.assert(!!baseFolder); baseFolder.modifiedTime = this.now(); @@ -562,7 +579,7 @@ interface Array {}` this.fs.delete(fileOrDirectory.path); this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Deleted); - if (isFolder(fileOrDirectory)) { + if (isFsFolder(fileOrDirectory)) { Debug.assert(fileOrDirectory.entries.length === 0 || isRenaming); const relativePath = this.getRelativePathToDirectory(fileOrDirectory.fullPath, fileOrDirectory.fullPath); // Invoke directory and recursive directory watcher for the folder @@ -635,23 +652,23 @@ interface Array {}` }; } - private toFile(fileOrDirectory: FileOrFolder): File { - const file = this.toFsEntry(fileOrDirectory.path) as File; - file.content = fileOrDirectory.content; - file.fileSize = fileOrDirectory.fileSize; - return file; + private toFsFile(file: File): FsFile { + const fsFile = this.toFsEntry(file.path) as FsFile; + fsFile.content = file.content; + fsFile.fileSize = file.fileSize; + return fsFile; } - private toSymLink(fileOrDirectory: FileOrFolder): SymLink { - const symLink = this.toFsEntry(fileOrDirectory.path) as SymLink; - symLink.symLink = getNormalizedAbsolutePath(fileOrDirectory.symLink, getDirectoryPath(symLink.fullPath)); - return symLink; + private toFsSymLink(symLink: SymLink): FsSymLink { + const fsSymLink = this.toFsEntry(symLink.path) as FsSymLink; + fsSymLink.symLink = getNormalizedAbsolutePath(symLink.symLink, getDirectoryPath(fsSymLink.fullPath)); + return fsSymLink; } - private toFolder(path: string): Folder { - const folder = this.toFsEntry(path) as Folder; - folder.entries = [] as SortedArray; - return folder; + private toFsFolder(path: string): FsFolder { + const fsFolder = this.toFsEntry(path) as FsFolder; + fsFolder.entries = [] as SortedArray; + return fsFolder; } private getRealFsEntry(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)): T | undefined { @@ -659,7 +676,7 @@ interface Array {}` return fsEntry; } - if (isSymLink(fsEntry)) { + if (isFsSymLink(fsEntry)) { return this.getRealFsEntry(isFsEntry, this.toPath(fsEntry.symLink)); } @@ -676,20 +693,20 @@ interface Array {}` return undefined; } - private isFile(fsEntry: FSEntry) { + private isFsFile(fsEntry: FSEntry) { return !!this.getRealFile(fsEntry.path, fsEntry); } - private getRealFile(path: Path, fsEntry?: FSEntry): File | undefined { - return this.getRealFsEntry(isFile, path, fsEntry); + private getRealFile(path: Path, fsEntry?: FSEntry): FsFile | undefined { + return this.getRealFsEntry(isFsFile, path, fsEntry); } - private isFolder(fsEntry: FSEntry) { + private isFsFolder(fsEntry: FSEntry) { return !!this.getRealFolder(fsEntry.path, fsEntry); } - private getRealFolder(path: Path, fsEntry = this.fs.get(path)): Folder | undefined { - return this.getRealFsEntry(isFolder, path, fsEntry); + private getRealFolder(path: Path, fsEntry = this.fs.get(path)): FsFolder | undefined { + return this.getRealFsEntry(isFsFolder, path, fsEntry); } fileExists(s: string) { @@ -711,7 +728,7 @@ interface Array {}` getFileSize(s: string) { const path = this.toFullPath(s); const entry = this.fs.get(path); - if (isFile(entry)) { + if (isFsFile(entry)) { return entry.fileSize ? entry.fileSize : entry.content.length; } return undefined; @@ -726,7 +743,7 @@ interface Array {}` const path = this.toFullPath(s); const folder = this.getRealFolder(path); if (folder) { - return mapDefined(folder.entries, entry => this.isFolder(entry) ? getBaseFileName(entry.fullPath) : undefined); + return mapDefined(folder.entries, entry => this.isFsFolder(entry) ? getBaseFileName(entry.fullPath) : undefined); } Debug.fail(folder ? "getDirectories called on file" : "getDirectories called on missing folder"); return []; @@ -739,10 +756,10 @@ interface Array {}` const folder = this.getRealFolder(this.toPath(dir)); if (folder) { folder.entries.forEach((entry) => { - if (this.isFolder(entry)) { + if (this.isFsFolder(entry)) { directories.push(getBaseFileName(entry.fullPath)); } - else if (this.isFile(entry)) { + else if (this.isFsFile(entry)) { files.push(getBaseFileName(entry.fullPath)); } else { @@ -840,24 +857,24 @@ interface Array {}` } createDirectory(directoryName: string): void { - const folder = this.toFolder(directoryName); + const folder = this.toFsFolder(directoryName); // base folder has to be present const base = getDirectoryPath(folder.path); - const baseFolder = this.fs.get(base) as Folder; - Debug.assert(isFolder(baseFolder)); + const baseFolder = this.fs.get(base) as FsFolder; + Debug.assert(isFsFolder(baseFolder)); Debug.assert(!this.fs.get(folder.path)); this.addFileOrFolderInFolder(baseFolder, folder); } writeFile(path: string, content: string): void { - const file = this.toFile({ path, content }); + const file = this.toFsFile({ path, content }); // base folder has to be present const base = getDirectoryPath(file.path); - const folder = this.fs.get(base) as Folder; - Debug.assert(isFolder(folder)); + const folder = this.fs.get(base) as FsFolder; + Debug.assert(isFsFolder(folder)); this.addFileOrFolderInFolder(folder, file); } @@ -885,7 +902,7 @@ interface Array {}` const dirFullPath = this.realpath(getDirectoryPath(fullPath)); const realFullPath = combinePaths(dirFullPath, getBaseFileName(fullPath)); const fsEntry = this.fs.get(this.toPath(realFullPath)); - if (isSymLink(fsEntry)) { + if (isFsSymLink(fsEntry)) { return this.realpath(fsEntry.symLink); }