mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-07 23:08:20 -06:00
Few renames to distinguish between fs File and File in the test case to load in the VFS with watch
This commit is contained in:
parent
618da24d6a
commit
5ecfa782fc
@ -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: `
|
||||
/// <reference path="./file2.ts" />
|
||||
export var t1 = 10;`
|
||||
};
|
||||
const file2: FileOrFolder = {
|
||||
const file2: File = {
|
||||
path: "/a/b/file2.ts",
|
||||
content: `
|
||||
/// <reference path="./file1.ts" />
|
||||
@ -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: `
|
||||
/// <reference path="./moduleFile1.ts" />
|
||||
@ -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: `
|
||||
/// <reference path="./moduleFile2.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";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<string>;"
|
||||
};
|
||||
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<T> {}"
|
||||
};
|
||||
@ -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"] })
|
||||
};
|
||||
|
||||
@ -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) };
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 ///<ref", () => {
|
||||
const commonFile2Name = "commonFile2.ts";
|
||||
const file1: FileOrFolder = {
|
||||
const file1: File = {
|
||||
path: "/a/b/commonFile1.ts",
|
||||
content: `/// <reference path="${commonFile2Name}"/>
|
||||
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: `
|
||||
/// <reference path="./file2.ts" />
|
||||
export var t1 = 10;`
|
||||
};
|
||||
const file2: FileOrFolder = {
|
||||
const file2: File = {
|
||||
path: "/a/b/file2.ts",
|
||||
content: `
|
||||
/// <reference path="./file1.ts" />
|
||||
@ -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: `
|
||||
/// <reference path="./moduleFile1.ts" />
|
||||
@ -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: `
|
||||
/// <reference path="./moduleFile2.ts" />
|
||||
@ -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`
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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;"
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/// <reference path="harness.ts" />
|
||||
|
||||
namespace ts.TestFSWithWatch {
|
||||
export const libFile: FileOrFolder = {
|
||||
export const libFile: File = {
|
||||
path: "/a/lib/lib.d.ts",
|
||||
content: `/// <reference no-default-lib="true"/>
|
||||
interface Boolean {}
|
||||
@ -39,7 +39,7 @@ interface Array<T> {}`
|
||||
environmentVariables?: Map<string>;
|
||||
}
|
||||
|
||||
export function createWatchedSystem(fileOrFolderList: ReadonlyArray<FileOrFolder>, params?: TestServerHostCreationParameters): TestServerHost {
|
||||
export function createWatchedSystem(fileOrFolderList: ReadonlyArray<FileOrFolderOrSymLink>, params?: TestServerHostCreationParameters): TestServerHost {
|
||||
if (!params) {
|
||||
params = {};
|
||||
}
|
||||
@ -54,7 +54,7 @@ interface Array<T> {}`
|
||||
return host;
|
||||
}
|
||||
|
||||
export function createServerHost(fileOrFolderList: ReadonlyArray<FileOrFolder>, params?: TestServerHostCreationParameters): TestServerHost {
|
||||
export function createServerHost(fileOrFolderList: ReadonlyArray<FileOrFolderOrSymLink>, params?: TestServerHostCreationParameters): TestServerHost {
|
||||
if (!params) {
|
||||
params = {};
|
||||
}
|
||||
@ -69,11 +69,28 @@ interface Array<T> {}`
|
||||
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((<File>fileOrFolderOrSymLink).content);
|
||||
}
|
||||
|
||||
function isSymLink(fileOrFolderOrSymLink: FileOrFolderOrSymLink): fileOrFolderOrSymLink is SymLink {
|
||||
return isString((<SymLink>fileOrFolderOrSymLink).symLink);
|
||||
}
|
||||
|
||||
interface FSEntry {
|
||||
@ -82,29 +99,29 @@ interface Array<T> {}`
|
||||
modifiedTime: Date;
|
||||
}
|
||||
|
||||
interface File extends FSEntry {
|
||||
interface FsFile extends FSEntry {
|
||||
content: string;
|
||||
fileSize?: number;
|
||||
}
|
||||
|
||||
interface Folder extends FSEntry {
|
||||
interface FsFolder extends FSEntry {
|
||||
entries: SortedArray<FSEntry>;
|
||||
}
|
||||
|
||||
interface SymLink extends FSEntry {
|
||||
interface FsSymLink extends FSEntry {
|
||||
symLink: string;
|
||||
}
|
||||
|
||||
function isFolder(s: FSEntry): s is Folder {
|
||||
return s && isArray((<Folder>s).entries);
|
||||
function isFsFolder(s: FSEntry): s is FsFolder {
|
||||
return s && isArray((<FsFolder>s).entries);
|
||||
}
|
||||
|
||||
function isFile(s: FSEntry): s is File {
|
||||
return s && isString((<File>s).content);
|
||||
function isFsFile(s: FSEntry): s is FsFile {
|
||||
return s && isString((<FsFile>s).content);
|
||||
}
|
||||
|
||||
function isSymLink(s: FSEntry): s is SymLink {
|
||||
return s && isString((<SymLink>s).symLink);
|
||||
function isFsSymLink(s: FSEntry): s is FsSymLink {
|
||||
return s && isString((<FsSymLink>s).symLink);
|
||||
}
|
||||
|
||||
function invokeWatcherCallbacks<T>(callbacks: T[], invokeCallback: (cb: T) => void): void {
|
||||
@ -306,12 +323,12 @@ interface Array<T> {}`
|
||||
private readonly dynamicPriorityWatchFile: HostWatchFile;
|
||||
private readonly customRecursiveWatchDirectory: HostWatchDirectory | undefined;
|
||||
|
||||
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderList: ReadonlyArray<FileOrFolder>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map<string>) {
|
||||
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderorSymLinkList: ReadonlyArray<FileOrFolderOrSymLink>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map<string>) {
|
||||
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<T> {}`
|
||||
return new Date(this.time);
|
||||
}
|
||||
|
||||
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>, options?: Partial<ReloadWatchInvokeOptions>) {
|
||||
reloadFS(fileOrFolderOrSymLinkList: ReadonlyArray<FileOrFolderOrSymLink>, options?: Partial<ReloadWatchInvokeOptions>) {
|
||||
const mapNewLeaves = createMap<true>();
|
||||
const isNewFs = this.fs.size === 0;
|
||||
fileOrFolderList = fileOrFolderList.concat(this.withSafeList ? safeList : []);
|
||||
const filesOrFoldersToLoad: ReadonlyArray<FileOrFolder> = !this.useWindowsStylePath ? fileOrFolderList :
|
||||
fileOrFolderList.map<FileOrFolder>(f => {
|
||||
fileOrFolderOrSymLinkList = fileOrFolderOrSymLinkList.concat(this.withSafeList ? safeList : []);
|
||||
const filesOrFoldersToLoad: ReadonlyArray<FileOrFolderOrSymLink> = !this.useWindowsStylePath ? fileOrFolderOrSymLinkList :
|
||||
fileOrFolderOrSymLinkList.map<FileOrFolderOrSymLink>(f => {
|
||||
const result = clone(f);
|
||||
result.path = this.getHostSpecificPath(f.path);
|
||||
return result;
|
||||
@ -389,8 +406,8 @@ interface Array<T> {}`
|
||||
// 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<T> {}`
|
||||
// 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<T> {}`
|
||||
// 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<T> {}`
|
||||
modifyFile(filePath: string, content: string, options?: Partial<ReloadWatchInvokeOptions>) {
|
||||
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<T> {}`
|
||||
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<T> {}`
|
||||
|
||||
// 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<T> {}`
|
||||
}
|
||||
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<T> {}`
|
||||
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<T> {}`
|
||||
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<T> {}`
|
||||
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<T> {}`
|
||||
};
|
||||
}
|
||||
|
||||
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<FSEntry>;
|
||||
return folder;
|
||||
private toFsFolder(path: string): FsFolder {
|
||||
const fsFolder = this.toFsEntry(path) as FsFolder;
|
||||
fsFolder.entries = [] as SortedArray<FSEntry>;
|
||||
return fsFolder;
|
||||
}
|
||||
|
||||
private getRealFsEntry<T extends FSEntry>(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)): T | undefined {
|
||||
@ -659,7 +676,7 @@ interface Array<T> {}`
|
||||
return fsEntry;
|
||||
}
|
||||
|
||||
if (isSymLink(fsEntry)) {
|
||||
if (isFsSymLink(fsEntry)) {
|
||||
return this.getRealFsEntry(isFsEntry, this.toPath(fsEntry.symLink));
|
||||
}
|
||||
|
||||
@ -676,20 +693,20 @@ interface Array<T> {}`
|
||||
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<T> {}`
|
||||
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<T> {}`
|
||||
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<T> {}`
|
||||
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<T> {}`
|
||||
}
|
||||
|
||||
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<T> {}`
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user