From 8ccf0af3ac56f026e01790097bc18d74c50a346d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 26 Oct 2017 15:05:56 -0700 Subject: [PATCH 1/4] Add tsconfig.json for RWC projects that lack them. This should make all RWC projects browseable with an editor on Windows (except two, see below). On Linux it still works pretty well if you are willing to lowercase the imports of the file you're interested in. Many RWC projects already have tsconfig.json files, but this change creates one for projects that don't -- *after* running their respective RWC test. That's because all the information is most easily available at that time, and you probably won't need it until then anyway. Note that two RWC projects use relative paths in their list of stored files and don't work with this simple scheme. I'll look at that next, but if I can't figure it out in the next hour or two, I'd prefer to merge this since it's immediately useful for all the other projects. --- src/harness/loggedIO.ts | 2 +- src/harness/rwcRunner.ts | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index fcc163e77f3..c5d428f3095 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -159,7 +159,7 @@ namespace Playback { } const canonicalizeForHarness = ts.createGetCanonicalFileName(/*caseSensitive*/ false); // This is done so tests work on windows _and_ linux - function sanitizeTestFilePath(name: string) { + export function sanitizeTestFilePath(name: string) { const path = ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", canonicalizeForHarness); if (ts.startsWith(path, "/")) { return path.substring(1); diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 2b4fc7b24e4..9e17aa84b0c 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -70,10 +70,11 @@ namespace RWC { opts.options.noEmitOnError = false; }); + let tsconfigFile: IOLogFile; runWithIOLog(ioLog, oldIO => { let fileNames = opts.fileNames; - const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined); + tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined); if (tsconfigFile) { const tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path); tsconfigFiles.push({ unitName: tsconfigFile.path, content: tsconfigFileContents.content }); @@ -155,6 +156,11 @@ namespace RWC { compilerResult = output.result; }); + if (!tsconfigFile) { + const files = inputFiles.map(f => Playback.sanitizeTestFilePath(f.unitName)); + Harness.IO.writeFile(`internal/cases/rwc/${baseName}/read/tsconfig.json`, JSON.stringify({ compilerOptions, files })); + } + function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile { const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)); let content: string; From 3ac91d109b4a84f1ae824fa4014165339edc218c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 27 Oct 2017 14:31:48 -0700 Subject: [PATCH 2/4] Generate tsconfig in tsc-instrumented instead --- src/harness/loggedIO.ts | 28 ++++++++++++++++++++++++---- src/harness/rwcRunner.ts | 8 +------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index c5d428f3095..ff23458d284 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -159,7 +159,7 @@ namespace Playback { } const canonicalizeForHarness = ts.createGetCanonicalFileName(/*caseSensitive*/ false); // This is done so tests work on windows _and_ linux - export function sanitizeTestFilePath(name: string) { + function sanitizeTestFilePath(name: string) { const path = ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", canonicalizeForHarness); if (ts.startsWith(path, "/")) { return path.substring(1); @@ -249,13 +249,33 @@ namespace Playback { wrapper.endRecord = () => { if (recordLog !== undefined) { let i = 0; - const fn = () => recordLogFileNameBase + i; - while (underlying.fileExists(ts.combinePaths(fn(), "test.json"))) i++; - underlying.writeFile(ts.combinePaths(fn(), "test.json"), JSON.stringify(oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(path, string), fn()), null, 4)); // tslint:disable-line:no-null-keyword + const getBase = () => recordLogFileNameBase + i; + while (underlying.fileExists(ts.combinePaths(getBase(), "test.json"))) i++; + const newLog = oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(path, string), getBase()); + underlying.writeFile(ts.combinePaths(getBase(), "test.json"), JSON.stringify(newLog, null, 4)); // tslint:disable-line:no-null-keyword + const syntheticTsconfig = generateTsconfig(newLog); + if (syntheticTsconfig) { + underlying.writeFile(ts.combinePaths(getBase(), "tsconfig.json"), JSON.stringify(syntheticTsconfig, null, 4)); // tslint:disable-line:no-null-keyword + } recordLog = undefined; } }; + function generateTsconfig(newLog: IOLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } { + if (newLog.filesRead.some(file => /tsconfig.json$/.test(file.path))) { + return; + } + const files = []; + for (const file of newLog.filesRead) { + if (file.result.contentsPath && + !/lib\.d\.ts$/.test(file.result.contentsPath) && + /\.[tj]s$/.test(file.result.contentsPath)) { + files.push(file.result.contentsPath); + } + } + return { compilerOptions: ts.parseCommandLine(newLog.arguments).options, files }; + } + wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)( path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }), memoize(path => { diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 9e17aa84b0c..2b4fc7b24e4 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -70,11 +70,10 @@ namespace RWC { opts.options.noEmitOnError = false; }); - let tsconfigFile: IOLogFile; runWithIOLog(ioLog, oldIO => { let fileNames = opts.fileNames; - tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined); + const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined); if (tsconfigFile) { const tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path); tsconfigFiles.push({ unitName: tsconfigFile.path, content: tsconfigFileContents.content }); @@ -156,11 +155,6 @@ namespace RWC { compilerResult = output.result; }); - if (!tsconfigFile) { - const files = inputFiles.map(f => Playback.sanitizeTestFilePath(f.unitName)); - Harness.IO.writeFile(`internal/cases/rwc/${baseName}/read/tsconfig.json`, JSON.stringify({ compilerOptions, files })); - } - function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile { const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)); let content: string; From d2771a8e765221dd94033b576df037152962dea2 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 27 Oct 2017 14:34:40 -0700 Subject: [PATCH 3/4] Improve regex for tsconfig test --- src/harness/loggedIO.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index ff23458d284..888ee2fe2e1 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -262,7 +262,7 @@ namespace Playback { }; function generateTsconfig(newLog: IOLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } { - if (newLog.filesRead.some(file => /tsconfig.json$/.test(file.path))) { + if (newLog.filesRead.some(file => /tsconfig.+json$/.test(file.path))) { return; } const files = []; From c5b199014cdfb72b1741f545d6f44695abb8a428 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 30 Oct 2017 10:20:11 -0700 Subject: [PATCH 4/4] Use Harness.isDefaultLibraryFile to detect lib.d.ts --- src/harness/loggedIO.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 888ee2fe2e1..55be4068e83 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -268,7 +268,7 @@ namespace Playback { const files = []; for (const file of newLog.filesRead) { if (file.result.contentsPath && - !/lib\.d\.ts$/.test(file.result.contentsPath) && + Harness.isDefaultLibraryFile(file.result.contentsPath) && /\.[tj]s$/.test(file.result.contentsPath)) { files.push(file.result.contentsPath); }