From 813f0e75e27c9fbba43f2bf3950bed836147a99a Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 9 Sep 2014 14:15:06 -0700 Subject: [PATCH] Build the declaration files generated in the rwc run to make sure there arent any errors --- src/harness/compilerRunner.ts | 69 ++++++--------------------- src/harness/harness.ts | 87 +++++++++++++++++++++++++++++++---- src/harness/rwcRunner.ts | 32 +++++++++++-- 3 files changed, 120 insertions(+), 68 deletions(-) diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 60da87b1dfc..e6d171a9780 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -61,9 +61,11 @@ class CompilerBaselineRunner extends RunnerBase { var otherFiles: { unitName: string; content: string }[]; var harnessCompiler: Harness.Compiler.HarnessCompiler; - var declToBeCompiled: { unitName: string; content: string }[] = []; - var declOtherFiles: { unitName: string; content: string }[] = []; - var declResult: Harness.Compiler.CompilerResult; + var declFileCompilationResult: { + declInputFiles: { unitName: string; content: string }[]; + declOtherFiles: { unitName: string; content: string }[]; + declResult: Harness.Compiler.CompilerResult; + }; var createNewInstance = false; @@ -147,9 +149,7 @@ class CompilerBaselineRunner extends RunnerBase { toBeCompiled = undefined; otherFiles = undefined; harnessCompiler = undefined; - declToBeCompiled = undefined; - declOtherFiles = undefined; - declResult = undefined; + declFileCompilationResult = undefined; }); function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string { @@ -176,61 +176,18 @@ class CompilerBaselineRunner extends RunnerBase { // Source maps? it('Correct sourcemap content for ' + fileName, () => { - if (result.sourceMapRecord) { + if (options.sourceMap) { Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.ts$/, '.sourcemap.txt'), () => { - return result.sourceMapRecord; + return result.getSourceMapRecord(); }); } }); // Compile .d.ts files it('Correct compiler generated.d.ts for ' + fileName, () => { - if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) { - throw new Error('There were no errors and declFiles generated did not match number of js files generated'); - } - - // if the .d.ts is non-empty, confirm it compiles correctly as well - if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) { - function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) { - if (Harness.Compiler.isDTS(file.unitName)) { - dtsFiles.push(file); - } - else { - var declFile = findResultCodeFile(file.unitName); - // Look if there is --out file corresponding to this ts file - if (!declFile && options.out) { - declFile = findResultCodeFile(options.out); - if (!declFile || findUnit(declFile.fileName, declToBeCompiled) || - findUnit(declFile.fileName, declOtherFiles)) { - return; - } - } - - if (declFile) { - dtsFiles.push({ unitName: declFile.fileName, content: declFile.code }); - return; - } - } - - function findResultCodeFile(fileName: string) { - return ts.forEach(result.declFilesCode, - declFile => declFile.fileName === (fileName.substr(0, fileName.length - ".ts".length) + ".d.ts") - ? declFile : undefined); - } - - function findUnit(fileName: string, units: { unitName: string; content: string }[]) { - return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined); - } - } - - ts.forEach(toBeCompiled, file => addDtsFile(file, declToBeCompiled)); - ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles)); - harnessCompiler.compileFiles(declToBeCompiled, declOtherFiles, function (compileResult) { - declResult = compileResult; - }, function (settings) { - harnessCompiler.setCompilerSettings(tcSettings); - }); - } + declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { + harnessCompiler.setCompilerSettings(tcSettings); + }, options); }); @@ -270,10 +227,10 @@ class CompilerBaselineRunner extends RunnerBase { } } - if (declResult && declResult.errors.length) { + if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) { jsCode += '\r\n\r\n//// [DtsFileErrors]\r\n'; jsCode += '\r\n\r\n'; - jsCode += getErrorBaseline(declToBeCompiled, declOtherFiles, declResult); + jsCode += getErrorBaseline(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles, declFileCompilationResult.declResult); } if (jsCode.length > 0) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 5ee3139d8f7..72bfa348a69 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -768,15 +768,81 @@ module Harness { }); this.lastErrors = errors; - var result = new CompilerResult(fileOutputs, errors, []); - // Covert the source Map data into the baseline - result.updateSourceMapRecord(program, emitResult ? emitResult.sourceMaps : undefined); + var result = new CompilerResult(fileOutputs, errors, program, sys.getCurrentDirectory(), emitResult ? emitResult.sourceMaps : undefined); onComplete(result, checker); // reset what newline means in case the last test changed it sys.newLine = '\r\n'; return options; } + + public compileDeclarationFiles(inputFiles: { unitName: string; content: string; }[], + otherFiles: { unitName: string; content: string; }[], + result: CompilerResult, + settingsCallback?: (settings: ts.CompilerOptions) => void, + options?: ts.CompilerOptions) { + if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) { + throw new Error('There were no errors and declFiles generated did not match number of js files generated'); + } + + // if the .d.ts is non-empty, confirm it compiles correctly as well + if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) { + var declInputFiles: { unitName: string; content: string }[] = []; + var declOtherFiles: { unitName: string; content: string }[] = []; + var declResult: Harness.Compiler.CompilerResult; + + ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles)); + ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles)); + this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) { + declResult = compileResult; + }, settingsCallback, options); + + return { declInputFiles: declInputFiles, declOtherFiles: declOtherFiles, declResult: declResult }; + } + + function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) { + if (isDTS(file.unitName)) { + dtsFiles.push(file); + } + else if (isTS(file.unitName)) { + var declFile = findResultCodeFile(file.unitName); + if (!findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) { + dtsFiles.push({ unitName: declFile.fileName, content: declFile.code }); + } + } + + function findResultCodeFile(fileName: string) { + var dTsFileName = ts.forEach(result.program.getSourceFiles(), sourceFile => { + if (sourceFile.filename === fileName) { + // Is this file going to be emitted separately + var sourceFileName: string; + if (ts.isExternalModule(sourceFile) || !options.out) { + if (options.outDir) { + var sourceFilePath = ts.getNormalizedPathFromPathCompoments(ts.getNormalizedPathComponents(sourceFile.filename, result.currentDirectoryForProgram)); + sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), ""); + sourceFileName = ts.combinePaths(options.outDir, sourceFilePath); + } + else { + sourceFileName = sourceFile.filename; + } + } + else { + // Goes to single --out file + sourceFileName = options.out; + } + + return ts.getModuleNameFromFilename(sourceFileName) + ".d.ts"; + } + }); + + return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined); + } + + function findUnit(fileName: string, units: { unitName: string; content: string; }[]) { + return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined); + } + } + } } export function getMinimalDiagnostic(err: ts.Diagnostic): HarnessDiagnostic { @@ -956,6 +1022,10 @@ module Harness { return str.substr(str.length - end.length) === end; } + export function isTS(fileName: string) { + return stringEndsWith(fileName, '.ts'); + } + export function isDTS(fileName: string) { return stringEndsWith(fileName, '.d.ts'); } @@ -974,10 +1044,10 @@ module Harness { public errors: HarnessDiagnostic[] = []; public declFilesCode: GeneratedFile[] = []; public sourceMaps: GeneratedFile[] = []; - public sourceMapRecord: string; /** @param fileResults an array of strings for the fileName and an ITextWriter with its code */ - constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], sourceMapRecordLines: string[]) { + constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], public program: ts.Program, + public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) { var lines: string[] = []; fileResults.forEach(emittedFile => { @@ -995,12 +1065,11 @@ module Harness { }); this.errors = errors; - this.sourceMapRecord = sourceMapRecordLines.join('\r\n'); } - public updateSourceMapRecord(program: ts.Program, sourceMapData: ts.SourceMapData[]) { - if (sourceMapData) { - this.sourceMapRecord = Harness.SourceMapRecoder.getSourceMapRecord(sourceMapData, program, this.files); + public getSourceMapRecord() { + if (this.sourceMapData) { + return Harness.SourceMapRecoder.getSourceMapRecord(this.sourceMapData, this.program, this.files); } } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 93d003bf4db..2166de0e956 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -62,6 +62,7 @@ module RWC { var inputFiles: { unitName: string; content: string; }[] = []; var otherFiles: { unitName: string; content: string; }[] = []; var compilerResult: Harness.Compiler.CompilerResult; + var compilerOptions: ts.CompilerOptions; it('can compile', () => { runWithIOLog(ioLog, () => { harnessCompiler.reset(); @@ -92,7 +93,7 @@ module RWC { opts.options.noLib = true; // Emit the results - harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => { + compilerOptions = harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => { compilerResult = compileResult; }, /*settingsCallback*/ undefined, opts.options); }); @@ -113,6 +114,17 @@ module RWC { var baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc' }; var baseName = /(.*)\/(.*).json/.exec(Harness.Path.switchToForwardSlashes(jsonPath))[2]; + // Compile .d.ts files + var declFileCompilationResult: { + declInputFiles: { unitName: string; content: string }[]; + declOtherFiles: { unitName: string; content: string }[]; + declResult: Harness.Compiler.CompilerResult; + }; + it('Correct compiler generated.d.ts', () => { + declFileCompilationResult = harnessCompiler.compileDeclarationFiles(inputFiles, otherFiles, compilerResult, /*settingscallback*/ undefined, compilerOptions); + }); + + it('has the expected emitted code', () => { Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => { return collateOutputs(compilerResult.files, s => SyntacticCleaner.clean(s)); @@ -139,9 +151,9 @@ module RWC { }); it('has correct source map record', () => { - if (compilerResult.sourceMapRecord) { + if (compilerOptions.sourceMap) { Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => { - return compilerResult.sourceMapRecord; + return compilerResult.getSourceMapRecord(); }, false, baselineOpts); } }); @@ -158,6 +170,20 @@ module RWC { }, false, baselineOpts); }); + it('has no errors in generated declaration files', () => { + if (compilerOptions.declaration && !compilerResult.errors.length) { + Harness.Baseline.runBaseline('has no errors in generated declaration files', baseName + '.dts.errors.txt', () => { + if (declFileCompilationResult.declResult.errors.length === 0) { + return null; + } + + return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) + + sys.newLine + sys.newLine + + Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors); + }, false, baselineOpts); + } + }); + // TODO: Type baselines (need to refactor out from compilerRunner) } }