From 4803fda8621f205563857dd9bdfebfd7c8ee8fc6 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 7 May 2018 16:53:25 -0700 Subject: [PATCH 1/2] Make new harness fake host more performant in large complications --- src/compiler/core.ts | 1 + src/compiler/moduleNameResolver.ts | 7 ++++++- src/harness/fakes.ts | 21 +++++++++++---------- src/harness/utils.ts | 25 ------------------------- 4 files changed, 18 insertions(+), 36 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c5e9a75b4ee07..df9354e480f5e 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2223,6 +2223,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 ca282da18b8d6..8bb65e57616d5 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 c6d955e821590..1919505f71b7b 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; @@ -202,7 +200,8 @@ namespace fakes { export class CompilerHost implements ts.CompilerHost { public readonly sys: System; public readonly defaultLibLocation: string; - public readonly outputs: documents.TextDocument[] = []; + private readonly outputNames: string[] = []; + private readonly outputsMap: ts.Map = ts.createMap(); public readonly traces: string[] = []; public readonly shouldAssertInvariants = !Harness.lightMode; @@ -220,6 +219,10 @@ namespace fakes { this._setParentNodes = setParentNodes; } + public get outputs() { + return ts.map(this.outputNames, e => this.outputsMap.get(e)); + } + public get vfs() { return this.sys.vfs; } @@ -267,13 +270,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) { - this.outputs.push(document); - } - else { - this.outputs[index] = document; + const canonical = ts.toPath(fileName, this.sys.getCurrentDirectory(), ts.createGetCanonicalFileName(this.sys.useCaseSensitiveFileNames)); + if (!this.outputsMap.has(canonical)) { + this.outputNames.push(canonical); } + this.outputsMap.set(canonical, document); } public trace(s: string): void { diff --git a/src/harness/utils.ts b/src/harness/utils.ts index 03e9e56169b01..83e51a065a055 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; From 2de51193de7335f94d6b83f5827741afe92406e1 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 8 May 2018 11:32:42 -0700 Subject: [PATCH 2/2] Use sortedmap --- src/harness/fakes.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/harness/fakes.ts b/src/harness/fakes.ts index 1919505f71b7b..d9cd6ee69c7cd 100644 --- a/src/harness/fakes.ts +++ b/src/harness/fakes.ts @@ -200,8 +200,8 @@ namespace fakes { export class CompilerHost implements ts.CompilerHost { public readonly sys: System; public readonly defaultLibLocation: string; - private readonly outputNames: string[] = []; - private readonly outputsMap: ts.Map = ts.createMap(); + public readonly outputs: documents.TextDocument[] = []; + private readonly _outputsMap: collections.SortedMap; public readonly traces: string[] = []; public readonly shouldAssertInvariants = !Harness.lightMode; @@ -217,10 +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; - } - - public get outputs() { - return ts.map(this.outputNames, e => this.outputsMap.get(e)); + this._outputsMap = new collections.SortedMap(this.vfs.stringComparer); } public get vfs() { @@ -270,11 +267,11 @@ namespace fakes { const document = new documents.TextDocument(fileName, content); document.meta.set("fileName", fileName); this.vfs.filemeta(fileName).set("document", document); - const canonical = ts.toPath(fileName, this.sys.getCurrentDirectory(), ts.createGetCanonicalFileName(this.sys.useCaseSensitiveFileNames)); - if (!this.outputsMap.has(canonical)) { - this.outputNames.push(canonical); + if (!this._outputsMap.has(document.file)) { + this._outputsMap.set(document.file, this.outputs.length); + this.outputs.push(document); } - this.outputsMap.set(canonical, document); + this.outputs[this._outputsMap.get(document.file)] = document; } public trace(s: string): void {