From cf261c34aad403f775ddbb025bfbbb9f5733f761 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 9 Nov 2017 16:08:40 -0800 Subject: [PATCH] Retire Harness.compileFiles --- src/harness/compiler.ts | 8 +- src/harness/compilerRunner.ts | 4 +- src/harness/harness.ts | 156 ------------------- src/harness/unittests/programMissingFiles.ts | 15 +- src/harness/utils.ts | 2 + src/harness/vfs.ts | 4 +- 6 files changed, 19 insertions(+), 170 deletions(-) diff --git a/src/harness/compiler.ts b/src/harness/compiler.ts index c6f0f831f81..6b4fcc62422 100644 --- a/src/harness/compiler.ts +++ b/src/harness/compiler.ts @@ -16,6 +16,7 @@ namespace compiler { public readonly defaultLibLocation: string; public readonly outputs: TextDocument[] = []; public readonly traces: string[] = []; + public readonly shouldAssertInvariants = !Harness.lightMode; private _setParentNodes: boolean; private _sourceFiles: KeyedCollection; @@ -130,7 +131,12 @@ namespace compiler { } } - const parsed = ts.createSourceFile(fileName, content, languageVersion, this._setParentNodes); + + const parsed = ts.createSourceFile(fileName, content, languageVersion, this._setParentNodes || this.shouldAssertInvariants); + if (this.shouldAssertInvariants) { + Utils.assertInvariants(parsed, /*parent*/ undefined); + } + this._sourceFiles.set(canonicalFileName, parsed); if (cacheKey) { diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index d8f82abe4ec..7aa26b9c8cd 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -46,8 +46,8 @@ class CompilerBaselineRunner extends RunnerBase { } private makeUnitName(name: string, root: string) { - const path = ts.toPath(name, root, (fileName) => Harness.Compiler.getCanonicalFileName(fileName)); - const pathStart = ts.toPath(Harness.IO.getCurrentDirectory(), "", (fileName) => Harness.Compiler.getCanonicalFileName(fileName)); + const path = ts.toPath(name, root, utils.identity); + const pathStart = ts.toPath(Harness.IO.getCurrentDirectory(), "", utils.identity); return pathStart ? path.replace(pathStart, "/") : path; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 964662aaa3e..2ab0b8c7a35 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1030,19 +1030,12 @@ namespace Harness { return result; } - const carriageReturnLineFeed = "\r\n"; - const lineFeed = "\n"; - export const defaultLibFileName = "lib.d.ts"; export const es2015DefaultLibFileName = "lib.es2015.d.ts"; // Cache of lib files from "built/local" let libFileNameSourceFileMap: ts.Map | undefined; - // Cache of lib files from "tests/lib/" - const testLibFileNameSourceFileMap = ts.createMap(); - const es6TestLibFileNameSourceFileMap = ts.createMap(); - export function getDefaultLibrarySourceFile(fileName = defaultLibFileName): ts.SourceFile { if (!isDefaultLibraryFile(fileName)) { return undefined; @@ -1084,155 +1077,6 @@ namespace Harness { return fileName; } - export function createCompilerHost( - inputFiles: TestFile[], - writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void, - scriptTarget: ts.ScriptTarget, - useCaseSensitiveFileNames: boolean, - // the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host - currentDirectory: string, - newLineKind?: ts.NewLineKind, - libFiles?: string): ts.CompilerHost { - - // Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames - const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); - - /** Maps a symlink name to a realpath. Used only for exposing `realpath`. */ - const realPathMap = ts.createMap(); - /** - * Maps a file name to a source file. - * This will have a different SourceFile for every symlink pointing to that file; - * if the program resolves realpaths then symlink entries will be ignored. - */ - const fileMap = ts.createMap(); - for (const file of inputFiles) { - if (file.content !== undefined) { - const fileName = ts.normalizePath(file.unitName); - const path = ts.toPath(file.unitName, currentDirectory, getCanonicalFileName); - if (file.fileOptions && file.fileOptions.symlink) { - const links = file.fileOptions.symlink.split(","); - for (const link of links) { - const linkPath = ts.toPath(link, currentDirectory, getCanonicalFileName); - realPathMap.set(linkPath, fileName); - // Create a different SourceFile for every symlink. - const sourceFile = createSourceFileAndAssertInvariants(linkPath, file.content, scriptTarget); - fileMap.set(linkPath, sourceFile); - } - } - const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget); - fileMap.set(path, sourceFile); - } - } - - if (libFiles) { - // Because @libFiles don't change between execution. We would cache the result of the files and reuse it to speed help compilation - for (const fileName of libFiles.split(",")) { - const libFileName = "tests/lib/" + fileName; - - if (scriptTarget <= ts.ScriptTarget.ES5) { - if (!testLibFileNameSourceFileMap.get(libFileName)) { - testLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget)); - } - } - else { - if (!es6TestLibFileNameSourceFileMap.get(libFileName)) { - es6TestLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget)); - } - } - } - } - - function getSourceFile(fileName: string) { - fileName = ts.normalizePath(fileName); - const fromFileMap = fileMap.get(toPath(fileName)); - if (fromFileMap) { - return fromFileMap; - } - else if (fileName === fourslashFileName) { - const tsFn = "tests/cases/fourslash/" + fourslashFileName; - fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget); - return fourslashSourceFile; - } - else if (ts.startsWith(fileName, "tests/lib/")) { - return scriptTarget <= ts.ScriptTarget.ES5 ? testLibFileNameSourceFileMap.get(fileName) : es6TestLibFileNameSourceFileMap.get(fileName); - } - else { - // Don't throw here -- the compiler might be looking for a test that actually doesn't exist as part of the TC - // Return if it is other library file, otherwise return undefined - return getDefaultLibrarySourceFile(fileName); - } - } - - const newLine = - newLineKind === ts.NewLineKind.CarriageReturnLineFeed ? carriageReturnLineFeed : - newLineKind === ts.NewLineKind.LineFeed ? lineFeed : - Harness.IO.newLine(); - - function toPath(fileName: string): ts.Path { - return ts.toPath(fileName, currentDirectory, getCanonicalFileName); - } - - return { - getCurrentDirectory: () => currentDirectory, - getSourceFile, - getDefaultLibFileName, - writeFile, - getCanonicalFileName, - useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, - getNewLine: () => newLine, - fileExists: fileName => fileMap.has(toPath(fileName)), - readFile(fileName: string): string | undefined { - const file = fileMap.get(toPath(fileName)); - if (ts.endsWith(fileName, "json")) { - // strip comments - return file.getText(); - } - return file.text; - }, - realpath: (fileName: string): ts.Path => { - const path = toPath(fileName); - return (realPathMap.get(path) as ts.Path) || path; - }, - directoryExists: dir => { - let path = ts.toPath(dir, currentDirectory, getCanonicalFileName); - // Strip trailing /, which may exist if the path is a drive root - if (path[path.length - 1] === "/") { - path = path.substr(0, path.length - 1); - } - return mapHasFileInDirectory(path, fileMap); - }, - getDirectories: d => { - const path = ts.toPath(d, currentDirectory, getCanonicalFileName); - const result: string[] = []; - ts.forEachKey(fileMap, key => { - if (key.indexOf(path) === 0 && key.lastIndexOf("/") > path.length) { - let dirName = key.substr(path.length, key.indexOf("/", path.length + 1) - path.length); - if (dirName[0] === "/") { - dirName = dirName.substr(1); - } - if (result.indexOf(dirName) < 0) { - result.push(dirName); - } - } - }); - return result; - } - }; - } - - function mapHasFileInDirectory(directoryPath: ts.Path, map: ts.Map<{}>): boolean { - if (!map) { - return false; - } - let exists = false; - ts.forEachKey(map, fileName => { - if (!exists && ts.startsWith(fileName, directoryPath) && fileName[directoryPath.length] === "/") { - exists = true; - } - }); - return exists; - } - interface HarnessOptions { useCaseSensitiveFileNames?: boolean; includeBuiltFile?: string; diff --git a/src/harness/unittests/programMissingFiles.ts b/src/harness/unittests/programMissingFiles.ts index ce8abc232e7..6e0602998f0 100644 --- a/src/harness/unittests/programMissingFiles.ts +++ b/src/harness/unittests/programMissingFiles.ts @@ -1,4 +1,5 @@ /// +/// namespace ts { function verifyMissingFilePaths(missingPaths: ReadonlyArray, expected: ReadonlyArray) { @@ -39,15 +40,11 @@ namespace ts { "/// \n" // No extension }; - const testCompilerHost = Harness.Compiler.createCompilerHost( - /*inputFiles*/ [emptyFile, referenceFile], - /*writeFile*/ undefined, - /*scriptTarget*/ undefined, - /*useCaseSensitiveFileNames*/ false, - /*currentDirectory*/ "d:\\pretend\\", - /*newLineKind*/ NewLineKind.LineFeed, - /*libFiles*/ undefined - ); + const testCompilerHost = new compiler.CompilerHost( + vfs.VirtualFileSystem.createFromTestFiles( + { useCaseSensitiveFileNames: false, currentDirectory: "d:\\pretend\\" }, + [emptyFile, referenceFile]), + { newLine: NewLineKind.LineFeed }); it("handles no missing root files", () => { const program = createProgram([emptyFileRelativePath], options, testCompilerHost); diff --git a/src/harness/utils.ts b/src/harness/utils.ts index 79ab489304e..518a1be993f 100644 --- a/src/harness/utils.ts +++ b/src/harness/utils.ts @@ -1,4 +1,6 @@ namespace utils { + export function identity(v: T) { return v; } + export function getByteOrderMarkLength(text: string) { if (text.length >= 2) { const ch0 = text.charCodeAt(0); diff --git a/src/harness/vfs.ts b/src/harness/vfs.ts index 238cb65e059..643b805a926 100644 --- a/src/harness/vfs.ts +++ b/src/harness/vfs.ts @@ -1373,7 +1373,7 @@ namespace vfs { } export interface VirtualFile { - // #region Event "contentChanged" + // #region Event "contentChanged" on(event: "contentChanged", listener: (entry: VirtualFile) => void): this; once(event: "contentChanged", listener: (entry: VirtualFile) => void): this; addListener(event: "contentChanged", listener: (entry: VirtualFile) => void): this; @@ -1385,7 +1385,7 @@ namespace vfs { } export interface VirtualFile { - // #region Untyped events + // #region Untyped events on(event: string | symbol, listener: (...args: any[]) => void): this; once(event: string | symbol, listener: (...args: any[]) => void): this; addListener(event: string | symbol, listener: (...args: any[]) => void): this;