From 421990ed8199caa1b3edcd7ef0b98acb6fc18611 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 26 Aug 2015 18:14:38 -0700 Subject: [PATCH 1/4] Revert "Address CR" This reverts commit 8a4c56bb761256906ec7b2af4f342d7eb8c2a094. --- src/harness/harness.ts | 10 +++++++++- src/harness/rwcRunner.ts | 11 +++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 5cde3ad3647d5..097340082e356 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1415,7 +1415,15 @@ module Harness { assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName); }); - assert.equal(totalErrorsReported, diagnostics.length, "total number of errors"); + let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => { + return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName)); + }); + + let numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => { + // Count an error generated from tests262-harness folder.This should only apply for test262 + return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; + }); + return minimalDiagnosticsToString(diagnostics) + Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n"); } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index cf748c3070b53..ea6f7b7ebb185 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -19,12 +19,6 @@ module RWC { } } - let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts"); - let defaultLib = { - unitName: ts.normalizePath(defaultLibPath), - content: Harness.IO.readFile(defaultLibPath) - }; - export function runRWCTest(jsonPath: string) { describe("Testing a RWC project: " + jsonPath, () => { let inputFiles: { unitName: string; content: string; }[] = []; @@ -72,6 +66,11 @@ module RWC { }); if (!useCustomLibraryFile) { + let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts"); + let defaultLib = { + unitName: ts.normalizePath(defaultLibPath), + content: Harness.IO.readFile(defaultLibPath) + }; inputFiles.push(defaultLib); } From 1d9465379819a32505e0a82448bee42652a2000d Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 26 Aug 2015 18:14:52 -0700 Subject: [PATCH 2/4] Revert "Read default lib from the local file system instead of log-array when do Not use custom library file" This reverts commit 735efee7ce8a5cd594c6b2e647aaf11ae2ddbc51. --- src/harness/harness.ts | 3 +++ src/harness/rwcRunner.ts | 12 +++--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 097340082e356..de67594885179 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1424,6 +1424,9 @@ module Harness { return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; }); + // Verify we didn't miss any errors in total + assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); + return minimalDiagnosticsToString(diagnostics) + Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n"); } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index ea6f7b7ebb185..d8b52ec2e396b 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -65,15 +65,6 @@ module RWC { opts.options.noEmitOnError = false; }); - if (!useCustomLibraryFile) { - let defaultLibPath = ts.sys.resolvePath("built/local/lib.d.ts"); - let defaultLib = { - unitName: ts.normalizePath(defaultLibPath), - content: Harness.IO.readFile(defaultLibPath) - }; - inputFiles.push(defaultLib); - } - runWithIOLog(ioLog, () => { harnessCompiler.reset(); @@ -105,6 +96,9 @@ module RWC { if (useCustomLibraryFile) { inputFiles.push(getHarnessCompilerInputUnit(fileRead.path)); } + else { + inputFiles.push(Harness.getDefaultLibraryFile()); + } } } } From af2a49992fa1d22a93766b8932829c9900a8075c Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 26 Aug 2015 18:54:25 -0700 Subject: [PATCH 3/4] Move RWC runner to use Harness.IO --- src/compiler/commandLineParser.ts | 6 +++--- src/harness/harness.ts | 17 +++++++++++++-- src/harness/loggedIO.ts | 34 +++++++++++++++++------------ src/harness/rwcRunner.ts | 36 +++++++++++++++++++------------ 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7a7ba34da87eb..cfad85d1e3320 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -237,13 +237,13 @@ namespace ts { } ]; - export function parseCommandLine(commandLine: string[]): ParsedCommandLine { + export function parseCommandLine(commandLine: string[], readFile?: (fileName: string) => string): ParsedCommandLine { let options: CompilerOptions = {}; let fileNames: string[] = []; let errors: Diagnostic[] = []; let shortOptionNames: Map = {}; let optionNameMap: Map = {}; - + forEach(optionDeclarations, option => { optionNameMap[option.name.toLowerCase()] = option; if (option.shortName) { @@ -313,7 +313,7 @@ namespace ts { } function parseResponseFile(fileName: string) { - let text = sys.readFile(fileName); + let text = readFile ? readFile(fileName): sys.readFile(fileName); if (!text) { errors.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, fileName)); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index de67594885179..78546f81c73ff 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -425,6 +425,9 @@ module Harness { listFiles(path: string, filter: RegExp, options?: { recursive?: boolean }): string[]; log(text: string): void; getMemoryUsage?(): number; + args(): string[]; + getExecutingFilePath(): string; + exit(exitCode?: number): void; } export var IO: IO; @@ -446,7 +449,10 @@ module Harness { } else { fso = {}; } - + + export const args = () => ts.sys.args; + export const getExecutingFilePath = () => ts.sys.getExecutingFilePath(); + export const exit = (exitCode: number) => ts.sys.exit(exitCode); export const resolvePath = (path: string) => ts.sys.resolvePath(path); export const getCurrentDirectory = () => ts.sys.getCurrentDirectory(); export const newLine = () => harnessNewLine; @@ -517,6 +523,9 @@ module Harness { export const getCurrentDirectory = () => ts.sys.getCurrentDirectory(); export const newLine = () => harnessNewLine; export const useCaseSensitiveFileNames = () => ts.sys.useCaseSensitiveFileNames; + export const args = () => ts.sys.args; + export const getExecutingFilePath = () => ts.sys.getExecutingFilePath(); + export const exit = (exitCode: number) => ts.sys.exit(exitCode); export const readFile: typeof IO.readFile = path => ts.sys.readFile(path); export const writeFile: typeof IO.writeFile = (path, content) => ts.sys.writeFile(path, content); @@ -589,6 +598,10 @@ module Harness { export const newLine = () => harnessNewLine; export const useCaseSensitiveFileNames = () => false; export const getCurrentDirectory = () => ""; + export const args = () => []; + export const getExecutingFilePath = () => ""; + export const exit = (exitCode: number) => {}; + let supportsCodePage = () => false; module Http { @@ -1804,7 +1817,7 @@ module Harness { } export function getDefaultLibraryFile(): { unitName: string, content: string } { - let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts"; + let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts"; return { unitName: libFile, content: IO.readFile(libFile) diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index db82a47d362c2..5a572e220b3ff 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -93,7 +93,7 @@ module Playback { return run; } - export interface PlaybackSystem extends ts.System, PlaybackControl { } + export interface PlaybackIO extends Harness.IO, PlaybackControl { } function createEmptyLog(): IOLog { return { @@ -223,8 +223,8 @@ module Playback { // console.log("Swallowed write operation during replay: " + name); } - export function wrapSystem(underlying: ts.System): PlaybackSystem { - let wrapper: PlaybackSystem = {}; + export function wrapIO(underlying: Harness.IO): PlaybackIO { + let wrapper: PlaybackIO = {}; initWrapper(wrapper, underlying); wrapper.startReplayFromFile = logFn => { @@ -239,18 +239,24 @@ module Playback { recordLog = undefined; } }; - - Object.defineProperty(wrapper, "args", { - get() { - if (replayLog !== undefined) { - return replayLog.arguments; - } else if (recordLog !== undefined) { - recordLog.arguments = underlying.args; - } - return underlying.args; + + wrapper.args = () => { + if (replayLog !== undefined) { + return replayLog.arguments; + } else if (recordLog !== undefined) { + recordLog.arguments = underlying.args(); } - }); - + return underlying.args(); + } + + wrapper.newLine = () => underlying.newLine(); + wrapper.useCaseSensitiveFileNames = () => underlying.useCaseSensitiveFileNames(); + wrapper.directoryName = (path): string => { throw new Error("NotSupported"); }; + wrapper.createDirectory = path => { throw new Error("NotSupported"); }; + wrapper.directoryExists = (path): boolean => { throw new Error("NotSupported"); }; + wrapper.deleteFile = path => { throw new Error("NotSupported"); }; + wrapper.listFiles = (path, filter, options): string[] => { throw new Error("NotSupported"); }; + wrapper.log = text => underlying.log(text); wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)( (path) => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path: path }), diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index d8b52ec2e396b..c89a8b1d91029 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -5,17 +5,17 @@ module RWC { function runWithIOLog(ioLog: IOLog, fn: () => void) { - let oldSys = ts.sys; + let oldIO = Harness.IO; - let wrappedSys = Playback.wrapSystem(ts.sys); - wrappedSys.startReplayFromData(ioLog); - ts.sys = wrappedSys; + let wrappedIO = Playback.wrapIO(oldIO); + wrappedIO.startReplayFromData(ioLog); + Harness.IO = wrappedIO; try { fn(); } finally { - wrappedSys.endReplay(); - ts.sys = oldSys; + wrappedIO.endReplay(); + Harness.IO = oldIO; } } @@ -32,7 +32,9 @@ module RWC { let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2]; let currentDirectory: string; let useCustomLibraryFile: boolean; - + + const defaultLibraryFile = Harness.getDefaultLibraryFile(); + after(() => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Therefore we have to clean out large objects after the test is done. @@ -57,7 +59,7 @@ module RWC { currentDirectory = ioLog.currentDirectory; useCustomLibraryFile = ioLog.useCustomLibraryFile; runWithIOLog(ioLog, () => { - opts = ts.parseCommandLine(ioLog.arguments); + opts = ts.parseCommandLine(ioLog.arguments, fileName => Harness.IO.readFile(fileName)); assert.equal(opts.errors.length, 0); // To provide test coverage of output javascript file, @@ -75,9 +77,10 @@ module RWC { // Add files to compilation let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath; + let prependDefaultLib = false; for (let fileRead of ioLog.filesRead) { // Check if the file is already added into the set of input files. - const resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path)); + const resolvedPath = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path)); let inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath)); if (!Harness.isLibraryFile(fileRead.path)) { @@ -97,11 +100,16 @@ module RWC { inputFiles.push(getHarnessCompilerInputUnit(fileRead.path)); } else { - inputFiles.push(Harness.getDefaultLibraryFile()); + // set the flag to put default library to the beginning of the list + prependDefaultLib = true; } } } } + + if (prependDefaultLib) { + inputFiles.unshift(defaultLibraryFile); + } // do not use lib since we already read it in above opts.options.noLib = true; @@ -118,13 +126,13 @@ module RWC { }); function getHarnessCompilerInputUnit(fileName: string) { - let unitName = ts.normalizeSlashes(ts.sys.resolvePath(fileName)); + let unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)); let content: string = null; try { - content = ts.sys.readFile(unitName); + content = Harness.IO.readFile(unitName); } catch (e) { - content = ts.sys.readFile(fileName); + content = Harness.IO.readFile(fileName); } return { unitName, content }; } @@ -187,7 +195,7 @@ module RWC { } return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) + - ts.sys.newLine + ts.sys.newLine + + Harness.IO.newLine() + Harness.IO.newLine() + Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors); }, false, baselineOpts); } From 8df7cbb515a67c091d07f4c741e45901a75cc7a4 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Thu, 27 Aug 2015 15:27:12 -0700 Subject: [PATCH 4/4] pass IO when getting default library instead of reading it to prevent memory leaks, do not count errors in library files twice --- src/harness/harness.ts | 21 ++++++++++++++------- src/harness/rwcRunner.ts | 16 ++++------------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 78546f81c73ff..10a87108d437c 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1340,8 +1340,8 @@ module Harness { export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) { diagnostics.sort(ts.compareDiagnostics); let outputLines: string[] = []; - // Count up all the errors we find so we don't miss any - let totalErrorsReported = 0; + // Count up all errors that were found in files other than lib.d.ts so we don't miss any + let totalErrorsReportedInNonLibraryFiles = 0; function outputErrorText(error: ts.Diagnostic) { let message = ts.flattenDiagnosticMessageText(error.messageText, Harness.IO.newLine()); @@ -1352,8 +1352,15 @@ module Harness { .filter(s => s.length > 0) .map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s); errLines.forEach(e => outputLines.push(e)); - - totalErrorsReported++; + + // do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics + // if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers) + // then they will be added twice thus triggering 'total errors' assertion with condition + // 'totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length + + if (!error.file || !isLibraryFile(error.file.fileName)) { + totalErrorsReportedInNonLibraryFiles++; + } } // Report global errors @@ -1438,7 +1445,7 @@ module Harness { }); // Verify we didn't miss any errors in total - assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); + assert.equal(totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors"); return minimalDiagnosticsToString(diagnostics) + Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n"); @@ -1816,11 +1823,11 @@ module Harness { return filePath.indexOf(Harness.libFolder) === 0; } - export function getDefaultLibraryFile(): { unitName: string, content: string } { + export function getDefaultLibraryFile(io: Harness.IO): { unitName: string, content: string } { let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "lib.d.ts"; return { unitName: libFile, - content: IO.readFile(libFile) + content: io.readFile(libFile) }; } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index c89a8b1d91029..a1aaeed3d553b 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -4,7 +4,7 @@ /// module RWC { - function runWithIOLog(ioLog: IOLog, fn: () => void) { + function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) { let oldIO = Harness.IO; let wrappedIO = Playback.wrapIO(oldIO); @@ -12,7 +12,7 @@ module RWC { Harness.IO = wrappedIO; try { - fn(); + fn(oldIO); } finally { wrappedIO.endReplay(); Harness.IO = oldIO; @@ -32,9 +32,6 @@ module RWC { let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2]; let currentDirectory: string; let useCustomLibraryFile: boolean; - - const defaultLibraryFile = Harness.getDefaultLibraryFile(); - after(() => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Therefore we have to clean out large objects after the test is done. @@ -67,7 +64,7 @@ module RWC { opts.options.noEmitOnError = false; }); - runWithIOLog(ioLog, () => { + runWithIOLog(ioLog, oldIO => { harnessCompiler.reset(); // Load the files @@ -77,7 +74,6 @@ module RWC { // Add files to compilation let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath; - let prependDefaultLib = false; for (let fileRead of ioLog.filesRead) { // Check if the file is already added into the set of input files. const resolvedPath = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path)); @@ -101,15 +97,11 @@ module RWC { } else { // set the flag to put default library to the beginning of the list - prependDefaultLib = true; + inputFiles.unshift(Harness.getDefaultLibraryFile(oldIO)); } } } } - - if (prependDefaultLib) { - inputFiles.unshift(defaultLibraryFile); - } // do not use lib since we already read it in above opts.options.noLib = true;