From 556c316fedee6b88b0b192f5c40db99f76577929 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 8 May 2018 12:46:33 -0700 Subject: [PATCH] Make new harness fake host more performant in large complications (#23951) * Make new harness fake host more performant in large complications * Use sortedmap --- src/compiler/core.ts | 1 + src/compiler/moduleNameResolver.ts | 7 ++++++- src/harness/fakes.ts | 14 ++++++-------- src/harness/utils.ts | 25 ------------------------- 4 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 20c3562271c..9cc7d0680e6 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2227,6 +2227,7 @@ namespace ts { const reduced = [components[0]]; for (let i = 1; i < components.length; i++) { const component = components[i]; + if (!component) continue; if (component === ".") continue; if (component === "..") { if (reduced.length > 1) { diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index ca282da18b8..8bb65e57616 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -119,7 +119,12 @@ namespace ts { export function readJson(path: string, host: { readFile(fileName: string): string | undefined }): object { try { const jsonText = host.readFile(path); - return jsonText ? JSON.parse(jsonText) : {}; + if (!jsonText) return {}; + const result = parseConfigFileTextToJson(path, jsonText); + if (result.error) { + return {}; + } + return result.config; } catch (e) { // gracefully handle if readFile fails or returns not JSON diff --git a/src/harness/fakes.ts b/src/harness/fakes.ts index 3e450f90d57..79d3503cb80 100644 --- a/src/harness/fakes.ts +++ b/src/harness/fakes.ts @@ -39,9 +39,7 @@ namespace fakes { public readFile(path: string) { try { const content = this.vfs.readFileSync(path, "utf8"); - return content === undefined ? undefined : - vpath.extname(path) === ".json" ? utils.removeComments(utils.removeByteOrderMark(content), utils.CommentRemoval.leadingAndTrailing) : - utils.removeByteOrderMark(content); + return content === undefined ? undefined : utils.removeByteOrderMark(content); } catch { return undefined; @@ -203,6 +201,7 @@ namespace fakes { public readonly sys: System; public readonly defaultLibLocation: string; public readonly outputs: documents.TextDocument[] = []; + private readonly _outputsMap: collections.SortedMap; public readonly traces: string[] = []; public readonly shouldAssertInvariants = !Harness.lightMode; @@ -218,6 +217,7 @@ namespace fakes { this._newLine = ts.getNewLineCharacter(options, () => this.sys.newLine); this._sourceFiles = new collections.SortedMap({ comparer: sys.vfs.stringComparer, sort: "insertion" }); this._setParentNodes = setParentNodes; + this._outputsMap = new collections.SortedMap(this.vfs.stringComparer); } public get vfs() { @@ -271,13 +271,11 @@ namespace fakes { const document = new documents.TextDocument(fileName, content); document.meta.set("fileName", fileName); this.vfs.filemeta(fileName).set("document", document); - const index = this.outputs.findIndex(output => this.vfs.stringComparer(document.file, output.file) === 0); - if (index < 0) { + if (!this._outputsMap.has(document.file)) { + this._outputsMap.set(document.file, this.outputs.length); this.outputs.push(document); } - else { - this.outputs[index] = document; - } + this.outputs[this._outputsMap.get(document.file)] = document; } public trace(s: string): void { diff --git a/src/harness/utils.ts b/src/harness/utils.ts index 03e9e56169b..83e51a065a0 100644 --- a/src/harness/utils.ts +++ b/src/harness/utils.ts @@ -2,31 +2,6 @@ * Common utilities */ namespace utils { - const leadingCommentRegExp = /^(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+/; - const trailingCommentRegExp = /(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+$/; - const leadingAndTrailingCommentRegExp = /^(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+|(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+$/g; - const allCommentRegExp = /(['"])(?:(?!\1).|\\[^])*\1|(\/\*[^]*?\*\/|\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)/g; - - export const enum CommentRemoval { - leading, - trailing, - leadingAndTrailing, - all - } - - export function removeComments(text: string, removal: CommentRemoval) { - switch (removal) { - case CommentRemoval.leading: - return text.replace(leadingCommentRegExp, ""); - case CommentRemoval.trailing: - return text.replace(trailingCommentRegExp, ""); - case CommentRemoval.leadingAndTrailing: - return text.replace(leadingAndTrailingCommentRegExp, ""); - case CommentRemoval.all: - return text.replace(allCommentRegExp, (match, quote) => quote ? match : ""); - } - } - const testPathPrefixRegExp = /(?:(file:\/{3})|\/)\.(ts|lib|src)\//g; export function removeTestPathPrefixes(text: string, retainTrailingDirectorySeparator?: boolean) { return text !== undefined ? text.replace(testPathPrefixRegExp, (_, scheme) => scheme || (retainTrailingDirectorySeparator ? "/" : "")) : undefined;